Provided by: cmake-data_3.10.2-1ubuntu2.18.04.2_all bug

NAME

       cmake-compile-features - CMake Compile Features Reference

INTRODUCTION

       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:  Compile  Feature
       Requirements, Optional Compile Features and Conditional Compilation Options.

       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.

       The  CMAKE_C_KNOWN_FEATURES and CMAKE_CXX_KNOWN_FEATURES global properties contain all the
       features  known  to  CMake,  regardless  of  compiler  support  for  the   feature.    The
       CMAKE_C_COMPILE_FEATURES  and  CMAKE_CXX_COMPILE_FEATURES  variables  contain all features
       CMake knows are known to the compiler, regardless of language standard  or  compile  flags
       needed to use them.

       Features  known  to  CMake  are  named  mostly  following the same convention as the Clang
       feature test macros.   The  are  some  exceptions,  such  as  CMake  using  cxx_final  and
       cxx_override instead of the single cxx_override_control used by Clang.

COMPILE FEATURE REQUIREMENTS

       Compile  feature requirements may be specified with the target_compile_features() command.
       For example, if a target must be compiled with  compiler  support  for  the  cxx_constexpr
       feature:

          add_library(mylib requires_constexpr.cpp)
          target_compile_features(mylib PRIVATE cxx_constexpr)

       In processing the requirement for the cxx_constexpr feature, cmake(1) will ensure that the
       in-use C++ compiler is capable of the feature, and will add any necessary  flags  such  as
       -std=gnu++11  to  the  compile  lines  of C++ files in the mylib target.  A FATAL_ERROR is
       issued if the compiler is not capable of the feature.

       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.

       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 -std=gnu++98 is used.  CMake adds the -std=gnu++11 flag  if  cxx_variadic_templates  is
       specified as a requirement.

       In  the above example, mylib requires cxx_constexpr when it is built itself, but consumers
       of mylib are not required  to  use  a  compiler  which  supports  cxx_constexpr.   If  the
       interface  of  mylib  does require the cxx_constexpr feature (or any other known feature),
       that   may   be   specified   with    the    PUBLIC    or    INTERFACE    signatures    of
       target_compile_features():

          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)

       Feature requirements are evaluated transitively by consuming the link implementation.  See
       cmake-buildsystem(7) for more  on  transitive  behavior  of  build  properties  and  usage
       requirements.

   Requiring Language Standards
       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.  cxx_std_11)  that
       requires  use  of a compiler mode aware of that standard.  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.

       For  example,  if  C++  11 features are used extensively in a project’s header files, then
       clients must use a compiler mode aware of C++ 11 or above.  This can be requested with the
       code:

          target_compile_features(mylib PUBLIC cxx_std_11)

       In  this example, CMake will ensure the compiler is invoked in a mode that is aware of C++
       11 (or above), adding flags such as -std=gnu++11 if necessary.  This  applies  to  sources
       within mylib as well as any dependents (that may include headers from mylib).

   Availability of Compiler Extensions
       Because  the CXX_EXTENSIONS target property is ON by default, CMake uses extended variants
       of language dialects by default, such as -std=gnu++11 instead of -std=c++11.  That  target
       property may be set to OFF 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.

