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 d6272d774c

Fixes: QTBUG-84346
Change-Id: I18c29574c9957fe05b86f701c8c14ec07e0f045b
Reviewed-by: Cristian Adam <cristian.adam@qt.io>
This commit is contained in:
Alexandru Croitor 2020-06-04 18:21:13 +02:00
parent 94dcb5454f
commit 37b132cd4e
3 changed files with 33 additions and 17 deletions

View File

@ -211,6 +211,14 @@ set(__qt_cmake_private_path
"${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_BINDIR}/qt-cmake-private") "${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_BINDIR}/qt-cmake-private")
set(__qt_cmake_standalone_test_path set(__qt_cmake_standalone_test_path
"${__build_internals_install_dir}/${__build_internals_standalone_test_template_dir}") "${__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) if(UNIX)
string(PREPEND __qt_cmake_private_path "exec ") string(PREPEND __qt_cmake_private_path "exec ")
set(__qt_cmake_standalone_passed_args "\"$@\" -DPWD=\"$PWD\"") set(__qt_cmake_standalone_passed_args "\"$@\" -DPWD=\"$PWD\"")

View File

@ -223,6 +223,12 @@ endmacro()
function(qt_get_standalone_tests_confg_files_path out_var) function(qt_get_standalone_tests_confg_files_path out_var)
set(path "${QT_CONFIG_INSTALL_DIR}/${INSTALL_CMAKE_NAMESPACE}BuildInternals/StandaloneTests") 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) set("${out_var}" "${path}" PARENT_SCOPE)
endfunction() endfunction()
@ -231,10 +237,6 @@ macro(qt_build_tests)
# Find location of TestsConfig.cmake. These contain the modules that need to be # Find location of TestsConfig.cmake. These contain the modules that need to be
# find_package'd when testing. # find_package'd when testing.
qt_get_standalone_tests_confg_files_path(_qt_build_tests_install_prefix) 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) include("${_qt_build_tests_install_prefix}/${PROJECT_NAME}TestsConfig.cmake" OPTIONAL)
# Of course we always need the test module as well. # Of course we always need the test module as well.
@ -246,9 +248,9 @@ macro(qt_build_tests)
qt_set_language_standards() qt_set_language_standards()
if(NOT QT_SUPERBUILD) if(NOT QT_SUPERBUILD)
# Restore original install prefix. For super builds it needs to be done in # Set up fake standalone tests install prefix, so we don't pollute the Qt install
# qt5/CMakeLists.txt. # prefix. For super builds it needs to be done in qt5/CMakeLists.txt.
qt_restore_backed_up_install_prefix() qt_set_up_fake_standalone_tests_install_prefix()
endif() endif()
endif() endif()
@ -297,16 +299,15 @@ function(qt_get_relocatable_install_prefix out_var)
set(${out_var} "${CMAKE_INSTALL_PREFIX}" PARENT_SCOPE) set(${out_var} "${CMAKE_INSTALL_PREFIX}" PARENT_SCOPE)
endfunction() endfunction()
function(qt_restore_backed_up_install_prefix) function(qt_set_up_fake_standalone_tests_install_prefix)
# Restore the CMAKE_INSTALL_PREFIX that was set before loading BuildInternals. # Set a fake local (non-cache) CMAKE_INSTALL_PREFIX.
# Useful for standalone tests, we don't want to accidentally install a test into the Qt prefix. # Needed 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) #
# If CMAKE_INSTALL_PREFIX was default initialized, that means it points to something # 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 # 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 # during standalone tests configuration, the folder creation might fail due to missing
# permissions in the /usr/local (which is the wrong place anyway). # 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 # If the prefix was specified by the user at the command line, honor it, hoping that the
# user knows what they are doing. # user knows what they are doing.
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) 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}") set(new_install_prefix "${QT_BACKUP_CMAKE_INSTALL_PREFIX_BEFORE_EXTRA_INCLUDE}")
endif() 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() endfunction()
macro(qt_examples_build_begin) macro(qt_examples_build_begin)

View File

@ -6,14 +6,12 @@ find_package(Qt6 REQUIRED COMPONENTS BuildInternals)
# Includes QtSetup and friends for private CMake API. # Includes QtSetup and friends for private CMake API.
qt_build_internals_set_up_private_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 # Find all StandaloneTestsConfig.cmake files, and include them
# This will find all Qt packages that are required for standalone tests. # 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 # It will find more packages that needed for a certain test, but will ensure any test can
# be built. # be built.
qt_get_standalone_tests_confg_files_path(standalone_tests_config_path) qt_get_standalone_tests_confg_files_path(standalone_tests_config_path)
file(GLOB config_files "${standalone_tests_config_path}/*") file(GLOB config_files "${standalone_tests_config_path}/*")
foreach(file ${config_files}) foreach(file ${config_files})
include("${file}") include("${file}")
@ -29,5 +27,10 @@ else()
set(absolute_project_path "${QT_STANDALONE_TEST_PATH}") set(absolute_project_path "${QT_STANDALONE_TEST_PATH}")
endif() 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 the test project path as a subdirectory project.
add_subdirectory("${absolute_project_path}" "build_dir") add_subdirectory("${absolute_project_path}" "build_dir")