Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMake/Testing/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ endmacro()
# Add 'CMake script' Tests
#
add_cmakescript_test(ctk_list_to_string_test ctkListToString)
add_cmakescript_test(ctk_function_get_include_dirs_test ctkFunctionGetIncludeDirs)
3 changes: 1 addition & 2 deletions CMake/ctkFunctionGeneratePluginManifest.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,7 @@ function(ctkFunctionGeneratePluginManifest MANIFEST_QRC_FILEPATH_VAR)

set(_manifest_filename "MANIFEST.MF")
set(_manifest_filepath "${CMAKE_CURRENT_BINARY_DIR}/${_manifest_filename}")
string(REPLACE "." "_" _symbolic_name ${MY_SYMBOLIC_NAME})
set(_manifest_qrc_filepath "${CMAKE_CURRENT_BINARY_DIR}/${_symbolic_name}_manifest.qrc")
set(_manifest_qrc_filepath "${CMAKE_CURRENT_BINARY_DIR}/manifest.qrc")

set(_manifest_qrc_content
"<!DOCTYPE RCC><RCC version=\"1.0\">
Expand Down
109 changes: 90 additions & 19 deletions CMake/ctkFunctionGetIncludeDirs.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -55,25 +55,39 @@ function(ctkFunctionGetIncludeDirs var_include_dirs)
)
endif()

list(APPEND _include_dirs
# Ensure AUTOUIC-generated headers (ui_*.h) are on the include path.
#
# By default CMake writes them to:
#
# - Single-config generators (Ninja/Makefiles):
# <AUTOGEN_BUILD_DIR>/include
#
# - Multi-config generators (VS, Xcode, Ninja Multi-Config):
# <AUTOGEN_BUILD_DIR>/include_<CONFIG>
#
# where AUTOGEN_BUILD_DIR defaults to:
# <target-binary-dir>/<target-name>_autogen
#
# References:
# - https://cmake.org/cmake/help/latest/manual/cmake-qt.7.html#autouic
# - https://cmake.org/cmake/help/latest/prop_tgt/AUTOGEN_BUILD_DIR.html
${${dep}_BINARY_DIR}/${dep}_autogen/include$<$<BOOL:${_isMultiConfig}>:_$<CONFIG>>
)
# Ensure AUTOUIC-generated headers (ui_*.h) are on the include path.
#
# By default CMake writes them to:
#
# - Single-config generators (Ninja/Makefiles):
# <AUTOGEN_BUILD_DIR>/include
#
# - Multi-config generators (VS, Xcode, Ninja Multi-Config):
# <AUTOGEN_BUILD_DIR>/include_<CONFIG>
#
# where AUTOGEN_BUILD_DIR defaults to:
# <target-binary-dir>/<target-name>_autogen
#
# References:
# - https://cmake.org/cmake/help/latest/manual/cmake-qt.7.html#autouic
# - https://cmake.org/cmake/help/latest/prop_tgt/AUTOGEN_BUILD_DIR.html
#
# Plug-ins are excluded, because that directory also holds AUTOMOC's
# output, in a subdirectory named after a hash of the source directory
# relative to the source tree. Plug-ins of a project tend to keep their
# sources in the same relative directory, so the hash is identical for
# all of them, and mocs_compilation.cpp includes its moc output with
# angle brackets. Since CMake appends a target's own autogen include dir
# last, a plug-in would compile a dependency's meta object instead of its
# own whenever both have a header of the same name. A plug-in has no
# reason to include another plug-in's generated ui_*.h.
#
# ${dep}_INCLUDE_SUFFIXES is only ever set by ctkMacroBuildPlugin.
if(NOT DEFINED ${dep}_INCLUDE_SUFFIXES)
list(APPEND _include_dirs
${${dep}_BINARY_DIR}/${dep}_autogen/include$<$<BOOL:${_isMultiConfig}>:_$<CONFIG>>
)
endif()

# For external projects, CTKConfig.cmake contains variables
# listening the include dirs for CTK libraries and plugins
Expand Down Expand Up @@ -114,3 +128,60 @@ function(ctkFunctionGetIncludeDirs var_include_dirs)
set(${var_include_dirs} ${_include_dirs} PARENT_SCOPE)

endfunction()

#
# cmake -DTEST_ctk_function_get_include_dirs_test:BOOL=ON -P ctkFunctionGetIncludeDirs.cmake
#
function(ctk_function_get_include_dirs_test)

include(${CMAKE_CURRENT_LIST_DIR}/ctkMacroParseArguments.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/ctkMacroListFilter.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/ctkMacroTargetLibraries.cmake)

