diff options
Diffstat (limited to 'cmake')
-rw-r--r-- | cmake/QtBaseGlobalTargets.cmake | 18 | ||||
-rw-r--r-- | cmake/QtBuild.cmake | 197 | ||||
-rw-r--r-- | cmake/QtConfig.cmake.in | 1 | ||||
-rw-r--r-- | cmake/QtModuleToolsConfig.cmake.in | 5 | ||||
-rw-r--r-- | cmake/QtPostProcess.cmake | 6 | ||||
-rw-r--r-- | cmake/QtSetup.cmake | 14 | ||||
-rw-r--r-- | cmake/QtToolsConfig.cmake.in | 35 | ||||
-rw-r--r-- | cmake/README.md | 4 |
8 files changed, 233 insertions, 47 deletions
diff --git a/cmake/QtBaseGlobalTargets.cmake b/cmake/QtBaseGlobalTargets.cmake index 73deb51b49..613dc49242 100644 --- a/cmake/QtBaseGlobalTargets.cmake +++ b/cmake/QtBaseGlobalTargets.cmake @@ -11,6 +11,7 @@ target_include_directories(Platform target_compile_definitions(Platform INTERFACE ${QT_PLATFORM_DEFINITIONS}) set(config_install_dir "${INSTALL_LIBDIR}/cmake/${INSTALL_CMAKE_NAMESPACE}") +# Generate and install Qt5 config file. configure_package_config_file( "${PROJECT_SOURCE_DIR}/cmake/QtConfig.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/${INSTALL_CMAKE_NAMESPACE}Config.cmake" @@ -28,6 +29,23 @@ install(FILES COMPONENT Devel ) +# Generate and install Qt5Tools config file. +configure_package_config_file( + "${PROJECT_SOURCE_DIR}/cmake/QtToolsConfig.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/${INSTALL_CMAKE_NAMESPACE}ToolsConfig.cmake" + INSTALL_DESTINATION "${config_install_dir}" +) +write_basic_package_version_file( + ${CMAKE_CURRENT_BINARY_DIR}/${INSTALL_CMAKE_NAMESPACE}ToolsConfigVersion.cmake + VERSION ${PROJECT_VERSION} + COMPATIBILITY AnyNewerVersion +) +install(FILES + "${CMAKE_CURRENT_BINARY_DIR}/${INSTALL_CMAKE_NAMESPACE}ToolsConfig.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/${INSTALL_CMAKE_NAMESPACE}ToolsConfigVersion.cmake" + DESTINATION "${config_install_dir}Tools" + COMPONENT Devel +) ## Library to hold global features: ## These features are stored and accessed via Qt::GlobalConfig, but the diff --git a/cmake/QtBuild.cmake b/cmake/QtBuild.cmake index aaa68d8c0a..0057190360 100644 --- a/cmake/QtBuild.cmake +++ b/cmake/QtBuild.cmake @@ -91,12 +91,32 @@ else() set(QT_HAS_NAMESPACE ON) endif() -macro(qt_internal_set_known_qt_modules) - set(KNOWN_QT_MODULES ${ARGN} CACHE INTERNAL "Known Qt modules" FORCE) +macro(qt_internal_set_qt_known_modules) + set(QT_KNOWN_MODULES ${ARGN} CACHE INTERNAL "Known Qt modules" FORCE) endmacro() # Reset: -qt_internal_set_known_qt_modules("") +qt_internal_set_qt_known_modules("") + +set(QT_KNOWN_MODULES_WITH_TOOLS "" CACHE INTERNAL "Known Qt modules with tools" FORCE) +macro(qt_internal_append_known_modules_with_tools module) + if(NOT ${module} IN_LIST QT_KNOWN_MODULES_WITH_TOOLS) + set(QT_KNOWN_MODULES_WITH_TOOLS "${QT_KNOWN_MODULES_WITH_TOOLS};${module}" + CACHE INTERNAL "Known Qt modules with tools" FORCE) + endif() +endmacro() + +macro(qt_internal_append_known_module_tool module tool) + if(NOT ${tool} IN_LIST QT_KNOWN_MODULE_${module}_TOOLS) + list(APPEND QT_KNOWN_MODULE_${module}_TOOLS "${tool}") + set(QT_KNOWN_MODULE_${module}_TOOLS "${QT_KNOWN_MODULE_${module}_TOOLS}" + CACHE INTERNAL "Known Qt module ${module} tools" FORCE) + endif() +endmacro() + +# Reset syncqt cache variable, to make sure it gets recomputed on reconfiguration, otherwise +# it might not get installed. +unset(QT_SYNCQT CACHE) # For adjusting variables when running tests, we need to know what # the correct variable is for separating entries in PATH-alike @@ -202,12 +222,18 @@ function(qt_ensure_sync_qt) return() endif() - get_target_property(mocPath "${QT_CMAKE_EXPORT_NAMESPACE}::moc" LOCATION) - get_filename_component(binDirectory "${mocPath}" DIRECTORY) - # We could put this into the cache, but on the other hand there's no real need to - # pollute the app's cache with this. For the first qtbase build, the variable is - # set in global scope. - set(QT_SYNCQT "${binDirectory}/syncqt.pl" CACHE FILEPATH "syncqt script") + # When building qtbase, use the source syncqt, otherwise use the installed one. + if(EXISTS "${PROJECT_SOURCE_DIR}/bin/syncqt.pl") + set(QT_SYNCQT "${PROJECT_SOURCE_DIR}/bin/syncqt.pl" CACHE FILEPATH "syncqt script") + message(STATUS "Using source syncqt found at: ${QT_SYNCQT}") + install(PROGRAMS "${PROJECT_SOURCE_DIR}/bin/syncqt.pl" DESTINATION "${INSTALL_LIBEXECDIR}") + else() + get_filename_component(syncqt_absolute_path + "${CMAKE_INSTALL_PREFIX}/${INSTALL_LIBEXECDIR}/syncqt.pl" + ABSOLUTE) + set(QT_SYNCQT "${syncqt_absolute_path}" CACHE FILEPATH "syncqt script") + message(STATUS "Using installed syncqt found at: ${QT_SYNCQT}") + endif() endfunction() # A version of cmake_parse_arguments that makes sure all arguments are processed and errors out @@ -349,8 +375,11 @@ function(qt_autogen_tools target) set_target_properties("${target}" PROPERTIES AUTO${captitalAutogenTool} ON - AUTO${captitalAutogenTool}_EXECUTABLE "$<TARGET_FILE:Qt::${autogen_tool}>") - set_property(TARGET ${target} APPEND PROPERTY AUTOGEN_TARGET_DEPENDS Qt::${autogen_tool}) + AUTO${captitalAutogenTool}_EXECUTABLE + "$<TARGET_FILE:${QT_CMAKE_EXPORT_NAMESPACE}::${autogen_tool}>") + set_property(TARGET ${target} APPEND PROPERTY + AUTOGEN_TARGET_DEPENDS + ${QT_CMAKE_EXPORT_NAMESPACE}::${autogen_tool}) endforeach() set_directory_properties(PROPERTIES @@ -506,14 +535,16 @@ function(add_qt_module target) qt_internal_module_info(module "${target}") # Process arguments: - qt_parse_all_arguments(arg "add_qt_module" "NO_MODULE_HEADERS;STATIC" "CONFIG_MODULE_NAME" + qt_parse_all_arguments(arg "add_qt_module" + "NO_MODULE_HEADERS;STATIC;DISABLE_TOOLS_EXPORT" + "CONFIG_MODULE_NAME" "${__default_private_args};${__default_public_args}" ${ARGN}) if(NOT DEFINED arg_CONFIG_MODULE_NAME) set(arg_CONFIG_MODULE_NAME "${module_lower}") endif() - qt_internal_set_known_qt_modules("${KNOWN_QT_MODULES}" "${target}") + qt_internal_set_qt_known_modules("${QT_KNOWN_MODULES}" "${target}") ### Define Targets: if(${arg_STATIC}) @@ -651,7 +682,7 @@ function(add_qt_module target) # When a public module depends on private, also make its private depend on the other's private set(qt_libs_private "") - foreach(it ${KNOWN_QT_MODULES}) + foreach(it ${QT_KNOWN_MODULES}) list(FIND arg_LIBRARIES "Qt::${it}Private" pos) if(pos GREATER -1) list(APPEND qt_libs_private "Qt::${it}Private") @@ -699,6 +730,64 @@ function(add_qt_module target) DESTINATION "${config_install_dir}" COMPONENT Devel ) + + if(NOT ${arg_DISABLE_TOOLS_EXPORT}) + qt_export_tools(${target}) + endif() +endfunction() + +function(qt_export_tools module_name) + # If no tools were defined belonging to this module, don't create a config and targets file. + # Guards against the case when doing a cross-build and the function is called manually and not + # by add_qt_module. + + if(NOT "${module_name}" IN_LIST QT_KNOWN_MODULES_WITH_TOOLS) + return() + endif() + + # The tools target name. For example: CoreTools + set(target "${module_name}Tools") + set(config_install_dir "${INSTALL_LIBDIR}/cmake/${INSTALL_CMAKE_NAMESPACE}${target}") + + # Add the extra cmake statements to make the tool targets global, so it doesn't matter where + # find_package is called. + # Also assemble a list of tool targets to expose in the config file for informational purposes. + set(extra_cmake_statements "") + set(tool_targets "") + foreach(tool_name ${QT_KNOWN_MODULE_${module_name}_TOOLS}) + set(extra_cmake_statements "${extra_cmake_statements} +get_property(is_global TARGET ${INSTALL_CMAKE_NAMESPACE}::${tool_name} PROPERTY IMPORTED_GLOBAL) +if(NOT is_global) + set_property(TARGET ${INSTALL_CMAKE_NAMESPACE}::${tool_name} PROPERTY IMPORTED_GLOBAL TRUE) +endif() +") + list(APPEND tool_targets "${QT_CMAKE_EXPORT_NAMESPACE}::${tool_name}") + endforeach() + + string(APPEND extra_cmake_statements +"set(${QT_CMAKE_EXPORT_NAMESPACE}${module_name}Tools_TARGETS \"${tool_targets}\")") + + configure_package_config_file( + "${QT_CMAKE_DIR}/QtModuleToolsConfig.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/${INSTALL_CMAKE_NAMESPACE}${target}Config.cmake" + INSTALL_DESTINATION "${config_install_dir}" + ) + write_basic_package_version_file( + "${CMAKE_CURRENT_BINARY_DIR}/${INSTALL_CMAKE_NAMESPACE}${target}ConfigVersion.cmake" + VERSION ${PROJECT_VERSION} + COMPATIBILITY AnyNewerVersion + ) + + install(FILES + "${CMAKE_CURRENT_BINARY_DIR}/${INSTALL_CMAKE_NAMESPACE}${target}Config.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/${INSTALL_CMAKE_NAMESPACE}${target}ConfigVersion.cmake" + DESTINATION "${config_install_dir}" + COMPONENT Devel + ) + + install(EXPORT "${INSTALL_CMAKE_NAMESPACE}${target}Targets" + NAMESPACE "${QT_CMAKE_EXPORT_NAMESPACE}::" + DESTINATION "${INSTALL_LIBDIR}/cmake/${INSTALL_CMAKE_NAMESPACE}${target}") endfunction() function(qt_internal_check_directory_or_type name dir type default result_var) @@ -903,28 +992,68 @@ function(add_qt_test_helper name) add_qt_executable("${name}" NO_INSTALL OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/.." ${ARGN}) endfunction() +# Sets QT_WILL_BUILD_TOOLS if tools will be built. +function(qt_check_if_tools_will_be_built) + set01(will_build_tools NOT CMAKE_CROSSCOMPILING AND NOT QT_FORCE_FIND_TOOLS) + set(QT_WILL_BUILD_TOOLS ${will_build_tools} CACHE INTERNAL "Are tools going to be built" FORCE) +endfunction() # This function is used to define a "Qt tool", such as moc, uic or rcc. # The BOOTSTRAP option allows building it as standalone program, otherwise # it will be linked against QtCore. function(add_qt_tool name) - set01(_build_tools "x${HOST_QT_TOOLS_DIRECTORY}" STREQUAL "x") - if (NOT _build_tools) - message("Searching for ${name}.") - find_program("_PROG_${name}" "${name}" PATHS "${HOST_QT_TOOLS_DIRECTORY}" NO_DEFAULT_PATH) - if (_PROG_${name} STREQUAL "_PROG_${name}-NOTFOUND") - message(FATAL_ERROR "The name \"${name}\" was not found in the " - "HOST_QT_TOOLS_DIRECTORY (\"${HOST_QT_TOOLS_DIRECTORY}\").") - else() - message(STATUS "${name} was found at ${_PROG_${name}}.") - add_executable("${name}" IMPORTED GLOBAL) - set_target_properties("${name}" PROPERTIES IMPORTED_LOCATION "${_PROG_${name}}") - qt_internal_add_target_aliases("${name}") - endif() + qt_parse_all_arguments(arg "add_qt_tool" "BOOTSTRAP;NO_QT;NO_INSTALL" "TOOLS_TARGET" + "${__default_private_args}" ${ARGN}) + + # Handle case when a tool does not belong to a module and it can't be built either (like + # during a cross-compile). + if(NOT arg_TOOLS_TARGET AND NOT QT_WILL_BUILD_TOOLS) + message(FATAL_ERROR "The tool \"${name}\" has not been assigned to a module via" + " TOOLS_TARGET (so it can't be found) and it can't be built" + " (QT_WILL_BUILD_TOOLS is ${QT_WILL_BUILD_TOOLS}).") + endif() + + set(full_name "${QT_CMAKE_EXPORT_NAMESPACE}::${name}") + if(TARGET ${full_name}) + get_property(path TARGET ${full_name} PROPERTY LOCATION) + message(STATUS "Tool '${full_name}' was found at ${path}.") return() endif() - qt_parse_all_arguments(arg "add_qt_tool" "BOOTSTRAP;NO_QT;NO_INSTALL" "" "${__default_private_args}" ${ARGN}) + if(arg_TOOLS_TARGET AND NOT QT_WILL_BUILD_TOOLS) + set(tools_package_name "Qt5${arg_TOOLS_TARGET}Tools") + message(STATUS "Searching for tool '${full_name}' in package ${tools_package_name}.") + + # Only search in path provided by QT_HOST_PATH. We need to do it with CMAKE_PREFIX_PATH + # instead of PATHS option, because any find_dependency call inside a Tools package would + # not get the proper prefix when using PATHS. + set(BACKUP_CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH}) + set(CMAKE_PREFIX_PATH "${QT_HOST_PATH}") + find_package( + ${tools_package_name} + ${PROJECT_VERSION} + NO_PACKAGE_ROOT_PATH + NO_CMAKE_ENVIRONMENT_PATH + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_PACKAGE_REGISTRY + NO_CMAKE_SYSTEM_PATH + NO_CMAKE_SYSTEM_PACKAGE_REGISTRY) + set(CMAKE_PREFIX_PATH ${BACKUP_CMAKE_PREFIX_PATH}) + + if(${${tools_package_name}_FOUND} AND TARGET ${full_name}) + get_property(path TARGET ${full_name} PROPERTY LOCATION) + message(STATUS "${full_name} was found at ${path} using package ${tools_package_name}.") + return() + endif() + endif() + + if(NOT QT_WILL_BUILD_TOOLS) + message(FATAL_ERROR "The tool \"${full_name}\" was not found in the " + "${tools_package_name} package. " + "Package found: ${${tools_package_name}_FOUND}") + else() + message(STATUS "Tool '${full_name}' will be built from source.") + endif() set(disable_autogen_tools "${arg_DISABLE_AUTOGEN_TOOLS}") if (arg_NO_QT) @@ -973,8 +1102,16 @@ function(add_qt_tool name) ) qt_internal_add_target_aliases("${name}") - if(NOT arg_NO_INSTALL) - install(TARGETS "${name}" EXPORT "Qt${PROJECT_VERSION_MAJOR}ToolsTargets" DESTINATION ${INSTALL_TARGETS_DEFAULT_ARGS}) + if(NOT arg_NO_INSTALL AND arg_TOOLS_TARGET) + # Assign a tool to an export set, and mark the module to which the tool belongs. + qt_internal_append_known_modules_with_tools("${arg_TOOLS_TARGET}") + + # Also append the tool to the module list. + qt_internal_append_known_module_tool("${arg_TOOLS_TARGET}" "${name}") + + install(TARGETS "${name}" + EXPORT "Qt${PROJECT_VERSION_MAJOR}${arg_TOOLS_TARGET}ToolsTargets" + DESTINATION ${INSTALL_TARGETS_DEFAULT_ARGS}) endif() endfunction() diff --git a/cmake/QtConfig.cmake.in b/cmake/QtConfig.cmake.in index 69586fe52e..f30cd82cf1 100644 --- a/cmake/QtConfig.cmake.in +++ b/cmake/QtConfig.cmake.in @@ -8,7 +8,6 @@ endif() get_filename_component(_qt_cmake_dir "${CMAKE_CURRENT_LIST_DIR}/.." ABSOLUTE) include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@Targets.cmake") -include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@ToolsTargets.cmake") # if (NOT @INSTALL_CMAKE_NAMESPACE@_FIND_COMPONENTS) # set(@INSTALL_CMAKE_NAMESPACE@_NOT_FOUND_MESSAGE "The Qt package requires at least one component") diff --git a/cmake/QtModuleToolsConfig.cmake.in b/cmake/QtModuleToolsConfig.cmake.in new file mode 100644 index 0000000000..4dc658a10b --- /dev/null +++ b/cmake/QtModuleToolsConfig.cmake.in @@ -0,0 +1,5 @@ +@PACKAGE_INIT@ + +include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Targets.cmake") + +@extra_cmake_statements@ diff --git a/cmake/QtPostProcess.cmake b/cmake/QtPostProcess.cmake index 0d50d7fa47..e63bcc0538 100644 --- a/cmake/QtPostProcess.cmake +++ b/cmake/QtPostProcess.cmake @@ -13,8 +13,8 @@ function(qt_internal_write_depends_file target) endfunction() function(qt_internal_create_depends_files) - message("Generating depends files for ${KNOWN_QT_MODULES}...") - foreach (target ${KNOWN_QT_MODULES}) + message("Generating depends files for ${QT_KNOWN_MODULES}...") + foreach (target ${QT_KNOWN_MODULES}) get_target_property(depends "${target}" LINK_LIBRARIES) set(qtdeps "") foreach (dep ${depends}) @@ -26,7 +26,7 @@ function(qt_internal_create_depends_files) set(dep "${CMAKE_MATCH_1}") endif() - list(FIND KNOWN_QT_MODULES "${dep}" _pos) + list(FIND QT_KNOWN_MODULES "${dep}" _pos) if (_pos GREATER -1) list(APPEND qtdeps "${dep}") endif() diff --git a/cmake/QtSetup.cmake b/cmake/QtSetup.cmake index c7d6f50b73..7285c0c516 100644 --- a/cmake/QtSetup.cmake +++ b/cmake/QtSetup.cmake @@ -54,18 +54,10 @@ include(QtCompilerOptimization) include(QtCompilerFlags) ## Find host tools (if non native): -set(HOST_QT_TOOLS_DIRECTORY "" CACHE PATH "Directory with Qt host tools.") +set(QT_HOST_PATH "" CACHE PATH "Installed Qt host directory path, used for cross compiling.") -if (CMAKE_CROSSCOMPILING AND "x${HOST_QT_TOOLS_DIRECTORY}" STREQUAL "x") - message(FATAL_ERROR "You need to set HOST_QT_TOOLS_DIRECTORY for a cross-complile.") -endif() - -## Find syncqt in HOST TOOLS or locally: -if("x${HOST_QT_TOOLS_DIRECTORY}" STREQUAL "x") - set(QT_SYNCQT "${PROJECT_SOURCE_DIR}/bin/syncqt.pl") - install(PROGRAMS "${QT_SYNCQT}" DESTINATION "${INSTALL_BINDIR}") -else() - set(QT_SYNCQT "${HOST_QT_TOOLS_DIRECTORY}/syncqt.pl") +if (CMAKE_CROSSCOMPILING AND NOT IS_DIRECTORY ${QT_HOST_PATH}) + message(FATAL_ERROR "You need to set QT_HOST_PATH to cross compile Qt.") endif() ## Enable support for sanitizers: diff --git a/cmake/QtToolsConfig.cmake.in b/cmake/QtToolsConfig.cmake.in new file mode 100644 index 0000000000..7b2fa1de74 --- /dev/null +++ b/cmake/QtToolsConfig.cmake.in @@ -0,0 +1,35 @@ +@PACKAGE_INIT@ + +get_filename_component(_qt_tools_cmake_dir "${CMAKE_CURRENT_LIST_DIR}/.." ABSOLUTE) + + if (NOT @INSTALL_CMAKE_NAMESPACE@Tools_FIND_COMPONENTS) + set(@INSTALL_CMAKE_NAMESPACE@Tools_NOT_FOUND_MESSAGE + "The Qt tools package requires at least one component.") + set(@INSTALL_CMAKE_NAMESPACE@Tools_FOUND False) + return() + endif() + +foreach(module ${@INSTALL_CMAKE_NAMESPACE@Tools_FIND_COMPONENTS}) + find_package(@INSTALL_CMAKE_NAMESPACE@${module}Tools + ${_@INSTALL_CMAKE_NAMESPACE@Tools_FIND_PARTS_QUIET} + ${_@INSTALL_CMAKE_NAMESPACE@Tools_FIND_PARTS_REQUIRED} + PATHS ${_qt_tools_cmake_dir} NO_DEFAULT_PATH + ) + if (NOT @INSTALL_CMAKE_NAMESPACE@${module}Tools_FOUND) + string(CONFIGURE ${_qt5_module_location_template} _expected_module_location @ONLY) + + if (@INSTALL_CMAKE_NAMESPACE@_FIND_REQUIRED_${module}) + set(_Qt_NOTFOUND_MESSAGE + "${_Qt_NOTFOUND_MESSAGE}Failed to find Qt component \"${module}\" config file.") + elseif(NOT Qt_FIND_QUIETLY) + message(WARNING "Failed to find Qt component \"${module}\" config file.") + endif() + + unset(_expected_module_location) + endif() +endforeach() + +if (_Qt_NOTFOUND_MESSAGE) + set(@INSTALL_CMAKE_NAMESPACE@Tools_NOT_FOUND_MESSAGE "${_Qt_NOTFOUND_MESSAGE}") + set(@INSTALL_CMAKE_NAMESPACE@Tools_FOUND False) +endif() diff --git a/cmake/README.md b/cmake/README.md index d48c45c9b1..4a21e5f783 100644 --- a/cmake/README.md +++ b/cmake/README.md @@ -126,10 +126,10 @@ Yocto based device SDKs come with an environment setup script that needs to be s In order to make sure that Qt picks up the code generator tools from the host build, you need to pass an extra parameter to cmake: ``` - -DHOST_QT_TOOLS_DIRECTORY=/path/to/your/host_build/bin + -DQT_HOST_PATH=/path/to/your/host_build ``` -The specified path needs to point to a directory that contains all the binaries of the host build of Qt. +The specified path needs to point to a directory that contains an installed host build of Qt. # Debugging CMake files |