OPTIONAL COMPILE FEATURES

       Compile  features may be preferred if available, without creating a hard requirement.  For
       example, a library may provides  alternative  implementations  depending  on  whether  the
       cxx_variadic_templates feature is available:

          #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

       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
       WriteCompilerDetectionHeader       module.        The       module       contains      the
       write_compiler_detection_header function which accepts parameters to control  the  content
       of the generated header file:

          write_compiler_detection_header(
            FILE "${CMAKE_CURRENT_BINARY_DIR}/foo_compiler_detection.h"
            PREFIX Foo
            COMPILERS GNU
            FEATURES
              cxx_variadic_templates
          )

       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.

       For each feature listed in FEATURES, a preprocessor definition is created  in  the  header
       file, and defined to either 1 or 0.

       Additionally,  some  features  call  for  additional  defines,  such  as the cxx_final and
       cxx_override features. Rather than being  used  in  #ifdef  code,  the  final  keyword  is
       abstracted  by  a symbol which is defined to either final, 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:

          struct Interface {
            virtual void Execute() = 0;
          };

          struct Concrete Foo_FINAL {
            void Execute() Foo_OVERRIDE;
          };

       In  this  case, Foo_FINAL will expand to final if the compiler supports the keyword, or to
       empty otherwise.

       In this use-case, the CMake code will wish to enable a  particular  language  standard  if
       available  from  the compiler. The CXX_STANDARD target property variable may be set to the
       desired language standard for a particular target, and the CMAKE_CXX_STANDARD may  be  set
       to influence all following targets:

          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 'final' 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 'final' 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)

       The  write_compiler_detection_header  function  also  creates compatibility code for other
       features which have standard equivalents.  For example, the cxx_static_assert  feature  is
       emulated   with   a   template   and   abstracted   via   the  <PREFIX>_STATIC_ASSERT  and
       <PREFIX>_STATIC_ASSERT_MSG function-macros.

CONDITIONAL COMPILATION OPTIONS

       Libraries may provide entirely different header  files  depending  on  requested  compiler
       features.

       For example, a header at with_variadics/interface.h may contain:

          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();
            }
          };

       while a header at no_variadics/interface.h may contain:

          template<int I1, int I2 = 0, int I3 = 0, int I4 = 0>
          struct Interface
          {
            static int accumulate() { return I1 + I2 + I3 + I4; }
          };

       It would be possible to write a abstraction interface.h header containing something like:

          #include "foo_compiler_detection.h"
          #if Foo_COMPILER_CXX_VARIADIC_TEMPLATES
          #include "with_variadics/interface.h"
          #else
          #include "no_variadics/interface.h"
          #endif

       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.

       CMake provides a COMPILE_FEATURES generator expression to implement such conditions.  This
       may  be  used  with  the  build-property commands such as target_include_directories() and
       target_link_libraries() to set the appropriate buildsystem properties:

          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}>"
            )

       Consuming  code  then  simply  links  to  the  foo  target   as   usual   and   uses   the
       feature-appropriate include directory

          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)

SUPPORTED COMPILERS

       CMake  is  currently  aware  of  the C++ standards and compile features available from the
       following compiler ids as of the versions specified for each:

       • AppleClang: Apple Clang for Xcode versions 4.4 though 6.2.

       • Clang: Clang compiler versions 2.9 through 3.4.

       • GNU: GNU compiler versions 4.4 through 5.0.

       • MSVC: Microsoft Visual Studio versions 2010 through 2017.

       • SunPro: Oracle SolarisStudio versions 12.4 through 12.5.

       • Intel: Intel compiler versions 12.1 through 17.0.

       CMake is currently aware of the C  standards  and  compile  features  available  from  the
       following compiler ids as of the versions specified for each:

       • all compilers and versions listed above for C++.

       • GNU: GNU compiler versions 3.4 through 5.0.

       CMake  is  currently  aware  of the C++ standards and their associated meta-features (e.g.
       cxx_std_11) available from the following compiler ids as of  the  versions  specified  for
       each:

       • Cray: Cray Compiler Environment version 8.1 through 8.5.8.

       • PGI: PGI version 12.10 through 17.5.

       • XL: IBM XL version 10.1 through 13.1.5.

       CMake  is  currently  aware  of  the  C standards and their associated meta-features (e.g.
       c_std_99) available from the following compiler ids as of the versions specified for each:

       • all compilers and versions listed above with only meta-features for C++.

       CMake is currently aware of the CUDA standards from the following compiler ids as  of  the
       versions specified for each:

       • NVIDIA: NVIDIA nvcc compiler 7.5 though 8.0.

COPYRIGHT

       2000-2021 Kitware, Inc. and Contributors