diff options
46 files changed, 507 insertions, 59 deletions
diff --git a/Help/command/target_compile_features.rst b/Help/command/target_compile_features.rst index 9559600..a6503db 100644 --- a/Help/command/target_compile_features.rst +++ b/Help/command/target_compile_features.rst @@ -28,4 +28,5 @@ an ``IMPORTED`` target. Arguments to ``target_compile_features`` may use "generator expressions" with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)` manual for available -expressions. +expressions. See the :manual:`cmake-compile-features(7)` manual for +information on compile features. diff --git a/Help/index.rst b/Help/index.rst index a4abfbf..2d3f156 100644 --- a/Help/index.rst +++ b/Help/index.rst @@ -27,6 +27,7 @@ Reference Manuals /manual/cmake-buildsystem.7 /manual/cmake-commands.7 + /manual/cmake-compile-features.7 /manual/cmake-developer.7 /manual/cmake-generator-expressions.7 /manual/cmake-generators.7 diff --git a/Help/manual/cmake-compile-features.7.rst b/Help/manual/cmake-compile-features.7.rst new file mode 100644 index 0000000..c014846 --- /dev/null +++ b/Help/manual/cmake-compile-features.7.rst @@ -0,0 +1,297 @@ +.. cmake-manual-description: CMake Compile Features Reference + +cmake-compile-features(7) +************************* + +.. only:: html or latex + + .. contents:: + +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 :prop_gbl:`CMAKE_C_KNOWN_FEATURES` and +:prop_gbl:`CMAKE_CXX_KNOWN_FEATURES` global properties contain all the +features known to CMake, regardless of compiler support for the feature. +The :variable:`CMAKE_C_COMPILE_FEATURES` and +:variable:`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 execptions, 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 +:command:`target_compile_features` command. For example, if a target must +be compiled with compiler support for the +:prop_gbl:`cxx_constexpr <CMAKE_CXX_KNOWN_FEATURES>` feature: + +.. code-block:: cmake + + add_library(mylib requires_constexpr.cpp) + target_compile_features(mylib PRIVATE cxx_constexpr) + +In processing the requirement for the ``cxx_constexpr`` feature, +:manual:`cmake(1)` will ensure that the in-use C++ compiler is capable +of the feature, and will add any necessary flags such as ``-std=c++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=c++98`` is +used. CMake adds the ``-std=c++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 :command:`target_compile_features`: + +.. code-block:: cmake + + 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=c++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 :manual:`cmake-buildsystem(7)` for more on +transitive behavior of build properties and usage requirements. + +Note that new use of compile feature requirements may expose +cross-platform bugs in user code. For example, the GNU compiler uses the +``gnu++98`` language by default as of GCC version 4.8. User code may +be relying on that by expecting the ``typeof`` GNU extension to work. +However, if the :command:`target_compile_features` command is used to +specify the requirement for ``cxx_constexpr``, a ``-std=c++11`` flag may +be added, and the ``typeof`` extension would no longer be available. The +solution is to specify that compiler extensions are relied upon by setting +the :prop_tgt:`CXX_EXTENSIONS` target property to ``ON`` when starting to +use the :command:`target_compile_features` command. + +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: + +.. code-block:: 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 + +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 :module:`WriteCompilerDetectionHeader` module. The +module contains the ``write_compiler_detection_header`` function which +accepts parameters to control the content of the generated header file: + +.. code-block:: cmake + + 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: + +.. code-block:: c++ + + struct Interface { + virtual void Execute() = 0; + }; + + struct Concrete Foo_CXX_FINAL { + void Execute() Foo_CXX_OVERRIDE; + }; + +In this case, ``Foo_CXX_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 :prop_tgt:`CXX_STANDARD` +target property variable may be set to the desired language standard +for a particular target, and the :variable:`CMAKE_CXX_STANDARD` may be +set to influence all following targets: + +.. code-block:: cmake + + 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_DECL_CXX_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_DECL_CXX_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: + +.. code-block:: 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(); + } + }; + +while a header at ``no_variadics/interface.h`` may contain: + +.. code-block:: c++ + + 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: + +.. code-block:: c++ + + #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`` +:manual:`generator expression <cmake-generator-expressions(7)>` to implement +such conditions. This may be used with the build-property commands such as +:command:`target_include_directories` and :command:`target_link_libraries` +to set the appropriate :manual:`buildsystem <cmake-buildsystem(7)>` +properties: + +.. code-block:: cmake + + add_library(foo INTERFACE) + target_link_libraries(foo + INTERFACE + "$<$<COMPILE_FEATURES:cxx_variadic_templates>:${CMAKE_CURRENT_SOURCE_DIR}/with_variadics>" + "$<$<NOT:$<COMPILE_FEATURES:cxx_variadic_templates>>:${CMAKE_CURRENT_SOURCE_DIR}/no_variadics>") + +Consuming code then simply links to the ``foo`` target as usual and uses +the feature-appropriate include directory + +.. code-block:: cmake + + 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) diff --git a/Help/manual/cmake-developer.7.rst b/Help/manual/cmake-developer.7.rst index 7f31970..4ab9786 100644 --- a/Help/manual/cmake-developer.7.rst +++ b/Help/manual/cmake-developer.7.rst @@ -197,6 +197,51 @@ Templates Some template code is permitted, but with some limitations. Member templates may not be used, and template friends may not be used. +Adding Compile Features +======================= + +CMake reports an error if a compiler whose features are known does not report +support for a particular requested feature. A compiler is considered to have +known features if it reports support for at least one feature. + +When adding a new compile feature to CMake, it is therefore necessary to list +support for the feature for all CompilerIds which already have one or more +feature supported, if the new feature is available for any version of the +compiler. + +When adding the first supported feature to a particular CompilerId, it is +necessary to list support for all features known to cmake (See +:variable:`CMAKE_C_COMPILE_FEATURES` and +:variable:`CMAKE_CXX_COMPILE_FEATURES` as appropriate), where available for +the compiler. + +It is sensible to record the features for the most recent version of a +particular CompilerId first, and then work backwards. It is sensible to +try to create a continuous range of versions of feature releases of the +compiler. Gaps in the range indicate incorrect features recorded for +intermediate releases. + +Generally, features are made available for a particular version if the +compiler vendor documents availability of the feature with that +version. Note that sometimes partially implemented features appear to +be functional in previous releases (such as ``cxx_constexpr`` in GNU 4.6, +though availability is documented in GNU 4.7), and sometimes compiler vendors +document availability of features, though supporting infrastructure is +not available (such as ``__has_feature(cxx_generic_lambdas)`` indicating +non-availability in Clang 3.4, though it is documented as available, and +fixed in Clang 3.5). Similar cases for other compilers and versions +need to be investigated when extending CMake to support them. + +When a vendor releases a new version of a known compiler which supports +a previously unsupported feature, and there are already known features for +that compiler, the feature should be listed as supported in CMake for +that version of the compiler as soon as reasonably possible. + +Standard-specific/compiler-specific variables such +``CMAKE_CXX98_COMPILE_FEATURES`` are deliberately not documented. They +only exist for the compiler-specific implementation of adding the ``-std`` +compile flag for compilers which need that. + Help ==== diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst index 9184580..f04702e 100644 --- a/Help/manual/cmake-generator-expressions.7.rst +++ b/Help/manual/cmake-generator-expressions.7.rst @@ -88,7 +88,9 @@ otherwise expands to nothing. target, and ``0`` otherwise. If this expression is used while evaluating the link implementation of a target and if any dependency transitively increases the required :prop_tgt:`C_STANDARD` or :prop_tgt:`CXX_STANDARD` - for the 'head' target, an error is reported. + for the 'head' target, an error is reported. See the + :manual:`cmake-compile-features(7)` manual for information on + compile features. Informational Expressions ========================= diff --git a/Help/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.rst b/Help/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.rst index 643bd3b..ed89d40 100644 --- a/Help/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.rst +++ b/Help/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.rst @@ -8,7 +8,9 @@ C++ compiler. If the feature is available with the C++ compiler, it will be listed in the :variable:`CMAKE_CXX_COMPILE_FEATURES` variable. The features listed here may be used with the :command:`target_compile_features` -command. +command. See the :manual:`cmake-compile-features(7)` manual for information on +compile features. + The features known to this version of CMake are: diff --git a/Help/prop_gbl/CMAKE_C_KNOWN_FEATURES.rst b/Help/prop_gbl/CMAKE_C_KNOWN_FEATURES.rst index c57bc73..18cd030 100644 --- a/Help/prop_gbl/CMAKE_C_KNOWN_FEATURES.rst +++ b/Help/prop_gbl/CMAKE_C_KNOWN_FEATURES.rst @@ -8,7 +8,8 @@ C compiler. If the feature is available with the C compiler, it will be listed in the :variable:`CMAKE_C_COMPILE_FEATURES` variable. The features listed here may be used with the :command:`target_compile_features` -command. +command. See the :manual:`cmake-compile-features(7)` manual for information on +compile features. The features known to this version of CMake are: diff --git a/Help/prop_tgt/COMPILE_FEATURES.rst b/Help/prop_tgt/COMPILE_FEATURES.rst index dc32825..225ffee 100644 --- a/Help/prop_tgt/COMPILE_FEATURES.rst +++ b/Help/prop_tgt/COMPILE_FEATURES.rst @@ -8,4 +8,5 @@ in the :variable:`CMAKE_CXX_COMPILE_FEATURES` variable. Contents of ``COMPILE_FEATURES`` may use "generator expressions" with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)` manual for -available expressions. +available expressions. See the :manual:`cmake-compile-features(7)` manual +for information on compile features. diff --git a/Help/prop_tgt/CXX_EXTENSIONS.rst b/Help/prop_tgt/CXX_EXTENSIONS.rst index b9c9931..d7f87a4 100644 --- a/Help/prop_tgt/CXX_EXTENSIONS.rst +++ b/Help/prop_tgt/CXX_EXTENSIONS.rst @@ -6,3 +6,10 @@ Boolean specifying whether compiler specific extensions are requested. This property specifies whether compiler specific extensions should be used. For some compilers, this results in adding a flag such as ``-std=gnu++11`` instead of ``-std=c++11`` to the compile line. + +See the :manual:`cmake-compile-features(7)` manual for information on +compile features. + +This property is initialized by the value of +the :variable:`CMAKE_CXX_EXTENSIONS` variable if it is set when a target +is created. diff --git a/Help/prop_tgt/CXX_STANDARD.rst b/Help/prop_tgt/CXX_STANDARD.rst index fdd5aac..8f299bb 100644 --- a/Help/prop_tgt/CXX_STANDARD.rst +++ b/Help/prop_tgt/CXX_STANDARD.rst @@ -22,6 +22,9 @@ flag will not result in an error or warning, but will instead add the ``-std=c++98`` flag if supported. This "decay" behavior may be controlled with the :prop_tgt:`CXX_STANDARD_REQUIRED` target property. +See the :manual:`cmake-compile-features(7)` manual for information on +compile features. + This property is initialized by the value of the :variable:`CMAKE_CXX_STANDARD` variable if it is set when a target is created. diff --git a/Help/prop_tgt/CXX_STANDARD_REQUIRED.rst b/Help/prop_tgt/CXX_STANDARD_REQUIRED.rst index f082805..ac103a4 100644 --- a/Help/prop_tgt/CXX_STANDARD_REQUIRED.rst +++ b/Help/prop_tgt/CXX_STANDARD_REQUIRED.rst @@ -9,6 +9,9 @@ property is ``OFF`` or unset, the :prop_tgt:`CXX_STANDARD` target property is treated as optional and may "decay" to a previous standard if the requested is not available. +See the :manual:`cmake-compile-features(7)` manual for information on +compile features. + This property is initialized by the value of the :variable:`CMAKE_CXX_STANDARD_REQUIRED` variable if it is set when a target is created. diff --git a/Help/prop_tgt/C_EXTENSIONS.rst b/Help/prop_tgt/C_EXTENSIONS.rst index 246e93d..0772ecc 100644 --- a/Help/prop_tgt/C_EXTENSIONS.rst +++ b/Help/prop_tgt/C_EXTENSIONS.rst @@ -6,3 +6,10 @@ Boolean specifying whether compiler specific extensions are requested. This property specifies whether compiler specific extensions should be used. For some compilers, this results in adding a flag such as ``-std=gnu11`` instead of ``-std=c11`` to the compile line. + +See the :manual:`cmake-compile-features(7)` manual for information on +compile features. + +This property is initialized by the value of +the :variable:`CMAKE_C_EXTENSIONS` variable if it is set when a target +is created. diff --git a/Help/prop_tgt/C_STANDARD.rst b/Help/prop_tgt/C_STANDARD.rst index 9fdc0bb..a0c939a 100644 --- a/Help/prop_tgt/C_STANDARD.rst +++ b/Help/prop_tgt/C_STANDARD.rst @@ -22,6 +22,9 @@ flag will not result in an error or warning, but will instead add the ``-std=c99`` or ``-std=c90`` flag if supported. This "decay" behavior may be controlled with the :prop_tgt:`C_STANDARD_REQUIRED` target property. +See the :manual:`cmake-compile-features(7)` manual for information on +compile features. + This property is initialized by the value of the :variable:`CMAKE_C_STANDARD` variable if it is set when a target is created. diff --git a/Help/prop_tgt/C_STANDARD_REQUIRED.rst b/Help/prop_tgt/C_STANDARD_REQUIRED.rst index 6c39e96..a7304f4 100644 --- a/Help/prop_tgt/C_STANDARD_REQUIRED.rst +++ b/Help/prop_tgt/C_STANDARD_REQUIRED.rst @@ -9,6 +9,9 @@ property is ``OFF`` or unset, the :prop_tgt:`C_STANDARD` target property is treated as optional and may "decay" to a previous standard if the requested is not available. +See the :manual:`cmake-compile-features(7)` manual for information on +compile features. + This property is initialized by the value of the :variable:`CMAKE_C_STANDARD_REQUIRED` variable if it is set when a target is created. diff --git a/Help/prop_tgt/INTERFACE_COMPILE_FEATURES.rst b/Help/prop_tgt/INTERFACE_COMPILE_FEATURES.rst index a98e362..7abdecb 100644 --- a/Help/prop_tgt/INTERFACE_COMPILE_FEATURES.rst +++ b/Help/prop_tgt/INTERFACE_COMPILE_FEATURES.rst @@ -11,4 +11,6 @@ to require the features specified in the interface of ``foo``. Contents of ``INTERFACE_COMPILE_FEATURES`` may use "generator expressions" with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)` -manual for available expressions. +manual for available expressions. See the +:manual:`cmake-compile-features(7)` manual for information on compile +features. diff --git a/Help/release/dev/variable_watch-no-allowed-access.rst b/Help/release/dev/variable_watch-no-allowed-access.rst new file mode 100644 index 0000000..ba7b4a5 --- /dev/null +++ b/Help/release/dev/variable_watch-no-allowed-access.rst @@ -0,0 +1,8 @@ +variable_watch-no-allowed-access +-------------------------------- + +* Callbacks established by the :command:`variable_watch` command will no + longer receive the ``ALLOWED_UNKNOWN_READ_ACCESS`` access type when + the undocumented ``CMAKE_ALLOW_UNKNOWN_VARIABLE_READ_ACCESS`` variable is + set. Uninitialized variable accesses will always be reported as + ``UNKNOWN_READ_ACCESS``. diff --git a/Help/variable/CMAKE_CXX_COMPILE_FEATURES.rst b/Help/variable/CMAKE_CXX_COMPILE_FEATURES.rst index 1102c21..460c78c 100644 --- a/Help/variable/CMAKE_CXX_COMPILE_FEATURES.rst +++ b/Help/variable/CMAKE_CXX_COMPILE_FEATURES.rst @@ -6,3 +6,6 @@ List of features known to the C++ compiler These features are known to be available for use with the C++ compiler. This list is a subset of the features listed in the :prop_gbl:`CMAKE_CXX_KNOWN_FEATURES` global property. + +See the :manual:`cmake-compile-features(7)` manual for information on +compile features. diff --git a/Help/variable/CMAKE_CXX_EXTENSIONS.rst b/Help/variable/CMAKE_CXX_EXTENSIONS.rst index 734d508..6448371 100644 --- a/Help/variable/CMAKE_CXX_EXTENSIONS.rst +++ b/Help/variable/CMAKE_CXX_EXTENSIONS.rst @@ -6,3 +6,6 @@ Default value for ``CXX_EXTENSIONS`` property of targets. This variable is used to initialize the :prop_tgt:`CXX_EXTENSIONS` property on all targets. See that target property for additional information. + +See the :manual:`cmake-compile-features(7)` manual for information on +compile features. diff --git a/Help/variable/CMAKE_CXX_STANDARD.rst b/Help/variable/CMAKE_CXX_STANDARD.rst index 5fd4138..963a42a 100644 --- a/Help/variable/CMAKE_CXX_STANDARD.rst +++ b/Help/variable/CMAKE_CXX_STANDARD.rst @@ -6,3 +6,6 @@ Default value for ``CXX_STANDARD`` property of targets. This variable is used to initialize the :prop_tgt:`CXX_STANDARD` property on all targets. See that target property for additional information. + +See the :manual:`cmake-compile-features(7)` manual for information on +compile features. diff --git a/Help/variable/CMAKE_CXX_STANDARD_REQUIRED.rst b/Help/variable/CMAKE_CXX_STANDARD_REQUIRED.rst index ff005da..f7750fa 100644 --- a/Help/variable/CMAKE_CXX_STANDARD_REQUIRED.rst +++ b/Help/variable/CMAKE_CXX_STANDARD_REQUIRED.rst @@ -6,3 +6,6 @@ Default value for ``CXX_STANDARD_REQUIRED`` property of targets. This variable is used to initialize the :prop_tgt:`CXX_STANDARD_REQUIRED` property on all targets. See that target property for additional information. + +See the :manual:`cmake-compile-features(7)` manual for information on +compile features. diff --git a/Help/variable/CMAKE_C_COMPILE_FEATURES.rst b/Help/variable/CMAKE_C_COMPILE_FEATURES.rst index 7d1c8b1..1106246 100644 --- a/Help/variable/CMAKE_C_COMPILE_FEATURES.rst +++ b/Help/variable/CMAKE_C_COMPILE_FEATURES.rst @@ -6,3 +6,6 @@ List of features known to the C compiler These features are known to be available for use with the C compiler. This list is a subset of the features listed in the :prop_gbl:`CMAKE_C_KNOWN_FEATURES` global property. + +See the :manual:`cmake-compile-features(7)` manual for information on +compile features. diff --git a/Help/variable/CMAKE_C_EXTENSIONS.rst b/Help/variable/CMAKE_C_EXTENSIONS.rst index ff2569b..5e935fc 100644 --- a/Help/variable/CMAKE_C_EXTENSIONS.rst +++ b/Help/variable/CMAKE_C_EXTENSIONS.rst @@ -6,3 +6,6 @@ Default value for ``C_EXTENSIONS`` property of targets. This variable is used to initialize the :prop_tgt:`C_EXTENSIONS` property on all targets. See that target property for additional information. + +See the :manual:`cmake-compile-features(7)` manual for information on +compile features. diff --git a/Help/variable/CMAKE_C_STANDARD.rst b/Help/variable/CMAKE_C_STANDARD.rst index c1f8c29..3098ce5 100644 --- a/Help/variable/CMAKE_C_STANDARD.rst +++ b/Help/variable/CMAKE_C_STANDARD.rst @@ -6,3 +6,6 @@ Default value for ``C_STANDARD`` property of targets. This variable is used to initialize the :prop_tgt:`C_STANDARD` property on all targets. See that target property for additional information. + +See the :manual:`cmake-compile-features(7)` manual for information on +compile features. diff --git a/Help/variable/CMAKE_C_STANDARD_REQUIRED.rst b/Help/variable/CMAKE_C_STANDARD_REQUIRED.rst index 13ea49f..c24eea4 100644 --- a/Help/variable/CMAKE_C_STANDARD_REQUIRED.rst +++ b/Help/variable/CMAKE_C_STANDARD_REQUIRED.rst @@ -6,3 +6,6 @@ Default value for ``C_STANDARD_REQUIRED`` property of targets. This variable is used to initialize the :prop_tgt:`C_STANDARD_REQUIRED` property on all targets. See that target property for additional information. + +See the :manual:`cmake-compile-features(7)` manual for information on +compile features. diff --git a/Modules/WriteCompilerDetectionHeader.cmake b/Modules/WriteCompilerDetectionHeader.cmake index d7b89cb..f80943d 100644 --- a/Modules/WriteCompilerDetectionHeader.cmake +++ b/Modules/WriteCompilerDetectionHeader.cmake @@ -46,6 +46,9 @@ # :prop_gbl:`CMAKE_C_KNOWN_FEATURES` and # :prop_gbl:`CMAKE_CXX_KNOWN_FEATURES` global properties. # +# See the :manual:`cmake-compile-features(7)` manual for information on +# compile features. +# # Feature Test Macros # =================== # diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index bd1f7c2..659b695 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,5 +1,5 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 0) -set(CMake_VERSION_PATCH 20140523) +set(CMake_VERSION_PATCH 20140527) #set(CMake_VERSION_RC 1) diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 9f33b92..aca7a93 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -103,6 +103,7 @@ cmMakefile::cmMakefile(): Internal(new Internals) this->GeneratingBuildSystem = false; this->NumLastMatches = 0; + this->SuppressWatches = false; } cmMakefile::cmMakefile(const cmMakefile& mf): Internal(new Internals) @@ -153,6 +154,7 @@ cmMakefile::cmMakefile(const cmMakefile& mf): Internal(new Internals) this->OutputToSource = mf.OutputToSource; this->NumLastMatches = mf.NumLastMatches; + this->SuppressWatches = mf.SuppressWatches; } //---------------------------------------------------------------------------- @@ -2463,7 +2465,7 @@ const char* cmMakefile::GetDefinition(const std::string& name) const } #ifdef CMAKE_BUILD_WITH_CMAKE cmVariableWatch* vv = this->GetVariableWatch(); - if ( vv ) + if ( vv && !this->SuppressWatches ) { if ( def ) { @@ -2472,19 +2474,8 @@ const char* cmMakefile::GetDefinition(const std::string& name) const } else { - // are unknown access allowed - const char* allow = this->Internal->VarStack.top() - .Get("CMAKE_ALLOW_UNKNOWN_VARIABLE_READ_ACCESS"); - if(cmSystemTools::IsOn(allow)) - { - vv->VariableAccessed(name, - cmVariableWatch::ALLOWED_UNKNOWN_VARIABLE_READ_ACCESS, def, this); - } - else - { - vv->VariableAccessed(name, + vv->VariableAccessed(name, cmVariableWatch::UNKNOWN_VARIABLE_READ_ACCESS, def, this); - } } } #endif @@ -2570,10 +2561,14 @@ const char *cmMakefile::ExpandVariablesInString(std::string& source, original = source; newResult = source; compareResults = true; + // Suppress variable watches to avoid calling hooks twice. Suppress new + // dereferences since the OLD behavior is still what is actually used. + this->SuppressWatches = true; newError = ExpandVariablesInStringNew(newErrorstr, newResult, escapeQuotes, noEscapes, atOnly, filename, line, removeEmpty, replaceAt); + this->SuppressWatches = false; } case cmPolicies::OLD: mtype = ExpandVariablesInStringOld(errorstr, source, escapeQuotes, diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 11904a6..9a4b9c7 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -1127,6 +1127,8 @@ private: const std::string& feature) const; bool HaveCxxFeatureAvailable(cmTarget const* target, const std::string& feature) const; + + mutable bool SuppressWatches; }; //---------------------------------------------------------------------------- diff --git a/Source/cmVariableWatch.cxx b/Source/cmVariableWatch.cxx index 8ad6fce..cb6cb12 100644 --- a/Source/cmVariableWatch.cxx +++ b/Source/cmVariableWatch.cxx @@ -16,7 +16,6 @@ static const char* const cmVariableWatchAccessStrings[] = "READ_ACCESS", "UNKNOWN_READ_ACCESS", "UNKNOWN_DEFINED_ACCESS", - "ALLOWED_UNKNOWN_READ_ACCESS", "MODIFIED_ACCESS", "REMOVED_ACCESS", "NO_ACCESS" diff --git a/Source/cmVariableWatch.h b/Source/cmVariableWatch.h index c86fad0..0ca4a55 100644 --- a/Source/cmVariableWatch.h +++ b/Source/cmVariableWatch.h @@ -53,7 +53,6 @@ public: VARIABLE_READ_ACCESS = 0, UNKNOWN_VARIABLE_READ_ACCESS, UNKNOWN_VARIABLE_DEFINED_ACCESS, - ALLOWED_UNKNOWN_VARIABLE_READ_ACCESS, VARIABLE_MODIFIED_ACCESS, VARIABLE_REMOVED_ACCESS, NO_ACCESS diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 5014ef3..8d2b7fc 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -2394,7 +2394,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release --output-log "${CMake_BINARY_DIR}/Tests/CTestTestTimeout/testOutput.log" ) set_tests_properties(CTestTestTimeout PROPERTIES - PASS_REGULAR_EXPRESSION "TestTimeout *\\.+ *\\*\\*\\*Timeout.*CheckChild *\\.+ *Passed") + PASS_REGULAR_EXPRESSION "TestTimeout *\\.+ *\\*\\*\\*Timeout.*TestSleep *\\.+ *Passed.*timeout correctly killed child") add_test( NAME CTestTestRerunFailed diff --git a/Tests/CTestTestTimeout/CMakeLists.txt b/Tests/CTestTestTimeout/CMakeLists.txt index 476d0a5..2e3bd6a 100644 --- a/Tests/CTestTestTimeout/CMakeLists.txt +++ b/Tests/CTestTestTimeout/CMakeLists.txt @@ -11,18 +11,14 @@ if(NOT TIMEOUT) endif() add_definitions(-DTIMEOUT=${TIMEOUT}) -add_executable (Timeout timeout.c) +add_executable (Sleep sleep.c) add_test(NAME TestTimeout - COMMAND ${CMAKE_COMMAND} -D Timeout=$<TARGET_FILE:Timeout> + COMMAND ${CMAKE_COMMAND} -D Sleep=$<TARGET_FILE:Sleep> -D Log=${CMAKE_CURRENT_BINARY_DIR}/timeout.log -P ${CMAKE_CURRENT_SOURCE_DIR}/timeout.cmake ) set_tests_properties(TestTimeout PROPERTIES TIMEOUT ${TIMEOUT}) -add_test(NAME CheckChild - COMMAND ${CMAKE_COMMAND} -D Timeout=$<TARGET_FILE:Timeout> - -D Log=${CMAKE_CURRENT_BINARY_DIR}/timeout.log - -P ${CMAKE_CURRENT_SOURCE_DIR}/check.cmake - ) -set_tests_properties(CheckChild PROPERTIES DEPENDS TestTimeout) +add_test(NAME TestSleep COMMAND Sleep) +set_tests_properties(TestSleep PROPERTIES DEPENDS TestTimeout) diff --git a/Tests/CTestTestTimeout/check.cmake b/Tests/CTestTestTimeout/check.cmake deleted file mode 100644 index b16f2aa..0000000 --- a/Tests/CTestTestTimeout/check.cmake +++ /dev/null @@ -1,9 +0,0 @@ -# Block just as long as timeout.cmake would if it were not killed. -execute_process(COMMAND ${Timeout}) - -# Verify that the log is empty, which indicates that the grandchild -# was killed before it finished sleeping. -file(READ "${Log}" LOG) -if(NOT "${LOG}" STREQUAL "") - message(FATAL_ERROR "${LOG}") -endif() diff --git a/Tests/CTestTestTimeout/sleep.c b/Tests/CTestTestTimeout/sleep.c new file mode 100644 index 0000000..33ce307 --- /dev/null +++ b/Tests/CTestTestTimeout/sleep.c @@ -0,0 +1,21 @@ +#if defined(_WIN32) +# include <windows.h> +#else +# include <unistd.h> +#endif + +#include <stdio.h> + +int main(void) +{ + fprintf(stderr, "before sleep\n"); + fflush(stderr); /* should not be needed, but just in case */ +#if defined(_WIN32) + Sleep((TIMEOUT+4)*1000); +#else + sleep((TIMEOUT+4)); +#endif + fprintf(stderr, "after sleep\n"); + fflush(stderr); /* should not be needed, but just in case */ + return 0; +} diff --git a/Tests/CTestTestTimeout/test.cmake.in b/Tests/CTestTestTimeout/test.cmake.in index 4178849..68c74d8 100644 --- a/Tests/CTestTestTimeout/test.cmake.in +++ b/Tests/CTestTestTimeout/test.cmake.in @@ -24,3 +24,16 @@ CTEST_START(Experimental) CTEST_CONFIGURE(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res) CTEST_BUILD(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res) CTEST_TEST(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res) + +set(log ${CTEST_BINARY_DIRECTORY}/timeout.log) +if(EXISTS "${log}") + # Verify that the timeout test did not finish sleeping. + file(STRINGS "${log}" after_sleep REGEX "after sleep") + if(after_sleep) + message(FATAL_ERROR "Log indicates timeout did not kill child.") + else() + message("Log indicates timeout correctly killed child.") + endif() +else() + message(FATAL_ERROR "Log does not exist:\n ${log}") +endif() diff --git a/Tests/CTestTestTimeout/timeout.c b/Tests/CTestTestTimeout/timeout.c deleted file mode 100644 index 370ab22..0000000 --- a/Tests/CTestTestTimeout/timeout.c +++ /dev/null @@ -1,18 +0,0 @@ -#if defined(_WIN32) -# include <windows.h> -#else -# include <unistd.h> -#endif - -#include <stdio.h> - -int main(void) -{ -#if defined(_WIN32) - Sleep((TIMEOUT+4)*1000); -#else - sleep((TIMEOUT+4)); -#endif - printf("timeout process finished sleeping!\n"); - return -1; -} diff --git a/Tests/CTestTestTimeout/timeout.cmake b/Tests/CTestTestTimeout/timeout.cmake index 198cc97..0989b65 100644 --- a/Tests/CTestTestTimeout/timeout.cmake +++ b/Tests/CTestTestTimeout/timeout.cmake @@ -3,4 +3,4 @@ file(REMOVE ${Log}) # Run a child that sleeps longer than the timout of this test. # Log its output so check.cmake can verify it dies. -execute_process(COMMAND ${Timeout} OUTPUT_FILE ${Log}) +execute_process(COMMAND ${Sleep} ERROR_FILE ${Log}) diff --git a/Tests/RunCMake/CMP0053/CMP0053-NEW-stderr.txt b/Tests/RunCMake/CMP0053/CMP0053-NEW-stderr.txt new file mode 100644 index 0000000..836b0ff --- /dev/null +++ b/Tests/RunCMake/CMP0053/CMP0053-NEW-stderr.txt @@ -0,0 +1,2 @@ +^called +--><--$ diff --git a/Tests/RunCMake/CMP0053/CMP0053-NEW.cmake b/Tests/RunCMake/CMP0053/CMP0053-NEW.cmake new file mode 100644 index 0000000..6ffedc6 --- /dev/null +++ b/Tests/RunCMake/CMP0053/CMP0053-NEW.cmake @@ -0,0 +1,8 @@ +cmake_policy(SET CMP0053 NEW) + +function (watch_callback) + message("called") +endfunction () + +variable_watch(test watch_callback) +message("-->${test}<--") diff --git a/Tests/RunCMake/CMP0053/CMP0053-OLD-stderr.txt b/Tests/RunCMake/CMP0053/CMP0053-OLD-stderr.txt new file mode 100644 index 0000000..836b0ff --- /dev/null +++ b/Tests/RunCMake/CMP0053/CMP0053-OLD-stderr.txt @@ -0,0 +1,2 @@ +^called +--><--$ diff --git a/Tests/RunCMake/CMP0053/CMP0053-OLD.cmake b/Tests/RunCMake/CMP0053/CMP0053-OLD.cmake new file mode 100644 index 0000000..41f5347 --- /dev/null +++ b/Tests/RunCMake/CMP0053/CMP0053-OLD.cmake @@ -0,0 +1,8 @@ +cmake_policy(SET CMP0053 OLD) + +function (watch_callback) + message("called") +endfunction () + +variable_watch(test watch_callback) +message("-->${test}<--") diff --git a/Tests/RunCMake/CMP0053/CMP0053-WARN-stderr.txt b/Tests/RunCMake/CMP0053/CMP0053-WARN-stderr.txt new file mode 100644 index 0000000..836b0ff --- /dev/null +++ b/Tests/RunCMake/CMP0053/CMP0053-WARN-stderr.txt @@ -0,0 +1,2 @@ +^called +--><--$ diff --git a/Tests/RunCMake/CMP0053/CMP0053-WARN.cmake b/Tests/RunCMake/CMP0053/CMP0053-WARN.cmake new file mode 100644 index 0000000..b010d13 --- /dev/null +++ b/Tests/RunCMake/CMP0053/CMP0053-WARN.cmake @@ -0,0 +1,6 @@ +function (watch_callback) + message("called") +endfunction () + +variable_watch(test watch_callback) +message("-->${test}<--") diff --git a/Tests/RunCMake/CMP0053/CMakeLists.txt b/Tests/RunCMake/CMP0053/CMakeLists.txt new file mode 100644 index 0000000..3482e6b --- /dev/null +++ b/Tests/RunCMake/CMP0053/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.0) +project(${RunCMake_TEST} CXX) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/CMP0053/RunCMakeTest.cmake b/Tests/RunCMake/CMP0053/RunCMakeTest.cmake new file mode 100644 index 0000000..6521ac0 --- /dev/null +++ b/Tests/RunCMake/CMP0053/RunCMakeTest.cmake @@ -0,0 +1,5 @@ +include(RunCMake) + +run_cmake(CMP0053-OLD) +run_cmake(CMP0053-NEW) +run_cmake(CMP0053-WARN) diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 4efc73a..165f027 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -35,6 +35,7 @@ add_RunCMake_test(CMP0046) add_RunCMake_test(CMP0049) add_RunCMake_test(CMP0050) add_RunCMake_test(CMP0051) +add_RunCMake_test(CMP0053) add_RunCMake_test(CTest) if(UNIX AND "${CMAKE_GENERATOR}" MATCHES "Unix Makefiles") add_RunCMake_test(CompilerChange) |