function(ctk_function_get_include_dirs_test_check id dirs pattern expected)
set(_found 0)
foreach(_dir IN LISTS dirs)
if(_dir MATCHES "${pattern}")
set(_found 1)
endif()
endforeach()
if(NOT _found EQUAL expected)
message(FATAL_ERROR "Problem with ctkFunctionGetIncludeDirs() - See testcase: ${id}\n"
"pattern:${pattern}\n"
"found:${_found}\n"
"expected:${expected}\n"
"dirs:${dirs}")
endif()
endfunction()

# A library and a plug-in dependency. Only ctkMacroBuildPlugin defines
# <target>_INCLUDE_SUFFIXES, so that is what tells the two apart.
set(CTKFoo_SOURCE_DIR "/src/Libs/Foo")
set(CTKFoo_BINARY_DIR "/bin/Libs/Foo")

set(org_commontk_bar_SOURCE_DIR "/src/Plugins/org.commontk.bar")
set(org_commontk_bar_BINARY_DIR "/bin/Plugins/org.commontk.bar")
set(org_commontk_bar_INCLUDE_SUFFIXES "")

set(mytarget_DEPENDENCIES CTKFoo org_commontk_bar)

set(dirs )
ctkFunctionGetIncludeDirs(dirs mytarget)

# A library contributes its autogen dir, because a dependent may include the
# ui_*.h generated for it.
ctk_function_get_include_dirs_test_check(1 "${dirs}" "CTKFoo_autogen" 1)

# A plug-in does not. That directory also holds AUTOMOC output in a
# subdirectory named after a hash of the source directory relative to the
# source tree, which collides between plug-ins sharing that layout.
ctk_function_get_include_dirs_test_check(2 "${dirs}" "org_commontk_bar_autogen" 0)

# The plug-in is still on the include path, only its autogen dir is not.
ctk_function_get_include_dirs_test_check(3 "${dirs}" "org.commontk.bar" 1)

message("SUCCESS")
endfunction()
if(TEST_ctk_function_get_include_dirs_test)
ctk_function_get_include_dirs_test()
endif()
20 changes: 18 additions & 2 deletions CMake/ctkMacroBuildPlugin.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -223,10 +223,9 @@ macro(ctkMacroBuildPlugin)

# Add any other additional resource files
if(_plugin_cached_resources_in_source_tree OR _plugin_cached_resources_in_binary_tree)
string(REPLACE "." "_" _plugin_symbolicname ${Plugin-SymbolicName})
set(plugin_qrc_filepath)
ctkMacroGeneratePluginResourcefile(plugin_qrc_filepath
NAME ${_plugin_symbolicname}_cached.qrc
NAME cached.qrc
PREFIX ${Plugin-SymbolicName}
RESOURCES ${_plugin_cached_resources_in_source_tree}
BINARY_RESOURCES ${_plugin_cached_resources_in_binary_tree}
Expand Down Expand Up @@ -257,9 +256,19 @@ macro(ctkMacroBuildPlugin)
HAVE_QT${CTK_QT_VERSION}
)

# The autogen include directories of the dependencies are only needed to
# compile this plug-in. They must not become part of its exported interface:
# they contain $<CONFIG>, and a consumer generating configurations that were
# never built here would reference directories that do not exist, which CMake
# rejects when it reads the imported target.
set(my_autogen_includes ${my_includes})
list(FILTER my_autogen_includes INCLUDE REGEX "_autogen/include")
list(FILTER my_includes EXCLUDE REGEX "_autogen/include")

target_include_directories(${lib_name}
PUBLIC "$<BUILD_INTERFACE:${my_includes}>"
"$<INSTALL_INTERFACE:${CTK_INSTALL_PLUGIN_INCLUDE_DIR}/${Plugin-SymbolicName}>"
PRIVATE ${my_autogen_includes}
)

# Configure CMake Qt automatic code generation
Expand All @@ -273,7 +282,14 @@ macro(ctkMacroBuildPlugin)
endforeach()
list(REMOVE_DUPLICATES uic_search_paths)

# A plug-in target name is derived from its symbolic name and is long, and
# the default autogen directory repeats it below a directory that already
# carries it. Together with the names of the generated sources this can
# exceed the 260 character path limit of the Windows toolchain. The autogen
# directory only has to be unique per target, and the plug-in's binary
# directory already is.
set_target_properties(${lib_name} PROPERTIES
AUTOGEN_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/autogen"
AUTOMOC ON
AUTORCC ON
AUTOUIC ON
Expand Down
Loading