C++11 and beyond
As long as you can require that a user install CMake, you’ll have access to the newest way to enable C++ standards. This is the most powerful way, with the nicest syntax and the best support for new standards, and the best target behavior for mixing standards and options. Assuming you have a target named , it looks like this:
For the first line, we get to pick between cxx_std_11
, cxx_std_14
, and cxx_std_17
. The second line is optional, but will avoid extensions being added; without it you’d get things like -std=g++11
replacing . The first line even works on INTERFACE
targets; only actual compiled targets can use the second line.
If a target further down the dependency chain specifies a higher C++ level, this interacts nicely. It’s really just a more advanced version of the following method, so it interacts nicely with that, too.
If you have optional features, you can use the list CMAKE_CXX_COMPILE_FEATURES
and use if(... IN_LIST ...)
from CMake 3.3+ to see if that feature is supported, and add it conditionally. See the docs here for other use cases.
A related feature, , is worth checking out. It is a module that lets you make a file with macros allowing you to check and support optional features for specific compilers. Like any header generator, this will require that you build with CMake so that your header can be generated as part of the build process (only important if you care about supporting multiple build systems, or if you are making a no-build header-only library).
There is another way that C++ standards are supported; a specific set of three properties (both global and target level). The global properties are:
Which is better, but still doesn’t have the sort of explicit control that compiler features have for populating PRIVATE
and INTERFACE
properties, so it really is only useful on final targets.
You can find more information about the final two methods on Craig Scott’s useful blog post.
Don’t set manual flags yourself. You’ll then become responsible for mainting correct flags for every release of every compiler, error messages for unsupported compilers won’t be useful, and some IDEs might not pick up the manual flags.