482 lines
14 KiB
Groff
482 lines
14 KiB
Groff
|
.\" Man page generated from reStructuredText.
|
|||
|
.
|
|||
|
.TH "CMAKE-COMPILE-FEATURES" "7" "Aug 20, 2020" "3.18.2" "CMake"
|
|||
|
.SH NAME
|
|||
|
cmake-compile-features \- CMake Compile Features Reference
|
|||
|
.
|
|||
|
.nr rst2man-indent-level 0
|
|||
|
.
|
|||
|
.de1 rstReportMargin
|
|||
|
\\$1 \\n[an-margin]
|
|||
|
level \\n[rst2man-indent-level]
|
|||
|
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
|
-
|
|||
|
\\n[rst2man-indent0]
|
|||
|
\\n[rst2man-indent1]
|
|||
|
\\n[rst2man-indent2]
|
|||
|
..
|
|||
|
.de1 INDENT
|
|||
|
.\" .rstReportMargin pre:
|
|||
|
. RS \\$1
|
|||
|
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
|
|||
|
. nr rst2man-indent-level +1
|
|||
|
.\" .rstReportMargin post:
|
|||
|
..
|
|||
|
.de UNINDENT
|
|||
|
. RE
|
|||
|
.\" indent \\n[an-margin]
|
|||
|
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
|
.nr rst2man-indent-level -1
|
|||
|
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||
|
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
|||
|
..
|
|||
|
.SH INTRODUCTION
|
|||
|
.sp
|
|||
|
Project source code may depend on, or be conditional on, the availability
|
|||
|
of certain features of the compiler. There are three use\-cases which arise:
|
|||
|
\fI\%Compile Feature Requirements\fP, \fI\%Optional Compile Features\fP
|
|||
|
and \fI\%Conditional Compilation Options\fP\&.
|
|||
|
.sp
|
|||
|
While features are typically specified in programming language standards,
|
|||
|
CMake provides a primary user interface based on granular handling of
|
|||
|
the features, not the language standard that introduced the feature.
|
|||
|
.sp
|
|||
|
The \fBCMAKE_C_KNOWN_FEATURES\fP, \fBCMAKE_CUDA_KNOWN_FEATURES\fP,
|
|||
|
and \fBCMAKE_CXX_KNOWN_FEATURES\fP global properties contain all the
|
|||
|
features known to CMake, regardless of compiler support for the feature.
|
|||
|
The \fBCMAKE_C_COMPILE_FEATURES\fP, \fBCMAKE_CUDA_COMPILE_FEATURES\fP
|
|||
|
, and \fBCMAKE_CXX_COMPILE_FEATURES\fP variables contain all features
|
|||
|
CMake knows are known to the compiler, regardless of language standard
|
|||
|
or compile flags needed to use them.
|
|||
|
.sp
|
|||
|
Features known to CMake are named mostly following the same convention
|
|||
|
as the Clang feature test macros. There are some exceptions, such as
|
|||
|
CMake using \fBcxx_final\fP and \fBcxx_override\fP instead of the single
|
|||
|
\fBcxx_override_control\fP used by Clang.
|
|||
|
.sp
|
|||
|
Note that there are no separate compile features properties or variables for
|
|||
|
the \fBOBJC\fP or \fBOBJCXX\fP languages. These are based off \fBC\fP or \fBC++\fP
|
|||
|
respectively, so the properties and variables for their corresponding base
|
|||
|
language should be used instead.
|
|||
|
.SH COMPILE FEATURE REQUIREMENTS
|
|||
|
.sp
|
|||
|
Compile feature requirements may be specified with the
|
|||
|
\fBtarget_compile_features()\fP command. For example, if a target must
|
|||
|
be compiled with compiler support for the
|
|||
|
\fBcxx_constexpr\fP feature:
|
|||
|
.INDENT 0.0
|
|||
|
.INDENT 3.5
|
|||
|
.sp
|
|||
|
.nf
|
|||
|
.ft C
|
|||
|
add_library(mylib requires_constexpr.cpp)
|
|||
|
target_compile_features(mylib PRIVATE cxx_constexpr)
|
|||
|
.ft P
|
|||
|
.fi
|
|||
|
.UNINDENT
|
|||
|
.UNINDENT
|
|||
|
.sp
|
|||
|
In processing the requirement for the \fBcxx_constexpr\fP feature,
|
|||
|
\fBcmake(1)\fP will ensure that the in\-use C++ compiler is capable
|
|||
|
of the feature, and will add any necessary flags such as \fB\-std=gnu++11\fP
|
|||
|
to the compile lines of C++ files in the \fBmylib\fP target. A
|
|||
|
\fBFATAL_ERROR\fP is issued if the compiler is not capable of the
|
|||
|
feature.
|
|||
|
.sp
|
|||
|
The exact compile flags and language standard are deliberately not part
|
|||
|
of the user interface for this use\-case. CMake will compute the
|
|||
|
appropriate compile flags to use by considering the features specified
|
|||
|
for each target.
|
|||
|
.sp
|
|||
|
Such compile flags are added even if the compiler supports the
|
|||
|
particular feature without the flag. For example, the GNU compiler
|
|||
|
supports variadic templates (with a warning) even if \fB\-std=gnu++98\fP is
|
|||
|
used. CMake adds the \fB\-std=gnu++11\fP flag if \fBcxx_variadic_templates\fP
|
|||
|
is specified as a requirement.
|
|||
|
.sp
|
|||
|
In the above example, \fBmylib\fP requires \fBcxx_constexpr\fP when it
|
|||
|
is built itself, but consumers of \fBmylib\fP are not required to use a
|
|||
|
compiler which supports \fBcxx_constexpr\fP\&. If the interface of
|
|||
|
\fBmylib\fP does require the \fBcxx_constexpr\fP feature (or any other
|
|||
|
known feature), that may be specified with the \fBPUBLIC\fP or
|
|||
|
\fBINTERFACE\fP signatures of \fBtarget_compile_features()\fP:
|
|||
|
.INDENT 0.0
|
|||
|
.INDENT 3.5
|
|||
|
.sp
|
|||
|
.nf
|
|||
|
.ft C
|
|||
|
add_library(mylib requires_constexpr.cpp)
|
|||
|
# cxx_constexpr is a usage\-requirement
|
|||
|
target_compile_features(mylib PUBLIC cxx_constexpr)
|
|||
|
|
|||
|
# main.cpp will be compiled with \-std=gnu++11 on GNU for cxx_constexpr.
|
|||
|
add_executable(myexe main.cpp)
|
|||
|
target_link_libraries(myexe mylib)
|
|||
|
.ft P
|
|||
|
.fi
|
|||
|
.UNINDENT
|
|||
|
.UNINDENT
|
|||
|
.sp
|
|||
|
Feature requirements are evaluated transitively by consuming the link
|
|||
|
implementation. See \fBcmake\-buildsystem(7)\fP for more on
|
|||
|
transitive behavior of build properties and usage requirements.
|
|||
|
.SS Requiring Language Standards
|
|||
|
.sp
|
|||
|
In projects that use a large number of commonly available features from
|
|||
|
a particular language standard (e.g. C++ 11) one may specify a
|
|||
|
meta\-feature (e.g. \fBcxx_std_11\fP) that requires use of a compiler mode
|
|||
|
that is at minimum aware of that standard, but could be greater.
|
|||
|
This is simpler than specifying all the features individually, but does
|
|||
|
not guarantee the existence of any particular feature.
|
|||
|
Diagnosis of use of unsupported features will be delayed until compile time.
|
|||
|
.sp
|
|||
|
For example, if C++ 11 features are used extensively in a project’s
|
|||
|
header files, then clients must use a compiler mode that is no less
|
|||
|
than C++ 11. This can be requested with the code:
|
|||
|
.INDENT 0.0
|
|||
|
.INDENT 3.5
|
|||
|
.sp
|
|||
|
.nf
|
|||
|
.ft C
|
|||
|
target_compile_features(mylib PUBLIC cxx_std_11)
|
|||
|
.ft P
|
|||
|
.fi
|
|||
|
.UNINDENT
|
|||
|
.UNINDENT
|
|||
|
.sp
|
|||
|
In this example, CMake will ensure the compiler is invoked in a mode
|
|||
|
of at\-least C++ 11 (or C++ 14, C++ 17, …), adding flags such as
|
|||
|
\fB\-std=gnu++11\fP if necessary. This applies to sources within \fBmylib\fP
|
|||
|
as well as any dependents (that may include headers from \fBmylib\fP).
|
|||
|
.SS Availability of Compiler Extensions
|
|||
|
.sp
|
|||
|
Because the \fBCXX_EXTENSIONS\fP target property is \fBON\fP by default,
|
|||
|
CMake uses extended variants of language dialects by default, such as
|
|||
|
\fB\-std=gnu++11\fP instead of \fB\-std=c++11\fP\&. That target property may be
|
|||
|
set to \fBOFF\fP to use the non\-extended variant of the dialect flag. Note
|
|||
|
that because most compilers enable extensions by default, this could
|
|||
|
expose cross\-platform bugs in user code or in the headers of third\-party
|
|||
|
dependencies.
|
|||
|
.SH OPTIONAL COMPILE FEATURES
|
|||
|
.sp
|
|||
|
Compile features may be preferred if available, without creating a hard
|
|||
|
requirement. For example, a library may provides alternative
|
|||
|
implementations depending on whether the \fBcxx_variadic_templates\fP
|
|||
|
feature is available:
|
|||
|
.INDENT 0.0
|
|||
|
.INDENT 3.5
|
|||
|
.sp
|
|||
|
.nf
|
|||
|
.ft C
|
|||
|
#if Foo_COMPILER_CXX_VARIADIC_TEMPLATES
|
|||
|
template<int I, int... Is>
|
|||
|
struct Interface;
|
|||
|
|
|||
|
template<int I>
|
|||
|
struct Interface<I>
|
|||
|
{
|
|||
|
static int accumulate()
|
|||
|
{
|
|||
|
return I;
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
template<int I, int... Is>
|
|||
|
struct Interface
|
|||
|
{
|
|||
|
static int accumulate()
|
|||
|
{
|
|||
|
return I + Interface<Is...>::accumulate();
|
|||
|
}
|
|||
|
};
|
|||
|
#else
|
|||
|
template<int I1, int I2 = 0, int I3 = 0, int I4 = 0>
|
|||
|
struct Interface
|
|||
|
{
|
|||
|
static int accumulate() { return I1 + I2 + I3 + I4; }
|
|||
|
};
|
|||
|
#endif
|
|||
|
.ft P
|
|||
|
.fi
|
|||
|
.UNINDENT
|
|||
|
.UNINDENT
|
|||
|
.sp
|
|||
|
Such an interface depends on using the correct preprocessor defines for the
|
|||
|
compiler features. CMake can generate a header file containing such
|
|||
|
defines using the \fBWriteCompilerDetectionHeader\fP module. The
|
|||
|
module contains the \fBwrite_compiler_detection_header\fP function which
|
|||
|
accepts parameters to control the content of the generated header file:
|
|||
|
.INDENT 0.0
|
|||
|
.INDENT 3.5
|
|||
|
.sp
|
|||
|
.nf
|
|||
|
.ft C
|
|||
|
write_compiler_detection_header(
|
|||
|
FILE "${CMAKE_CURRENT_BINARY_DIR}/foo_compiler_detection.h"
|
|||
|
PREFIX Foo
|
|||
|
COMPILERS GNU
|
|||
|
FEATURES
|
|||
|
cxx_variadic_templates
|
|||
|
)
|
|||
|
.ft P
|
|||
|
.fi
|
|||
|
.UNINDENT
|
|||
|
.UNINDENT
|
|||
|
.sp
|
|||
|
Such a header file may be used internally in the source code of a project,
|
|||
|
and it may be installed and used in the interface of library code.
|
|||
|
.sp
|
|||
|
For each feature listed in \fBFEATURES\fP, a preprocessor definition
|
|||
|
is created in the header file, and defined to either \fB1\fP or \fB0\fP\&.
|
|||
|
.sp
|
|||
|
Additionally, some features call for additional defines, such as the
|
|||
|
\fBcxx_final\fP and \fBcxx_override\fP features. Rather than being used in
|
|||
|
\fB#ifdef\fP code, the \fBfinal\fP keyword is abstracted by a symbol
|
|||
|
which is defined to either \fBfinal\fP, a compiler\-specific equivalent, or
|
|||
|
to empty. That way, C++ code can be written to unconditionally use the
|
|||
|
symbol, and compiler support determines what it is expanded to:
|
|||
|
.INDENT 0.0
|
|||
|
.INDENT 3.5
|
|||
|
.sp
|
|||
|
.nf
|
|||
|
.ft C
|
|||
|
struct Interface {
|
|||
|
virtual void Execute() = 0;
|
|||
|
};
|
|||
|
|
|||
|
struct Concrete Foo_FINAL {
|
|||
|
void Execute() Foo_OVERRIDE;
|
|||
|
};
|
|||
|
.ft P
|
|||
|
.fi
|
|||
|
.UNINDENT
|
|||
|
.UNINDENT
|
|||
|
.sp
|
|||
|
In this case, \fBFoo_FINAL\fP will expand to \fBfinal\fP if the
|
|||
|
compiler supports the keyword, or to empty otherwise.
|
|||
|
.sp
|
|||
|
In this use\-case, the CMake code will wish to enable a particular language
|
|||
|
standard if available from the compiler. The \fBCXX_STANDARD\fP
|
|||
|
target property variable may be set to the desired language standard
|
|||
|
for a particular target, and the \fBCMAKE_CXX_STANDARD\fP may be
|
|||
|
set to influence all following targets:
|
|||
|
.INDENT 0.0
|
|||
|
.INDENT 3.5
|
|||
|
.sp
|
|||
|
.nf
|
|||
|
.ft C
|
|||
|
write_compiler_detection_header(
|
|||
|
FILE "${CMAKE_CURRENT_BINARY_DIR}/foo_compiler_detection.h"
|
|||
|
PREFIX Foo
|
|||
|
COMPILERS GNU
|
|||
|
FEATURES
|
|||
|
cxx_final cxx_override
|
|||
|
)
|
|||
|
|
|||
|
# Includes foo_compiler_detection.h and uses the Foo_FINAL symbol
|
|||
|
# which will expand to \(aqfinal\(aq if the compiler supports the requested
|
|||
|
# CXX_STANDARD.
|
|||
|
add_library(foo foo.cpp)
|
|||
|
set_property(TARGET foo PROPERTY CXX_STANDARD 11)
|
|||
|
|
|||
|
# Includes foo_compiler_detection.h and uses the Foo_FINAL symbol
|
|||
|
# which will expand to \(aqfinal\(aq if the compiler supports the feature,
|
|||
|
# even though CXX_STANDARD is not set explicitly. The requirement of
|
|||
|
# cxx_constexpr causes CMake to set CXX_STANDARD internally, which
|
|||
|
# affects the compile flags.
|
|||
|
add_library(foo_impl foo_impl.cpp)
|
|||
|
target_compile_features(foo_impl PRIVATE cxx_constexpr)
|
|||
|
.ft P
|
|||
|
.fi
|
|||
|
.UNINDENT
|
|||
|
.UNINDENT
|
|||
|
.sp
|
|||
|
The \fBwrite_compiler_detection_header\fP function also creates compatibility
|
|||
|
code for other features which have standard equivalents. For example, the
|
|||
|
\fBcxx_static_assert\fP feature is emulated with a template and abstracted
|
|||
|
via the \fB<PREFIX>_STATIC_ASSERT\fP and \fB<PREFIX>_STATIC_ASSERT_MSG\fP
|
|||
|
function\-macros.
|
|||
|
.SH CONDITIONAL COMPILATION OPTIONS
|
|||
|
.sp
|
|||
|
Libraries may provide entirely different header files depending on
|
|||
|
requested compiler features.
|
|||
|
.sp
|
|||
|
For example, a header at \fBwith_variadics/interface.h\fP may contain:
|
|||
|
.INDENT 0.0
|
|||
|
.INDENT 3.5
|
|||
|
.sp
|
|||
|
.nf
|
|||
|
.ft C
|
|||
|
template<int I, int... Is>
|
|||
|
struct Interface;
|
|||
|
|
|||
|
template<int I>
|
|||
|
struct Interface<I>
|
|||
|
{
|
|||
|
static int accumulate()
|
|||
|
{
|
|||
|
return I;
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
template<int I, int... Is>
|
|||
|
struct Interface
|
|||
|
{
|
|||
|
static int accumulate()
|
|||
|
{
|
|||
|
return I + Interface<Is...>::accumulate();
|
|||
|
}
|
|||
|
};
|
|||
|
.ft P
|
|||
|
.fi
|
|||
|
.UNINDENT
|
|||
|
.UNINDENT
|
|||
|
.sp
|
|||
|
while a header at \fBno_variadics/interface.h\fP may contain:
|
|||
|
.INDENT 0.0
|
|||
|
.INDENT 3.5
|
|||
|
.sp
|
|||
|
.nf
|
|||
|
.ft C
|
|||
|
template<int I1, int I2 = 0, int I3 = 0, int I4 = 0>
|
|||
|
struct Interface
|
|||
|
{
|
|||
|
static int accumulate() { return I1 + I2 + I3 + I4; }
|
|||
|
};
|
|||
|
.ft P
|
|||
|
.fi
|
|||
|
.UNINDENT
|
|||
|
.UNINDENT
|
|||
|
.sp
|
|||
|
It would be possible to write a abstraction \fBinterface.h\fP header
|
|||
|
containing something like:
|
|||
|
.INDENT 0.0
|
|||
|
.INDENT 3.5
|
|||
|
.sp
|
|||
|
.nf
|
|||
|
.ft C
|
|||
|
#include "foo_compiler_detection.h"
|
|||
|
#if Foo_COMPILER_CXX_VARIADIC_TEMPLATES
|
|||
|
#include "with_variadics/interface.h"
|
|||
|
#else
|
|||
|
#include "no_variadics/interface.h"
|
|||
|
#endif
|
|||
|
.ft P
|
|||
|
.fi
|
|||
|
.UNINDENT
|
|||
|
.UNINDENT
|
|||
|
.sp
|
|||
|
However this could be unmaintainable if there are many files to
|
|||
|
abstract. What is needed is to use alternative include directories
|
|||
|
depending on the compiler capabilities.
|
|||
|
.sp
|
|||
|
CMake provides a \fBCOMPILE_FEATURES\fP
|
|||
|
\fBgenerator expression\fP to implement
|
|||
|
such conditions. This may be used with the build\-property commands such as
|
|||
|
\fBtarget_include_directories()\fP and \fBtarget_link_libraries()\fP
|
|||
|
to set the appropriate \fBbuildsystem\fP
|
|||
|
properties:
|
|||
|
.INDENT 0.0
|
|||
|
.INDENT 3.5
|
|||
|
.sp
|
|||
|
.nf
|
|||
|
.ft C
|
|||
|
add_library(foo INTERFACE)
|
|||
|
set(with_variadics ${CMAKE_CURRENT_SOURCE_DIR}/with_variadics)
|
|||
|
set(no_variadics ${CMAKE_CURRENT_SOURCE_DIR}/no_variadics)
|
|||
|
target_include_directories(foo
|
|||
|
INTERFACE
|
|||
|
"$<$<COMPILE_FEATURES:cxx_variadic_templates>:${with_variadics}>"
|
|||
|
"$<$<NOT:$<COMPILE_FEATURES:cxx_variadic_templates>>:${no_variadics}>"
|
|||
|
)
|
|||
|
.ft P
|
|||
|
.fi
|
|||
|
.UNINDENT
|
|||
|
.UNINDENT
|
|||
|
.sp
|
|||
|
Consuming code then simply links to the \fBfoo\fP target as usual and uses
|
|||
|
the feature\-appropriate include directory
|
|||
|
.INDENT 0.0
|
|||
|
.INDENT 3.5
|
|||
|
.sp
|
|||
|
.nf
|
|||
|
.ft C
|
|||
|
add_executable(consumer_with consumer_with.cpp)
|
|||
|
target_link_libraries(consumer_with foo)
|
|||
|
set_property(TARGET consumer_with CXX_STANDARD 11)
|
|||
|
|
|||
|
add_executable(consumer_no consumer_no.cpp)
|
|||
|
target_link_libraries(consumer_no foo)
|
|||
|
.ft P
|
|||
|
.fi
|
|||
|
.UNINDENT
|
|||
|
.UNINDENT
|
|||
|
.SH SUPPORTED COMPILERS
|
|||
|
.sp
|
|||
|
CMake is currently aware of the \fBC++ standards\fP
|
|||
|
and \fBcompile features\fP available from
|
|||
|
the following \fBcompiler ids\fP as of the
|
|||
|
versions specified for each:
|
|||
|
.INDENT 0.0
|
|||
|
.IP \(bu 2
|
|||
|
\fBAppleClang\fP: Apple Clang for Xcode versions 4.4+.
|
|||
|
.IP \(bu 2
|
|||
|
\fBClang\fP: Clang compiler versions 2.9+.
|
|||
|
.IP \(bu 2
|
|||
|
\fBGNU\fP: GNU compiler versions 4.4+.
|
|||
|
.IP \(bu 2
|
|||
|
\fBMSVC\fP: Microsoft Visual Studio versions 2010+.
|
|||
|
.IP \(bu 2
|
|||
|
\fBSunPro\fP: Oracle SolarisStudio versions 12.4+.
|
|||
|
.IP \(bu 2
|
|||
|
\fBIntel\fP: Intel compiler versions 12.1+.
|
|||
|
.UNINDENT
|
|||
|
.sp
|
|||
|
CMake is currently aware of the \fBC standards\fP
|
|||
|
and \fBcompile features\fP available from
|
|||
|
the following \fBcompiler ids\fP as of the
|
|||
|
versions specified for each:
|
|||
|
.INDENT 0.0
|
|||
|
.IP \(bu 2
|
|||
|
all compilers and versions listed above for C++.
|
|||
|
.IP \(bu 2
|
|||
|
\fBGNU\fP: GNU compiler versions 3.4+
|
|||
|
.UNINDENT
|
|||
|
.sp
|
|||
|
CMake is currently aware of the \fBC++ standards\fP and
|
|||
|
their associated meta\-features (e.g. \fBcxx_std_11\fP) available from the
|
|||
|
following \fBcompiler ids\fP as of the
|
|||
|
versions specified for each:
|
|||
|
.INDENT 0.0
|
|||
|
.IP \(bu 2
|
|||
|
\fBCray\fP: Cray Compiler Environment version 8.1+.
|
|||
|
.IP \(bu 2
|
|||
|
\fBPGI\fP: PGI version 12.10+.
|
|||
|
.IP \(bu 2
|
|||
|
\fBXL\fP: IBM XL version 10.1+.
|
|||
|
.UNINDENT
|
|||
|
.sp
|
|||
|
CMake is currently aware of the \fBC standards\fP and
|
|||
|
their associated meta\-features (e.g. \fBc_std_99\fP) available from the
|
|||
|
following \fBcompiler ids\fP as of the
|
|||
|
versions specified for each:
|
|||
|
.INDENT 0.0
|
|||
|
.IP \(bu 2
|
|||
|
all compilers and versions listed above with only meta\-features for C++.
|
|||
|
.IP \(bu 2
|
|||
|
\fBTI\fP: Texas Instruments compiler.
|
|||
|
.UNINDENT
|
|||
|
.sp
|
|||
|
CMake is currently aware of the \fBCUDA standards\fP and
|
|||
|
their associated meta\-features (e.g. \fBcuda_std_11\fP) available from the
|
|||
|
following \fBcompiler ids\fP as of the
|
|||
|
versions specified for each:
|
|||
|
.INDENT 0.0
|
|||
|
.IP \(bu 2
|
|||
|
\fBNVIDIA\fP: NVIDIA nvcc compiler 7.5+.
|
|||
|
.UNINDENT
|
|||
|
.SH COPYRIGHT
|
|||
|
2000-2020 Kitware, Inc. and Contributors
|
|||
|
.\" Generated by docutils manpage writer.
|
|||
|
.
|