From 37b132cd4e081821ddc261d24abe8f914123547a Mon Sep 17 00:00:00 2001 From: Alexandru Croitor Date: Thu, 4 Jun 2020 18:21:13 +0200 Subject: [PATCH] CMake: Fix standalone tests to work properly on reconfiguration And also fix qt-cmake-standalone-test to work for prefix builds. The gist of it is that we have to protect tests not to be installed into the Qt install prefix, but we also have to make sure that the CMAKE_INSTALL_PREFIX is not changed globally (via cache value), so that reconfiguration still works. This took way too long to figure out. Amends d6272d774c7415186aa398e59f234d0073458072 Fixes: QTBUG-84346 Change-Id: I18c29574c9957fe05b86f701c8c14ec07e0f045b Reviewed-by: Cristian Adam --- cmake/QtBaseGlobalTargets.cmake | 8 +++++ .../QtBuildInternalsConfig.cmake | 33 +++++++++++-------- .../CMakeLists.txt | 9 +++-- 3 files changed, 33 insertions(+), 17 deletions(-) diff --git a/cmake/QtBaseGlobalTargets.cmake b/cmake/QtBaseGlobalTargets.cmake index 366b23c6c1..d37c7f1cc0 100644 --- a/cmake/QtBaseGlobalTargets.cmake +++ b/cmake/QtBaseGlobalTargets.cmake @@ -211,6 +211,14 @@ 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(QT_WILL_INSTALL) + # Need to prepend the install prefix when doing prefix builds, because the build internals + # install dir is relative in that case.. + qt_path_join(__qt_cmake_standalone_test_path + "${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}" + "${__qt_cmake_standalone_test_path}") +endif() if(UNIX) string(PREPEND __qt_cmake_private_path "exec ") set(__qt_cmake_standalone_passed_args "\"$@\" -DPWD=\"$PWD\"") diff --git a/cmake/QtBuildInternals/QtBuildInternalsConfig.cmake b/cmake/QtBuildInternals/QtBuildInternalsConfig.cmake index baf77105b9..d3e3754e6f 100644 --- a/cmake/QtBuildInternals/QtBuildInternalsConfig.cmake +++ b/cmake/QtBuildInternals/QtBuildInternalsConfig.cmake @@ -223,6 +223,12 @@ endmacro() function(qt_get_standalone_tests_confg_files_path out_var) set(path "${QT_CONFIG_INSTALL_DIR}/${INSTALL_CMAKE_NAMESPACE}BuildInternals/StandaloneTests") + + # QT_CONFIG_INSTALL_DIR is relative in prefix builds. + if(QT_WILL_INSTALL) + qt_path_join(path "${CMAKE_INSTALL_PREFIX}" "${path}") + endif() + set("${out_var}" "${path}" PARENT_SCOPE) endfunction() @@ -231,10 +237,6 @@ macro(qt_build_tests) # Find location of TestsConfig.cmake. These contain the modules that need to be # find_package'd when testing. qt_get_standalone_tests_confg_files_path(_qt_build_tests_install_prefix) - if(QT_WILL_INSTALL) - qt_path_join(_qt_build_tests_install_prefix - ${CMAKE_INSTALL_PREFIX} ${_qt_build_tests_install_prefix}) - endif() include("${_qt_build_tests_install_prefix}/${PROJECT_NAME}TestsConfig.cmake" OPTIONAL) # Of course we always need the test module as well. @@ -246,9 +248,9 @@ macro(qt_build_tests) qt_set_language_standards() if(NOT QT_SUPERBUILD) - # Restore original install prefix. For super builds it needs to be done in - # qt5/CMakeLists.txt. - qt_restore_backed_up_install_prefix() + # Set up fake standalone tests install prefix, so we don't pollute the Qt install + # prefix. For super builds it needs to be done in qt5/CMakeLists.txt. + qt_set_up_fake_standalone_tests_install_prefix() endif() endif() @@ -297,16 +299,15 @@ function(qt_get_relocatable_install_prefix out_var) 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. - get_property(helpstring CACHE CMAKE_INSTALL_PREFIX PROPERTY HELPSTRING) - +function(qt_set_up_fake_standalone_tests_install_prefix) + # Set a fake local (non-cache) CMAKE_INSTALL_PREFIX. + # Needed for standalone tests, we don't want to accidentally install a test into the Qt prefix. + # # If CMAKE_INSTALL_PREFIX was default initialized, that means it points to something # like /usr/local which we don't want. Why? When metatype json files are created # during standalone tests configuration, the folder creation might fail due to missing # permissions in the /usr/local (which is the wrong place anyway). - # Instead specify a dummy install prefix in the current build dir. + # # If the prefix was specified by the user at the command line, honor it, hoping that the # user knows what they are doing. if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) @@ -315,7 +316,11 @@ function(qt_restore_backed_up_install_prefix) set(new_install_prefix "${QT_BACKUP_CMAKE_INSTALL_PREFIX_BEFORE_EXTRA_INCLUDE}") endif() - set(CMAKE_INSTALL_PREFIX "${new_install_prefix}" CACHE STRING "${helpstring}" FORCE) + # It's IMPORTANT that this is not a cache variable. Otherwise + # qt_get_standalone_tests_confg_files_path() will not work on re-configuration. + message(STATUS + "Setting local standalone test install prefix (non-cached) to '${new_install_prefix}'.") + set(CMAKE_INSTALL_PREFIX "${new_install_prefix}" PARENT_SCOPE) endfunction() macro(qt_examples_build_begin) diff --git a/cmake/QtBuildInternals/QtStandaloneTestTemplateProject/CMakeLists.txt b/cmake/QtBuildInternals/QtStandaloneTestTemplateProject/CMakeLists.txt index d77192d563..a84c567b5a 100644 --- a/cmake/QtBuildInternals/QtStandaloneTestTemplateProject/CMakeLists.txt +++ b/cmake/QtBuildInternals/QtStandaloneTestTemplateProject/CMakeLists.txt @@ -6,14 +6,12 @@ find_package(Qt6 REQUIRED COMPONENTS BuildInternals) # Includes QtSetup and friends for private CMake API. qt_build_internals_set_up_private_api() -# Restore original install prefix. -qt_restore_backed_up_install_prefix() - # Find all StandaloneTestsConfig.cmake files, and include them # This will find all Qt packages that are required for standalone tests. # It will find more packages that needed for a certain test, but will ensure any test can # be built. qt_get_standalone_tests_confg_files_path(standalone_tests_config_path) + file(GLOB config_files "${standalone_tests_config_path}/*") foreach(file ${config_files}) include("${file}") @@ -29,5 +27,10 @@ else() set(absolute_project_path "${QT_STANDALONE_TEST_PATH}") endif() +# Just before adding the test, change the local (non-cache) install prefix to something other than +# the Qt install prefix, so that tests don't try to install and pollute the Qt install prefix. +# Needs to be called after qt_get_standalone_tests_confg_files_path(). +qt_set_up_fake_standalone_tests_install_prefix() + # Add the test project path as a subdirectory project. add_subdirectory("${absolute_project_path}" "build_dir")