Skip to content

Commit 6ae9cc6

Browse files
authored
Merge pull request InsightSoftwareConsortium#5721 from blowekamp/cmake_interface_module
Modernize ITK Module System with CMake Interface Libraries
2 parents fdc5b4a + 14665e6 commit 6ae9cc6

File tree

28 files changed

+2557
-391
lines changed

28 files changed

+2557
-391
lines changed

CMake/ITKConfig.cmake.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ set(ITK_BUILD_DOCUMENTATION "@ITK_BUILD_DOCUMENTATION@")
5959
# List of available ITK modules.
6060
set(ITK_MODULES_ENABLED "@ITK_CONFIG_MODULES_ENABLED@")
6161

62+
# Define the ITK library namespace for CMake targets, without the trailing ::.
63+
set(ITK_LIBRARY_NAMESPACE "@ITK_LIBRARY_NAMESPACE@")
64+
6265
# Import ITK targets.
6366
set(ITK_CONFIG_TARGETS_FILE "@ITK_CONFIG_TARGETS_FILE@")
6467
if(NOT ITK_TARGETS_IMPORTED@ITK_CONFIG_TARGETS_CONDITION@)

CMake/ITKFactoryRegistration.cmake

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -136,10 +136,11 @@
136136
# Caveats
137137
# -------
138138
#
139-
# Since the both include directory containing the registration manager headers
140-
# and the `ITK_IO_FACTORY_REGISTER_MANAGER` COMPILE_DEFINITIONS are set as
141-
# directory properties, including external project (themselves including ITK)
142-
# after including ITK can have unintended side effects.
139+
# The include directory containing the registration manager headers and the
140+
# `ITK_<FACTORY_NAME>_FACTORY_REGISTER_MANAGER` COMPILE_DEFINITIONS are set as
141+
# target interface properties on the factory meta-module targets (ITKImageIO,
142+
# ITKMeshIO, ITKTransformIO, ITKFFTImageFilterInit). This ensures proper propagation
143+
# to dependent targets through modern CMake usage requirements.
143144
#
144145

145146
# _itk_configure_FactoryRegisterManager(<factory_type> <formats>)
@@ -148,6 +149,8 @@
148149
# `<CMAKE_CURRENT_BINARY_DIR>/ITKFactoryRegistration/`.
149150
#
150151
# Header is named using the template `itk<factory_type>FactoryRegisterManager.h`
152+
# The include directory and compile definitions are added to the corresponding
153+
# factory meta-module target's INTERFACE properties.
151154
#
152155
function(_itk_configure_FactoryRegisterManager factory_type formats)
153156
set(LIST_OF_FACTORIES_REGISTRATION "")
@@ -169,6 +172,30 @@ function(_itk_configure_FactoryRegisterManager factory_type formats)
169172
"${CMAKE_CURRENT_BINARY_DIR}/ITKFactoryRegistration/itk${factory_type}FactoryRegisterManager.h"
170173
@ONLY
171174
)
175+
176+
# These functions may be called in the ITK source ( or a fetch content sub-project ),
177+
# so support is needed when the namespaced meta-module target is an alias to the real target.
178+
set(_meta_module ITK${factory_type})
179+
if(ITK_LIBRARY_NAMESPACE)
180+
set(_meta_module ${ITK_LIBRARY_NAMESPACE}::ITK${factory_type})
181+
endif()
182+
get_property(
183+
aliased_target_name
184+
TARGET ${_meta_module}
185+
PROPERTY ALIASED_TARGET
186+
)
187+
if(aliased_target_name)
188+
set(_meta_module ${aliased_target_name})
189+
endif()
190+
# Override the include directories to the current generated FactoryRegistration path.
191+
# Enables multiple calls to adding factories with different sets of factories, in a project.
192+
set_property(
193+
TARGET
194+
${_meta_module}
195+
PROPERTY
196+
INTERFACE_INCLUDE_DIRECTORIES
197+
"$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/ITKFactoryRegistration>"
198+
)
172199
endfunction()
173200

174201
# _itk_ADD_FACTORY_REGISTRATION(<registration_list_var> <names_list_var> <module_name> <factory_name>)

