diff options
author | Leander Beernaert <leander.beernaert@qt.io> | 2020-04-27 15:04:57 +0200 |
---|---|---|
committer | Joerg Bornemann <joerg.bornemann@qt.io> | 2020-06-02 22:42:15 +0200 |
commit | 5a779a4ad350accadc4337d332eedb29ba1cc26b (patch) | |
tree | 50263a99b188539a28aaf733a07bb0072eab8fa8 /cmake | |
parent | 47c6466d0acc6d8d733b4fdbaf980a60bbfc93ef (diff) |
CMake: Make it possible to build tools when cross-compiling
This patch allows tools to be built for the target platform when the
QT_BUILD_TOOLS_WHEN_CROSSCOMPILING parameter is set at configuration
time.
To avoid naming conflicts, the target tools are suffixed with "_native".
The qt_get_tool_target_name() function can be used to get the tool name
for both scenarios (cross and non-cross compilation).
Extend pro2cmake to refer to the right target name for tools.
The relevant write_XXX functions have a new target_ref parameter that
will be "${target_name}" for tools and literally the target name for
everything else.
Fixes: QTBUG-81901
Change-Id: If4efbc1fae07a4a3a044dd09c9c06be6d517825e
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'cmake')
-rw-r--r-- | cmake/QtBuild.cmake | 97 | ||||
-rw-r--r-- | cmake/QtModuleDependencies.cmake.in | 22 | ||||
-rw-r--r-- | cmake/QtPostProcess.cmake | 5 | ||||
-rw-r--r-- | cmake/QtSetup.cmake | 7 |
4 files changed, 108 insertions, 23 deletions
diff --git a/cmake/QtBuild.cmake b/cmake/QtBuild.cmake index a89ef60994..941ee1223a 100644 --- a/cmake/QtBuild.cmake +++ b/cmake/QtBuild.cmake @@ -1088,7 +1088,7 @@ function(qt_get_build_parts out_var) list(APPEND parts "tests") endif() - if(NOT CMAKE_CROSSCOMPILING) + if(NOT CMAKE_CROSSCOMPILING OR QT_BUILD_TOOLS_WHEN_CROSSCOMPILING) list(APPEND parts "tools") endif() @@ -2860,10 +2860,13 @@ QMAKE_PRL_LIBS_FOR_CMAKE = ${prl_libs} 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. + # Bail out when cross-compiling, unless QT_BUILD_TOOLS_WHEN_CROSSCOMPILING is on. + if(CMAKE_CROSSCOMPILING AND NOT QT_BUILD_TOOLS_WHEN_CROSSCOMPILING) + return() + endif() - if(NOT "${module_name}" IN_LIST QT_KNOWN_MODULES_WITH_TOOLS OR CMAKE_CROSSCOMPILING) + # If no tools were defined belonging to this module, don't create a config and targets file. + if(NOT "${module_name}" IN_LIST QT_KNOWN_MODULES_WITH_TOOLS) return() endif() @@ -2892,6 +2895,9 @@ function(qt_export_tools module_name) list(APPEND package_deps "${extra_packages}") endif() + if (CMAKE_CROSSCOMPILING AND QT_BUILD_TOOLS_WHEN_CROSSCOMPILING) + string(REGEX REPLACE "_native$" "" tool_name ${tool_name}) + endif() set(extra_cmake_statements "${extra_cmake_statements} if (NOT QT_NO_CREATE_TARGETS) get_property(is_global TARGET ${INSTALL_CMAKE_NAMESPACE}::${tool_name} PROPERTY IMPORTED_GLOBAL) @@ -3832,10 +3838,10 @@ endfunction() # Sets QT_WILL_BUILD_TOOLS if tools will be built. function(qt_check_if_tools_will_be_built) - if(NOT CMAKE_CROSSCOMPILING AND NOT QT_FORCE_FIND_TOOLS) - set(will_build_tools TRUE) - else() + if(QT_FORCE_FIND_TOOLS OR (CMAKE_CROSSCOMPILING AND NOT QT_BUILD_TOOLS_WHEN_CROSSCOMPILING)) set(will_build_tools FALSE) + else() + set(will_build_tools TRUE) endif() set(QT_WILL_BUILD_TOOLS ${will_build_tools} CACHE INTERNAL "Are tools going to be built" FORCE) endfunction() @@ -4114,10 +4120,40 @@ function(qt_get_main_cmake_configuration out_var) set("${out_var}" "${config}" PARENT_SCOPE) endfunction() +# Returns the target name for the tool with the given name. +# +# In most cases, the target name is the same as the tool name. +# If the user specifies to build tools when cross-compiling, then the +# suffix "_native" is appended. +function(qt_get_tool_target_name out_var name) + if (CMAKE_CROSSCOMPILING AND QT_BUILD_TOOLS_WHEN_CROSSCOMPILING) + set(${out_var} ${name}_native PARENT_SCOPE) + else() + set(${out_var} ${name} PARENT_SCOPE) + endif() +endfunction() + +# Returns the tool name for a given tool target. +# This is the inverse of qt_get_tool_target_name. +function(qt_tool_target_to_name out_var target) + set(name ${target}) + if (CMAKE_CROSSCOMPILING AND QT_BUILD_TOOLS_WHEN_CROSSCOMPILING) + string(REGEX REPLACE "_native$" "" name ${target}) + endif() + set(${out_var} ${name} PARENT_SCOPE) +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(qt_add_tool name) +# +# We must pass this function a target name obtained from +# qt_get_tool_target_name like this: +# qt_get_tool_target_name(target_name my_tool) +# qt_add_tool(${target_name}) +# +function(qt_add_tool target_name) + qt_tool_target_to_name(name ${target_name}) qt_parse_all_arguments(arg "qt_add_tool" "BOOTSTRAP;NO_QT;NO_INSTALL" "TOOLS_TARGET;${__default_target_info_args}" "${__default_private_args}" ${ARGN}) @@ -4130,14 +4166,24 @@ function(qt_add_tool name) " (QT_WILL_BUILD_TOOLS is ${QT_WILL_BUILD_TOOLS}).") endif() + if(CMAKE_CROSSCOMPILING AND QT_BUILD_TOOLS_WHEN_CROSSCOMPILING AND (name STREQUAL target_name)) + message(FATAL_ERROR + "qt_add_tool must be passed a target obtained from qt_get_tool_target_name.") + endif() + set(full_name "${QT_CMAKE_EXPORT_NAMESPACE}::${name}") + set(imported_tool_target_found FALSE) if(TARGET ${full_name}) get_property(path TARGET ${full_name} PROPERTY LOCATION) message(STATUS "Tool '${full_name}' was found at ${path}.") - return() + set(imported_tool_target_found TRUE) + if(CMAKE_CROSSCOMPILING AND NOT QT_BUILD_TOOLS_WHEN_CROSSCOMPILING) + return() + endif() endif() - if(arg_TOOLS_TARGET AND NOT QT_WILL_BUILD_TOOLS) + if(arg_TOOLS_TARGET AND (NOT QT_WILL_BUILD_TOOLS OR QT_BUILD_TOOLS_WHEN_CROSSCOMPILING) + AND NOT imported_tool_target_found) set(tools_package_name "Qt6${arg_TOOLS_TARGET}Tools") message(STATUS "Searching for tool '${full_name}' in package ${tools_package_name}.") @@ -4173,7 +4219,9 @@ function(qt_add_tool name) qt_internal_append_known_modules_with_tools("${arg_TOOLS_TARGET}") get_property(path TARGET ${full_name} PROPERTY LOCATION) message(STATUS "${full_name} was found at ${path} using package ${tools_package_name}.") - return() + if (NOT QT_BUILD_TOOLS_WHEN_CROSSCOMPILING) + return() + endif() endif() endif() @@ -4182,7 +4230,11 @@ function(qt_add_tool name) "${tools_package_name} package. " "Package found: ${${tools_package_name}_FOUND}") else() - message(STATUS "Tool '${full_name}' will be built from source.") + if(QT_BUILD_TOOLS_WHEN_CROSSCOMPILING) + message(STATUS "Tool '${target_name}' will be cross-built from source.") + else() + message(STATUS "Tool '${full_name}' will be built from source.") + endif() endif() set(disable_autogen_tools "${arg_DISABLE_AUTOGEN_TOOLS}") @@ -4211,7 +4263,7 @@ function(qt_add_tool name) set(no_qt NO_QT) endif() - qt_add_executable("${name}" OUTPUT_DIRECTORY "${QT_BUILD_DIR}/${INSTALL_BINDIR}" + qt_add_executable("${target_name}" OUTPUT_DIRECTORY "${QT_BUILD_DIR}/${INSTALL_BINDIR}" ${bootstrap} ${no_qt} NO_INSTALL @@ -4231,12 +4283,19 @@ function(qt_add_tool name) TARGET_COMPANY "${arg_TARGET_COMPANY}" TARGET_COPYRIGHT "${arg_TARGET_COPYRIGHT}" ) - qt_internal_add_target_aliases("${name}") + qt_internal_add_target_aliases("${target_name}") + + if (NOT target_name STREQUAL name) + set_target_properties(${target_name} PROPERTIES + OUTPUT_NAME ${name} + EXPORT_NAME ${name} + ) + endif() # If building with a multi-config configuration, the main configuration tool will be placed in # ./bin, while the rest will be in <CONFIG> specific subdirectories. qt_get_tool_cmake_configuration(tool_cmake_configuration) - set_target_properties("${name}" PROPERTIES + set_target_properties("${target_name}" PROPERTIES RUNTIME_OUTPUT_DIRECTORY_${tool_cmake_configuration} "${QT_BUILD_DIR}/${INSTALL_BINDIR}" ) @@ -4245,7 +4304,7 @@ function(qt_add_tool name) 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}") + qt_internal_append_known_module_tool("${arg_TOOLS_TARGET}" "${target_name}") qt_get_cmake_configurations(cmake_configs) @@ -4257,19 +4316,19 @@ function(qt_add_tool name) OUT_VAR install_targets_default_args CMAKE_CONFIG "${cmake_config}" ALL_CMAKE_CONFIGS "${cmake_configs}") - qt_install(TARGETS "${name}" + qt_install(TARGETS "${target_name}" ${install_initial_call_args} CONFIGURATIONS ${cmake_config} ${install_targets_default_args}) unset(install_initial_call_args) endforeach() - qt_apply_rpaths(TARGET "${name}" INSTALL_PATH "${INSTALL_BINDIR}" RELATIVE_RPATH) + qt_apply_rpaths(TARGET "${target_name}" INSTALL_PATH "${INSTALL_BINDIR}" RELATIVE_RPATH) endif() if(QT_FEATURE_separate_debug_info AND (UNIX OR MINGW)) - qt_enable_separate_debug_info(${name} ${INSTALL_BINDIR}) + qt_enable_separate_debug_info(${target_name} ${INSTALL_BINDIR}) endif() endfunction() diff --git a/cmake/QtModuleDependencies.cmake.in b/cmake/QtModuleDependencies.cmake.in index ffb9e8a5d3..5d94eb9a5d 100644 --- a/cmake/QtModuleDependencies.cmake.in +++ b/cmake/QtModuleDependencies.cmake.in @@ -28,9 +28,17 @@ set(_tool_deps "@main_module_tool_deps@") # The tools do not provide linkage targets but executables, where a mismatch # between 32-bit target and 64-bit host does not matter. -set(BACKUP_CMAKE_SIZEOF_VOID_P "${CMAKE_SIZEOF_VOID_P}") +set(BACKUP_@target@_CMAKE_SIZEOF_VOID_P "${CMAKE_SIZEOF_VOID_P}") set(CMAKE_SIZEOF_VOID_P "") +if(QT_HOST_PATH) + # Make sure that the tools find the host tools first + set(BACKUP_@target@_CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH}) + set(BACKUP_@target@_CMAKE_FIND_ROOT_PATH ${CMAKE_FIND_ROOT_PATH}) + list(PREPEND CMAKE_PREFIX_PATH "${QT_HOST_PATH}") + list(PREPEND CMAKE_FIND_ROOT_PATH "${QT_HOST_PATH}") +endif() + foreach(_target_dep ${_tool_deps}) list(GET _target_dep 0 pkg) list(GET _target_dep 1 version) @@ -39,11 +47,19 @@ foreach(_target_dep ${_tool_deps}) if (NOT ${pkg}_FOUND) set(@INSTALL_CMAKE_NAMESPACE@@target@_FOUND FALSE) - set(CMAKE_SIZEOF_VOID_P "${BACKUP_CMAKE_SIZEOF_VOID_P}") + set(CMAKE_SIZEOF_VOID_P "${BACKUP_@target@_CMAKE_SIZEOF_VOID_P}") + if(QT_HOST_PATH) + set(CMAKE_PREFIX_PATH ${BACKUP_@target@_CMAKE_PREFIX_PATH}) + set(CMAKE_FIND_ROOT_PATH ${BACKUP_@target@_CMAKE_FIND_ROOT_PATH}) + endif() return() endif() endforeach() -set(CMAKE_SIZEOF_VOID_P "${BACKUP_CMAKE_SIZEOF_VOID_P}") +if(QT_HOST_PATH) + set(CMAKE_PREFIX_PATH ${BACKUP_@target@_CMAKE_PREFIX_PATH}) + set(CMAKE_FIND_ROOT_PATH ${BACKUP_@target@_CMAKE_FIND_ROOT_PATH}) +endif() +set(CMAKE_SIZEOF_VOID_P "${BACKUP_@target@_CMAKE_SIZEOF_VOID_P}") # note: target_deps example: "Qt6Core\;5.12.0;Qt6Gui\;5.12.0" set(_target_deps "@target_deps@") diff --git a/cmake/QtPostProcess.cmake b/cmake/QtPostProcess.cmake index e6e763c8fe..02ab986a3d 100644 --- a/cmake/QtPostProcess.cmake +++ b/cmake/QtPostProcess.cmake @@ -406,6 +406,11 @@ endif()\n") "set(BUILD_WITH_PCH \"${BUILD_WITH_PCH}\" CACHE STRING \"\")\n") endif() + if(CMAKE_CROSSCOMPILING AND QT_BUILD_TOOLS_WHEN_CROSSCOMPILING) + string(APPEND QT_EXTRA_BUILD_INTERNALS_VARS + "set(QT_BUILD_TOOLS_WHEN_CROSSCOMPILING \"TRUE\" CACHE BOOL \"\" FORCE)\n") + endif() + # Rpath related things that need to be re-used when building other repos. string(APPEND QT_EXTRA_BUILD_INTERNALS_VARS "set(CMAKE_INSTALL_RPATH \"${CMAKE_INSTALL_RPATH}\" CACHE STRING \"\")\n") diff --git a/cmake/QtSetup.cmake b/cmake/QtSetup.cmake index 39142fa332..d892273443 100644 --- a/cmake/QtSetup.cmake +++ b/cmake/QtSetup.cmake @@ -125,8 +125,13 @@ option(QT_NO_MAKE_TESTS "Should tests be built as part of the default 'all' targ # When cross-building, we don't build tools by default. Sometimes this also covers Qt apps as well. # Like in qttools/assistant/assistant.pro, load(qt_app), which is guarded by a qtNomakeTools() call. +set(qt_no_make_tools_default OFF) +if(CMAKE_CROSSCOMPILING AND NOT QT_BUILD_TOOLS_WHEN_CROSSCOMPILING) + set(qt_no_make_tools_default ON) +endif() option(QT_NO_MAKE_TOOLS "Should tools be built as part of the default 'all' target." - "${CMAKE_CROSSCOMPILING}") + "${qt_no_make_tools_default}") +unset(qt_no_make_tools_default) include(CTest) enable_testing() |