############################################################################# # # ViSP, open source Visual Servoing Platform software. # Copyright (C) 2005 - 2023 by Inria. All rights reserved. # # This software is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # See the file LICENSE.txt at the root directory of this source # distribution for additional information about the GNU GPL. # # For using ViSP with software that can not be combined with the GNU # GPL, please contact Inria about acquiring a ViSP Professional # Edition License. # # See https://visp.inria.fr for more information. # # This software was developed at: # Inria Rennes - Bretagne Atlantique # Campus Universitaire de Beaulieu # 35042 Rennes Cedex # France # # If you have questions regarding the use of this file, please contact # Inria at visp@inria.fr # # This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE # WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. # ############################################################################# # Local variables (set for each module): # # name - short name in lower case i.e. core # the_module - full name in lower case i.e. visp_core # Global variables: # # VISP_MODULE_${the_module}_LOCATION # VISP_MODULE_${the_module}_BINARY_DIR # VISP_MODULE_${the_module}_DESCRIPTION # VISP_MODULE_${the_module}_CLASS - PUBLIC|INTERNAL|BINDINGS # VISP_MODULE_${the_module}_HEADERS # VISP_MODULE_${the_module}_SOURCES # VISP_MODULE_${the_module}_DEPS - final flattened set of module dependencies # VISP_MODULE_${the_module}_DEPS_TO_LINK - differs from above for world build only # VISP_MODULE_${the_module}_DEPS_EXT - non-module dependencies # VISP_MODULE_${the_module}_REQ_DEPS # VISP_MODULE_${the_module}_OPT_DEPS # VISP_MODULE_${the_module}_PRIVATE_REQ_DEPS - private module deps that are not exposed in interface # VISP_MODULE_${the_module}_PRIVATE_OPT_DEPS - private module deps that are not exposed in interface # VISP_MODULE_${the_module}_CHILDREN - list of submodules for compound modules (cmake >= 2.8.8) # VISP_MODULE_${the_module}_WRAPPERS - list of wrappers supporting this module # HAVE_${the_module} - for fast check of module availability # To control the setup of the module you could also set: # the_description - text to be used as current module description # VISP_MODULE_TYPE - STATIC|SHARED - set to force override global settings for current module # BUILD_${the_module}_INIT - ON|OFF (default ON) - initial value for BUILD_${the_module} # VISP_MODULE_CHILDREN - list of submodules # The verbose template for ViSP module: # # vp_add_module(modname ) # vp_glob_module_sources(() # or glob them manually and vp_set_module_sources(...) # vp_module_include_directories() # vp_create_module() # # If module have no "extra" then you can define it in one line: # # vp_define_module(modname ) # clean flags for modules enabled on previous cmake run # this is necessary to correctly handle modules removal foreach(mod ${VISP_MODULES_BUILD} ${VISP_MODULES_DISABLED_USER} ${VISP_MODULES_DISABLED_AUTO} ${VISP_MODULES_DISABLED_FORCE}) if(HAVE_${mod}) unset(HAVE_${mod} CACHE) endif() unset(VISP_MODULE_${mod}_DEPS CACHE) unset(VISP_MODULE_${mod}_DEPS_EXT CACHE) unset(VISP_MODULE_${mod}_REQ_DEPS CACHE) unset(VISP_MODULE_${mod}_OPT_DEPS CACHE) unset(VISP_MODULE_${mod}_PRIVATE_REQ_DEPS CACHE) unset(VISP_MODULE_${mod}_PRIVATE_OPT_DEPS CACHE) unset(VISP_MODULE_${mod}_LINK_DEPS CACHE) unset(VISP_MODULE_${mod}_INC_DEPS CACHE) unset(VISP_MODULE_${mod}_SYSTEM_INC_DEPS CACHE) unset(VISP_MODULE_${mod}_WRAPPERS CACHE) endforeach() # clean modules info which needs to be recalculated set(VISP_MODULES_PUBLIC "" CACHE INTERNAL "List of ViSP modules marked for export") set(VISP_MODULES_BUILD "" CACHE INTERNAL "List of ViSP modules included into the build") set(VISP_MODULES_DISABLED_USER "" CACHE INTERNAL "List of ViSP modules explicitly disabled by user") set(VISP_MODULES_DISABLED_AUTO "" CACHE INTERNAL "List of ViSP modules implicitly disabled due to dependencies") set(VISP_MODULES_DISABLED_FORCE "" CACHE INTERNAL "List of ViSP modules which can not be build in current configuration") # adds dependencies to ViSP module # Usage: # add_dependencies(visp_ [REQUIRED] [] [OPTIONAL ]) # Notes: # * - can include full names of modules or full pathes to shared/static libraries or cmake targets macro(vp_add_dependencies full_modname) vp_debug_message("vp_add_dependencies(" ${full_modname} ${ARGN} ")") #we don't clean the dependencies here to allow this macro several times for every module foreach(d "REQUIRED" ${ARGN}) if(d STREQUAL "REQUIRED") set(__depsvar VISP_MODULE_${full_modname}_REQ_DEPS) elseif(d STREQUAL "OPTIONAL") set(__depsvar VISP_MODULE_${full_modname}_OPT_DEPS) elseif(d STREQUAL "PRIVATE_REQUIRED") set(__depsvar VISP_MODULE_${full_modname}_PRIVATE_REQ_DEPS) elseif(d STREQUAL "PRIVATE_OPTIONAL") set(__depsvar VISP_MODULE_${full_modname}_PRIVATE_OPT_DEPS) elseif(d STREQUAL "WRAP") set(__depsvar VISP_MODULE_${full_modname}_WRAPPERS) else() list(APPEND ${__depsvar} "${d}") endif() endforeach() unset(__depsvar) vp_list_unique(VISP_MODULE_${full_modname}_REQ_DEPS) vp_list_unique(VISP_MODULE_${full_modname}_OPT_DEPS) vp_list_unique(VISP_MODULE_${full_modname}_PRIVATE_REQ_DEPS) vp_list_unique(VISP_MODULE_${full_modname}_PRIVATE_OPT_DEPS) vp_list_unique(VISP_MODULE_${full_modname}_WRAPPERS) set(VISP_MODULE_${full_modname}_REQ_DEPS ${VISP_MODULE_${full_modname}_REQ_DEPS} CACHE INTERNAL "Required dependencies of ${full_modname} module") set(VISP_MODULE_${full_modname}_OPT_DEPS ${VISP_MODULE_${full_modname}_OPT_DEPS} CACHE INTERNAL "Optional dependencies of ${full_modname} module") set(VISP_MODULE_${full_modname}_PRIVATE_REQ_DEPS ${VISP_MODULE_${full_modname}_PRIVATE_REQ_DEPS} CACHE INTERNAL "Required private dependencies of ${full_modname} module") set(VISP_MODULE_${full_modname}_PRIVATE_OPT_DEPS ${VISP_MODULE_${full_modname}_PRIVATE_OPT_DEPS} CACHE INTERNAL "Optional private dependencies of ${full_modname} module") set(VISP_MODULE_${full_modname}_WRAPPERS ${VISP_MODULE_${full_modname}_WRAPPERS} CACHE INTERNAL "List of wrappers supporting module ${full_modname}") endmacro() # declare new ViSP module in current folder # Usage: # vp_add_module( [INTERNAL|BINDINGS] [REQUIRED] [] # [OPTIONAL ] # [PRIVATE_OPTIONAL|PRIVATE_REQUIRED] []) # Example: # vp_add_module(mymodule INTERNAL visp_core OPTIONAL visp_ar) macro(vp_add_module _name) vp_debug_message("vp_add_module(" ${_name} ${ARGN} ")") string(TOLOWER "${_name}" name) set(the_module visp_${name}) #message("Found module: ${the_module}") # the first pass - collect modules info, the second pass - create targets if(VISP_INITIAL_PASS) #guard agains redefinition if(";${VISP_MODULES_BUILD};${VISP_MODULES_DISABLED_USER};" MATCHES ";${the_module};") message(FATAL_ERROR "Redefinition of the ${the_module} module. at: ${CMAKE_CURRENT_SOURCE_DIR} previously defined at: ${VISP_MODULE_${the_module}_LOCATION} ") endif() if(NOT DEFINED the_description) set(the_description "The ViSP ${name} module") endif() if(NOT DEFINED BUILD_${the_module}_INIT) set(BUILD_${the_module}_INIT ON) endif() # create option to enable/disable this module option(BUILD_MODULE_${the_module} "Include ${the_module} module into ViSP build" ${BUILD_${the_module}_INIT}) # remember the module details set(VISP_MODULE_${the_module}_DESCRIPTION "${the_description}" CACHE INTERNAL "Brief description of ${the_module} module") set(VISP_MODULE_${the_module}_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}" CACHE INTERNAL "Location of ${the_module} module sources") set(VISP_MODULE_${the_module}_LINK_DEPS "" CACHE INTERNAL "") set(VISP_MODULE_${the_module}_INC_DEPS "" CACHE INTERNAL "") set(VISP_MODULE_${the_module}_SYSTEM_INC_DEPS "" CACHE INTERNAL "") # parse list of dependencies if("${ARGV1}" STREQUAL "INTERNAL" OR "${ARGV1}" STREQUAL "BINDINGS") set(VISP_MODULE_${the_module}_CLASS "${ARGV1}" CACHE INTERNAL "The category of the module") set(__vp_argn__ ${ARGN}) list(REMOVE_AT __vp_argn__ 0) vp_add_dependencies(${the_module} ${__vp_argn__}) unset(__vp_argn__) else() set(VISP_MODULE_${the_module}_CLASS "PUBLIC" CACHE INTERNAL "The category of the module") vp_add_dependencies(${the_module} ${ARGN}) if(BUILD_MODULE_${the_module}) set(VISP_MODULES_PUBLIC ${VISP_MODULES_PUBLIC} "${the_module}" CACHE INTERNAL "List of ViSP modules marked for export") endif() endif() if(BUILD_MODULE_${the_module}) set(VISP_MODULES_BUILD ${VISP_MODULES_BUILD} "${the_module}" CACHE INTERNAL "List of ViSP modules included into the build") else() set(VISP_MODULES_DISABLED_USER ${VISP_MODULES_DISABLED_USER} "${the_module}" CACHE INTERNAL "List of ViSP modules explicitly disabled by user") endif() # add reverse wrapper dependencies foreach (wrapper ${VISP_MODULE_${the_module}_WRAPPERS}) vp_add_dependencies(visp_${wrapper} OPTIONAL ${the_module}) endforeach() # add submodules if any set(VISP_MODULE_${the_module}_CHILDREN "${VISP_MODULE_CHILDREN}" CACHE INTERNAL "List of ${the_module} submodules") # stop processing of current file return() else() set(VISP_MODULE_${the_module}_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}" CACHE INTERNAL "") if(NOT BUILD_MODULE_${the_module}) return() # extra protection from redefinition endif() endif() endmacro() # excludes module from current configuration macro(vp_module_disable_ module) set(__modname ${module}) if(NOT __modname MATCHES "^visp_") set(__modname visp_${module}) endif() list(APPEND VISP_MODULES_DISABLED_FORCE "${__modname}") set(HAVE_${__modname} OFF CACHE INTERNAL "Module ${__modname} can not be built in current configuration") set(VISP_MODULE_${__modname}_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}" CACHE INTERNAL "Location of ${__modname} module sources") set(VISP_MODULES_DISABLED_FORCE "${VISP_MODULES_DISABLED_FORCE}" CACHE INTERNAL "List of ViSP modules which can not be build in current configuration") if(BUILD_${__modname}) # touch variable controlling build of the module to suppress "unused variable" CMake warning endif() unset(__modname) endmacro() macro(vp_module_disable module) vp_module_disable_(${module}) return() # leave the current folder endmacro() # remove visp_ prefix from name macro(vp_short_module_name name) if(${name} MATCHES "^visp_") string(REGEX REPLACE "^visp_" "" ${name} "${${name}}") endif() endmacro() # collect modules from specified directories # NB: must be called only once! macro(vp_glob_modules) if(DEFINED VISP_INITIAL_PASS) message(FATAL_ERROR "ViSP has already loaded its modules. Calling vp_glob_modules second time is not allowed.") endif() set(__directories_observed "") # collect modules set(VISP_INITIAL_PASS ON) set(VISP_PROCESSING_EXTRA_MODULES 0) foreach(__path ${ARGN}) if("${__path}" STREQUAL "EXTRA") set(VISP_PROCESSING_EXTRA_MODULES 1) else() get_filename_component(__path "${__path}" ABSOLUTE) list(FIND __directories_observed "${__path}" __pathIdx) if(__pathIdx GREATER -1) message(FATAL_ERROR "The directory ${__path} is observed for ViSP modules second time.") endif() list(APPEND __directories_observed "${__path}") file(GLOB __vpmodules RELATIVE "${__path}" "${__path}/*") vp_list_remove_item(__vpmodules ".git") if(VISP_PROCESSING_EXTRA_MODULES) # Remove tutorial, example, demo from potential contrib module list # They will be processed in visp/CMakeLists.txt vp_list_remove_item(__vpmodules "tutorial") vp_list_remove_item(__vpmodules "example") vp_list_remove_item(__vpmodules "demo") vp_list_remove_item(__vpmodules "apps") vp_list_remove_item(__vpmodules "doc") vp_list_remove_item(__vpmodules ".gitignore") vp_list_remove_item(__vpmodules ".travis.yml") vp_list_remove_item(__vpmodules "LICENSE") vp_list_remove_item(__vpmodules "README.md") endif() # TODO: Improve the following if to put a macro instead of manually copying the code # Here we have 3 internal loops. The depth of the loop (3) could be a var set(__count 0) if(__vpmodules) list(SORT __vpmodules) foreach(mod ${__vpmodules}) get_filename_component(__modpath "${__path}/${mod}" ABSOLUTE) set(__propagate FALSE) # Indicate if we should check for subdirs that may contain a CMakeLists.txt file if(EXISTS "${__modpath}/CMakeLists.txt") if(${mod} STREQUAL "modules") # Process specific case where there is a /modules/CMakeLists.txt file common to all modules include(${__modpath}/CMakeLists.txt) set(__propagate TRUE) else() list(FIND __directories_observed "${__modpath}" __pathIdx) if(__pathIdx GREATER -1) message(FATAL_ERROR "The module from ${__modpath} is already loaded.") endif() list(APPEND __directories_observed "${__modpath}") add_subdirectory("${__modpath}" "${CMAKE_CURRENT_BINARY_DIR}/${mod}/.${mod}") if (DEFINED VISP_MODULE_visp_${mod}_LOCATION) math(EXPR __count "${__count} + 1") endif() endif() else() set(__propagate TRUE) endif() if(__propagate) # modules in visp/tracker get_filename_component(__subpath "${__path}/${mod}" ABSOLUTE) file(GLOB __vpsubmodules RELATIVE "${__subpath}" "${__subpath}/*") if(__vpsubmodules) list(SORT __vpsubmodules) foreach(submod ${__vpsubmodules}) get_filename_component(__submodpath "${__subpath}/${submod}" ABSOLUTE) if(EXISTS "${__submodpath}/CMakeLists.txt") list(FIND __directories_observed "${__submodpath}" __pathIdx) if(__pathIdx GREATER -1) message(FATAL_ERROR "The module from ${__submodpath} is already loaded.") endif() list(APPEND __directories_observed "${__submodpath}") add_subdirectory("${__submodpath}" "${CMAKE_CURRENT_BINARY_DIR}/${submod}/.${submod}") if (DEFINED VISP_MODULE_visp_${submod}_LOCATION) math(EXPR __count "${__count} + 1") endif() else() # modules in ustk/image_processing get_filename_component(__subsubpath "${__subpath}/${submod}" ABSOLUTE) file(GLOB __vpsubsubmodules RELATIVE "${__subsubpath}" "${__subsubpath}/*") if(__vpsubsubmodules) list(SORT __vpsubsubmodules) foreach(subsubmod ${__vpsubsubmodules}) get_filename_component(__subsubmodpath "${__subsubpath}/${subsubmod}" ABSOLUTE) if(EXISTS "${__subsubmodpath}/CMakeLists.txt") list(FIND __directories_observed "${__subsubmodpath}" __pathIdx) if(__pathIdx GREATER -1) message(FATAL_ERROR "The module from ${__subsubmodpath} is already loaded.") endif() list(APPEND __directories_observed "${__subsubmodpath}") add_subdirectory("${__subsubmodpath}" "${CMAKE_CURRENT_BINARY_DIR}/${subsubmod}/.${subsubmod}") if (DEFINED VISP_MODULE_visp_${subsubmod}_LOCATION) math(EXPR __count "${__count} + 1") endif() else() # modules in ustk/image_processing/tracking get_filename_component(__subsubsubpath "${__subsubpath}/${subsubmod}" ABSOLUTE) file(GLOB __vpsubsubsubmodules RELATIVE "${__subsubsubpath}" "${__subsubsubpath}/*") if(__vpsubsubsubmodules) list(SORT __vpsubsubsubmodules) foreach(subsubsubmod ${__vpsubsubsubmodules}) get_filename_component(__subsubsubmodpath "${__subsubsubpath}/${subsubsubmod}" ABSOLUTE) if(EXISTS "${__subsubsubmodpath}/CMakeLists.txt") list(FIND __directories_observed "${__subsubsubmodpath}" __pathIdx) if(__pathIdx GREATER -1) message(FATAL_ERROR "The module from ${__subsubsubmodpath} is already loaded.") endif() list(APPEND __directories_observed "${__subsubsubmodpath}") add_subdirectory("${__subsubsubmodpath}" "${CMAKE_CURRENT_BINARY_DIR}/${subsubsubmod}/.${subsubsubmod}") if (DEFINED VISP_MODULE_visp_$subsubsubmod_LOCATION) math(EXPR __count "${__count} + 1") endif() endif() endforeach() endif() endif() endforeach() endif() endif() endforeach() endif() endif() endforeach() endif() endif() if (VISP_PROCESSING_EXTRA_MODULES AND ${__count} LESS 1) message(SEND_ERROR "No contrib modules found in folder: ${__path}\nPlease provide path to 'visp_contrib/modules' folder.") endif() endforeach() vp_clear_vars(__vpmodules __directories_observed __path __modpath __pathIdx __vpsubmodules __subpath __submodpath) # resolve dependencies __vp_resolve_dependencies() # create modules set(VISP_INITIAL_PASS OFF PARENT_SCOPE) set(VISP_INITIAL_PASS OFF) foreach(m ${VISP_MODULES_BUILD}) if(m MATCHES "^visp_") string(REGEX REPLACE "^visp_" "" __shortname "${m}") add_subdirectory("${VISP_MODULE_${m}_LOCATION}" "${CMAKE_CURRENT_BINARY_DIR}/${__shortname}") else() message(WARNING "Check module name: ${m}") add_subdirectory("${VISP_MODULE_${m}_LOCATION}" "${CMAKE_CURRENT_BINARY_DIR}/${m}") endif() endforeach() unset(__shortname) endmacro() # disables ViSP module with missing dependencies function(__vp_module_turn_off the_module) list(REMOVE_ITEM VISP_MODULES_DISABLED_AUTO "${the_module}") list(APPEND VISP_MODULES_DISABLED_AUTO "${the_module}") list(REMOVE_ITEM VISP_MODULES_BUILD "${the_module}") list(REMOVE_ITEM VISP_MODULES_PUBLIC "${the_module}") set(HAVE_${the_module} OFF CACHE INTERNAL "Module ${the_module} can not be built in current configuration") set(VISP_MODULES_DISABLED_AUTO "${VISP_MODULES_DISABLED_AUTO}" CACHE INTERNAL "") set(VISP_MODULES_BUILD "${VISP_MODULES_BUILD}" CACHE INTERNAL "") set(VISP_MODULES_PUBLIC "${VISP_MODULES_PUBLIC}" CACHE INTERNAL "") endfunction() # sort modules by dependencies function(__vp_sort_modules_by_deps __lst) vp_list_sort(${__lst}) set(input ${${__lst}}) set(result "") while(input) list(LENGTH input length_before) foreach (m ${input}) # check if module is in the result already if (NOT ";${result};" MATCHES ";${m};") # scan through module dependencies... set(unresolved_deps_found FALSE) foreach (d ${VISP_MODULE_${m}_CHILDREN} ${VISP_MODULE_${m}_DEPS}) # ... which are not already in the result and are enabled if ((NOT ";${result};" MATCHES ";${d};") AND HAVE_${d}) set(unresolved_deps_found TRUE) break() endif() endforeach() # chek if all dependencies for this module has been resolved if (NOT unresolved_deps_found) list(APPEND result ${m}) list(REMOVE_ITEM input ${m}) endif() endif() endforeach() list(LENGTH input length_after) # check for infinite loop or unresolved dependencies if (NOT length_after LESS length_before) message(WARNING "Unresolved dependencies or loop in dependency graph (${length_after})\n" "Processed ${__lst}: ${${__lst}}\n" "Good modules: ${result}\n" "Bad modules: ${input}" ) list(APPEND result ${input}) break() endif() endwhile() set(${__lst} "${result}" PARENT_SCOPE) endfunction() # resolve dependensies function(__vp_resolve_dependencies) foreach(m ${VISP_MODULES_DISABLED_USER}) set(HAVE_${m} OFF CACHE INTERNAL "Module ${m} will not be built in current configuration") endforeach() foreach(m ${VISP_MODULES_BUILD}) set(HAVE_${m} ON CACHE INTERNAL "Module ${m} will be built in current configuration") endforeach() # disable MODULES with unresolved dependencies set(has_changes ON) while(has_changes) set(has_changes OFF) foreach(m ${VISP_MODULES_BUILD}) set(__deps ${VISP_MODULE_${m}_REQ_DEPS} ${VISP_MODULE_${m}_PRIVATE_REQ_DEPS}) while(__deps) vp_list_pop_front(__deps d) string(TOLOWER "${d}" upper_d) if(NOT (HAVE_${d} OR HAVE_${upper_d} OR TARGET ${d} OR EXISTS ${d})) if(d MATCHES "^visp_") # TODO Remove this condition in the future and use HAVE_ variables only message(STATUS "Module ${m} disabled because ${d} dependency can't be resolved!") __vp_module_turn_off(${m}) set(has_changes ON) break() else() message(STATUS "Assume that non-module dependency is available: ${d} (for module ${m})") endif() endif() endwhile() endforeach() endwhile() # message(STATUS "List of active modules: ${VISP_MODULES_BUILD}") foreach(m ${VISP_MODULES_BUILD}) set(deps_${m} ${VISP_MODULE_${m}_REQ_DEPS}) foreach(d ${VISP_MODULE_${m}_OPT_DEPS}) if(NOT (";${deps_${m}};" MATCHES ";${d};")) if(HAVE_${d} OR TARGET ${d}) list(APPEND deps_${m} ${d}) endif() endif() endforeach() # message(STATUS "Initial deps of ${m} (w/o private deps): ${deps_${m}}") endforeach() # propagate dependencies set(has_changes ON) while(has_changes) set(has_changes OFF) foreach(m2 ${VISP_MODULES_BUILD}) # transfer deps of m2 to m foreach(m ${VISP_MODULES_BUILD}) if((NOT m STREQUAL m2) AND ";${deps_${m}};" MATCHES ";${m2};") foreach(d ${deps_${m2}}) if(NOT (";${deps_${m}};" MATCHES ";${d};")) # message(STATUS " Transfer dependency ${d} from ${m2} to ${m}") list(APPEND deps_${m} ${d}) set(has_changes ON) endif() endforeach() endif() endforeach() endforeach() endwhile() # process private deps #foreach(m ${VISP_MODULES_BUILD}) # foreach(d ${VISP_MODULE_${m}_PRIVATE_REQ_DEPS}) # if(NOT (";${deps_${m}};" MATCHES ";${d};")) # list(APPEND deps_${m} ${d}) # endif() # endforeach() # foreach(d ${VISP_MODULE_${m}_PRIVATE_OPT_DEPS}) # if(NOT (";${deps_${m}};" MATCHES ";${d};")) # if(HAVE_${d} OR TARGET ${d}) # list(APPEND deps_${m} ${d}) # endif() # endif() # endforeach() #endforeach() vp_list_sort(VISP_MODULES_BUILD) foreach(m ${VISP_MODULES_BUILD}) #message(STATUS "FULL deps of ${m}: ${deps_${m}}") set(VISP_MODULE_${m}_DEPS ${deps_${m}}) set(VISP_MODULE_${m}_DEPS_EXT ${deps_${m}}) vp_list_filterout(VISP_MODULE_${m}_DEPS_EXT "^visp_[^ ]+$") if(VISP_MODULE_${m}_DEPS_EXT AND VISP_MODULE_${m}_DEPS) list(REMOVE_ITEM VISP_MODULE_${m}_DEPS ${VISP_MODULE_${m}_DEPS_EXT}) endif() endforeach() # reorder dependencies foreach(m ${VISP_MODULES_BUILD}) __vp_sort_modules_by_deps(VISP_MODULE_${m}_DEPS) vp_list_sort(VISP_MODULE_${m}_DEPS_EXT) set(LINK_DEPS ${VISP_MODULE_${m}_DEPS}) set(VISP_MODULE_${m}_DEPS ${VISP_MODULE_${m}_DEPS} CACHE INTERNAL "Flattened dependencies of ${m} module") set(VISP_MODULE_${m}_DEPS_EXT ${VISP_MODULE_${m}_DEPS_EXT} CACHE INTERNAL "Extra dependencies of ${m} module") set(VISP_MODULE_${m}_DEPS_TO_LINK ${LINK_DEPS} CACHE INTERNAL "Flattened dependencies of ${m} module (for linker)") # message(STATUS " module deps of ${m}: ${VISP_MODULE_${m}_DEPS}") # message(STATUS " module link deps of ${m}: ${VISP_MODULE_${m}_DEPS_TO_LINK}") # message(STATUS " extra deps of ${m}: ${VISP_MODULE_${m}_DEPS_EXT}") # message(STATUS "") endforeach() __vp_sort_modules_by_deps(VISP_MODULES_BUILD) set(VISP_MODULES_PUBLIC ${VISP_MODULES_PUBLIC} CACHE INTERNAL "List of ViSP modules marked for export") set(VISP_MODULES_BUILD ${VISP_MODULES_BUILD} CACHE INTERNAL "List of ViSP modules included into the build") set(VISP_MODULES_DISABLED_AUTO ${VISP_MODULES_DISABLED_AUTO} CACHE INTERNAL "List of ViSP modules implicitly disabled due to dependencies") endfunction() # setup include paths for the list of passed modules macro(vp_target_include_modules target) set(is_system "") set(is_private "") vp_get_apple_sdk_dir(apple_sdk_dir) foreach(d ${ARGN}) if("${d}" STREQUAL "SYSTEM") set(is_system "SYSTEM") elseif("${d}" STREQUAL "PRIVATE") set(is_private "PRIVATE") elseif(d MATCHES "^visp_" AND HAVE_${d}) if (EXISTS "${VISP_MODULE_${d}_LOCATION}/include") vp_target_include_directories(${target} "${VISP_MODULE_${d}_LOCATION}/include") endif() elseif(EXISTS "${d}") # Exclude all include dirs starting with MacOS SDK path vp_string_starts_with(${d} ${apple_sdk_dir} apple_sdk_dir_found) if (NOT apple_sdk_dir_found) # FS keep external deps inc if(is_system) set(VISP_MODULE_${the_module}_SYSTEM_INC_DEPS "${VISP_MODULE_${the_module}_SYSTEM_INC_DEPS};${d}" CACHE INTERNAL "") elseif(NOT is_private) set(VISP_MODULE_${the_module}_INC_DEPS "${VISP_MODULE_${the_module}_INC_DEPS};${d}" CACHE INTERNAL "") endif() vp_target_include_directories(${target} "${is_system}" "${d}") endif() endif() endforeach() vp_list_unique(VISP_MODULE_${the_module}_INC_DEPS) vp_list_unique(VISP_MODULE_${the_module}_SYSTEM_INC_DEPS) endmacro() # setup include paths for the list of passed modules and recursively add dependent modules macro(vp_target_include_modules_recurse target) foreach(d ${ARGN}) if(d MATCHES "^visp_" AND HAVE_${d}) if (EXISTS "${VISP_MODULE_${d}_LOCATION}/include") vp_target_include_directories(${target} "${VISP_MODULE_${d}_LOCATION}/include") endif() if(VISP_MODULE_${d}_DEPS) vp_target_include_modules(${target} ${VISP_MODULE_${d}_DEPS}) endif() elseif(EXISTS "${d}") vp_target_include_directories(${target} "${d}") endif() endforeach() endmacro() # setup include path for ViSP headers for specified module # vp_module_include_directories() macro(vp_module_include_directories) vp_target_include_directories(${the_module} "${VISP_MODULE_${the_module}_LOCATION}/include" "${VISP_MODULE_${the_module}_LOCATION}/src" "${CMAKE_CURRENT_BINARY_DIR}" # for precompiled headers ) vp_target_include_modules(${the_module} ${VISP_MODULE_${the_module}_DEPS} ${ARGN}) endmacro() # sets header and source files for the current module # NB: all files specified as headers will be installed # Usage: # vp_set_module_sources([HEADERS] [SOURCES] ) macro(vp_set_module_sources) vp_debug_message("vp_set_module_sources(" ${ARGN} ")") set(VISP_MODULE_${the_module}_HEADERS "") set(VISP_MODULE_${the_module}_SOURCES "") foreach(f "HEADERS" ${ARGN}) if(f STREQUAL "HEADERS" OR f STREQUAL "SOURCES") set(__filesvar "VISP_MODULE_${the_module}_${f}") else() list(APPEND ${__filesvar} "${f}") endif() endforeach() # use full paths for module to be independent from the module location vp_convert_to_full_paths(VISP_MODULE_${the_module}_HEADERS) if(${the_module} MATCHES visp_core) list(APPEND VISP_MODULE_${the_module}_HEADERS "${VISP_INCLUDE_DIR}/visp3/core/vpConfig.h") list(APPEND VISP_MODULE_${the_module}_HEADERS "${VISP_INCLUDE_DIR}/visp3/visp_modules.h") endif() set(VISP_MODULE_${the_module}_HEADERS ${VISP_MODULE_${the_module}_HEADERS} CACHE INTERNAL "List of header files for ${the_module}") set(VISP_MODULE_${the_module}_SOURCES ${VISP_MODULE_${the_module}_SOURCES} CACHE INTERNAL "List of source files for ${the_module}") endmacro() # finds and sets headers and sources for the standard ViSP module # Usage: # vp_glob_module_sources() macro(vp_glob_module_sources) vp_debug_message("vp_glob_module_sources(" ${ARGN} ")") set(_argn ${ARGN}) file(GLOB_RECURSE lib_srcs "${CMAKE_CURRENT_LIST_DIR}/src/*.cpp" ) file(GLOB_RECURSE lib_int_hdrs "${CMAKE_CURRENT_LIST_DIR}/src/*.hpp" "${CMAKE_CURRENT_LIST_DIR}/src/*.h" ) file(GLOB lib_hdrs "${CMAKE_CURRENT_LIST_DIR}/include/visp3/*.h" "${CMAKE_CURRENT_LIST_DIR}/include/visp3/${name}/*.h" ) vp_source_group("Src" DIRBASE "${CMAKE_CURRENT_LIST_DIR}/src" FILES ${lib_srcs} ${lib_int_hdrs}) vp_source_group("Include" DIRBASE "${CMAKE_CURRENT_LIST_DIR}/include" FILES ${lib_hdrs}) vp_set_module_sources(${_argn} HEADERS ${lib_hdrs} SOURCES ${lib_srcs} ${lib_int_hdrs}) endmacro() # finds and copy data from a source to a destination # Usage: # vp_glob_module_data( ) macro(vp_glob_module_copy_data src dst) set(__data "") file(GLOB_RECURSE __data "${CMAKE_CURRENT_LIST_DIR}/${src}" ) foreach(__d ${__data}) file(COPY ${__d} DESTINATION "${VISP_BINARY_DIR}/${dst}" FILE_PERMISSIONS OWNER_READ GROUP_READ WORLD_READ OWNER_WRITE ) # install set(__install_dst "${VISP_INSTALL_DATAROOTDIR}/${dst}") if(NOT "x${ARGN}" STREQUAL "xNO_INSTALL") install(FILES ${__d} DESTINATION "${__install_dst}" PERMISSIONS OWNER_READ GROUP_READ WORLD_READ OWNER_WRITE ) endif() endforeach() endmacro() # creates old headers for compat with previous releases in include/visp # Usage: # vp_create_compat_headers() macro(vp_create_compat_headers) vp_debug_message("vp_create_compat_headers(" ${ARGN} ")") set(VISP_HEADER_CONTENT_CONFIGMAKE "") foreach(h ${ARGN}) get_filename_component(__h_name_we ${h} NAME_WE) get_filename_component(__h_name ${h} NAME) if(${__h_name} MATCHES "visp_modules.h") set(VISP_HEADER_CONTENT_CONFIGMAKE "#ifndef __${__h_name_we}_gen_h_\n#define __${__h_name_we}_gen_h_\n\n#include \n\n#endif\n") else() set(VISP_HEADER_CONTENT_CONFIGMAKE "#ifndef __${__h_name_we}_gen_h_\n#define __${__h_name_we}_gen_h_\n\n#include \n\n#endif\n") endif() set(__compat_header_dst "${VISP_INCLUDE_DIR}/visp/${__h_name_we}.h") configure_file("${VISP_SOURCE_DIR}/cmake/templates/vpHeader.h.in" ${__compat_header_dst}) endforeach() unset(__h_name_we) unset(__h_name) unset(__compat_header_dst) endmacro() # creates headers for modules include/visp3//vp.h # Usage: # vp_create_global_module_header() macro(vp_create_global_module_header module) vp_debug_message("vp_create_global_module_header(" ${module} ")") set(__name ${module}) vp_short_module_name(__name) set(__module_header_dst "${VISP_INCLUDE_DIR}/visp3/${module}.h") set(VISP_HEADER_CONTENT_CONFIGMAKE "#ifndef __${module}_h_\n#define __${module}_h_\n") # when core, include also vpConfig.h if(__name MATCHES "^core$") set(VISP_HEADER_CONTENT_CONFIGMAKE "${VISP_HEADER_CONTENT_CONFIGMAKE}\n#include ") endif() # include the modules we depend on if(VISP_MODULE_${module}_REQ_DEPS) foreach(dep ${VISP_MODULE_${module}_REQ_DEPS}) vp_short_module_name(dep) set(VISP_HEADER_CONTENT_CONFIGMAKE "${VISP_HEADER_CONTENT_CONFIGMAKE}\n#include ") endforeach() endif() foreach(h ${VISP_MODULE_${module}_HEADERS}) string(REGEX REPLACE "^.*/include/visp3" "visp3" h "${h}") set(VISP_HEADER_CONTENT_CONFIGMAKE "${VISP_HEADER_CONTENT_CONFIGMAKE}\n#include <${h}>") endforeach() set(VISP_HEADER_CONTENT_CONFIGMAKE "${VISP_HEADER_CONTENT_CONFIGMAKE}\n\n#endif\n") configure_file("${VISP_SOURCE_DIR}/cmake/templates/vpHeader.h.in" ${__module_header_dst}) install(FILES ${__module_header_dst} DESTINATION ${VISP_INC_INSTALL_PATH}/visp3 COMPONENT dev ) unset(__module_header_dst) endmacro() # creates ViSP module in current folder # creates new target, configures standard dependencies, compilers flags, install rules # Usage: # vp_create_module() # vp_create_module() macro(vp_create_module) vp_debug_message("vp_create_module(" ${ARGN} ")") set(VISP_MODULE_${the_module}_LINK_DEPS "${VISP_MODULE_${the_module}_LINK_DEPS};${ARGN}" CACHE INTERNAL "") _vp_create_module() set(the_module_target ${the_module}) endmacro() macro(_vp_create_module) vp_create_compat_headers(${VISP_MODULE_${the_module}_HEADERS}) vp_create_global_module_header(${the_module}) vp_add_library(${the_module} ${VISP_MODULE_TYPE} ${VISP_MODULE_${the_module}_HEADERS} ${VISP_MODULE_${the_module}_SOURCES}) vp_target_link_libraries(${the_module} PUBLIC ${VISP_MODULE_${the_module}_DEPS_TO_LINK} ${VISP_MODULE_${the_module}_DEPS_EXT} ${VISP_MODULE_${the_module}_LINK_DEPS} PRIVATE ${VISP_MODULE_${the_module}_PRIVATE_REQ_DEPS} ${VISP_MODULE_${the_module}_PRIVATE_OPT_DEPS} ${VISP_LINKER_LIBS}) add_dependencies(visp_modules ${the_module}) if(ENABLE_SOLUTION_FOLDERS) set_target_properties(${the_module} PROPERTIES FOLDER "modules") endif() set_target_properties(${the_module} PROPERTIES OUTPUT_NAME "${the_module}${VISP_DLLVERSION}" DEBUG_POSTFIX "${VISP_DEBUG_POSTFIX}" ARCHIVE_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH} LIBRARY_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH} RUNTIME_OUTPUT_DIRECTORY ${BINARY_OUTPUT_PATH} # FS: Remove next line. Should be added only for shared libs. See below #DEFINE_SYMBOL visp_EXPORTS ) if(BUILD_FAT_JAVA_LIB) # force exports from static modules too if(BUILD_SHARED_LIBS) message(FATAL_ERROR "Assertion failed: BUILD_SHARED_LIBS=OFF must be off if BUILD_FAT_JAVA_LIB=ON") endif() target_compile_definitions(${the_module} PRIVATE visp_EXPORTS) endif() #set_property(TARGET ${the_module} APPEND PROPERTY # # Here we need also to add system include dirs, otherwise they are missing # INTERFACE_INCLUDE_DIRECTORIES ${VISP_MODULE_${the_module}_INC_DEPS} ${VISP_MODULE_${the_module}_SYSTEM_INC_DEPS} #) #set_property(TARGET ${the_module} APPEND PROPERTY # INTERFACE_SYSTEM_INCLUDE_DIRECTORIES ${VISP_MODULE_${the_module}_SYSTEM_INC_DEPS} #) set(inc "${VISP_MODULE_${the_module}_INC_DEPS};${VISP_MODULE_${the_module}_SYSTEM_INC_DEPS}") if(NOT (CMAKE_VERSION VERSION_LESS "3.11.0")) # https://gitlab.kitware.com/cmake/cmake/-/merge_requests/1264 : eliminates "Cannot specify compile definitions for imported target" error message target_include_directories(${the_module} SYSTEM INTERFACE "$") else() set_target_properties(${the_module} PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "$" INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "$" ) endif() # For dynamic link numbering convenions if(NOT ANDROID) # Android SDK build scripts can include only .so files into final .apk # As result we should not set version properties for Android set_target_properties(${the_module} PROPERTIES VERSION ${VISP_VERSION} SOVERSION ${VISP_SOVERSION} ) endif() if((NOT DEFINED VISP_MODULE_TYPE AND BUILD_SHARED_LIBS) OR (DEFINED VISP_MODULE_TYPE AND VISP_MODULE_TYPE STREQUAL SHARED)) set_target_properties(${the_module} PROPERTIES COMPILE_DEFINITIONS visp_EXPORTS) set_target_properties(${the_module} PROPERTIES DEFINE_SYMBOL visp_EXPORTS) endif() if(MSVC) if(CMAKE_CROSSCOMPILING) set_target_properties(${the_module} PROPERTIES LINK_FLAGS "/NODEFAULTLIB:secchk") endif() set_target_properties(${the_module} PROPERTIES LINK_FLAGS "/NODEFAULTLIB:libc /DEBUG") endif() get_target_property(_target_type ${the_module} TYPE) if(VISP_MODULE_${the_module}_CLASS STREQUAL "PUBLIC" AND ("${_target_type}" STREQUAL "SHARED_LIBRARY" OR (NOT BUILD_SHARED_LIBS OR NOT INSTALL_CREATE_DISTRIB))) vp_install_target(${the_module} EXPORT VISPModules OPTIONAL RUNTIME DESTINATION ${VISP_BIN_INSTALL_PATH} COMPONENT libs LIBRARY DESTINATION ${VISP_LIB_INSTALL_PATH} COMPONENT libs ARCHIVE DESTINATION ${VISP_LIB_ARCHIVE_INSTALL_PATH} COMPONENT dev ) endif() foreach(m ${VISP_MODULE_${the_module}_CHILDREN} ${the_module}) # only "public" headers need to be installed if(VISP_MODULE_${m}_HEADERS AND ";${VISP_MODULES_PUBLIC};" MATCHES ";${m};") foreach(hdr ${VISP_MODULE_${m}_HEADERS}) string(REGEX REPLACE "^.*visp3/" "visp3/" hdr2 "${hdr}") if(NOT hdr2 MATCHES "visp3/${m}/private.*" AND hdr2 MATCHES "^(visp3/?.*)/[^/]+.h(..)?$" ) install(FILES ${hdr} OPTIONAL DESTINATION "${VISP_INC_INSTALL_PATH}/${CMAKE_MATCH_1}" COMPONENT dev) endif() endforeach() endif() endforeach() endmacro() # short command for adding simple ViSP module # see vp_add_module for argument details # Usage: # vp_define_module(module_name [INTERNAL] [REQUIRED] [] [OPTIONAL ]) macro(vp_define_module module_name) vp_debug_message("vp_define_module(" ${module_name} ${ARGN} ")") set(_argn ${ARGN}) vp_add_module(${module_name} ${_argn}) vp_glob_module_sources() vp_module_include_directories() vp_create_module() endmacro() # ensures that all passed modules are available # sets VP_DEPENDENCIES_FOUND variable to TRUE/FALSE macro(vp_check_dependencies) set(VP_DEPENDENCIES_FOUND TRUE) foreach(d ${ARGN}) if(d MATCHES "^visp_[^ ]+$" AND NOT HAVE_${d}) set(VP_DEPENDENCIES_FOUND FALSE) break() endif() endforeach() endmacro() # auxiliary macro to parse arguments of vp_add_tests commands macro(__vp_parse_test_sources tests_type) set(VISP_${tests_type}_${the_module}_SOURCES "") set(VISP_${tests_type}_${the_module}_SOURCES_EXCLUDE "") set(VISP_${tests_type}_${the_module}_DEPS "") set(VISP_${tests_type}_${the_module}_DEPS_PRIVATE_INCLUDE_DIRS "") set(VISP_${tests_type}_${the_module}_DEPS_PRIVATE_LIBRARIES "") set(VISP_${tests_type}_${the_module}_CTEST_EXCLUDE_FOLDER "") set(VISP_${tests_type}_${the_module}_CTEST_EXCLUDE_FILE "") set(__file_group_name "") set(__file_group_sources "") foreach(arg "DEPENDS_ON" ${ARGN} "FILES") if(arg STREQUAL "FILES") set(__currentvar "__file_group_sources") if(__file_group_name AND __file_group_sources) source_group("${__file_group_name}" FILES ${__file_group_sources}) list(APPEND VISP_${tests_type}_${the_module}_SOURCES ${__file_group_sources}) endif() set(__file_group_name "") set(__file_group_sources "") elseif(arg STREQUAL "DEPENDS_ON") set(__currentvar "VISP_${tests_type}_${the_module}_DEPS") elseif(" ${__currentvar}" STREQUAL " __file_group_sources" AND NOT __file_group_name) # spaces to avoid CMP0054 set(__file_group_name "${arg}") elseif(arg STREQUAL "CTEST_EXCLUDE_PATH") set(__currentvar "VISP_${tests_type}_${the_module}_CTEST_EXCLUDE_FOLDER") elseif(arg STREQUAL "CTEST_EXCLUDE_FILE") set(__currentvar "VISP_${tests_type}_${the_module}_CTEST_EXCLUDE_FILE") elseif(arg STREQUAL "SOURCES_EXCLUDE") set(__currentvar "VISP_${tests_type}_${the_module}_SOURCES_EXCLUDE") elseif(arg STREQUAL "PRIVATE_INCLUDE_DIRS") set(__currentvar "VISP_${tests_type}_${the_module}_DEPS_PRIVATE_INCLUDE_DIRS") elseif(arg STREQUAL "PRIVATE_LIBRARIES") set(__currentvar "VISP_${tests_type}_${the_module}_DEPS_PRIVATE_LIBRARIES") else() list(APPEND ${__currentvar} "${arg}") endif() endforeach() unset(__file_group_name) unset(__file_group_sources) unset(__currentvar) endmacro() # this is a command for adding ViSP tests to the module # vp_add_tests([FILES ] # [FILES_EXCLUDE ] # [DEPENDS_ON] # [CTEST_EXCLUDE_PATH] ) # [CTEST_EXCLUDE_FILE] ) # [PRIVATE_INCLUDE_DIRS] # [PRIVATE_LIBRARIES] # # When a test is located in a folder which name ends with "with-dataset" like # "test/core/image-with-dataset/test.cpp" the test is added only if the dataset is # found by cmake. This was introduced for isolated testing. macro(vp_add_tests) vp_debug_message("vp_add_tests(" ${ARGN} ")") set(test_path "${CMAKE_CURRENT_LIST_DIR}/test") if(BUILD_TESTS AND EXISTS "${test_path}") __vp_parse_test_sources(TEST ${ARGN}) set(__exclude_ctest "") foreach(__folder ${VISP_TEST_${the_module}_CTEST_EXCLUDE_FOLDER} ) file(GLOB_RECURSE __files "${CMAKE_CURRENT_LIST_DIR}/test/${__folder}/*.cpp") list(APPEND __exclude_ctest ${__files}) endforeach() foreach(__file ${VISP_TEST_${the_module}_CTEST_EXCLUDE_FILE} ) if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/test/${__file}") list(APPEND __exclude_ctest "${CMAKE_CURRENT_LIST_DIR}/test/${__file}") endif() endforeach() set(__exclude_sources "") foreach(__source ${VISP_TEST_${the_module}_SOURCES_EXCLUDE} ) file(GLOB __files "${CMAKE_CURRENT_LIST_DIR}/test/${__source}") list(APPEND __exclude_sources ${__files}) endforeach() set(test_deps ${the_module} ${VISP_MODULE_${the_module}_DEPS}) foreach(d ${VISP_TEST_${the_module}_DEPS}) list(APPEND test_deps ${d}) list(APPEND test_deps ${VISP_MODULE_${d}_DEPS}) endforeach() vp_check_dependencies(${test_deps}) if(VP_DEPENDENCIES_FOUND) if(NOT VISP_TEST_${the_module}_SOURCES) file(GLOB_RECURSE test_srcs "${test_path}/*.cpp") vp_source_group("Src" DIRBASE "${test_path}" FILES ${test_srcs}) set(VISP_TEST_${the_module}_SOURCES ${test_srcs}) endif() foreach(t ${VISP_TEST_${the_module}_SOURCES}) # Check if source is not in exclude list list(FIND __exclude_sources ${t} __to_exclude_from_sources) if(${__to_exclude_from_sources} EQUAL -1) # Compute the name of the binary to create get_filename_component(the_target ${t} NAME_WE) # From source compile the binary and add link rules vp_add_executable(${the_target} ${t}) vp_target_include_modules(${the_target} ${test_deps} PRIVATE ${VISP_TEST_${the_module}_DEPS_PRIVATE_INCLUDE_DIRS}) vp_target_link_libraries(${the_target} ${test_deps} ${VISP_MODULE_${the_module}_DEPS} ${VISP_TEST_${the_module}_DEPS_PRIVATE_LIBRARIES}) # ctest only: # - if required dataset available if (NOT VISP_DATASET_FOUND) get_filename_component(__path ${t} DIRECTORY) if(__path MATCHES "with-dataset$") # dataset required list(APPEND __exclude_ctest "${t}") endif() endif() # - if not in the exclude list list(FIND __exclude_ctest ${t} __to_exclude_from_ctest) if(${__to_exclude_from_ctest} EQUAL -1) if(${t} MATCHES "perf*") add_test(${the_target} ${the_target}) elseif(${t} MATCHES "catch*") add_test(${the_target} ${the_target} ${LONG_OPTION_TO_DISABLE_DISPLAY}) else() add_test(${the_target} ${the_target} -c ${SHORT_OPTION_TO_DISABLE_DISPLAY}) endif() endif() # TODO FS add visp_test_${name} target to group all the tests add_dependencies(visp_tests ${the_target}) if(ENABLE_SOLUTION_FOLDERS) set_target_properties(${the_target} PROPERTIES FOLDER "tests") endif() endif() endforeach() else(VP_DEPENDENCIES_FOUND) # TODO: warn about unsatisfied dependencies endif(VP_DEPENDENCIES_FOUND) endif() endmacro() # setup include paths for the list of passed modules macro(vp_include_modules) foreach(d ${ARGN}) if(d MATCHES "^visp_" AND HAVE_${d}) if (EXISTS "${VISP_MODULE_${d}_LOCATION}/include") vp_include_directories("${VISP_MODULE_${d}_LOCATION}/include") endif() elseif(EXISTS "${d}") vp_include_directories("${d}") endif() endforeach() endmacro() # same as previous but with dependencies macro(vp_include_modules_recurse) vp_include_modules(${ARGN}) foreach(d ${ARGN}) if(d MATCHES "^visp_" AND HAVE_${d} AND DEFINED VISP_MODULE_${d}_DEPS) foreach (sub ${VISP_MODULE_${d}_DEPS}) vp_include_modules(${sub}) endforeach() endif() endforeach() endmacro() # This is a command to configure files as include headers of the corresponding module. # vp_add_config_file() # # If the input config filename is suffixed by .in or .cmake the suffix is removed # in the configured file. # # Warning: Should be called after add_module() # # Example: # add_module(my_module visp_core) # vp_add_config_file(cmake/template/vpConfigMyModule.h.in) # creates include/visp3/my_module/vpConfigMyModule.h macro(vp_add_config_file) set(MODULE_NAME ${the_module}) if(MODULE_NAME MATCHES "^visp_") string(REGEX REPLACE "^visp_" "" MODULE_NAME "${MODULE_NAME}") endif() # We need here to do the same job as in vp_create_global_module_header() macro # in order to create include/visp3/${the module}.h file that contains the config file # that has to be created # begin part of vp_create_global_module_header() macro set(__module_header_dst "${VISP_INCLUDE_DIR}/visp3/${the_module}.h") set(__header_content "#ifndef __${the_module}_h_\n#define __${the_module}_h_\n") # end of part of vp_create_global_module_header() macro foreach(d ${ARGN}) # Removes first "/" if it exists string(FIND ${d} "/" FIRST_SEPARATOR_POS) if(${FIRST_SEPARATOR_POS} EQUAL 0) string(SUBSTRING ${d} 1 -1 d) endif() # Find start of file name string(FIND ${d} "/" LAST_SEPARATOR_POS REVERSE) if(${LAST_SEPARATOR_POS} EQUAL -1) set(START 0) else() math(EXPR START "${LAST_SEPARATOR_POS}+1") endif() # Save entire path set(FILENAME_CONFIG ${d}) # Find file name string(FIND ${d} "." EXTENSION_POS REVERSE) if(${EXTENSION_POS} EQUAL -1) string(SUBSTRING ${d} ${START} -1 FILENAME_CONFIG_SHORT) else() string(SUBSTRING ${d} ${EXTENSION_POS} -1 EXT_CONFIG_FILE) if(EXT_CONFIG_FILE MATCHES ".cmake" OR EXT_CONFIG_FILE MATCHES ".in") math(EXPR LENGTH "${EXTENSION_POS} - ${START}") string(SUBSTRING ${d} ${START} ${LENGTH} FILENAME_CONFIG_SHORT) else() string(SUBSTRING ${d} ${START} -1 FILENAME_CONFIG_SHORT) endif() endif() configure_file("${VISP_MODULE_${the_module}_LOCATION}/${FILENAME_CONFIG}" "${VISP_INCLUDE_DIR}/visp3/${MODULE_NAME}/${FILENAME_CONFIG_SHORT}") vp_create_compat_headers("${VISP_INCLUDE_DIR}/visp3/${MODULE_NAME}/${FILENAME_CONFIG_SHORT}") # begin part of vp_create_global_module_header() macro set(__header_content "${__header_content}\n#include ") # end part of vp_create_global_module_header() macro install(FILES "${VISP_INCLUDE_DIR}/visp3/${MODULE_NAME}/${FILENAME_CONFIG_SHORT}" DESTINATION ${VISP_INC_INSTALL_PATH}/visp3/${MODULE_NAME} COMPONENT dev ) endforeach() # begin part of vp_create_global_module_header() macro # include the modules we depend on if(VISP_MODULE_${the_module}_REQ_DEPS) foreach(dep ${VISP_MODULE_${the_module}_REQ_DEPS}) vp_short_module_name(dep) set(__header_content "${__header_content}\n#include ") endforeach() endif() foreach(h ${VISP_MODULE_${the_module}_HEADERS}) string(REGEX REPLACE "^.*/include/visp3" "visp3" h "${h}") set(__header_content "${__header_content}\n#include <${h}>") endforeach() set(__header_content "${__header_content}\n\n#endif\n") set(VISP_HEADER_CONTENT_CONFIGMAKE ${__header_content}) configure_file("${VISP_SOURCE_DIR}/cmake/templates/vpHeader.h.in" ${__module_header_dst}) # install(FILES ${__module_header_dst} # DESTINATION ${VISP_INC_INSTALL_PATH}/visp3 # COMPONENT dev # ) unset(__module_header_dst) unset(__header_content) # end part of vp_create_global_module_header() macro endmacro() # This is a command to add a list of paths associated to the corresponding module # to the CMAKE_MODULE_PATH global var to find specific cmake material # vp_add_cmake_module_path() # Example: # vp_add_cmake_module_path(cmake) # Appends the cmake full path to CMAKE_MODULE_PATH var. macro(vp_add_cmake_module_path) foreach(d ${ARGN}) # Removes first "/" if it exists string(FIND ${d} "/" FIRST_SEPARATOR_POS) if(${FIRST_SEPARATOR_POS} EQUAL 0) string(SUBSTRING ${d} 1 -1 d) endif() if(EXISTS "${VISP_MODULE_${the_module}_LOCATION}/${d}") list(APPEND CMAKE_MODULE_PATH "${VISP_MODULE_${the_module}_LOCATION}/${d}") endif() endforeach() endmacro() macro(vp_cmake_configure file_name) set(__shortname ${the_module}) vp_short_module_name(__shortname) if(EXISTS ${VISP_MODULE_${the_module}_LOCATION}/${file_name}) configure_file(${VISP_MODULE_${the_module}_LOCATION}/${file_name} "${CMAKE_BINARY_DIR}/CMakeConfig-${__shortname}.cmake" @ONLY) endif() endmacro()