CMake/ITKModuleAPI.cmake

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ macro(_itk_module_config_recurse ns mod)
3030
list(APPEND _${ns}_USED_MODULES ${mod})
3131
itk_module_load("${mod}")
3232
list(APPEND ${ns}_LIBRARIES ${${mod}_LIBRARIES})
33+
list(APPEND ${ns}_INTERFACE_LIBRARIES ${${mod}_INTERFACE_LIBRARY})
3334
list(APPEND ${ns}_INCLUDE_DIRS ${${mod}_INCLUDE_DIRS})
3435
list(APPEND ${ns}_LIBRARY_DIRS ${${mod}_LIBRARY_DIRS})
3536
list(APPEND ${ns}_RUNTIME_LIBRARY_DIRS ${${mod}_RUNTIME_LIBRARY_DIRS})
@@ -75,6 +76,7 @@ endmacro()
7576
# <module>_TRANSITIVE_DEPENDS = List of dependencies on other modules (public link, compile)
7677
# <module>_PRIVATE_DEPENDS = List of dependencies on other modules (private link)
7778
# <module>_LIBRARIES = Libraries to link
79+
# <module>_INTERFACE_LIBRARY = Interface library for module
7880
# <module>_INCLUDE_DIRS = Header search path
7981
# <module>_LIBRARY_DIRS = Library search path (for outside dependencies)
8082
# <module>_RUNTIME_LIBRARY_DIRS = Runtime linker search path
@@ -88,7 +90,15 @@ macro(itk_module_load mod)
8890
# than ITKTargets.cmake are created when modules are built externally. Do not
8991
# include the targets file inside the module itself -- which occurs in a module's
9092
# test configuration.
91-
if(EXISTS "${${mod}_TARGETS_FILE}" AND NOT itk-module STREQUAL mod)
93+
if(
94+
EXISTS
95+
"${${mod}_TARGETS_FILE}"
96+
AND
97+
NOT
98+
"${itk-module}"
99+
STREQUAL
100+
"${mod}"
101+
)
92102
include("${${mod}_TARGETS_FILE}")
93103
endif()
94104
endif()
@@ -97,7 +107,8 @@ endmacro()
97107
# itk_module_config(<namespace> [modules...])
98108
#
99109
# Configures variables describing the given modules and their dependencies:
100-
# <namespace>_LIBRARIES = Libraries to link
110+
# <namespace>_LIBRARIES = Libraries
111+
# <namespace>_INTERFACE_LIBRARIES = Interface libraries to link with public interfaces
101112
# <namespace>_INCLUDE_DIRS = Header search path
102113
# <namespace>_LIBRARY_DIRS = Library search path (for outside dependencies)
103114
# <namespace>_RUNTIME_LIBRARY_DIRS = Runtime linker search path
@@ -123,6 +134,7 @@ endmacro()
123134
# future. For more details, read documentation in CMake/UseITK.cmake.
124135
macro(itk_module_config ns)
125136
set(${ns}_LIBRARIES "")
137+
set(${ns}_INTERFACE_LIBRARIES "")
126138
set(${ns}_INCLUDE_DIRS "")
127139
set(${ns}_LIBRARY_DIRS "")
128140
set(${ns}_RUNTIME_LIBRARY_DIRS "")
@@ -143,6 +155,7 @@ macro(itk_module_config ns)
143155
foreach(
144156
v
145157
${ns}_LIBRARIES
158+
${ns}_INTERFACE_LIBRARIES
146159
${ns}_INCLUDE_DIRS
147160
${ns}_LIBRARY_DIRS
148161
${ns}_RUNTIME_LIBRARY_DIRS
@@ -153,6 +166,7 @@ macro(itk_module_config ns)
153166
list(REMOVE_DUPLICATES ${v})
154167
endif()
155168
endforeach()
169+
156170
foreach(_factory ${${ns}_FACTORY_LIST})
157171
list(SORT ${ns}_${_factory}) # Sort to ensure a deterministic order
158172
endforeach()

CMake/ITKModuleEnablement.cmake

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,46 @@ macro(init_module_vars)
428428
set(${itk-module}-targets-build "${ITK_BINARY_DIR}/ITKTargets.cmake")
429429
endmacro()
430430

431+
#----------------------------------------------------------------------
432+
# Create factory meta-module interface libraries
433+
# These are created for ITKImageIO, ITKMeshIO, ITKTransformIO and FFTImageFilterInit factories
434+
foreach(_factory_name IN ITEMS ImageIO MeshIO TransformIO FFTImageFilterInit)
435+
set(itk-module ITK${_factory_name})
436+
if(NOT TARGET ${itk-module})
437+
add_library(${itk-module} INTERFACE)
438+
439+
init_module_vars(${itk-module})
440+
set(ITK_MODULE_${itk-module}_DECLARED 1)
441+
442+
# Factory modules will be added as dependencies to this meta-module.
443+
# When itk_generate_factory_registration() is called, it adds the include
444+
# directory containing the generated FactoryRegisterManager header file.
445+
#
446+
# Note: Compilation errors like "itkImageIOFactoryRegisterManager.h: No such file or directory"
447+
# indicate that itk_generate_factory_registration() has not been called to generate the header files.
448+
449+
# Add factory registration compile definition
450+
string(TOUPPER ${_factory_name} _factory_uc)
451+
target_compile_definitions(
452+
${itk-module}
453+
INTERFACE
454+
ITK_${_factory_uc}_FACTORY_REGISTER_MANAGER
455+
)
456+
457+
set(ITK_MODULE_${itk-module}_TARGETS_NAMESPACE "")
458+
if(ITK_LIBRARY_NAMESPACE)
459+
set(
460+
ITK_MODULE_${itk-module}_TARGETS_NAMESPACE
461+
"${ITK_LIBRARY_NAMESPACE}::"
462+
)
463+
endif()
464+
465+
# Export and install the factory interface library
466+
itk_module_target_export(${itk-module})
467+
itk_module_target_install(${itk-module})
468+
endif()
469+
endforeach()
470+
431471
# Build all modules.
432472
foreach(itk-module ${ITK_MODULES_ENABLED})
433473
if(NOT ${itk-module}_IS_TEST)

CMake/ITKModuleExternal.cmake

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,8 @@ set(
197197
set(${itk-module}_TARGETS_FILE_BUILD "${${itk-module}-targets-build}")
198198
file(WRITE "${${itk-module}_TARGETS_FILE_BUILD}" "") # Clear targets
199199
set(${itk-module}_ENABLE_SHARED "${ITK_MODULE_${itk-module}_ENABLE_SHARED}")
200+
set(${itk-module}-targets-namespace "")
201+
200202
itk_module_impl()
201203

202204
if(

CMake/ITKModuleHeaderTest.cmake

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,10 +122,11 @@ macro(itk_module_headertest _name)
122122
add_executable(${_test_name} ${_header_test_src})
123123
target_link_libraries(
124124
${_test_name}
125-
PUBLIC
126-
${${_name}_LIBRARIES}
127-
itksys
125+
PRIVATE
126+
${ITK_MODULE_${_name}_TARGETS_NAMESPACE}${_name}Module
127+
${ITK_MODULE_${_name}_TARGETS_NAMESPACE}ITKKWSysModule
128128
)
129+
129130
target_link_options(
130131
${_test_name}
131132
PRIVATE

CMake/ITKModuleInfo.cmake.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@ set(@itk-module@_PUBLIC_DEPENDS "@itk-module-PUBLIC_DEPENDS@")
55
set(@itk-module@_TRANSITIVE_DEPENDS "@itk-module-TRANSITIVE_DEPENDS@")
66
set(@itk-module@_PRIVATE_DEPENDS "@itk-module-PRIVATE_DEPENDS@")
77
set(@itk-module@_LIBRARIES "@itk-module-LIBRARIES@")
8+
set(@itk-module@_INTERFACE_LIBRARY "@itk-module-INTERFACE_LIBRARY@")
89
set(@itk-module@_INCLUDE_DIRS "@itk-module-INCLUDE_DIRS@")
910
set(@itk-module@_LIBRARY_DIRS "@itk-module-LIBRARY_DIRS@")
1011
set(@itk-module@_RUNTIME_LIBRARY_DIRS "@itk-module-RUNTIME_LIBRARY_DIRS@")
1112
set(@itk-module@_TARGETS_FILE "@itk-module-TARGETS_FILE@")
1213
set(@itk-module@_FACTORY_NAMES "@itk-module-FACTORY_NAMES@")
14+
1315
@itk-module-EXPORT_CODE@

0 commit comments

Comments
 (0)