diff options
author | Alexandru Croitor <alexandru.croitor@qt.io> | 2019-12-06 15:12:17 +0100 |
---|---|---|
committer | Alexandru Croitor <alexandru.croitor@qt.io> | 2020-01-27 11:47:57 +0000 |
commit | c9bea1ad62addb7582ddf0e8d790719c96a0ea90 (patch) | |
tree | e2f9c807399606e839c76504be8617fee18dfc20 /cmake/QtBuild.cmake | |
parent | cce8ada8141d786c1deda78fdba485b4c67f9687 (diff) |
Add initial support for CMake "Ninja Multi-Config" generator
This allows doing debug_and_release builds with Ninja on all
platforms.
The "Ninja Multi-Config generator" is available starting with CMake
3.17.
Desired configurations can be set via CMAKE_CONFIGURATION_TYPES.
Possible values: "Release, Debug, RelWithDebInfo, MinRelSize".
For example -DCMAKE_CONFIGURATION_TYPES="Release;Debug".
The first configuration is the 'default' configuration which is
built when calling ninja with no arguments.
To build all targets of a certain configuration use "ninja all:Release"
or "ninja all:Debug".
To build all targets in all configurations use "ninja all:all".
Note that the first configuration influences which configuration of
tools will be used when building the libraries for all configurations.
In simple terms, when configured with
-DCMAKE_CONFIGURATION_TYPES="Release;Debug" the release version of moc
is used by AUTOMOC.
When configured with -DCMAKE_CONFIGURATION_TYPES="Debug;Release"
the debug version of moc is used by AUTOMOC.
Framework builds and Ninja Multi-Config don't currently work together
due to multiple bugs in CMake, which ends up generating an invalid ninja
file with duplicate rules. There are also issues with placement of the
debug artifacts.
This will be handled in a follow up patch after CMake is fixed.
Task-number: QTBUG-76899
Change-Id: If224adc0b71b7d1d6606738101536146aa866cd7
Reviewed-by: Qt CMake Build Bot
Reviewed-by: Leander Beernaert <leander.beernaert@qt.io>
Reviewed-by: Cristian Adam <cristian.adam@qt.io>
Diffstat (limited to 'cmake/QtBuild.cmake')
-rw-r--r-- | cmake/QtBuild.cmake | 48 |
1 files changed, 43 insertions, 5 deletions
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") |