summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bin/qt-cmake.bat.in2
-rwxr-xr-xbin/qt-cmake.in2
-rw-r--r--cmake/QtAutoDetect.cmake18
-rw-r--r--cmake/QtBaseConfigureTests.cmake8
-rw-r--r--cmake/QtBaseGlobalTargets.cmake20
-rw-r--r--cmake/QtBuild.cmake48
-rw-r--r--cmake/QtBuildInternalsExtra.cmake.in4
-rw-r--r--cmake/QtPostProcess.cmake27
-rw-r--r--cmake/QtSetup.cmake14
-rw-r--r--coin/instructions/call_cmake.yaml1
-rw-r--r--src/corelib/Qt6CoreMacros.cmake21
-rw-r--r--src/tools/cmake_automoc_parser/main.cpp12
12 files changed, 161 insertions, 16 deletions
diff --git a/bin/qt-cmake.bat.in b/bin/qt-cmake.bat.in
index f27818a61b..6e5b27010b 100644
--- a/bin/qt-cmake.bat.in
+++ b/bin/qt-cmake.bat.in
@@ -1 +1 @@
-"@CMAKE_COMMAND@" -DCMAKE_TOOLCHAIN_FILE="@__GlobalConfig_install_dir_absolute@/qt.toolchain.cmake" %*
+"@CMAKE_COMMAND@" -DCMAKE_TOOLCHAIN_FILE="@__GlobalConfig_install_dir_absolute@/qt.toolchain.cmake" @__qt_cmake_extra@ %*
diff --git a/bin/qt-cmake.in b/bin/qt-cmake.in
index 1797d2ded5..2b42592267 100755
--- a/bin/qt-cmake.in
+++ b/bin/qt-cmake.in
@@ -1,3 +1,3 @@
#!/bin/sh
-exec @CMAKE_COMMAND@ -DCMAKE_TOOLCHAIN_FILE=@__GlobalConfig_install_dir_absolute@/qt.toolchain.cmake $*
+exec @CMAKE_COMMAND@ -DCMAKE_TOOLCHAIN_FILE=@__GlobalConfig_install_dir_absolute@/qt.toolchain.cmake @__qt_cmake_extra@ "$@"
diff --git a/cmake/QtAutoDetect.cmake b/cmake/QtAutoDetect.cmake
index 1823d1e572..95ace249ad 100644
--- a/cmake/QtAutoDetect.cmake
+++ b/cmake/QtAutoDetect.cmake
@@ -156,6 +156,24 @@ function(qt_auto_detect_ios)
endif()
endfunction()
+function(qt_auto_detect_cmake_config)
+ if(CMAKE_CONFIGURATION_TYPES)
+ # Allow users to specify this option.
+ if(NOT QT_MULTI_CONFIG_FIRST_CONFIG)
+ list(GET CMAKE_CONFIGURATION_TYPES 0 first_config_type)
+ set(QT_MULTI_CONFIG_FIRST_CONFIG "${first_config_type}")
+ set(QT_MULTI_CONFIG_FIRST_CONFIG "${first_config_type}" PARENT_SCOPE)
+ endif()
+
+ set(CMAKE_TRY_COMPILE_CONFIGURATION "${QT_MULTI_CONFIG_FIRST_CONFIG}" PARENT_SCOPE)
+ if(CMAKE_GENERATOR STREQUAL "Ninja Multi-Config")
+ set(CMAKE_NINJA_MULTI_CROSS_CONFIG_ENABLE ON PARENT_SCOPE)
+ set(CMAKE_NINJA_MULTI_DEFAULT_BUILD_TYPE "${QT_MULTI_CONFIG_FIRST_CONFIG}" PARENT_SCOPE)
+ endif()
+ endif()
+endfunction()
+
+qt_auto_detect_cmake_config()
qt_auto_detect_ios()
qt_auto_detect_android()
qt_auto_detect_vpckg()
diff --git a/cmake/QtBaseConfigureTests.cmake b/cmake/QtBaseConfigureTests.cmake
index 777adb7b5f..0d6bb1407b 100644
--- a/cmake/QtBaseConfigureTests.cmake
+++ b/cmake/QtBaseConfigureTests.cmake
@@ -28,8 +28,14 @@ function(qt_run_config_test_architecture)
if (EMSCRIPTEN)
set(_arch_file_suffix ".wasm")
endif()
+
+ set(arch_test_location "config.tests/arch")
+ if(QT_MULTI_CONFIG_FIRST_CONFIG)
+ string(APPEND arch_test_location "/${QT_MULTI_CONFIG_FIRST_CONFIG}")
+ endif()
+
set(_arch_file
- "${CMAKE_CURRENT_BINARY_DIR}/config.tests/arch/architecture_test${_arch_file_suffix}")
+ "${CMAKE_CURRENT_BINARY_DIR}/${arch_test_location}/architecture_test${_arch_file_suffix}")
if (NOT EXISTS "${_arch_file}")
message(FATAL_ERROR
"Failed to find compiled architecture detection executable at ${_arch_file}.")
diff --git a/cmake/QtBaseGlobalTargets.cmake b/cmake/QtBaseGlobalTargets.cmake
index 5f38f96681..9274512577 100644
--- a/cmake/QtBaseGlobalTargets.cmake
+++ b/cmake/QtBaseGlobalTargets.cmake
@@ -137,6 +137,26 @@ else()
qt_install(PROGRAMS "${QT_BUILD_DIR}/bin/qt-cmake.bat" DESTINATION "${INSTALL_BINDIR}")
endif()
+# Provide a private convenience wrapper with options which should not be propagated via the public
+# qt-cmake wrapper e.g. CMAKE_GENERATOR.
+# These options can not be set in a toolchain file, but only on the command line.
+# These options should not be in the public wrapper, because a consumer of Qt might want to build
+# their CMake app with the Unix Makefiles generator, while Qt should be built with the Ninja
+# generator.
+# The private wrapper is more conveient for building Qt itself, because a developer doesn't need
+# to specify the same options for each qt module built.
+set(__qt_cmake_extra "-G\"${CMAKE_GENERATOR}\"")
+if(UNIX)
+ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/bin/qt-cmake.in"
+ "${QT_BUILD_DIR}/${INSTALL_BINDIR}/qt-cmake-private" @ONLY)
+ qt_install(PROGRAMS "${QT_BUILD_DIR}/bin/qt-cmake-private" DESTINATION "${INSTALL_BINDIR}")
+else()
+ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/bin/qt-cmake.bat.in"
+ "${QT_BUILD_DIR}/${INSTALL_BINDIR}/qt-cmake-private.bat" @ONLY)
+ qt_install(PROGRAMS "${QT_BUILD_DIR}/bin/qt-cmake-private.bat" DESTINATION "${INSTALL_BINDIR}")
+endif()
+unset(__qt_cmake_extra)
+
## Library to hold global features:
## These features are stored and accessed via Qt::GlobalConfig, but the
## files always lived in Qt::Core, so we keep it that way
diff --git a/cmake/QtBuild.cmake b/cmake/QtBuild.cmake
index 0b434045b6..0070aac2d7 100644
--- a/cmake/QtBuild.cmake
+++ b/cmake/QtBuild.cmake
@@ -1463,7 +1463,9 @@ function(qt_finalize_framework_headers_copy target)
# Create a fake header file and copy it into the framework by marking it as PUBLIC_HEADER.
# CMake now takes care of creating the symlink.
set(fake_header ${target}_fake_header.h)
- file(GENERATE OUTPUT ${fake_header} CONTENT "// ignore this file\n")
+ qt_get_main_cmake_configuration(main_config)
+ file(GENERATE OUTPUT ${fake_header} CONTENT "// ignore this file\n"
+ CONDITION "$<CONFIG:${main_config}>")
string(PREPEND fake_header "${CMAKE_CURRENT_BINARY_DIR}/")
target_sources(${target} PRIVATE ${fake_header})
set_source_files_properties(${fake_header} PROPERTIES GENERATED ON)
@@ -1475,6 +1477,24 @@ function(qt_finalize_framework_headers_copy target)
endif()
endfunction()
+function(qt_clone_property_for_configs target property configs)
+ get_target_property(value "${target}" "${property}")
+ foreach(config ${configs})
+ string(TOUPPER "${config}" upper_config)
+ set_property(TARGET "${target}" PROPERTY "${property}_${upper_config}" "${value}")
+ endforeach()
+endfunction()
+
+function(qt_handle_multi_config_output_dirs target)
+ set(possible_configs "${CMAKE_BUILD_TYPE}")
+ if(CMAKE_CONFIGURATION_TYPES)
+ set(possible_configs "${CMAKE_CONFIGURATION_TYPES}")
+ endif()
+ qt_clone_property_for_configs(${target} LIBRARY_OUTPUT_DIRECTORY "${possible_configs}")
+ qt_clone_property_for_configs(${target} RUNTIME_OUTPUT_DIRECTORY "${possible_configs}")
+ qt_clone_property_for_configs(${target} ARCHIVE_OUTPUT_DIRECTORY "${possible_configs}")
+endfunction()
+
# This is the main entry function for creating a Qt module, that typically
# consists of a library, public header files, private header files and configurable
# features.
@@ -1542,12 +1562,11 @@ function(qt_add_module target)
set_target_properties(${target} PROPERTIES
LIBRARY_OUTPUT_DIRECTORY "${QT_BUILD_DIR}/${INSTALL_LIBDIR}"
RUNTIME_OUTPUT_DIRECTORY "${QT_BUILD_DIR}/${INSTALL_BINDIR}"
- RUNTIME_OUTPUT_DIRECTORY_RELEASE "${QT_BUILD_DIR}/${INSTALL_BINDIR}"
- RUNTIME_OUTPUT_DIRECTORY_DEBUG "${QT_BUILD_DIR}/${INSTALL_BINDIR}"
ARCHIVE_OUTPUT_DIRECTORY "${QT_BUILD_DIR}/${INSTALL_LIBDIR}"
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR}
)
+ qt_handle_multi_config_output_dirs("${target}")
if(is_framework)
set_target_properties(${target} PROPERTIES
@@ -2203,6 +2222,7 @@ function(qt_add_plugin target)
RUNTIME_OUTPUT_DIRECTORY "${output_directory}"
ARCHIVE_OUTPUT_DIRECTORY "${output_directory}"
QT_PLUGIN_CLASS_NAME "${arg_CLASS_NAME}")
+ qt_handle_multi_config_output_dirs("${target}")
qt_internal_library_deprecation_level(deprecation_define)
@@ -3028,6 +3048,21 @@ function(qt_add_cmake_library target)
endfunction()
+function(qt_get_tool_cmake_configuration out_var)
+ qt_get_main_cmake_configuration("${out_var}")
+ string(TOUPPER "${${out_var}}" upper_config)
+ set("${out_var}" "${upper_config}" PARENT_SCOPE)
+endfunction()
+
+function(qt_get_main_cmake_configuration out_var)
+ if(CMAKE_BUILD_TYPE)
+ set(config "${CMAKE_BUILD_TYPE}")
+ elseif(QT_MULTI_CONFIG_FIRST_CONFIG)
+ set(config "${QT_MULTI_CONFIG_FIRST_CONFIG}")
+ endif()
+ set("${out_var}" "${config}" 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.
@@ -3146,8 +3181,11 @@ function(qt_add_tool name)
)
qt_internal_add_target_aliases("${name}")
+ # 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
- RUNTIME_OUTPUT_DIRECTORY_RELEASE "${QT_BUILD_DIR}/${INSTALL_BINDIR}"
+ RUNTIME_OUTPUT_DIRECTORY_${tool_cmake_configuration} "${QT_BUILD_DIR}/${INSTALL_BINDIR}"
)
if(NOT arg_NO_INSTALL AND arg_TOOLS_TARGET)
@@ -3394,7 +3432,7 @@ function(qt_add_docs)
# Generate include dir list
- set(target_include_dirs_file "${doc_ouput_dir}/includes.txt")
+ set(target_include_dirs_file "${doc_ouput_dir}/$<CONFIG>/includes.txt")
set(include_paths_property "$<TARGET_PROPERTY:${target},INCLUDE_DIRECTORIES>")
if (NOT target_type STREQUAL "INTERFACE_LIBRARY")
diff --git a/cmake/QtBuildInternalsExtra.cmake.in b/cmake/QtBuildInternalsExtra.cmake.in
index 68e1271781..5278890337 100644
--- a/cmake/QtBuildInternalsExtra.cmake.in
+++ b/cmake/QtBuildInternalsExtra.cmake.in
@@ -3,7 +3,6 @@ set(QT_BUILD_SHARED_LIBS @BUILD_SHARED_LIBS@)
option(BUILD_SHARED_LIBS "Build Qt statically or dynamically" @BUILD_SHARED_LIBS@)
set(QT_CMAKE_EXPORT_NAMESPACE @QT_CMAKE_EXPORT_NAMESPACE@)
set(INSTALL_CMAKE_NAMESPACE @INSTALL_CMAKE_NAMESPACE@)
-set(CMAKE_BUILD_TYPE @CMAKE_BUILD_TYPE@)
set(QT_BUILD_INTERNALS_PATH "${CMAKE_CURRENT_LIST_DIR}")
# Propagate the original install prefix, so that a developer building a child module can
@@ -31,5 +30,8 @@ set(QT_NO_MAKE_TESTS @QT_NO_MAKE_TESTS@ CACHE BOOL
set(QT_NO_MAKE_EXAMPLES @QT_NO_MAKE_EXAMPLES@ CACHE BOOL
"Should examples be built as part of the default 'all' target.")
+# Propagate usage of ccache.
+set(QT_USE_CCACHE @QT_USE_CCACHE@ CACHE BOOL "Enable the use of ccache")
+
# Extra set of exported variables
@QT_EXTRA_BUILD_INTERNALS_VARS@
diff --git a/cmake/QtPostProcess.cmake b/cmake/QtPostProcess.cmake
index b20b85bef9..807b32063d 100644
--- a/cmake/QtPostProcess.cmake
+++ b/cmake/QtPostProcess.cmake
@@ -298,7 +298,6 @@ endfunction()
function(qt_generate_build_internals_extra_cmake_code)
if(PROJECT_NAME STREQUAL "QtBase")
- set(QT_EXTRA_BUILD_INTERNALS_VARS)
foreach(var IN LISTS QT_BASE_CONFIGURE_TESTS_VARS_TO_EXPORT)
string(APPEND QT_EXTRA_BUILD_INTERNALS_VARS "set(${var} \"${${var}}\" CACHE INTERNAL \"\")\n")
endforeach()
@@ -307,6 +306,32 @@ function(qt_generate_build_internals_extra_cmake_code)
qt_path_join(extra_file_path
${QT_CONFIG_BUILD_DIR}
${INSTALL_CMAKE_NAMESPACE}BuildInternals/QtBuildInternalsExtra.cmake)
+
+ if(CMAKE_BUILD_TYPE)
+ string(APPEND QT_EXTRA_BUILD_INTERNALS_VARS
+ "set(CMAKE_BUILD_TYPE \"${CMAKE_BUILD_TYPE}\")\n")
+ endif()
+ if(CMAKE_CONFIGURATION_TYPES)
+ string(APPEND QT_EXTRA_BUILD_INTERNALS_VARS
+ "set(CMAKE_CONFIGURATION_TYPES \"${CMAKE_CONFIGURATION_TYPES}\")\n")
+ endif()
+ if(CMAKE_TRY_COMPILE_CONFIGURATION)
+ string(APPEND QT_EXTRA_BUILD_INTERNALS_VARS
+ "set(CMAKE_TRY_COMPILE_CONFIGURATION \"${CMAKE_TRY_COMPILE_CONFIGURATION}\")\n")
+ endif()
+ if(QT_MULTI_CONFIG_FIRST_CONFIG)
+ string(APPEND QT_EXTRA_BUILD_INTERNALS_VARS
+ "set(QT_MULTI_CONFIG_FIRST_CONFIG \"${QT_MULTI_CONFIG_FIRST_CONFIG}\")\n")
+ endif()
+ if(CMAKE_NINJA_MULTI_CROSS_CONFIG_ENABLE)
+ string(APPEND QT_EXTRA_BUILD_INTERNALS_VARS
+ "set(CMAKE_NINJA_MULTI_CROSS_CONFIG_ENABLE \"${CMAKE_NINJA_MULTI_CROSS_CONFIG_ENABLE}\")\n")
+ endif()
+ if(CMAKE_NINJA_MULTI_DEFAULT_BUILD_TYPE)
+ string(APPEND QT_EXTRA_BUILD_INTERNALS_VARS
+ "set(CMAKE_NINJA_MULTI_DEFAULT_BUILD_TYPE \"${CMAKE_NINJA_MULTI_DEFAULT_BUILD_TYPE}\")\n")
+ endif()
+
configure_file(
"${CMAKE_CURRENT_LIST_DIR}/QtBuildInternalsExtra.cmake.in"
"${extra_file_path}"
diff --git a/cmake/QtSetup.cmake b/cmake/QtSetup.cmake
index 65bd5b9a21..90588c99b3 100644
--- a/cmake/QtSetup.cmake
+++ b/cmake/QtSetup.cmake
@@ -10,10 +10,22 @@ if(EXISTS "${CMAKE_SOURCE_DIR}/.git")
set(_default_build_type "Debug")
endif()
+# Reset content of extra build internal vars for each inclusion of QtSetup.
+unset(QT_EXTRA_BUILD_INTERNALS_VARS)
+
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "Setting build type to '${_default_build_type}' as none was specified.")
set(CMAKE_BUILD_TYPE "${_default_build_type}" CACHE STRING "Choose the type of build." FORCE)
- set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo") # Set the possible values of build type for cmake-gui
+ set_property(CACHE CMAKE_BUILD_TYPE
+ PROPERTY STRINGS
+ "Debug" "Release" "MinSizeRel" "RelWithDebInfo") # Set the possible values for cmake-gui.
+elseif(CMAKE_CONFIGURATION_TYPES)
+ message(STATUS "Building for multiple configurations: ${CMAKE_CONFIGURATION_TYPES}.")
+ message(STATUS "Main configuration is: ${QT_MULTI_CONFIG_FIRST_CONFIG}.")
+ if(CMAKE_NINJA_MULTI_DEFAULT_BUILD_TYPE)
+ message(STATUS
+ "Default build configuration set to '${CMAKE_NINJA_MULTI_DEFAULT_BUILD_TYPE}'.")
+ endif()
endif()
# Appends a 'debug postfix' to library targets (not executables)
diff --git a/coin/instructions/call_cmake.yaml b/coin/instructions/call_cmake.yaml
index 06a8980099..421a7c2ed1 100644
--- a/coin/instructions/call_cmake.yaml
+++ b/coin/instructions/call_cmake.yaml
@@ -13,6 +13,7 @@ instructions:
equals_value: Windows
- type: ExecuteCommand
command: "{{.InstallDir}}/bin/qt-cmake {{.Env.COIN_CMAKE_ARGS}}"
+ executeCommandArgumentSplitingBehavior: SplitAfterVariableSubstitution
maxTimeInSeconds: 6000
maxTimeBetweenOutput: 1200
userMessageOnFailure: >
diff --git a/src/corelib/Qt6CoreMacros.cmake b/src/corelib/Qt6CoreMacros.cmake
index da0b4641ae..cf860cd9ad 100644
--- a/src/corelib/Qt6CoreMacros.cmake
+++ b/src/corelib/Qt6CoreMacros.cmake
@@ -543,8 +543,20 @@ function(qt6_generate_meta_types_json_file target)
get_target_property(target_binary_dir ${target} BINARY_DIR)
- set(cmake_autogen_cache_file
- "${target_binary_dir}/CMakeFiles/${target}_autogen.dir/ParseCache.txt")
+ if(CMAKE_BUILD_TYPE)
+ set(cmake_autogen_cache_file
+ "${target_binary_dir}/CMakeFiles/${target}_autogen.dir/ParseCache.txt")
+ set(mutli_config_args
+ --cmake-autogen-include-dir-path "${target_binary_dir}/${target}_autogen/include"
+ )
+ else()
+ set(cmake_autogen_cache_file
+ "${target_binary_dir}/CMakeFiles/${target}_autogen.dir/ParseCache_$<CONFIG>.txt")
+ set(mutli_config_args
+ --cmake-autogen-include-dir-path "${target_binary_dir}/${target}_autogen/include_$<CONFIG>"
+ "--cmake-multi-config")
+ endif()
+
set(cmake_autogen_info_file
"${target_binary_dir}/CMakeFiles/${target}_autogen.dir/AutogenInfo.json")
set(type_list_file "${target_binary_dir}/meta_types/json_file_list.txt")
@@ -556,8 +568,9 @@ function(qt6_generate_meta_types_json_file target)
--cmake-autogen-cache-file "${cmake_autogen_cache_file}"
--cmake-autogen-info-file "${cmake_autogen_info_file}"
--output-file-path "${type_list_file}"
- --cmake-autogen-include-dir-path "${target_binary_dir}/${target}_autogen/include"
+ ${mutli_config_args}
COMMENT "Running Automoc file extraction"
+ COMMAND_EXPAND_LISTS
)
add_dependencies(${target}_automoc_json_extraction ${target}_autogen)
@@ -565,7 +578,7 @@ function(qt6_generate_meta_types_json_file target)
if (CMAKE_BUILD_TYPE)
string(TOLOWER ${target}_${CMAKE_BUILD_TYPE} target_lowercase)
else()
- message(FATAL_ERROR "add_custom_command's OUTPUT parameter does not support generator expressions, so we can't generate this file for multi-config generators")
+ string(TOLOWER ${target} target_lowercase)
endif()
set(metatypes_file "${target_binary_dir}/meta_types/qt6${target_lowercase}_metatypes.json")
add_custom_command(OUTPUT ${metatypes_file}
diff --git a/src/tools/cmake_automoc_parser/main.cpp b/src/tools/cmake_automoc_parser/main.cpp
index 456b06b072..60eb4b2977 100644
--- a/src/tools/cmake_automoc_parser/main.cpp
+++ b/src/tools/cmake_automoc_parser/main.cpp
@@ -264,6 +264,12 @@ int main(int argc, char **argv)
cmakeAutogenIncludeDirOption.setValueName(QStringLiteral("CMake AutoGen include directory"));
parser.addOption(cmakeAutogenIncludeDirOption);
+ QCommandLineOption isMultiConfigOption(
+ QStringLiteral("cmake-multi-config"));
+ isMultiConfigOption.setDescription(
+ QStringLiteral("Set this option when using CMake with a multi-config generator"));
+ parser.addOption(isMultiConfigOption);
+
QStringList arguments = QCoreApplication::arguments();
parser.process(arguments);
@@ -354,13 +360,17 @@ int main(int argc, char **argv)
}
// 2) Process headers
+ const bool isMultiConfig = parser.isSet(isMultiConfigOption);
for (auto mapIt = autoGenHeaders.begin(); mapIt != autoGenHeaders.end(); ++mapIt) {
auto it = parseCacheEntries.find(mapIt.key());
if (it == parseCacheEntries.end()) {
continue;
}
+ const QString pathPrefix = !isMultiConfig
+ ? QStringLiteral("../")
+ : QString();
const QString jsonPath =
- dir.filePath(QLatin1String("../") + mapIt.value() + QLatin1String(".json"));
+ dir.filePath(pathPrefix + mapIt.value() + QLatin1String(".json"));
jsonFileList.push_back(jsonPath);
}