summaryrefslogtreecommitdiffstats
path: root/cmake
diff options
context:
space:
mode:
authorAlexandru Croitor <alexandru.croitor@qt.io>2020-10-19 19:35:16 +0200
committerAlexandru Croitor <alexandru.croitor@qt.io>2020-10-23 01:32:39 +0200
commit5d81a5d4f9ad5b3cfb12e2c00fe63a29d056868f (patch)
tree3e24700ae313724a93a29108338e9542eba9a1b8 /cmake
parent2a3a99fe44d18e3560a4b7a05c230a59335da401 (diff)
CMake: Fix headersclean to build with proper flags
It's not sufficient to pass -I{prefix}/include when doing the header clean check. We need to propagate all target include directories and compile definitions, and also the compile flags for good measure. For macOS frameworks we also need to explicitly pass an -iframework flag (qmake passses -F instead), to ensure that <QtGui/qfoo.h> style includes are found when building other repos than qtbase. Task-number: QTBUG-82615 Change-Id: I76d12340bc01c5c948ff04df9a3df384dcb7e076 Reviewed-by: Cristian Adam <cristian.adam@qt.io>
Diffstat (limited to 'cmake')
-rw-r--r--cmake/QtHeadersClean.cmake85
1 files changed, 74 insertions, 11 deletions
diff --git a/cmake/QtHeadersClean.cmake b/cmake/QtHeadersClean.cmake
index cabffcd6e7..b363a86b4e 100644
--- a/cmake/QtHeadersClean.cmake
+++ b/cmake/QtHeadersClean.cmake
@@ -37,6 +37,42 @@ function(qt_internal_add_headers_clean_target
list(PREPEND compiler_to_run "${CMAKE_CXX_COMPILER_LAUNCHER}")
endif()
+ set(target_includes_genex "$<TARGET_PROPERTY:${module_target},INCLUDE_DIRECTORIES>")
+ set(includes_exist_genex "$<BOOL:${target_includes_genex}>")
+ set(target_includes_joined_genex
+ "$<${includes_exist_genex}:-I$<JOIN:${target_includes_genex},;-I>>")
+
+ set(target_defines_genex "$<TARGET_PROPERTY:${module_target},COMPILE_DEFINITIONS>")
+ set(defines_exist_genex "$<BOOL:${target_defines_genex}>")
+ set(target_defines_joined_genex
+ "$<${defines_exist_genex}:-D$<JOIN:${target_defines_genex},;-D>>")
+
+ # TODO: FIXME
+ # Passing COMPILE_OPTIONS can break add_custom_command() if the values contain genexes
+ # that add_custom_command does not support.
+ #
+ # Such a case happens on Linux where libraries linking against Threads::Threads bring in a
+ # '<$<COMPILE_LANG_AND_ID:CUDA,NVIDIA>' genex.
+ #
+ # If this is really required for headersclean (and qmake's headerclean implementation does
+ # actually pass all flags of the associated target), we'll have to replace the genex usage
+ # with an implementation that recursively processes a target's dependencies property
+ # to compile an expanded list of values for COMPILE_OPTIONS, and then filter out any genexes.
+ #
+ # This is similar to the proposed workaround at
+ # https://gitlab.kitware.com/cmake/cmake/-/issues/21074#note_814979
+ #
+ # See also https://gitlab.kitware.com/cmake/cmake/-/issues/21336
+ #
+ #set(target_compile_options_genex "$<TARGET_PROPERTY:${module_target},COMPILE_OPTIONS>")
+ #set(compile_options_exist_genex "$<BOOL:${target_compile_options_genex}>")
+ #set(target_compile_options_joined_genex
+ # "$<${compile_options_exist_genex}:$<JOIN:${target_compile_options_genex},;>>")
+
+ set(target_compile_flags_genex "$<TARGET_PROPERTY:${module_target},COMPILE_FLAGS>")
+ set(compile_flags_exist_genex "$<BOOL:${target_compile_flags_genex}>")
+ set(target_compile_flags_joined_genex
+ "$<${compile_flags_exist_genex}:$<JOIN:${target_compile_flags_genex},;>>")
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU"
OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang"
@@ -95,19 +131,38 @@ function(qt_internal_add_headers_clean_target
list(APPEND cxx_flags "${CMAKE_CXX_SYSROOT_FLAG}" "${CMAKE_OSX_SYSROOT}")
endif()
+ if(APPLE)
+ # For some reason CMake doesn't generate -iframework flags from the INCLUDE_DIRECTORIES
+ # generator expression we provide, so pass it explicitly and hope for the best.
+ get_target_property(is_framework "${target}" FRAMEWORK)
+ if(is_framework)
+ list(APPEND framework_includes
+ "-iframework" "${CMAKE_INSTALL_PREFIX}/${INSTALL_LIBDIR}")
+ endif()
+ endif()
+
foreach(header ${hclean_headers})
get_filename_component(input_path "${header}" ABSOLUTE)
set(artifact_path "header_${header}.o")
+ set(comment_header_path "${CMAKE_CURRENT_SOURCE_DIR}/${header}")
+ file(RELATIVE_PATH comment_header_path "${PROJECT_SOURCE_DIR}" "${comment_header_path}")
add_custom_command(
OUTPUT "${artifact_path}"
- COMMENT "headersclean: Checking header ${header}"
- COMMAND ${compiler_to_run} -c ${cxx_flags} ${hcleanFLAGS}
- -I "${QT_BUILD_DIR}/include" -I "${CMAKE_INSTALL_PREFIX}/include"
- ${hcleanDEFS} -xc++ "${input_path}"
+ COMMENT "headersclean: Checking header ${comment_header_path}"
+ COMMAND
+ ${compiler_to_run} -c ${cxx_flags}
+ "${target_compile_flags_joined_genex}"
+ "${target_defines_joined_genex}"
+ ${hcleanFLAGS}
+ "${target_includes_joined_genex}"
+ ${framework_includes}
+ ${hcleanDEFS}
+ -xc++ "${input_path}"
-o${artifact_path}
IMPLICIT_DEPENDS CXX
- VERBATIM)
+ VERBATIM
+ COMMAND_EXPAND_LISTS)
list(APPEND hclean_artifacts "${artifact_path}")
endforeach()
@@ -123,16 +178,24 @@ function(qt_internal_add_headers_clean_target
# We need realpath here to make sure path starts with drive letter
get_filename_component(input_path "${header}" REALPATH)
set(artifact_path "header_${header}.o")
+ set(comment_header_path "${CMAKE_CURRENT_SOURCE_DIR}/${header}")
+ file(RELATIVE_PATH comment_header_path "${PROJECT_SOURCE_DIR}" "${comment_header_path}")
add_custom_command(
OUTPUT "${artifact_path}"
- COMMENT "headersclean: Checking header ${header}"
- COMMAND ${compiler_to_run} -nologo -c ${CMAKE_CXX_FLAGS} ${hcleanFLAGS}
- -I "${QT_BUILD_DIR}/include" -I "${CMAKE_INSTALL_PREFIX}/include"
- ${hcleanDEFS} -FI "${input_path}"
- -Fo${artifact_path} "${source_path}"
+ COMMENT "headersclean: Checking header ${comment_header_path}"
+ COMMAND
+ ${compiler_to_run} -nologo -c ${CMAKE_CXX_FLAGS}
+ "${target_compile_flags_joined_genex}"
+ "${target_defines_joined_genex}"
+ ${hcleanFLAGS}
+ "${target_includes_joined_genex}"
+ ${hcleanDEFS}
+ -FI "${input_path}"
+ -Fo${artifact_path} "${source_path}"
IMPLICIT_DEPENDS CXX
- VERBATIM)
+ VERBATIM
+ COMMAND_EXPAND_LISTS)
list(APPEND hclean_artifacts "${artifact_path}")
endforeach()
else()