123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434 |
- ####################################################################################
- # Help function for building the NICE library and its sub-libraries.
- # Inspired by the OpenCV cmake build system.
- #
- # Author: Johannes Ruehle
- # Date: 2014-02-17
- #
- ####################################################################################
- # get a list of all sub directories in curdir
- MACRO(SUBDIRLIST result curdir)
- FILE(GLOB children RELATIVE ${curdir} ${curdir}/*)
- SET(dirlist "")
- FOREACH(child ${children})
- IF(IS_DIRECTORY ${curdir}/${child})
- SET(dirlist ${dirlist} ${child})
- ENDIF()
- ENDFOREACH()
- SET(${result} ${dirlist})
- ENDMACRO()
- # get a list of all sub directories in curdir (recursive)
- # this function lists only the directories that contain relevant files
- MACRO(SUBDIRREC result curdir)
- FILE(GLOB_RECURSE children RELATIVE ${curdir} ${curdir}/*.c ${curdir}/*.cpp ${curdir}/*.h ${curdir}/*.tcc ${curdir}/Makefile)
- SET(dirlist "")
- FOREACH(child ${children})
- #message(STATUS ${child})
- GET_FILENAME_COMPONENT(to_add ${curdir}/${child} PATH)
- FILE(RELATIVE_PATH to_add_rel ${curdir} ${to_add})
- IF(IS_DIRECTORY ${curdir}/${to_add_rel})
- SET(dirlist ${dirlist} ${to_add_rel})
- ENDIF()
- ENDFOREACH()
- IF(NOT "${dirlist}" MATCHES "")
- LIST(REMOVE_DUPLICATES dirlist)
- ENDIF()
- SET(${result} ${dirlist})
- ENDMACRO()
- # update internal and external dependencies
- #
- # ${internal_deps} contains all the folders that are
- # "allowed". files in folders that are not part of this list will
- # _NOT_ be built.
- # the relevant libdepend.inc files are parsed until no more changes
- # are made
- macro(UPDATE_NICE_DEPENDENCIES)
- set(update_dependencies ON)
- while(update_dependencies)
- message(STATUS "updating dependencies...")
- set(update_dependencies OFF)
- set(remove_these "")
- foreach(_curDep ${internal_deps})
- nice_get_real_path(_curDepPath ${NICE_CURR_DIR}/${_curDep})
- if(EXISTS ${_curDepPath}/libdepend.inc)
- #message(STATUS "Reading dependencies for ${_curDep}...")
- file(STRINGS ${_curDepPath}/libdepend.inc _dependencies REGEX "^[$][(]call( )+PKG_DEPEND_INT,")
- file(STRINGS ${_curDepPath}/libdepend.inc _extdependencies REGEX "^[$][(]call( )+PKG_DEPEND_EXT,")
- #message(STATUS "Deps: ${_dependencies}")
- #message(STATUS "Deps: ${_extdependencies}")
- list(LENGTH _dependencies _depCount)
- if(${_depCount} GREATER 0)
- foreach(_innerDep ${_dependencies})
- string(REGEX REPLACE "^[$][(]call( )+PKG_DEPEND_INT,(.*)[)].*$" "\\2" _innerDepName "${_innerDep}")
- string(REGEX REPLACE "(.*)/$" "\\1" _innerDepName ${_innerDepName})
- #message(STATUS "Inner dep: ${_innerDepName} (command: ${_innerDep})")
- list(FIND internal_deps "${_innerDepName}" _innerDepFound)
- if(${_innerDepFound} LESS 0)
- message(STATUS "Removing ${_curDep} from build because ${_innerDepName} is missing")
- set(remove_these ${remove_these} ${_curDep})
- set(update_dependencies ON)
- endif()
- endforeach()
- endif()
- list(LENGTH _extdependencies _extdepCount)
- if(${_extdepCount} GREATER 0)
- foreach(_extDep ${_extdependencies})
- string(REGEX REPLACE "^[$][(]call( )+PKG_DEPEND_EXT,(.*)[)].*$" "\\2" _extDepName "${_extDep}")
- string(REGEX REPLACE "(.*)/$" "\\1" _extDepName ${_extDepName})
- #message(STATUS "External dep: ${_extDepName} (command: ${_extDep})")
- list(FIND external_deps "${_extDepName}" _extDepFound)
- if(${_extDepFound} LESS 0)
- message(STATUS "Removing ${_curDep} from build because ${_extDepName} (external) is missing")
- set(remove_these ${remove_these} ${_curDep})
- set(update_dependencies ON)
- endif()
- endforeach()
- endif()
- endif()
- endforeach()
- foreach(_toRemove ${remove_these})
- message(STATUS "Checking subdirectories for ${_toRemove}")
- foreach(_checkDep ${internal_deps})
- if(${_checkDep} MATCHES "^${_toRemove}.*$")
- message(STATUS "Removing ${_checkDep}...")
- LIST(REMOVE_ITEM internal_deps ${_checkDep})
- endif()
- endforeach()
- endforeach()
- endwhile()
- message(STATUS "Done.")
- endmacro()
- # get absolute path with symlinks resolved
- macro(nice_get_real_path VAR PATHSTR)
- if(CMAKE_VERSION VERSION_LESS 2.8)
- get_filename_component(${VAR} "${PATHSTR}" ABSOLUTE)
- else()
- get_filename_component(${VAR} "${PATHSTR}" REALPATH)
- endif()
- endmacro()
- # get the source files and store them in the variables:
- # ${nice_${the_library}_TESTFILES_SRC} (unit test cpps)
- # ${nice_${the_library}_PROGFILES_SRC} (progs cpps)
- # ${nice_${the_library}_SRC} (library cpp and tcc excluding progs and unit test cpps)
- # ${nice_${the_library}_HDR} (all library header files)
- #
- # Two methods for obtaining the source files:
- # 1) recursively scan all subdirectories
- # cmake variable NICE_SOURCEFILES_FIND_GLOBALLYRECURSIVE has to be set and to be true (1).
- # Notes:
- # - To exclude certain source files from appending in the source var, use the file black listing
- # in a file "list_exclude_from_build.cmake" by adding it to the variable "list_exclude_from_build_SRC"
- # in that file.
- # - All *moc_* files will be removed from the source file list variables
- # 2) use the given *.cmake files that define variables containing the source and header files to be used for build:
- # corefiles.cmake (Source files for Library build)
- # progfiles.cmake (source files for progam builds)
- # testfiles.cmake (source files for unit test builds)
- #
- #
- #Note: Variable ${the_library} contains the current (sub-)library name that called this function,
- # e.g. ${the_library} == 'core', ${the_library}=='vislearning'
- #
- # Author: Johannes Ruehle
- # Date: 2014-02-17
- #
- macro(nice_get_source_files)
- if(NICE_SOURCEFILES_FIND_GLOBALLYRECURSIVE)
- message(STATUS "Recursively scanning for source files")
- #include local file containing a list of files to be excluded from compilation
- #list is in variable list_exclude_from_build_SRC
- if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/list_exclude_from_build.cmake")
- #message(STATUS "exclude list found")
- include(list_exclude_from_build.cmake)
- message(STATUS "exclude list:${list_exclude_from_build_SRC}")
- endif()
- ### Get all unit test cpp files recursively
- set(nice_${the_library}_TESTFILES_SRC "")
- set(nice_${the_library}_PROGFILES_SRC "")
- set(nice_${the_library}_MEXFILES_SRC "")
- set(nice_${the_library}_SRC"")
-
- #message(STATUS "CMAKE_CURRENT_SOURCE_DIR: ${CMAKE_CURRENT_SOURCE_DIR}")
- file(GLOB_RECURSE list_tmp1 RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" *.cpp *.tcc *.c *.C)
- #message(STATUS "list_tmp1: ${list_tmp1}")
- foreach( t_SrcFile ${list_tmp1})
- get_filename_component(t_SrcPath ${t_SrcFile} PATH)
- set(t_SrcPath ${the_library}/${t_SrcPath})
- string(REGEX REPLACE "(.*)/+$" "\\1" t_SrcPath ${t_SrcPath})
- list(FIND internal_deps ${t_SrcPath} dep_index)
- if(NOT ${dep_index} LESS 0)
- if( NOT t_SrcFile MATCHES "moc_" )
- if( t_SrcFile MATCHES "tests/" )
- #message(STATUS "test: ${t_SrcFile}")
- LIST(APPEND nice_${the_library}_TESTFILES_SRC ${t_SrcFile})
- elseif( t_SrcFile MATCHES "progs/" )
- #message(STATUS "prog: ${t_SrcFile}")
- LIST(APPEND nice_${the_library}_PROGFILES_SRC ${t_SrcFile})
- elseif( t_SrcFile MATCHES "Mex[.]" )
- message(STATUS "mex: ${t_SrcFile}")
- LIST(APPEND nice_${the_library}_MEXFILES_SRC ${t_SrcFile})
- else()
- LIST(APPEND nice_${the_library}_SRC ${t_SrcFile})
- endif()
- endif()
- else()
- message(STATUS "Not building ${t_SrcFile} because ${t_SrcPath} is excluded (dependencies)")
- endif()
- endforeach()
- ### Get all cpp and tcc files recursively but exclude progs and unit test files
- #file(GLOB_RECURSE nice_${the_library}_SRC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp *.tcc)
- #filter out source files listed on the blacklist to be excluded from build
- if(list_exclude_from_build_SRC)
- list( REMOVE_ITEM nice_${the_library}_SRC ${list_exclude_from_build_SRC} )
- list( REMOVE_ITEM nice_${the_library}_TESTFILES_SRC ${list_exclude_from_build_SRC} )
- endif()
- #message(STATUS "globallyrecusive_tests: ${nice_${the_library}_TESTFILES_SRC}")
- #message(STATUS "globallyrecusive_progs: ${nice_${the_library}_PROGFILES_SRC}")
- ### Get all header files recursively...
- # ... but filter the headers according to their "type", meaning whether they are part of a unit test, a prog, or a mex.
- # That means for example, that if you DO NOT WANT to build all progs in ./progs/ directories, all header files inside ./progs/ direcories
- # should be excluded and not be consided in the build. The same example applies to unit tests (./tests/) and mex filex.
- # The reason is: The filter mechanism described above was also appied to source code files. So, we need to take care to have
- # the source and header files synchronized, so that we avoid using only the header file of a class, but not its source code implementation file
- # which might lead to "undefined references" error. Especially in case of header file class definitions using Qt and an Q_OBJECT
- # definition, a header file is moc'ed but but will generate "undefined references" if the source code file is not available.
- file(GLOB_RECURSE list_tmp2 RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.h)
- set(nice_${the_library}_HDR "")
- foreach( t_HdrFile ${list_tmp2})
- get_filename_component(t_HdrPath ${t_HdrFile} PATH)
- set(t_HdrPath ${the_library}/${t_HdrPath})
- string(REGEX REPLACE "(.*)/+$" "\\1" t_HdrPath ${t_HdrPath})
- #list(FIND internal_deps ${t_HdrPath} dep_index)
- if( NOT t_HdrFile MATCHES "moc_" )
- if( t_HdrFile MATCHES "tests/" )
- if(BUILD_UNITTESTS)
- LIST(APPEND nice_${the_library}_HDR ${t_HdrFile})
- endif()
- elseif( t_HdrFile MATCHES "progs/" )
- if(BUILD_PROGRAMS)
- #message(STATUS "prog: ${t_HdrFile}")
- LIST(APPEND nice_${the_library}_HDR ${t_HdrFile})
- endif()
- elseif( t_HdrFile MATCHES "Mex[.]" )
- if(WITH_MEX)
- #message(STATUS "mex: ${t_HdrFile}")
- LIST(APPEND nice_${the_library}_HDR ${t_HdrFile})
- endif()
- else()
- LIST(APPEND nice_${the_library}_HDR ${t_HdrFile})
- endif()
- endif()
- endforeach()
- #message(STATUS "header files found: ${nice_${the_library}_HDR}")
- else()
- message(STATUS "Using source files from file lists (*.cmake)")
- #define variable nice_<libname>_HDR and nice_<libname>_SRC for library header and source files (don't include progs and test source files here)
- include( corefiles.cmake)
- #define variable nice_<libname>_PROGFILES_HDR and nice_<libname>_PROGFILES_SRC for program header and source files (don't include library and test source files here)
- include( progfiles.cmake)
- #define variable nice_<libname>_TESTFILES_HDR and nice_<libname>_TESTFILES_SRC for unit test header and source files (don't include library and progs source files here)
- include( testfiles.cmake)
- endif()
- endmacro()
- macro(nice_build_library)
- ADD_LIBRARY("nice_${the_library}" ${nice_${the_library}_HDR} ${nice_${the_library}_SRC})
- LIST(LENGTH nice_${the_library}_LINKING_DEPENDENCIES dependency_count)
- SET(tmp_dependencies "")
- IF(dependency_count GREATER 0)
- FOREACH(tmp_dependency ${nice_${the_library}_LINKING_DEPENDENCIES})
- IF("${tmp_dependency}" MATCHES "^nice_")
- STRING(REGEX REPLACE "^nice_(.*)" "\\1" tmp_dependency_nice ${tmp_dependency})
- LIST(FIND internal_deps ${tmp_dependency_nice} dep_found)
- IF(NOT ${dep_found} LESS 0)
- SET(tmp_dependencies ${tmp_dependencies} ${tmp_dependency})
- ELSE()
- MESSAGE(STATUS "${the_library} wants to link to NICE module: ${tmp_dependency_nice}, but it is not available.")
- ENDIF()
- ELSE()
- SET(tmp_dependencies ${tmp_dependencies} ${tmp_dependency})
- ENDIF()
- ENDFOREACH()
- ENDIF()
- SET(nice_${the_library}_LINKING_DEPENDENCIES ${tmp_dependencies})
- TARGET_LINK_LIBRARIES("nice_${the_library}" ${nice_${the_library}_LINKING_DEPENDENCIES})
- #TARGET_LINK_LIBRARIES("nice_${the_library}" ${nice_${the_library}_LINKING_DEPENDENCIES} ${Boost_LIBRARIES} ${OPENGL_LIBRARY} ${GLUT_LIBRARY} ${QT_LIBRARIES})
- SET_PROPERTY(TARGET "nice_${the_library}" PROPERTY FOLDER "library")
- INSTALL(TARGETS "nice_${the_library}" DESTINATION lib EXPORT "nice_${the_library}-exports")
- INSTALL(EXPORT "nice_${the_library}-exports" DESTINATION lib/exports)
- install(DIRECTORY ./ DESTINATION "include/${the_library}"
- FILES_MATCHING
- PATTERN "*.h"
- PATTERN "*.tcc"
- PATTERN ".git" EXCLUDE)
- configure_file( ../cmake/niceConfig.cmake.in "${PROJECT_BINARY_DIR}/lib/nice_${the_library}Config.cmake" )
- endmacro()
- # Create builds for all programs that are in the subvariable ${nice_${the_library}_PROGFILES_SRC}
- # and build them into "bin/${the_library}"
- #
- # Variable BUILD_PROGRAMS has to be set and true to invoke progam build. The Variable is controllable
- # via the main CMakeLists.txt file (or ccmake)
- #
- #Note: Variable ${the_library} contains the current (sub-)library name that called this function,
- # e.g. ${the_library} == 'core', ${the_library}=='vislearning'
- # using subvariables ${nice_${the_library}_PROGFILES_SRC}
- #
- # Author: Johannes Ruehle
- # Date: 2014-02-17
- #
- macro(nice_add_progs)
- if(BUILD_PROGRAMS)
- message(STATUS "building progs:")
-
- foreach(__progcpp ${nice_${the_library}_PROGFILES_SRC})
- get_filename_component(__progname ${__progcpp} NAME_WE )
- #message(STATUS "progname: ${__progname} ${__progcpp}")
-
- set(prog_target_name "${the_library}_${__progname}")
- ADD_EXECUTABLE( ${prog_target_name} ${__progcpp})
- TARGET_LINK_LIBRARIES(${prog_target_name} "nice_${the_library}")
- SET_TARGET_PROPERTIES(${prog_target_name} PROPERTIES OUTPUT_NAME "${__progname}")
-
- INSTALL(TARGETS ${prog_target_name} DESTINATION "bin/${the_library}")
-
- SET_PROPERTY(TARGET ${prog_target_name} PROPERTY FOLDER "programs/${the_library}")
-
- endforeach()
- endif()
- endmacro()
- # Add mex output
- macro(nice_add_mexes)
- if(WITH_MEX)
- message(STATUS "building mexes:")
-
- foreach(__mexcpp ${nice_${the_library}_MEXFILES_SRC})
- get_filename_component(__mexname ${__mexcpp} NAME_WE )
- message(STATUS "mexname: ${__mexname} ${__mexcpp}")
-
- set(mex_target_name "${the_library}_${__mexname}")
- ADD_LIBRARY("${mex_target_name}" SHARED ${__mexcpp})
- TARGET_LINK_LIBRARIES(${mex_target_name} "nice_${the_library}")
- SET_TARGET_PROPERTIES(${mex_target_name} PROPERTIES OUTPUT_NAME "${__mexname}")
- SET_TARGET_PROPERTIES(${mex_target_name} PROPERTIES SUFFIX "${MEX_ENDING}")
- SET_TARGET_PROPERTIES(${mex_target_name} PROPERTIES PREFIX "")
-
- INSTALL(TARGETS ${mex_target_name} DESTINATION "bin/${the_library}")
-
- SET_PROPERTY(TARGET ${mex_target_name} PROPERTY FOLDER "programs/${the_library}")
-
- endforeach()
- endif()
- endmacro()
- # Create unit test (using library CppUnitTest) for all cpp files in the subvariable ${nice_${the_library}_TESTFILES_SRC}
- # and build them into "bin/${the_library}"
- #
- # Variable BUILD_UNITTESTS has to be set and true to invoke unit test building.
- # The Variable is controllable via the main CMakeLists.txt file (or ccmake)
- #
- #Note: Variable ${the_library} contains the current (sub-)library name that called this function,
- # e.g. ${the_library} == 'core', ${the_library}=='vislearning'
- #
- # Author: Johannes Ruehle
- # Date: 2014-02-17
- #
- macro(nice_add_unittests)
- if(BUILD_UNITTESTS)
- INCLUDE_DIRECTORIES(${CPPUNIT_INCLUDE_DIR})
- message(STATUS "building tests:")
- foreach(__testcpp ${nice_${the_library}_TESTFILES_SRC})
- get_filename_component(__testname ${__testcpp} NAME_WE )
- nice_get_real_path(__testname_abspath ${__testcpp})
- get_filename_component(__testname_dir ${__testname_abspath} PATH)
- message(STATUS "unittest: ${__testname} ${__testcpp}")
-
- ADD_EXECUTABLE( ${__testname} ../templates/cppUnitTestRunner.cpp ${__testcpp})
- TARGET_LINK_LIBRARIES(${__testname} "nice_${the_library}" ${CPPUNIT_LIBRARIES} )
- INSTALL(TARGETS ${__testname} DESTINATION "tests/${the_library}")
- SET_PROPERTY(TARGET ${__testname} PROPERTY FOLDER "unittests/${the_library}")
- ADD_TEST(NAME ${__testname} WORKING_DIRECTORY ${__testname_dir} COMMAND ${__testname})
- endforeach()
- endif()
- endmacro()
- # Provides an option that the user can optionally select.
- # Can accept condition to control when option is available for user.
- # Usage:
- # option(<option_variable> "help string describing the option" <initial value or boolean expression> [IF <condition>])
- #
- # CopyRight: OpenCV
- macro(NICE_OPTION variable description value)
- set(__value ${value})
- set(__condition "")
- set(__varname "__value")
- foreach(arg ${ARGN})
- if(arg STREQUAL "IF" OR arg STREQUAL "if")
- set(__varname "__condition")
- else()
- list(APPEND ${__varname} ${arg})
- endif()
- endforeach()
- unset(__varname)
- if("${__condition}" STREQUAL "")
- set(__condition 2 GREATER 1)
- endif()
- if(${__condition})
- if("${__value}" MATCHES ";")
- if(${__value})
- option(${variable} "${description}" ON)
- else()
- option(${variable} "${description}" OFF)
- endif()
- elseif(DEFINED ${__value})
- if(${__value})
- option(${variable} "${description}" ON)
- else()
- option(${variable} "${description}" OFF)
- endif()
- else()
- option(${variable} "${description}" ${__value})
- endif()
- else()
- unset(${variable} CACHE)
- endif()
- unset(__condition)
- unset(__value)
- endmacro()
|