summaryrefslogtreecommitdiffstats
path: root/cmake
diff options
context:
space:
mode:
authorAlexandru Croitor <alexandru.croitor@qt.io>2020-05-05 10:30:35 +0200
committerJoerg Bornemann <joerg.bornemann@qt.io>2020-05-07 15:41:16 +0200
commitbf315c5526cb5cce6581de89f2747d7d2c3bad0a (patch)
tree0854ebfa49383f467ec10b6012c22bc598b56815 /cmake
parentc70dcffbdb83fad1c829ea3c2aff7b74e66f0eec (diff)
CMake: Make build system of installed Qt more relocatable
Aka handle CMAKE_INSTALL_PREFIX in a more relocatable way. The following story inspired this change. If a user wants to build a Qt repo into a different install prefix than the usual Qt one, this will fail configuration because we look for various things like syncqt, qdoc, etc relative to CMAKE_INSTALL_PREFIX, which will now point to a different location where none of the above tools are located. The intent for such a use case is to support building Qt packages with Conan, which sets a random install prefix when configuring a repo. The idea is to derive the qt prefix dynamically from the QtBuildInternals package location. Essentially it's a reverse relative path from the QtBuildInternalsConfig.cmake file to the install prefix that was specified when initially configuring qtbase. Once the dynamic prefix is computed (so we know where the possibly relocated Qt is), we can find tools like syncqt and qdoc. This is an initial attempt to support a use case like that. More design work will probably needed in case if tools / libs need to be found in a location different than the Qt install prefix (so support for multiple install prefixes / search paths). An example of such a case would be when building qtdeclarative and qtquickcontrols2 as Conan packages in one go. Most likely the qmltyperegistrar tool will be located in the random install prefix set by Conan, so building qtquickcontrols2 might fail due to not finding the tool in the original Qt install prefix. As to the implementation details, the change does the following: - Dynamically computes and sets the QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX variable when find_package()'ing QtBuildInternals. It's an absolute path pointing to where the relocated Qt is. - When building qtbase this variable is not yet available (due to QtBuildInternalsExtra not existing), in that case we set the variable to the absolute path of CMAKE_INSTALL_PREFIX (but only for the initial qtbase configuration). - Remove QT_BUILD_INTERNALS_ORIGINAL_INSTALL_PREFIX which was used for standalone tests purposes. It's not needed now that we compute the location of the Qt prefix dynamically. - The Unixy qt-cmake and qt-cmake-private shell scripts now use a relative path to find the toolchain file we created. - The toolchain file also dynamically computes the location of the Qt packages, and adds them to CMAKE_PREFIX_PATH. - A lot of existing CMAKE_INSTALL_PREFIX uses are replaced with QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX. This includes finding tool locations, mkspecs dir, path environment setup for tools, etc. - Some places still use CMAKE_PREFIX_PATH in the following cases - When determining paths while configuring qtbase (valid cases) - When I wasn't sure what the behavior should be, so I left them as-is (an example is documentation generation, do we want to install it into the random Conan prefix, or into the main prefix? Currently it installs in the random prefix). Note that relocating a Qt installation does not work for non-prefix / non-installed builds, due to hardcoded paths to include directories and libraries in generated FooTargets.cmake files. Task-number: QTBUG-83999 Change-Id: I87d6558729db93121b1715771034b03ce3295923 Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
Diffstat (limited to 'cmake')
-rw-r--r--cmake/QtBaseGlobalTargets.cmake16
-rw-r--r--cmake/QtBuild.cmake173
-rw-r--r--cmake/QtBuildInformation.cmake4
-rw-r--r--cmake/QtBuildInternals/QtBuildInternalsConfig.cmake34
-rw-r--r--cmake/QtBuildInternalsExtra.cmake.in32
-rw-r--r--cmake/QtPostProcess.cmake1
-rw-r--r--cmake/QtSetup.cmake8
-rw-r--r--cmake/qt.toolchain.cmake.in10
8 files changed, 179 insertions, 99 deletions
diff --git a/cmake/QtBaseGlobalTargets.cmake b/cmake/QtBaseGlobalTargets.cmake
index c82ef410a3..d00d536194 100644
--- a/cmake/QtBaseGlobalTargets.cmake
+++ b/cmake/QtBaseGlobalTargets.cmake
@@ -23,12 +23,21 @@ set(__GlobalConfig_path_suffix "${INSTALL_CMAKE_NAMESPACE}")
qt_path_join(__GlobalConfig_build_dir ${QT_CONFIG_BUILD_DIR} ${__GlobalConfig_path_suffix})
qt_path_join(__GlobalConfig_install_dir ${QT_CONFIG_INSTALL_DIR} ${__GlobalConfig_path_suffix})
set(__GlobalConfig_install_dir_absolute "${__GlobalConfig_install_dir}")
+set(__qt_bin_dir_absolute "${QT_INSTALL_DIR}/${INSTALL_BINDIR}")
if(QT_WILL_INSTALL)
# Need to prepend the install prefix when doing prefix builds, because the config install dir
# is relative then.
qt_path_join(__GlobalConfig_install_dir_absolute
- ${CMAKE_INSTALL_PREFIX} ${__GlobalConfig_install_dir_absolute})
+ ${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}
+ ${__GlobalConfig_install_dir_absolute})
+ qt_path_join(__qt_bin_dir_absolute
+ ${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX} ${__qt_bin_dir_absolute})
endif()
+# Compute relative path from $qt_prefix/bin dir to global CMake config install dir, to use in the
+# unix-y qt-cmake shell script, to make it work even if the installed Qt is relocated.
+file(RELATIVE_PATH
+ __GlobalConfig_relative_path_from_bin_dir_to_cmake_config_dir
+ ${__qt_bin_dir_absolute} ${__GlobalConfig_install_dir_absolute})
# Generate and install Qt6 config file.
configure_package_config_file(
@@ -158,7 +167,9 @@ endif()
string(REPLACE ";" "\n" init_vcpkg "${init_vcpkg}")
string(REPLACE ";" "\n" init_platform "${init_platform}")
string(REPLACE "LITERAL_SEMICOLON" ";" init_platform "${init_platform}")
+qt_compute_relative_path_from_cmake_config_dir_to_prefix()
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/qt.toolchain.cmake.in" "${__GlobalConfig_build_dir}/qt.toolchain.cmake" @ONLY)
+unset(qt_path_from_cmake_config_dir_to_prefix)
qt_install(FILES "${__GlobalConfig_build_dir}/qt.toolchain.cmake" DESTINATION "${__GlobalConfig_install_dir}" COMPONENT Devel)
# Also provide a convenience cmake wrapper
@@ -196,7 +207,8 @@ unset(__qt_cmake_extra)
# Instead a template CMakeLists.txt project is used which sets up all the necessary private bits
# and then calls add_subdirectory on the provided project path.
set(__qt_cmake_standalone_test_bin_name "qt-cmake-standalone-test")
-set(__qt_cmake_private_path "${CMAKE_INSTALL_PREFIX}/${INSTALL_BINDIR}/qt-cmake-private")
+set(__qt_cmake_private_path
+ "${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_BINDIR}/qt-cmake-private")
set(__qt_cmake_standalone_test_path
"${__build_internals_install_dir}/${__build_internals_standalone_test_template_dir}")
if(UNIX)
diff --git a/cmake/QtBuild.cmake b/cmake/QtBuild.cmake
index 7ed47fc4f2..1581b39a28 100644
--- a/cmake/QtBuild.cmake
+++ b/cmake/QtBuild.cmake
@@ -13,7 +13,8 @@ function(qt_configure_process_path name default docstring)
else()
get_filename_component(given_path_as_abs "${${name}}" ABSOLUTE BASE_DIR
"${CMAKE_INSTALL_PREFIX}")
- file(RELATIVE_PATH rel_path "${CMAKE_INSTALL_PREFIX}" "${given_path_as_abs}")
+ file(RELATIVE_PATH rel_path "${CMAKE_INSTALL_PREFIX}"
+ "${given_path_as_abs}")
# If absolute path given, check that it's inside the prefix (error out if not).
# TODO: Figure out if we need to support paths that are outside the prefix.
@@ -75,6 +76,59 @@ qt_configure_process_path(INSTALL_DESCRIPTIONSDIR
"${INSTALL_DATADIR}/modules"
"Module description files directory")
+function(qt_internal_set_up_global_paths)
+ # Compute the values of QT_BUILD_DIR, QT_INSTALL_DIR, QT_CONFIG_BUILD_DIR, QT_CONFIG_INSTALL_DIR
+ # taking into account whether the current build is a prefix build or a non-prefix build,
+ # and whether it is a superbuild or non-superbuild.
+ # A third case is when another module or standalone tests are built against a super-built Qt.
+ # The layout for the third case is the same as for non-superbuilds.
+ #
+ # These values should be prepended to file paths in commands or properties,
+ # in order to correctly place generated Config files, generated Targets files,
+ # excutables / libraries, when copying / installing files, etc.
+ #
+ # The build dir variables will always be absolute paths.
+ # The QT_INSTALL_DIR variable will have a relative path in a prefix build,
+ # which means that it can be empty, so use qt_join_path to prevent accidental absolute paths.
+ if(QT_SUPERBUILD)
+ # In this case, we always copy all the build products in qtbase/{bin,lib,...}
+ if(QT_WILL_INSTALL)
+ set(QT_BUILD_DIR "${QtBase_BINARY_DIR}")
+ set(QT_INSTALL_DIR "")
+ else()
+ set(QT_BUILD_DIR "${QtBase_BINARY_DIR}")
+ set(QT_INSTALL_DIR "${QtBase_BINARY_DIR}")
+ endif()
+ else()
+ if(QT_WILL_INSTALL)
+ # In the usual prefix build case, the build dir is the current module build dir,
+ # and the install dir is the prefix, so we don't set it.
+ set(QT_BUILD_DIR "${CMAKE_BINARY_DIR}")
+ set(QT_INSTALL_DIR "")
+ else()
+ # When doing a non-prefix build, both the build dir and install dir are the same,
+ # pointing to the qtbase build dir.
+ set(QT_BUILD_DIR "${CMAKE_INSTALL_PREFIX}")
+ set(QT_INSTALL_DIR "${QT_BUILD_DIR}")
+ endif()
+ endif()
+
+ set(__config_path_part "${INSTALL_LIBDIR}/cmake")
+ set(QT_CONFIG_BUILD_DIR "${QT_BUILD_DIR}/${__config_path_part}")
+ set(QT_CONFIG_INSTALL_DIR "${QT_INSTALL_DIR}")
+ if(QT_CONFIG_INSTALL_DIR)
+ string(APPEND QT_CONFIG_INSTALL_DIR "/")
+ endif()
+ string(APPEND QT_CONFIG_INSTALL_DIR ${__config_path_part})
+
+ set(QT_BUILD_DIR "${QT_BUILD_DIR}" PARENT_SCOPE)
+ set(QT_INSTALL_DIR "${QT_INSTALL_DIR}" PARENT_SCOPE)
+ set(QT_CONFIG_BUILD_DIR "${QT_CONFIG_BUILD_DIR}" PARENT_SCOPE)
+ set(QT_CONFIG_INSTALL_DIR "${QT_CONFIG_INSTALL_DIR}" PARENT_SCOPE)
+endfunction()
+qt_internal_set_up_global_paths()
+qt_get_relocatable_install_prefix(QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX)
+
# The variables might have already been set in QtBuildInternalsExtra.cmake if the file is included
# while building a new module and not QtBase. In that case, stop overriding the value.
if(NOT INSTALL_CMAKE_NAMESPACE)
@@ -94,8 +148,11 @@ if(NOT QT_MKSPECS_DIR)
if("${QT_BUILD_INTERNALS_PATH}" STREQUAL "")
get_filename_component(QT_MKSPECS_DIR "${CMAKE_CURRENT_LIST_DIR}/../mkspecs" ABSOLUTE)
else()
- # We can rely on CMAKE_INSTALL_PREFIX being set by QtBuildInternalsExtra.cmake
- get_filename_component(QT_MKSPECS_DIR "${CMAKE_INSTALL_PREFIX}/${INSTALL_MKSPECSDIR}" ABSOLUTE)
+ # We can rely on QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX being set by
+ # QtBuildInternalsExtra.cmake.
+ get_filename_component(
+ QT_MKSPECS_DIR
+ "${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_MKSPECSDIR}" ABSOLUTE)
endif()
set(QT_MKSPECS_DIR "${QT_MKSPECS_DIR}" CACHE INTERNAL "")
endif()
@@ -138,7 +195,7 @@ function(qt_setup_tool_path_command)
if(NOT WIN32)
return()
endif()
- set(bindir "${CMAKE_INSTALL_PREFIX}/${INSTALL_BINDIR}")
+ set(bindir "${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_BINDIR}")
file(TO_NATIVE_PATH "${bindir}" bindir)
list(APPEND command COMMAND)
list(APPEND command set PATH=${bindir}$<SEMICOLON>%PATH%)
@@ -305,51 +362,6 @@ else()
set(QT_PATH_SEPARATOR ":")
endif()
-# Compute the values of QT_BUILD_DIR, QT_INSTALL_DIR, QT_CONFIG_BUILD_DIR, QT_CONFIG_INSTALL_DIR
-# taking into account whether the current build is a prefix build or a non-prefix build,
-# and whether it is a superbuild or non-superbuild.
-# A third case is when another module or standalone tests are built against a super-built Qt.
-# The layout for the third case is the same as for non-superbuilds.
-#
-# These values should be prepended to file paths in commands or properties,
-# in order to correctly place generated Config files, generated Targets files,
-# excutables / libraries, when copying / installing files, etc.
-#
-# The build dir variables will always be absolute paths.
-# The QT_INSTALL_DIR variable will have a relative path in a prefix build,
-# which means that it can be empty, so use qt_join_path to prevent accidental absolute paths.
-if(QT_SUPERBUILD)
- # In this case, we always copy all the build products in qtbase/{bin,lib,...}
- if(QT_WILL_INSTALL)
- set(QT_BUILD_DIR "${QtBase_BINARY_DIR}")
- set(QT_INSTALL_DIR "")
- else()
- set(QT_BUILD_DIR "${QtBase_BINARY_DIR}")
- set(QT_INSTALL_DIR "${QtBase_BINARY_DIR}")
- endif()
-else()
- if(QT_WILL_INSTALL)
- # In the usual prefix build case, the build dir is the current module build dir,
- # and the install dir is the prefix, so we don't set it.
- set(QT_BUILD_DIR "${CMAKE_BINARY_DIR}")
- set(QT_INSTALL_DIR "")
- else()
- # When doing a non-prefix build, both the build dir and install dir are the same,
- # pointing to the qtbase build dir.
- set(QT_BUILD_DIR "${CMAKE_INSTALL_PREFIX}")
- set(QT_INSTALL_DIR "${QT_BUILD_DIR}")
- endif()
-endif()
-
-set(__config_path_part "${INSTALL_LIBDIR}/cmake")
-set(QT_CONFIG_BUILD_DIR "${QT_BUILD_DIR}/${__config_path_part}")
-set(QT_CONFIG_INSTALL_DIR "${QT_INSTALL_DIR}")
-if(QT_CONFIG_INSTALL_DIR)
- string(APPEND QT_CONFIG_INSTALL_DIR "/")
-endif()
-string(APPEND QT_CONFIG_INSTALL_DIR ${__config_path_part})
-unset(__config_path_part)
-
# This is used to hold extra cmake code that should be put into QtBuildInternalsExtra.cmake file
# at the QtPostProcess stage.
set(QT_BUILD_INTERNALS_EXTRA_CMAKE_CODE "")
@@ -848,10 +860,10 @@ function(qt_generate_qt_conf)
"[EffectivePaths]
Prefix=..
[DevicePaths]
-Prefix=${CMAKE_INSTALL_PREFIX}
+Prefix=${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}
[Paths]
-Prefix=${CMAKE_INSTALL_PREFIX}
-HostPrefix=${CMAKE_INSTALL_PREFIX}
+Prefix=${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}
+HostPrefix=${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}
Sysroot=
SysrootifyPrefix=false
TargetSpec=${QT_QMAKE_TARGET_MKSPEC}
@@ -1021,7 +1033,7 @@ function(qt_ensure_sync_qt)
message(STATUS "Using host syncqt found at: ${QT_SYNCQT}")
else()
get_filename_component(syncqt_absolute_path
- "${CMAKE_INSTALL_PREFIX}/${INSTALL_LIBEXECDIR}/syncqt.pl"
+ "${QT_BUILD_INTERNALS_RELOCATABLE_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}")
@@ -3319,15 +3331,17 @@ function(qt_add_test name)
set_tests_properties(${name} PROPERTIES TIMEOUT ${arg_TIMEOUT})
endif()
- # Get path to <original_qtbase_install_prefix>/bin, as well as CMAKE_INSTALL_PREFIX/bin, then
+ # Get path to <qt_relocatable_install_prefix>/bin, as well as CMAKE_INSTALL_PREFIX/bin, then
# prepend them to the PATH environment variable.
# It's needed on Windows to find the shared libraries and plugins.
- # original_qtbase_install_prefix is the CMAKE_INSTALL_PREFIX specified when building qtbase.
+ # qt_relocatable_install_prefix is dynamically computed from the location of where the Qt CMake
+ # package is found.
# The regular CMAKE_INSTALL_PREFIX can be different for example when building standalone tests.
- # Latest CMAKE_INSTALL_PREFIX takes priority for the PATH environment variable.
+ # Any given CMAKE_INSTALL_PREFIX takes priority over qt_relocatable_install_prefix for the
+ # PATH environment variable.
set(install_prefixes "${CMAKE_INSTALL_PREFIX}")
- if(QT_BUILD_INTERNALS_ORIGINAL_INSTALL_PREFIX)
- list(APPEND install_prefixes "${QT_BUILD_INTERNALS_ORIGINAL_INSTALL_PREFIX}")
+ if(QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX)
+ list(APPEND install_prefixes "${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}")
endif()
set(test_env_path "PATH=${CMAKE_CURRENT_BINARY_DIR}")
@@ -4083,13 +4097,13 @@ function(qt_add_docs)
endif()
if (NOT QT_SUPERBUILD OR QT_WILL_INSTALL)
- set(qdoc_bin "${CMAKE_INSTALL_PREFIX}/${INSTALL_BINDIR}/qdoc")
- set(qtattributionsscanner_bin "${CMAKE_INSTALL_PREFIX}/${INSTALL_BINDIR}/qtattributionsscanner")
- set(qhelpgenerator_bin "${CMAKE_INSTALL_PREFIX}/${INSTALL_BINDIR}/qhelpgenerator")
+ set(qdoc_bin "${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_BINDIR}/qdoc")
+ set(qtattributionsscanner_bin "${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_BINDIR}/qtattributionsscanner")
+ set(qhelpgenerator_bin "${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_BINDIR}/qhelpgenerator")
else()
- set(qdoc_bin "${CMAKE_INSTALL_PREFIX}/qtbase/${INSTALL_BINDIR}/qdoc")
- set(qtattributionsscanner_bin "${CMAKE_INSTALL_PREFIX}/qtbase/${INSTALL_BINDIR}/qtattributionsscanner")
- set(qhelpgenerator_bin "${CMAKE_INSTALL_PREFIX}/qtbase/${INSTALL_BINDIR}/qhelpgenerator")
+ set(qdoc_bin "${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/qtbase/${INSTALL_BINDIR}/qdoc")
+ set(qtattributionsscanner_bin "${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/qtbase/${INSTALL_BINDIR}/qtattributionsscanner")
+ set(qhelpgenerator_bin "${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/qtbase/${INSTALL_BINDIR}/qhelpgenerator")
endif()
get_target_property(target_type ${target} TYPE)
@@ -4122,11 +4136,11 @@ function(qt_add_docs)
set(qdoc_output_dir "${CMAKE_BINARY_DIR}/${INSTALL_DOCDIR}/${doc_target}")
set(index_dir "${CMAKE_BINARY_DIR}/${INSTALL_DOCDIR}")
elseif (QT_SUPERBUILD)
- set(qdoc_output_dir "${CMAKE_INSTALL_PREFIX}/qtbase/${INSTALL_DOCDIR}/${doc_target}")
- set(index_dir "${CMAKE_INSTALL_PREFIX}/qtbase/${INSTALL_DOCDIR}")
+ set(qdoc_output_dir "${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/qtbase/${INSTALL_DOCDIR}/${doc_target}")
+ set(index_dir "${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/qtbase/${INSTALL_DOCDIR}")
else()
- set(qdoc_output_dir "${CMAKE_INSTALL_PREFIX}/${INSTALL_DOCDIR}/${doc_target}")
- set(index_dir "${CMAKE_INSTALL_PREFIX}/${INSTALL_DOCDIR}")
+ set(qdoc_output_dir "${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_DOCDIR}/${doc_target}")
+ set(index_dir "${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_DOCDIR}")
endif()
# qtattributionsscanner
@@ -4149,10 +4163,12 @@ function(qt_add_docs)
"${include_path_args}"
)
- if (QT_SUPERBUILD AND NOT QT_WILL_INSTALL)
- set(qt_install_docs_env "${CMAKE_INSTALL_PREFIX}/qtbase/${INSTALL_DOCDIR}")
- else()
+ if (QT_WILL_INSTALL)
set(qt_install_docs_env "${CMAKE_INSTALL_PREFIX}/${INSTALL_DOCDIR}")
+ elseif (QT_SUPERBUILD)
+ set(qt_install_docs_env "${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/qtbase/${INSTALL_DOCDIR}")
+ else()
+ set(qt_install_docs_env "${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_DOCDIR}")
endif()
set(qdoc_env_args
@@ -4560,19 +4576,22 @@ function(qt_generate_qconfig_cpp)
# TODO: Clean this up, there's a bunch of unrealistic assumptions here.
# See qtConfOutput_preparePaths in qtbase/configure.pri.
if(WIN32)
- set(lib_location_absolute_path "${CMAKE_INSTALL_PREFIX}/${INSTALL_BINDIR}")
+ set(lib_location_absolute_path
+ "${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_BINDIR}")
else()
- set(lib_location_absolute_path "${CMAKE_INSTALL_PREFIX}/${INSTALL_LIBDIR}")
+ set(lib_location_absolute_path
+ "${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_LIBDIR}")
endif()
file(RELATIVE_PATH from_lib_location_to_prefix
- "${lib_location_absolute_path}" "${CMAKE_INSTALL_PREFIX}")
+ "${lib_location_absolute_path}" "${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}")
if(QT_HOST_PATH)
set(host_prefix "${QT_HOST_PATH}")
set(host_bin_dir_absolute_path "${QT_HOST_PATH}/${INSTALL_BINDIR}")
else()
- set(host_prefix "${CMAKE_INSTALL_PREFIX}")
- set(host_bin_dir_absolute_path "${CMAKE_INSTALL_PREFIX}/${INSTALL_BINDIR}")
+ set(host_prefix "${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}")
+ set(host_bin_dir_absolute_path
+ "${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_BINDIR}")
endif()
file(RELATIVE_PATH from_host_bin_dir_to_host_prefix
@@ -4581,7 +4600,7 @@ function(qt_generate_qconfig_cpp)
# TODO: Fix this to use the equivalent of extprefix on CMake (CMAKE_STAGING_PREFIX?)
# For now just assume ext prefix is same as regular prefix.
file(RELATIVE_PATH from_host_bin_dir_to_ext_prefix
- "${host_bin_dir_absolute_path}" "${CMAKE_INSTALL_PREFIX}")
+ "${host_bin_dir_absolute_path}" "${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}")
set(QT_CONFIGURE_LIBLOCATION_TO_PREFIX_PATH "${from_lib_location_to_prefix}")
diff --git a/cmake/QtBuildInformation.cmake b/cmake/QtBuildInformation.cmake
index 08d49aeba8..784c79a8b0 100644
--- a/cmake/QtBuildInformation.cmake
+++ b/cmake/QtBuildInformation.cmake
@@ -24,14 +24,14 @@ function(qt_print_build_instructions)
message("Qt is now configured for building. Just run '${build_command}'.")
if(QT_WILL_INSTALL)
message("Once everything is built, you must run '${install_command}'.")
- message("Qt will be installed into '${CMAKE_INSTALL_PREFIX}'")
+ message("Qt will be installed into '${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}'")
else()
message("Once everything is built, Qt is installed.")
message("You should NOT run '${install_command}'")
message("Note that this build cannot be deployed to other machines or devices.")
endif()
message("To configure and build other modules, you can use the following convenience script:
- ${CMAKE_INSTALL_PREFIX}/${INSTALL_BINDIR}/qt-cmake")
+ ${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_BINDIR}/qt-cmake")
message("\nIf reconfiguration fails for some reason, try to remove 'CMakeCache.txt' \
from the build directory \n")
endfunction()
diff --git a/cmake/QtBuildInternals/QtBuildInternalsConfig.cmake b/cmake/QtBuildInternals/QtBuildInternalsConfig.cmake
index eb3ff084f9..baf77105b9 100644
--- a/cmake/QtBuildInternals/QtBuildInternalsConfig.cmake
+++ b/cmake/QtBuildInternals/QtBuildInternalsConfig.cmake
@@ -263,6 +263,40 @@ macro(qt_build_tests)
endif()
endmacro()
+function(qt_compute_relative_path_from_cmake_config_dir_to_prefix)
+ # Compute the reverse relative path from the CMake config dir to the install prefix.
+ # This is used in QtBuildInternalsExtras to create a relocatable relative install prefix path.
+ # This path is used for finding syncqt and other things, regardless of initial install prefix
+ # (e.g installed Qt was archived and unpacked to a different path on a different machine).
+ #
+ # This is meant to be called only once when configuring qtbase.
+ #
+ # Similar code exists in Qt6CoreConfigExtras.cmake.in and src/corelib/CMakeLists.txt which
+ # might not be needed anymore.
+ if(QT_WILL_INSTALL)
+ get_filename_component(clean_config_prefix
+ "${CMAKE_INSTALL_PREFIX}/${QT_CONFIG_INSTALL_DIR}" ABSOLUTE)
+ else()
+ get_filename_component(clean_config_prefix "${QT_CONFIG_BUILD_DIR}" ABSOLUTE)
+ endif()
+ file(RELATIVE_PATH
+ qt_path_from_cmake_config_dir_to_prefix
+ ${clean_config_prefix} ${CMAKE_INSTALL_PREFIX})
+ set(qt_path_from_cmake_config_dir_to_prefix "${qt_path_from_cmake_config_dir_to_prefix}"
+ PARENT_SCOPE)
+endfunction()
+
+function(qt_get_relocatable_install_prefix out_var)
+ # We need to compute it only once while building qtbase. Afterwards it's loaded from
+ # QtBuildInternalsExtras.cmake.
+ if(QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX)
+ return()
+ endif()
+ # The QtBuildInternalsExtras value is dynamically computed, whereas the initial qtbase
+ # configuration uses an absolute path.
+ set(${out_var} "${CMAKE_INSTALL_PREFIX}" PARENT_SCOPE)
+endfunction()
+
function(qt_restore_backed_up_install_prefix)
# Restore the CMAKE_INSTALL_PREFIX that was set before loading BuildInternals.
# Useful for standalone tests, we don't want to accidentally install a test into the Qt prefix.
diff --git a/cmake/QtBuildInternalsExtra.cmake.in b/cmake/QtBuildInternalsExtra.cmake.in
index ea945a913d..7ab25082c2 100644
--- a/cmake/QtBuildInternalsExtra.cmake.in
+++ b/cmake/QtBuildInternalsExtra.cmake.in
@@ -5,18 +5,26 @@ set(QT_CMAKE_EXPORT_NAMESPACE @QT_CMAKE_EXPORT_NAMESPACE@)
set(INSTALL_CMAKE_NAMESPACE @INSTALL_CMAKE_NAMESPACE@)
set(QT_BUILD_INTERNALS_PATH "${CMAKE_CURRENT_LIST_DIR}")
-# Propagate the original install prefix, so that a developer building a child module can
-# specify CMAKE_PREFIX_PATH for finding the Qt modules instead of CMAKE_INSTALL_PREFIX.
-set(CMAKE_INSTALL_PREFIX @CMAKE_INSTALL_PREFIX@ CACHE PATH
- "Install path prefix, prepended onto install directories." FORCE)
-
-# Save the original install prefix in an additional variable.
-# While CMAKE_INSTALL_PREFIX may be overridden in certain cases (like for standalone tests building
-# or for singular qt-cmake-standalone-test usage), we still need the original qtbase install prefix
-# to know where the shared libraries are located to inject them into PATH when running tests via
-# ctest.
-set(QT_BUILD_INTERNALS_ORIGINAL_INSTALL_PREFIX @CMAKE_INSTALL_PREFIX@ CACHE PATH
- "Original install prefix specified when building qtbase." FORCE)
+# The relocatable install prefix is meant to be used to find things like host binaries (syncqt),
+# when the CMAKE_INSTALL_PREFIX is overridden to point to a different path (like when building a
+# a Qt repo using Conan, which will set a random install prefix instead of installing into the
+# original Qt install prefix).
+get_filename_component(QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX
+ ${CMAKE_CURRENT_LIST_DIR}/../@qt_path_from_cmake_config_dir_to_prefix@
+ ABSOLUTE)
+
+# If no explicit CMAKE_INSTALL_PREFIX is provided, force set the original Qt installation prefix,
+# so that further modules / repositories are installed into same original location.
+# This means by default when configuring qtsvg / qtdeclarative, they will be installed the regular
+# Qt installation prefix.
+# If an explicit installation prefix is specified, honor it.
+# This is an attempt to support Conan, aka handle installation of modules into a
+# different installation prefix than the original one. Also allow to opt out via a special variable.
+if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT AND
+ NOT QT_BUILD_INTERNALS_NO_FORCE_SET_INSTALL_PREFIX)
+ set(CMAKE_INSTALL_PREFIX @CMAKE_INSTALL_PREFIX@ CACHE PATH
+ "Install path prefix, prepended onto install directories." FORCE)
+endif()
# Propagate developer builds to other modules via BuildInternals package.
if(@FEATURE_developer_build@)
diff --git a/cmake/QtPostProcess.cmake b/cmake/QtPostProcess.cmake
index 9ad7515e53..1434999c06 100644
--- a/cmake/QtPostProcess.cmake
+++ b/cmake/QtPostProcess.cmake
@@ -382,6 +382,7 @@ function(qt_generate_build_internals_extra_cmake_code)
string(APPEND QT_EXTRA_BUILD_INTERNALS_VARS "${install_prefix_content}")
+ qt_compute_relative_path_from_cmake_config_dir_to_prefix()
configure_file(
"${CMAKE_CURRENT_LIST_DIR}/QtBuildInternalsExtra.cmake.in"
"${extra_file_path}"
diff --git a/cmake/QtSetup.cmake b/cmake/QtSetup.cmake
index 6bc3c74f69..39142fa332 100644
--- a/cmake/QtSetup.cmake
+++ b/cmake/QtSetup.cmake
@@ -51,8 +51,8 @@ set(CMAKE_C_VISIBILITY_PRESET hidden)
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)
-# Detect non-prefix builds, either when the install prefix is set to the binary dir
-# or when enabling developer builds and no prefix is specified.
+# Detect non-prefix builds: either when the qtbase install prefix is set to the binary dir
+# or when a developer build is explicitly enabled and no install prefix is specified.
# This detection only happens when building qtbase, and later is propagated via the generated
# QtBuildInternalsExtra.cmake file.
if (PROJECT_NAME STREQUAL "QtBase" AND NOT QT_BUILD_STANDALONE_TESTS)
@@ -62,8 +62,8 @@ if (PROJECT_NAME STREQUAL "QtBase" AND NOT QT_BUILD_STANDALONE_TESTS)
set(__qt_will_install_value OFF)
# Handle non-prefix builds by setting the CMake install prefix to point to qtbase's build
# dir.
- # While building another repo (like qtsvg), the CMAKE_INSTALL_PREFIX or CMAKE_PREFIX_PATH
- # (either work) should be set on the command line to point to the qtbase build dir.
+ # While building another repo (like qtsvg) the CMAKE_PREFIX_PATH
+ # should be set on the command line to point to the qtbase build dir.
set(CMAKE_INSTALL_PREFIX ${QtBase_BINARY_DIR} CACHE PATH
"Install path prefix, prepended onto install directories." FORCE)
else()
diff --git a/cmake/qt.toolchain.cmake.in b/cmake/qt.toolchain.cmake.in
index 63e5ee3d59..d623d9c0fb 100644
--- a/cmake/qt.toolchain.cmake.in
+++ b/cmake/qt.toolchain.cmake.in
@@ -11,8 +11,14 @@ if(qt_chainload_toolchain_file)
unset(qt_chainload_toolchain_file)
endif()
-list(PREPEND CMAKE_PREFIX_PATH "@CMAKE_INSTALL_PREFIX@")
-list(PREPEND CMAKE_FIND_ROOT_PATH "@CMAKE_INSTALL_PREFIX@")
+# Compute dynamically the Qt installation prefix from the location of this file. This allows
+# the usage of the toolchain file when the Qt installation is relocated.
+get_filename_component(QT_TOOLCHAIN_RELOCATABLE_INSTALL_PREFIX
+ ${CMAKE_CURRENT_LIST_DIR}/../@qt_path_from_cmake_config_dir_to_prefix@
+ ABSOLUTE)
+
+list(PREPEND CMAKE_PREFIX_PATH "${QT_TOOLCHAIN_RELOCATABLE_INSTALL_PREFIX}")
+list(PREPEND CMAKE_FIND_ROOT_PATH "${QT_TOOLCHAIN_RELOCATABLE_INSTALL_PREFIX}")
if(QT_HOST_PATH)
list(APPEND CMAKE_PREFIX_PATH "${QT_HOST_PATH}")