#--------------------------------------------------------------------- # Sub project name project(elxComponents) #--------------------------------------------------------------------- # Set the libraries to be linked. # Linux gave an error, if param was linked. This was only # when we still used .dll's. I'm not sure if it will still # give an error, but as long as linux does not complain # about the missing param, just leave it out. if(UNIX) if(NOT APPLE) set(elxLinkLibs elxCommon elxCore ${ITK_LIBRARIES}) endif() endif() # Interestingly, visual c++ and MAC-GCC do need param if(WIN32 OR APPLE) set(elxLinkLibs param elxCommon elxCore ${ITK_LIBRARIES}) endif() #-------------------------------------------------------------------- # Prepare elxInstallComponentFunctionDeclarations.h and # elxInstallComponentFunctionCalls.h # In the ADD_ELXCOMPONENT macro a line is added # set(InstallFunctionDeclarationFile ${elastix_BINARY_DIR}/elxInstallComponentFunctionDeclarations.h) set(InstallFunctionCallFile ${elastix_BINARY_DIR}/elxInstallComponentFunctionCalls.h) file(WRITE ${InstallFunctionDeclarationFile} "\n" "//This file is generated by CMake. Do not edit manually!\n\n") file(WRITE ${InstallFunctionCallFile} "\n" "//This file is generated by CMake. Do not edit manually!\n\n") #--------------------------------------------------------------------- # Macros that simplify the addition (and removal) of elx-components # # Usage: # ADD_ELXCOMPONENT( ) # # The name_of_lib should be equal to the name of the elx class, # which also should be the name used in the elxInstallMacro, in the # the .cxx file of the component. # # The REMOVE_ELXCOMPONENT is in some cases useful, if you want to # skip building the component in case some other cmake setting is not # correct. Most users will not need to invoke this macro though. # # Usage: # REMOVE_ELXCOMPONENT( ) # include(CMakeDependentOption) macro(REMOVE_ELXCOMPONENT name) # remove lib from link list if(DEFINED AllComponentLibs) set(dummy ${AllComponentLibs}) if(NOT "${dummy}" STREQUAL "") list(REMOVE_ITEM dummy ${name}) endif() else() set(dummy "") endif() set(AllComponentLibs ${dummy} CACHE INTERNAL "All component libraries for elastix/transformix" ) endmacro(REMOVE_ELXCOMPONENT) macro(ADD_ELXCOMPONENT name) # Compile this component or not set(defaultValue ON) if(${ARGV1} STREQUAL "OFF") set(defaultValue OFF) endif() mark_as_advanced(USE_${name}) set(USE_${name} ${defaultValue} CACHE BOOL "Compile this component") # If USE_ALL_COMPONENTS is turned ON, we make a backup of the # current value, and force the use_var to ON. If USE_ALL_COMPONENTS # is OFF, and there is a backup, set the use_var to the backed-up # value and remove the backup; otherwise, leave the use_var to its # current (default or user-specified) value. if(USE_ALL_COMPONENTS) # make backup if(NOT DEFINED USE_${name}_BACKUP) if(USE_${name}) set(USE_${name}_BACKUP ON CACHE INTERNAL "Backup of USE_var" FORCE) else() set(USE_${name}_BACKUP OFF CACHE INTERNAL "Backup of USE_var" FORCE) endif() endif() # turn use_var to on; set(USE_${name} ON CACHE BOOL "Compile this component" FORCE) else() # if there is a backup, set the use_var to the backed-up value # and remove the backup. if(DEFINED USE_${name}_BACKUP) # this unset command is important; it makes sure the use_var is reset unset(USE_${name} CACHE) if(USE_${name}_BACKUP) set(USE_${name} ON CACHE BOOL "Compile this component") else() set(USE_${name} OFF CACHE BOOL "Compile this component") endif() unset(USE_${name}_BACKUP CACHE) endif() endif() if(USE_${name}) # Create the list of files which create the library set(filelist ${ARGN}) list(REMOVE_ITEM filelist "ON" "OFF") # Create project and static library project(${name}) add_library(${name} STATIC ${filelist}) target_link_libraries(${name} ${elxLinkLibs}) if(NOT ELASTIX_NO_INSTALL_DEVELOPMENT) install(TARGETS ${name} ARCHIVE DESTINATION ${ELASTIX_ARCHIVE_DIR} LIBRARY DESTINATION ${ELASTIX_LIBRARY_DIR} RUNTIME DESTINATION ${ELASTIX_RUNTIME_DIR} COMPONENT Development) endif() # Group in IDE's like Visual Studio string(REGEX MATCH "[a-zA-Z]+" comp_group ${relative_path_to_comp}) set_property(TARGET ${name} PROPERTY FOLDER ${comp_group}) # Update AllComponentLibs, while avoiding duplicates: if(DEFINED AllComponentLibs) set(dummy ${AllComponentLibs}) if(NOT "${dummy}" STREQUAL "") list(REMOVE_ITEM dummy ${name}) endif() set(dummy ${dummy} ${name}) else() set(dummy ${name}) endif() set(AllComponentLibs ${dummy} CACHE INTERNAL "All component libraries for elastix/transformix") # Write lines to two files file(APPEND ${InstallFunctionDeclarationFile} "elxInstallComponentFunctionDeclarationMacro(" ${name} ");\n\n") file(APPEND ${InstallFunctionCallFile} "elxInstallComponentFunctionCallMacro(" ${name} ");\n\n") else(USE_${name}) # Remove from link list REMOVE_ELXCOMPONENT( ${name}) endif() endmacro(ADD_ELXCOMPONENT) #--------------------------------------------------------------------- # Option to turn on all components by default mark_as_advanced(USE_ALL_COMPONENTS) set(USE_ALL_COMPONENTS OFF CACHE BOOL "Compile all components") #--------------------------------------------------------------------- # Search for all components in the elastix source directory # # Initialize the list of link libs. set(AllComponentLibs "" CACHE INTERNAL "All component libraries for elastix/transformix" ) file(GLOB ListOfComponents "*/*/CMakeLists.txt") foreach(component ${ListOfComponents}) get_filename_component(path_to_comp ${component} PATH) # Make the path relative to the elxComponents_SOURCE_DIR string(REGEX REPLACE "${elxComponents_SOURCE_DIR}/" "" relative_path_to_comp ${path_to_comp}) add_subdirectory(${relative_path_to_comp}) endforeach() #---------------------------------------------------------------------- # Search for user components # These are components defined in external directories # outside elastix, defined by the user. foreach(userComponentDir ${ELASTIX_USER_COMPONENT_DIRS}) message(STATUS "Searching for user components in: ${userComponentDir}") file(GLOB_RECURSE listOfUserComponents "${userComponentDir}/CMakeLists.txt") foreach(userComponent ${listOfUserComponents}) # Get the path name get_filename_component(path_to_comp ${userComponent} PATH) # Read project name from cmakelists.txt # Find the first line that has the following structure: # ADD_ELXCOMPONENT( projectname [....] # spaces before/after/inbetween are allowed. # ADD_ELXCOMPONENT does not have to be capitalized. # Commented lines (where the first nonwhite character is a #) are ignored. file(STRINGS ${userComponent} addElxComponentLine LIMIT_COUNT 1 REGEX "^[ \t]*[Aa][Dd][Dd]_[Ee][Ll][Xx][Cc][Oo][Mm][Pp][Oo][Nn][Ee][Nn][Tt][ \t]*[(][ \t]*[^ #\t()]+") # Extract the projectname. string(REGEX REPLACE "^[ \t]*[Aa][Dd][Dd]_[Ee][Ll][Xx][Cc][Oo][Mm][Pp][Oo][Nn][Ee][Nn][Tt][ \t]*[(][ \t]*([^ #\t()]+).*" "\\1" componentName "${addElxComponentLine}") # Process the current component if(NOT "${componentName}" STREQUAL "") # For non-subdirectories, the binarydir should be specified. # We use the name of the component for that. set(binaryDir "${elastix_BINARY_DIR}/UserComponents/${componentName}") # Add. Make sure that the path relative to the ELASTIX_USER_COMPONENT_DIRS is set, # so that the component ends up in the correct source group. string(REGEX REPLACE "${ELASTIX_USER_COMPONENT_DIRS}/" "" relative_path_to_comp ${path_to_comp}) add_subdirectory(${path_to_comp} ${binaryDir}) message(STATUS "Found user component: ${relative_path_to_comp}") else() message(STATUS "No user component definition found in: ${userComponent}") endif() endforeach() endforeach()