New features in CMake 3.18
July 21, 2020 by Cristian Adam | Comments
On 15th of July Kitware has released CMake version 3.18. The release notes contain the list of changes.
Below you have some changes that should improve the life of a Qt developer using CMake.
Profiling support
Finding out where CMake is spending time configuring your project used to be difficult. Now with profiling support it got way easier.
The following command line parameters (which can be passed in Qt Creator 4.13 in the Initial CMake parameters project setting)
--profiling-format=google-trace
--profiling-output=qtcreator-cmake.json
will produce the a qtcreator-cmake.json
file (40 MiB in size for Qt Creator) which can be loaded in Qt Creator via the Chrome Trace Format Viewer.
It looks like this:
This feature was tracked on Kitware's side at !2760.
Precompiled headers
CMake got precompiled header support in version 3.16, but since then new features were added to CMake, which didn’t support precompiled headers.
CMake 3.18 fixes the following use cases:
- iOS multi-architecture (#20497)
- Ninja Multi-Config with MSVC (#20711)
- Ninja Multi-Config and reusable PCH for MSVC (#20721)
CMake 3.18 will run the AUTOMOC
step after the generated sources step (PCH, Unity) has been run. This used to be the other way around.
This fixes #20119 which required Qt Creator to have CMake configure the project twice as a workaround.
The downside is that if you have header-only libraries with the Q_OBJECT
macro and AUTOMOC
set to ON
, they will fail to compile with CMake 3.18. See #20980 and #20968 for more details.
To fix this you need to add a dummy source file to those libraries:
file(GENERATE
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/empty_pch.cxx
CONTENT "/*empty file*/")
target_sources(CommonPCH_Lib PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/empty_pch.cxx)
Unity builds
The UNITY_BUILD_MODE
target property was added to tell generators which algorithm to use for grouping included source files.
The default CMake 3.16 mode is BATCH
, the newly added CMake 3.18 mode is GROUP
.
add_library(example_library
source1.cxx
source2.cxx
source3.cxx
source4.cxx)
set_target_properties(example_library PROPERTIES
UNITY_BUILD_MODE BATCH
UNITY_BUILD_BATCH_SIZE 2)
Let’s say we have a naming conflict between source3.cxx
and source4.cxx
, since they are in the same batch, we would need to get creative in order to fix the problem.
Rather than having an object library with just source4.cxx
, or change the order of the source files (source4.cxx, source1.cxx, source2.cxx, source3.cxx
), we can now have the following:
add_library(example_library
source1.cxx
source2.cxx
source3.cxx
source4.cxx)
set_target_properties(example_library PROPERTIES
UNITY_BUILD_MODE GROUP)
set_source_files_properties(source1.cxx source2.cxx source3.cxx
PROPERTIES UNITY_GROUP "bucket1")
set_source_files_properties(source4.cxx
PROPERTIES UNITY_GROUP "bucket2")
This feature was tracked at Kitware's side at !4716.
Less compiler checks
Given the following C “Hello World” CMakeLists.txt
:
cmake_minimum_required(VERSION 3.17)
project(hello)
add_executable(hello hello.cpp)
When configuring with CMake 3.17 we would get the following output:
$ cmake -E time cmake -G Ninja -S . -B build
-- The C compiler identification is MSVC 19.25.28614.0
-- The CXX compiler identification is MSVC 19.25.28614.0
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/BuildTools/VC/Tools/MSVC/14.25.28610/bin/Hostx64/x64/cl.exe
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/BuildTools/VC/Tools/MSVC/14.25.28610/bin/Hostx64/x64/cl.exe - works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/BuildTools/VC/Tools/MSVC/14.25.28610/bin/Hostx64/x64/cl.exe
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/BuildTools/VC/Tools/MSVC/14.25.28610/bin/Hostx64/x64/cl.exe - works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: C:/Projects/c /HelloWorld/build
Elapsed time: 4 s. (time), 3.825 s. (clock)
With CMake 3.18 we would get:
$ cmake -E time cmake -G Ninja -S . -B build
-- The C compiler identification is MSVC 19.25.28614.0
-- The CXX compiler identification is MSVC 19.25.28614.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/BuildTools/VC/Tools/MSVC/14.25.28610/bin/Hostx64/x64/cl.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/BuildTools/VC/Tools/MSVC/14.25.28610/bin/Hostx64/x64/cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: C:/Projects/c /HelloWorld/build
Elapsed time: 2 s. (time), 2.029 s. (clock)
This is due to !4789 enable_language: Assume compiler works if ABI detection compiles!
CMake is now doing only two try_compile
instead of four, one for each default language C
and CXX
.
By having:
cmake_minimum_required(VERSION 3.17)
project(hello LANGUAGES CXX)
add_executable(hello hello.cpp)
We can have only one try_compile
:
$ cmake -E time cmake -G Ninja -S . -B build
-- The CXX compiler identification is MSVC 19.25.28614.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/BuildTools/VC/Tools/MSVC/14.25.28610/bin/Hostx64/x64/cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: C:/Projects/c /HelloWorld/build
Elapsed time: 1 s. (time), 1.222 s. (clock)
This should help when compiling examples Qt6 with CMake from Qt Creator.
Qt6 speed up features
The following features will allow for leaner and faster Qt6 CMake code:
- The
file(CONFIGURE)
subcommand was created in order to replicate theconfigure_file()
functionality without resorting to a pre-existing file on disk as input. The content is instead passed as a string. #20388 - The
cmake_language()
command was added for meta-operations on scripted or built-in commands, starting with a mode toCALL
other commands, andEVAL CODE
to inplace evaluate a CMake script. #18392, !4408 - The
set_property()
command with theSOURCE
scope gained theDIRECTORY
andTARGET_DIRECTORY
options to set properties in the provided directory scopes. #20128 - The
file()
command gained theARCHIVE_CREATE
andARCHIVE_EXTRACT
subcommands to expose thecmake(1) -E tar
functionality to CMake scripting code. #20443
Blog Topics:
Comments
Subscribe to our newsletter
Subscribe Newsletter
Try Qt 6.7 Now!
Download the latest release here: www.qt.io/download.
Qt 6.7 focuses on the expansion of supported platforms and industry standards. This makes code written with Qt more sustainable and brings more value in Qt as a long-term investment.
We're Hiring
Check out all our open positions here and follow us on Instagram to see what it's like to be #QtPeople.