CMake: Make QT_CMAKE_EXPORT_NAMESPACE available in the top-level scope

Previously QT_CMAKE_EXPORT_NAMESPACE was set by calling
find_package(QtBuildInternals) at repo dir scope, even in a top-level
build.

Starting with ddcafa0a51c65d86f6b5481f06fce5faeb75920d in
qtdeclarative, we now have a deferred call of
_qt_internal_write_deferred_qmlls_build_ini_file in the
CMAKE_BINARY_DIR scope, which lacks the QT_CMAKE_EXPORT_NAMESPACE
variable.
This caused errors in a top-level standalone tests build:
  Error evaluating generator expression $
    No target "::qtpaths"
    CMakeLists.txt:DEFERRED

To avoid the error we now set QT_CMAKE_EXPORT_NAMESPACE in the
top level scope.

To avoid duplicating the code into the QtBaseTopLevelHelpers,
we extract the qt_internal_top_level_setup_cmake_and_export_namespace
function into a new QtBuildInternalsHelpers.cmake file, which is
included by both QtBaseTopLevelHelpers.cmake and
QtBuildInternalsConfig.cmake.

We also copy and install that file.

This has less side effects than trying to call
find_package(QtBuildInternals) in the top-level scope.

Change-Id: I8e54e21d3f07ee86860cad49d6e43e0fdefbcee3
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
(cherry picked from commit 9b9a2398f30b6c35ef6be3ce929c352afb682910)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Alexandru Croitor 2025-06-05 13:06:55 +02:00 committed by Qt Cherry-pick Bot
parent 20dfcf4c59
commit 217d7e4fbf
4 changed files with 51 additions and 13 deletions

View File

@ -70,8 +70,25 @@ if(QT_WILL_INSTALL)
DESTINATION "${__build_internals_install_dir}")
endif()
set(__build_internals_extra_files
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/QtBuildInternals/QtBuildInternalsHelpers.cmake"
)
qt_copy_or_install(
FILES ${__build_internals_extra_files}
DESTINATION "${__build_internals_install_dir}")
# In prefix builds we also need to copy the files into the build dir.
if(QT_WILL_INSTALL)
foreach(__build_internals_file ${__build_internals_extra_files})
file(COPY "${__build_internals_file}" DESTINATION "${__build_internals_install_dir}")
endforeach()
endif()
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/QtBuildInternals/${__build_internals_standalone_test_template_dir}/CMakeLists.txt")
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/QtBuildInternals/${__build_internals_standalone_test_template_dir}/CMakeLists.txt"
${__build_internals_extra_files}
)
qt_internal_create_toolchain_file()

View File

@ -34,6 +34,23 @@ endmacro()
macro(qt_internal_top_level_setup_after_project)
qt_internal_top_level_setup_testing()
qt_internal_top_level_setup_cmake_and_export_namespace()
endmacro()
# Setting QT_CMAKE_EXPORT_NAMESPACE in the top-level scope is needed for any deferred call that is
# run on the top-level scope (CMAKE_BINARY_DIR).
macro(qt_internal_top_level_setup_cmake_and_export_namespace)
# Include the file that defines qt_internal_setup_cmake_and_export_namespace.
# We don't try to call find_package(QtBuildInternals) because that has a lot more side
# effects.
set(__qt6_build_internals_helpers_path
"${__qt6_qtbase_src_path}/cmake/QtBuildInternals/QtBuildInternalsHelpers.cmake")
if(NOT EXISTS "${__qt6_build_internals_helpers_path}")
message(FATAL_ERROR "Required file does not exist: '${__qt6_build_internals_helpers_path}'")
endif()
include("${__qt6_build_internals_helpers_path}")
qt_internal_setup_cmake_and_export_namespace()
endmacro()
macro(qt_internal_top_level_setup_testing)

View File

@ -11,18 +11,7 @@ if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/QtBuildInternalsExtra.cmake")
include(${CMAKE_CURRENT_LIST_DIR}/QtBuildInternalsExtra.cmake)
endif()
macro(qt_internal_setup_cmake_and_export_namespace)
# 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)
set(INSTALL_CMAKE_NAMESPACE "Qt${PROJECT_VERSION_MAJOR}"
CACHE STRING "CMake namespace [Qt${PROJECT_VERSION_MAJOR}]")
endif()
if(NOT QT_CMAKE_EXPORT_NAMESPACE)
set(QT_CMAKE_EXPORT_NAMESPACE "Qt${PROJECT_VERSION_MAJOR}"
CACHE STRING "CMake namespace used when exporting targets [Qt${PROJECT_VERSION_MAJOR}]")
endif()
endmacro()
include(${CMAKE_CURRENT_LIST_DIR}/QtBuildInternalsHelpers.cmake)
macro(qt_set_up_build_internals_paths)
# Set up the paths for the cmake modules located in the prefix dir. Prepend, so the paths are

View File

@ -0,0 +1,15 @@
# Copyright (C) 2025 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
macro(qt_internal_setup_cmake_and_export_namespace)
# 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)
set(INSTALL_CMAKE_NAMESPACE "Qt${PROJECT_VERSION_MAJOR}"
CACHE STRING "CMake namespace [Qt${PROJECT_VERSION_MAJOR}]")
endif()
if(NOT QT_CMAKE_EXPORT_NAMESPACE)
set(QT_CMAKE_EXPORT_NAMESPACE "Qt${PROJECT_VERSION_MAJOR}"
CACHE STRING "CMake namespace used when exporting targets [Qt${PROJECT_VERSION_MAJOR}]")
endif()
endmacro()