diff options
97 files changed, 1499 insertions, 293 deletions
diff --git a/Help/command/ctest_build.rst b/Help/command/ctest_build.rst index ac2a0c1..1347b42 100644 --- a/Help/command/ctest_build.rst +++ b/Help/command/ctest_build.rst @@ -22,3 +22,8 @@ of build errors and warnings detected. The APPEND option marks results for append to those previously submitted to a dashboard server since the last ctest_start. Append semantics are defined by the dashboard server in use. + +If set the contents of the variable CTEST_BUILD_FLAGS are passed as +additional arguments to the underlying build command. This can e.g. be +used to trigger a parallel build using the -j option of make. See +:module:`ProcessorCount` for an example. diff --git a/Help/command/file.rst b/Help/command/file.rst index 83ade1d..14ca20c 100644 --- a/Help/command/file.rst +++ b/Help/command/file.rst @@ -3,211 +3,299 @@ file File manipulation command. +------------------------------------------------------------------------------ + :: - file(WRITE filename "message to write"... ) - file(APPEND filename "message to write"... ) - file(READ filename variable [LIMIT numBytes] [OFFSET offset] [HEX]) - file(<MD5|SHA1|SHA224|SHA256|SHA384|SHA512> filename variable) - file(STRINGS filename variable [LIMIT_COUNT num] - [LIMIT_INPUT numBytes] [LIMIT_OUTPUT numBytes] - [LENGTH_MINIMUM numBytes] [LENGTH_MAXIMUM numBytes] - [NEWLINE_CONSUME] [REGEX regex] - [NO_HEX_CONVERSION]) - file(GLOB variable [RELATIVE path] [globbing expressions]...) - file(GLOB_RECURSE variable [RELATIVE path] - [FOLLOW_SYMLINKS] [globbing expressions]...) - file(RENAME <oldname> <newname>) - file(REMOVE [file1 ...]) - file(REMOVE_RECURSE [file1 ...]) - file(MAKE_DIRECTORY [directory1 directory2 ...]) - file(RELATIVE_PATH variable directory file) - file(TO_CMAKE_PATH path result) - file(TO_NATIVE_PATH path result) - file(DOWNLOAD url file [INACTIVITY_TIMEOUT timeout] - [TIMEOUT timeout] [STATUS status] [LOG log] [SHOW_PROGRESS] - [EXPECTED_HASH ALGO=value] [EXPECTED_MD5 sum] - [TLS_VERIFY on|off] [TLS_CAINFO file]) - file(UPLOAD filename url [INACTIVITY_TIMEOUT timeout] - [TIMEOUT timeout] [STATUS status] [LOG log] [SHOW_PROGRESS]) - file(TIMESTAMP filename variable [<format string>] [UTC]) - file(GENERATE OUTPUT output_file - <INPUT input_file|CONTENT input_content> - [CONDITION expression]) - -WRITE will write a message into a file called 'filename'. It -overwrites the file if it already exists, and creates the file if it -does not exist. (If the file is a build input, use configure_file to -update the file only when its content changes.) - -APPEND will write a message into a file same as WRITE, except it will -append it to the end of the file - -READ will read the content of a file and store it into the variable. -It will start at the given offset and read up to numBytes. If the -argument HEX is given, the binary data will be converted to -hexadecimal representation and this will be stored in the variable. - -MD5, SHA1, SHA224, SHA256, SHA384, and SHA512 will compute a -cryptographic hash of the content of a file. - -STRINGS will parse a list of ASCII strings from a file and store it in -a variable. Binary data in the file are ignored. Carriage return -(CR) characters are ignored. It works also for Intel Hex and Motorola -S-record files, which are automatically converted to binary format -when reading them. Disable this using NO_HEX_CONVERSION. - -LIMIT_COUNT sets the maximum number of strings to return. LIMIT_INPUT -sets the maximum number of bytes to read from the input file. -LIMIT_OUTPUT sets the maximum number of bytes to store in the output -variable. LENGTH_MINIMUM sets the minimum length of a string to -return. Shorter strings are ignored. LENGTH_MAXIMUM sets the maximum -length of a string to return. Longer strings are split into strings -no longer than the maximum length. NEWLINE_CONSUME allows newlines to -be included in strings instead of terminating them. - -REGEX specifies a regular expression that a string must match to be -returned. Typical usage + file(WRITE <filename> <content>...) + file(APPEND <filename> <content>...) + +Write ``<content>`` into a file called ``<filename>``. If the file does +not exist, it will be created. If the file already exists, ``WRITE`` +mode will overwrite it and ``APPEND`` mode will append to the end. +(If the file is a build input, use the :command:`configure_file` command +to update the file only when its content changes.) + +------------------------------------------------------------------------------ + +:: + + file(READ <filename> <variable> + [OFFSET <offset>] [LIMIT <max-in>] [HEX]) + +Read content from a file called ``<filename>`` and store it in a +``<variable>``. Optionally start from the given ``<offset>`` and +read at most ``<max-in>`` bytes. The ``HEX`` option causes data to +be converted to a hexadecimal representation (useful for binary data). + +------------------------------------------------------------------------------ :: + file(STRINGS <filename> <variable> [<options>...]) + +Parse a list of ASCII strings from ``<filename>`` and store it in +``<variable>``. Binary data in the file are ignored. Carriage return +(``\r``, CR) characters are ignored. The options are: + +``LENGTH_MAXIMUM <max-len>`` + Consider only strings of at most a given length. + +``LENGTH_MINIMUM <min-len>`` + Consider only strings of at least a given length. + +``LIMIT_COUNT <max-num>`` + Limit the number of distinct strings to be extracted. + +``LIMIT_INPUT <max-in>`` + Limit the number of input bytes to read from the file. + +``LIMIT_OUTPUT <max-out>`` + Limit the number of total bytes to store in the ``<variable>``. + +``NEWLINE_CONSUME`` + Treat newline characters (``\n``, LF) as part of string content + instead of terminating at them. + +``NO_HEX_CONVERSION`` + Intel Hex and Motorola S-record files are automatically converted to + binary while reading unless this option is given. + +``REGEX <regex>`` + Consider only strings that match the given regular expression. + +For example, the code + +.. code-block:: cmake + file(STRINGS myfile.txt myfile) -stores a list in the variable "myfile" in which each item is a line +stores a list in the variable ``myfile`` in which each item is a line from the input file. -GLOB will generate a list of all files that match the globbing -expressions and store it into the variable. Globbing expressions are -similar to regular expressions, but much simpler. If RELATIVE flag is -specified for an expression, the results will be returned as a -relative path to the given path. (We do not recommend using GLOB to -collect a list of source files from your source tree. If no -CMakeLists.txt file changes when a source is added or removed then the -generated build system cannot know when to ask CMake to regenerate.) +------------------------------------------------------------------------------ + +:: + + file(<MD5|SHA1|SHA224|SHA256|SHA384|SHA512> <filename> <variable>) + +Compute a cryptographic hash of the content of ``<filename>`` and +store it in a ``<variable>``. + +------------------------------------------------------------------------------ + +:: + + file(GLOB <variable> [RELATIVE <path>] [<globbing-expressions>...]) + file(GLOB_RECURSE <variable> [RELATIVE <path>] + [FOLLOW_SYMLINKS] [<globbing-expressions>...]) + +Generate a list of files that match the ``<globbing-expressions>`` and +store it into the ``<variable>``. Globbing expressions are similar to +regular expressions, but much simpler. If ``RELATIVE`` flag is +specified, the results will be returned as relative paths to the given +path. + +.. note:: + We do not recommend using GLOB to collect a list of source files from + your source tree. If no CMakeLists.txt file changes when a source is + added or removed then the generated build system cannot know when to + ask CMake to regenerate. + +Examples of globbing expressions include:: + + *.cxx - match all files with extension cxx + *.vt? - match all files with extension vta,...,vtz + f[3-5].txt - match files f3.txt, f4.txt, f5.txt + +The ``GLOB_RECURSE`` mode will traverse all the subdirectories of the +matched directory and match the files. Subdirectories that are symlinks +are only traversed if ``FOLLOW_SYMLINKS`` is given or policy +:policy:`CMP0009` is not set to ``NEW``. + +Examples of recursive globbing include:: + + /dir/*.py - match all python files in /dir and subdirectories + +------------------------------------------------------------------------------ + +:: + + file(RENAME <oldname> <newname>) + +Move a file or directory within a filesystem from ``<oldname>`` to +``<newname>``, replacing the destination atomically. + +------------------------------------------------------------------------------ + +:: + + file(REMOVE [<files>...]) + file(REMOVE_RECURSE [<files>...]) + +Remove the given files. The ``REMOVE_RECURSE`` mode will remove the given +files and directories, also non-empty directories + +------------------------------------------------------------------------------ + +:: + + file(MAKE_DIRECTORY [<directories>...]) -Examples of globbing expressions include: +Create the given directories and their parents as needed. + +------------------------------------------------------------------------------ :: - *.cxx - match all files with extension cxx - *.vt? - match all files with extension vta,...,vtz - f[3-5].txt - match files f3.txt, f4.txt, f5.txt + file(RELATIVE_PATH <variable> <directory> <file>) -GLOB_RECURSE will generate a list similar to the regular GLOB, except -it will traverse all the subdirectories of the matched directory and -match the files. Subdirectories that are symlinks are only traversed -if FOLLOW_SYMLINKS is given or cmake policy CMP0009 is not set to NEW. -See cmake --help-policy CMP0009 for more information. +Compute the relative path from a ``<directory>`` to a ``<file>`` and +store it in the ``<variable>``. -Examples of recursive globbing include: +------------------------------------------------------------------------------ :: - /dir/*.py - match all python files in /dir and subdirectories - -MAKE_DIRECTORY will create the given directories, also if their parent -directories don't exist yet - -RENAME moves a file or directory within a filesystem, replacing the -destination atomically. - -REMOVE will remove the given files, also in subdirectories - -REMOVE_RECURSE will remove the given files and directories, also -non-empty directories - -RELATIVE_PATH will determine relative path from directory to the given -file. - -TO_CMAKE_PATH will convert path into a cmake style path with unix /. -The input can be a single path or a system path like "$ENV{PATH}". -Note the double quotes around the ENV call TO_CMAKE_PATH only takes -one argument. This command will also convert the native list -delimiters for a list of paths like the PATH environment variable. - -TO_NATIVE_PATH works just like TO_CMAKE_PATH, but will convert from a -cmake style path into the native path style \ for windows and / for -UNIX. - -DOWNLOAD will download the given URL to the given file. If LOG var is -specified a log of the download will be put in var. If STATUS var is -specified the status of the operation will be put in var. The status -is returned in a list of length 2. The first element is the numeric -return value for the operation, and the second element is a string -value for the error. A 0 numeric error means no error in the -operation. If TIMEOUT time is specified, the operation will timeout -after time seconds, time should be specified as an integer. The -INACTIVITY_TIMEOUT specifies an integer number of seconds of -inactivity after which the operation should terminate. If -EXPECTED_HASH ALGO=value is specified, the operation will verify that -the downloaded file's actual hash matches the expected value, where -ALGO is one of MD5, SHA1, SHA224, SHA256, SHA384, or SHA512. If it -does not match, the operation fails with an error. ("EXPECTED_MD5 -sum" is short-hand for "EXPECTED_HASH MD5=sum".) If SHOW_PROGRESS is -specified, progress information will be printed as status messages -until the operation is complete. For https URLs CMake must be built -with OpenSSL. TLS/SSL certificates are not checked by default. Set -TLS_VERIFY to ON to check certificates and/or use EXPECTED_HASH to -verify downloaded content. Set TLS_CAINFO to specify a custom -Certificate Authority file. If either TLS option is not given CMake -will check variables CMAKE_TLS_VERIFY and CMAKE_TLS_CAINFO, -respectively. - -UPLOAD will upload the given file to the given URL. If LOG var is -specified a log of the upload will be put in var. If STATUS var is -specified the status of the operation will be put in var. The status -is returned in a list of length 2. The first element is the numeric -return value for the operation, and the second element is a string -value for the error. A 0 numeric error means no error in the -operation. If TIMEOUT time is specified, the operation will timeout -after time seconds, time should be specified as an integer. The -INACTIVITY_TIMEOUT specifies an integer number of seconds of -inactivity after which the operation should terminate. If -SHOW_PROGRESS is specified, progress information will be printed as -status messages until the operation is complete. - -TIMESTAMP will write a string representation of the modification time -of filename to variable. - -Should the command be unable to obtain a timestamp variable will be -set to the empty string "". - -See documentation of the string TIMESTAMP sub-command for more -details. - -The file() command also provides COPY and INSTALL signatures: + file(TO_CMAKE_PATH "<path>" <variable>) + file(TO_NATIVE_PATH "<path>" <variable>) + +The ``TO_CMAKE_PATH`` mode converts a native ``<path>`` into a cmake-style +path with forward-slashes (``/``). The input can be a single path or a +system search path like ``$ENV{PATH}``. A search path will be converted +to a cmake-style list separated by ``;`` characters. + +The ``TO_NATIVE_PATH`` mode converts a cmake-style ``<path>`` into a native +path with platform-specific slashes (``\`` on Windows and ``/`` elsewhere). + +Always use double quotes around the ``<path>`` to be sure it is treated +as a single argument to this command. + +------------------------------------------------------------------------------ + +:: + + file(DOWNLOAD <url> <file> [<options>...]) + file(UPLOAD <file> <url> [<options>...]) + +The ``DOWNLOAD`` mode downloads the given ``<url>`` to a local ``<file>``. +The ``UPLOAD`` mode uploads a local ``<file>`` to a given ``<url>``. + +Options to both ``DOWNLOAD`` and ``UPLOAD`` are: + +``INACTIVITY_TIMEOUT <seconds>`` + Terminate the operation after a period of inactivity. + +``LOG <variable>`` + Store a human-readable log of the operation in a variable. + +``SHOW_PROGRESS`` + Print progress information as status messages until the operation is + complete. + +``STATUS <variable>`` + Store the resulting status of the operation in a variable. + The status is a ``;`` separated list of length 2. + The first element is the numeric return value for the operation, + and the second element is a string value for the error. + A ``0`` numeric error means no error in the operation. + +``TIMEOUT <seconds>`` + Terminate the operation after a given total time has elapsed. + +Additional options to ``DOWNLOAD`` are: + +``EXPECTED_HASH ALGO=<value>`` + + Verify that the downloaded content hash matches the expected value, where + ``ALGO`` is one of ``MD5``, ``SHA1``, ``SHA224``, ``SHA256``, ``SHA384``, or + ``SHA512``. If it does not match, the operation fails with an error. + +``EXPECTED_MD5 <value>`` + Historical short-hand for ``EXPECTED_HASH MD5=<value>``. + +``TLS_VERIFY <ON|OFF>`` + Specify whether to verify the server certificate for ``https://`` URLs. + The default is to *not* verify. + +``TLS_CAINFO <file>`` + Specify a custom Certificate Authority file for ``https://`` URLs. + +For ``https://`` URLs CMake must be built with OpenSSL support. ``TLS/SSL`` +certificates are not checked by default. Set ``TLS_VERIFY`` to ``ON`` to +check certificates and/or use ``EXPECTED_HASH`` to verify downloaded content. +If neither ``TLS`` option is given CMake will check variables +``CMAKE_TLS_VERIFY`` and ``CMAKE_TLS_CAINFO``, respectively. + +------------------------------------------------------------------------------ + +:: + + file(TIMESTAMP <filename> <variable> [<format>] [UTC]) + +Compute a string representation of the modification time of ``<filename>`` +and store it in ``<variable>``. Should the command be unable to obtain a +timestamp variable will be set to the empty string (""). + +See the :command:`string(TIMESTAMP)` command for documentation of +the ``<format>`` and ``UTC`` options. + +------------------------------------------------------------------------------ + +:: + + file(GENERATE <options>...) + +Generate an output file for each build configuration supported by the current +:manual:`CMake Generator <cmake-generators(7)>`. Evaluate +:manual:`generator expressions <cmake-generator-expressions(7)>` +from the input content to produce the output content. The options are: + +``CONDITION <condition>`` + Generate the output file for a particular configuration only if + the condition is true. The condition must be either ``0`` or ``1`` + after evaluating generator expressions. + +``CONTENT <content>`` + Use the content given explicitly as input. + +``INPUT <input-file>`` + Use the content from a given file as input. + +``OUTPUT <output-file>`` + Specify the output file name to generate. Use generator expressions + such as ``$<CONFIG>`` to specify a configuration-specific output file + name. Multiple configurations may generate the same output file only + if the generated content is identical. Otherwise, the ``<output-file>`` + must evaluate to an unique name for each configuration. + +Exactly one ``CONTENT`` or ``INPUT`` option must be given. A specific +``OUTPUT`` file may be named by at most one invocation of ``file(GENERATE)``. + +------------------------------------------------------------------------------ :: - file(<COPY|INSTALL> files... DESTINATION <dir> - [FILE_PERMISSIONS permissions...] - [DIRECTORY_PERMISSIONS permissions...] + file(<COPY|INSTALL> <files>... DESTINATION <dir> + [FILE_PERMISSIONS <permissions>...] + [DIRECTORY_PERMISSIONS <permissions>...] [NO_SOURCE_PERMISSIONS] [USE_SOURCE_PERMISSIONS] [FILES_MATCHING] [[PATTERN <pattern> | REGEX <regex>] - [EXCLUDE] [PERMISSIONS permissions...]] [...]) + [EXCLUDE] [PERMISSIONS <permissions>...]] [...]) -The COPY signature copies files, directories, and symlinks to a +The ``COPY`` signature copies files, directories, and symlinks to a destination folder. Relative input paths are evaluated with respect to the current source directory, and a relative destination is evaluated with respect to the current build directory. Copying preserves input file timestamps, and optimizes out a file if it exists at the destination with the same timestamp. Copying preserves input -permissions unless explicit permissions or NO_SOURCE_PERMISSIONS are -given (default is USE_SOURCE_PERMISSIONS). See the install(DIRECTORY) -command for documentation of permissions, PATTERN, REGEX, and EXCLUDE -options. - -The INSTALL signature differs slightly from COPY: it prints status -messages, and NO_SOURCE_PERMISSIONS is default. Installation scripts -generated by the install() command use this signature (with some -undocumented options for internal use). - -GENERATE will write an <output_file> with content from an -<input_file>, or from <input_content>. The output is generated -conditionally based on the content of the <condition>. The file is -written at CMake generate-time and the input may contain generator -expressions. The <condition>, <output_file> and <input_file> may also -contain generator expressions. The <condition> must evaluate to -either '0' or '1'. The <output_file> must evaluate to a unique name -among all configurations and among all invocations of file(GENERATE). +permissions unless explicit permissions or ``NO_SOURCE_PERMISSIONS`` +are given (default is ``USE_SOURCE_PERMISSIONS``). +See the :command:`install(DIRECTORY)` command for documentation of +permissions, ``PATTERN``, ``REGEX``, and ``EXCLUDE`` options. + +The ``INSTALL`` signature differs slightly from ``COPY``: it prints +status messages, and ``NO_SOURCE_PERMISSIONS`` is default. +Installation scripts generated by the :command:`install` command +use this signature (with some undocumented options for internal use). 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..81adea0 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 ==== @@ -331,10 +376,10 @@ documentation: See the :manual:`cmake-policies(7)` manual and the :command:`cmake_policy` command. -``prop_cache, prop_dir, prop_gbl, prop_sf, prop_test, prop_tgt`` - A CMake cache, directory, global, source file, test, or target - property, respectively. See the :manual:`cmake-properties(7)` manual - and the :command:`set_property` command. +``prop_cache, prop_dir, prop_gbl, prop_sf, prop_inst, prop_test, prop_tgt`` + A CMake cache, directory, global, source file, installed file, test, + or target property, respectively. See the :manual:`cmake-properties(7)` + manual and the :command:`set_property` command. ``variable`` A CMake language variable. 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/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index 52dfd02..e4546c1 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst @@ -308,3 +308,12 @@ Properties on Cache Entries /prop_cache/STRINGS /prop_cache/TYPE /prop_cache/VALUE + +Properties on Installed Files +============================= + +.. toctree:: + :maxdepth: 1 + + /prop_inst/CPACK_NEVER_OVERWRITE.rst + /prop_inst/CPACK_PERMANENT.rst diff --git a/Help/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.rst b/Help/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.rst index 67fe00c..cf35467 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_inst/CPACK_NEVER_OVERWRITE.rst b/Help/prop_inst/CPACK_NEVER_OVERWRITE.rst new file mode 100644 index 0000000..11f44d0 --- /dev/null +++ b/Help/prop_inst/CPACK_NEVER_OVERWRITE.rst @@ -0,0 +1,6 @@ +CPACK_NEVER_OVERWRITE +--------------------- + +Request that this file not be overwritten on install or reinstall. + +The property is currently only supported by the WIX generator. diff --git a/Help/prop_inst/CPACK_PERMANENT.rst b/Help/prop_inst/CPACK_PERMANENT.rst new file mode 100644 index 0000000..5e191d0 --- /dev/null +++ b/Help/prop_inst/CPACK_PERMANENT.rst @@ -0,0 +1,6 @@ +CPACK_PERMANENT +--------------- + +Request that this file not be removed on uninstall. + +The property is currently only supported by the WIX generator. 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/FindFreetype.cmake b/Modules/FindFreetype.cmake index 1779b78..7d46d15 100644 --- a/Modules/FindFreetype.cmake +++ b/Modules/FindFreetype.cmake @@ -51,7 +51,9 @@ # wants explicit full paths and this trickery doesn't work too well. # I'm going to attempt to cut out the middleman and hope # everything still works. -find_path(FREETYPE_INCLUDE_DIR_ft2build ft2build.h +find_path( + FREETYPE_INCLUDE_DIR_ft2build + ft2build.h HINTS ENV FREETYPE_DIR PATHS @@ -62,10 +64,14 @@ find_path(FREETYPE_INCLUDE_DIR_ft2build ft2build.h ENV GTKMM_BASEPATH [HKEY_CURRENT_USER\\SOFTWARE\\gtkmm\\2.4;Path] [HKEY_LOCAL_MACHINE\\SOFTWARE\\gtkmm\\2.4;Path] - PATH_SUFFIXES include/freetype2 include freetype2 + PATH_SUFFIXES + include/freetype2 + include + freetype2 ) -find_path(FREETYPE_INCLUDE_DIR_freetype2 +find_path( + FREETYPE_INCLUDE_DIR_freetype2 NAMES freetype/config/ftheader.h config/ftheader.h @@ -79,14 +85,19 @@ find_path(FREETYPE_INCLUDE_DIR_freetype2 ENV GTKMM_BASEPATH [HKEY_CURRENT_USER\\SOFTWARE\\gtkmm\\2.4;Path] [HKEY_LOCAL_MACHINE\\SOFTWARE\\gtkmm\\2.4;Path] - PATH_SUFFIXES include/freetype2 include freetype2 + PATH_SUFFIXES + include/freetype2 + include + freetype2 ) find_library(FREETYPE_LIBRARY - NAMES freetype libfreetype freetype219 + NAMES + freetype + libfreetype + freetype219 HINTS ENV FREETYPE_DIR - PATH_SUFFIXES lib PATHS /usr/X11R6 /usr/local/X11R6 @@ -95,6 +106,8 @@ find_library(FREETYPE_LIBRARY ENV GTKMM_BASEPATH [HKEY_CURRENT_USER\\SOFTWARE\\gtkmm\\2.4;Path] [HKEY_LOCAL_MACHINE\\SOFTWARE\\gtkmm\\2.4;Path] + PATH_SUFFIXES + lib ) # set the user variables @@ -111,31 +124,41 @@ elseif(EXISTS "${FREETYPE_INCLUDE_DIR_freetype2}/freetype.h") endif() if(FREETYPE_INCLUDE_DIR_freetype2 AND FREETYPE_H) - file(STRINGS "${FREETYPE_H}" freetype_version_str - REGEX "^#[\t ]*define[\t ]+FREETYPE_(MAJOR|MINOR|PATCH)[\t ]+[0-9]+$") + file(STRINGS "${FREETYPE_H}" freetype_version_str + REGEX "^#[\t ]*define[\t ]+FREETYPE_(MAJOR|MINOR|PATCH)[\t ]+[0-9]+$") - unset(FREETYPE_VERSION_STRING) - foreach(VPART MAJOR MINOR PATCH) - foreach(VLINE ${freetype_version_str}) - if(VLINE MATCHES "^#[\t ]*define[\t ]+FREETYPE_${VPART}[\t ]+([0-9]+)$") - set(FREETYPE_VERSION_PART "${CMAKE_MATCH_1}") - if(FREETYPE_VERSION_STRING) - set(FREETYPE_VERSION_STRING "${FREETYPE_VERSION_STRING}.${FREETYPE_VERSION_PART}") - else() - set(FREETYPE_VERSION_STRING "${FREETYPE_VERSION_PART}") - endif() - unset(FREETYPE_VERSION_PART) - endif() - endforeach() + unset(FREETYPE_VERSION_STRING) + foreach(VPART MAJOR MINOR PATCH) + foreach(VLINE ${freetype_version_str}) + if(VLINE MATCHES "^#[\t ]*define[\t ]+FREETYPE_${VPART}[\t ]+([0-9]+)$") + set(FREETYPE_VERSION_PART "${CMAKE_MATCH_1}") + if(FREETYPE_VERSION_STRING) + set(FREETYPE_VERSION_STRING "${FREETYPE_VERSION_STRING}.${FREETYPE_VERSION_PART}") + else() + set(FREETYPE_VERSION_STRING "${FREETYPE_VERSION_PART}") + endif() + unset(FREETYPE_VERSION_PART) + endif() endforeach() + endforeach() endif() # handle the QUIETLY and REQUIRED arguments and set FREETYPE_FOUND to TRUE if # all listed variables are TRUE include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(Freetype - REQUIRED_VARS FREETYPE_LIBRARY FREETYPE_INCLUDE_DIRS - VERSION_VAR FREETYPE_VERSION_STRING) -mark_as_advanced(FREETYPE_LIBRARY FREETYPE_INCLUDE_DIR_freetype2 FREETYPE_INCLUDE_DIR_ft2build) +find_package_handle_standard_args( + Freetype + REQUIRED_VARS + FREETYPE_LIBRARY + FREETYPE_INCLUDE_DIRS + VERSION_VAR + FREETYPE_VERSION_STRING +) + +mark_as_advanced( + FREETYPE_LIBRARY + FREETYPE_INCLUDE_DIR_freetype2 + FREETYPE_INCLUDE_DIR_ft2build +) diff --git a/Modules/Platform/Windows-GNU.cmake b/Modules/Platform/Windows-GNU.cmake index 990acea..ffc5657 100644 --- a/Modules/Platform/Windows-GNU.cmake +++ b/Modules/Platform/Windows-GNU.cmake @@ -154,6 +154,7 @@ macro(__windows_compiler_gnu_abi lang) find_program(CMAKE_GNUtoMS_VCVARS NAMES vcvars32.bat DOC "Visual Studio vcvars32.bat" PATHS + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\12.0\\Setup\\VC;ProductDir]/bin" "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\11.0\\Setup\\VC;ProductDir]/bin" "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\10.0\\Setup\\VC;ProductDir]/bin" "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\9.0\\Setup\\VC;ProductDir]/bin" @@ -163,9 +164,10 @@ macro(__windows_compiler_gnu_abi lang) ) set(CMAKE_GNUtoMS_ARCH x86) elseif("${CMAKE_SIZEOF_VOID_P}" EQUAL 8) - find_program(CMAKE_GNUtoMS_VCVARS NAMES vcvarsamd64.bat + find_program(CMAKE_GNUtoMS_VCVARS NAMES vcvars64.bat vcvarsamd64.bat DOC "Visual Studio vcvarsamd64.bat" PATHS + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\12.0\\Setup\\VC;ProductDir]/bin/amd64" "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\11.0\\Setup\\VC;ProductDir]/bin/amd64" "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\10.0\\Setup\\VC;ProductDir]/bin/amd64" "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\9.0\\Setup\\VC;ProductDir]/bin/amd64" 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/CMakeLists.txt b/Source/CMakeLists.txt index 660c0c5..8ecf83c 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -163,6 +163,8 @@ set(SRCS cmComputeLinkInformation.h cmComputeTargetDepends.h cmComputeTargetDepends.cxx + cmCPackPropertiesGenerator.h + cmCPackPropertiesGenerator.cxx cmCryptoHash.cxx cmCryptoHash.h cmCustomCommand.cxx @@ -243,6 +245,8 @@ set(SRCS cmInstallGenerator.h cmInstallGenerator.cxx cmInstallExportGenerator.cxx + cmInstalledFile.h + cmInstalledFile.cxx cmInstallFilesGenerator.h cmInstallFilesGenerator.cxx cmInstallScriptGenerator.h diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 57f2ff6..1640c73 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 20140522) +set(CMake_VERSION_PATCH 20140529) #set(CMake_VERSION_RC 1) diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.cxx b/Source/CPack/WiX/cmCPackWIXGenerator.cxx index ec59715..a2995d1 100644 --- a/Source/CPack/WiX/cmCPackWIXGenerator.cxx +++ b/Source/CPack/WiX/cmCPackWIXGenerator.cxx @@ -15,6 +15,7 @@ #include <cmSystemTools.h> #include <cmGeneratedFileStream.h> #include <cmCryptoHash.h> +#include <cmInstalledFile.h> #include <CPack/cmCPackLog.h> #include <CPack/cmCPackComponentGroup.h> @@ -871,8 +872,11 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitons( } else { + cmInstalledFile const* installedFile = + this->GetInstalledFile(relativePath); + std::string componentId = fileDefinitions.EmitComponentFile( - directoryId, id, fullPath, *(this->Patch)); + directoryId, id, fullPath, *(this->Patch), installedFile); featureDefinitions.EmitComponentRef(componentId); diff --git a/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx b/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx index 3fd959e..451188e 100644 --- a/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx +++ b/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx @@ -12,6 +12,8 @@ #include "cmWIXFilesSourceWriter.h" +#include <cmInstalledFile.h> + #include <sys/types.h> #include <sys/stat.h> @@ -135,7 +137,8 @@ std::string cmWIXFilesSourceWriter::EmitComponentFile( std::string const& directoryId, std::string const& id, std::string const& filePath, - cmWIXPatch &patch) + cmWIXPatch &patch, + cmInstalledFile const* installedFile) { std::string componentId = std::string("CM_C") + id; std::string fileId = std::string("CM_F") + id; @@ -147,6 +150,18 @@ std::string cmWIXFilesSourceWriter::EmitComponentFile( AddAttribute("Id", componentId); AddAttribute("Guid", "*"); + if(installedFile) + { + if(installedFile->GetPropertyAsBool("CPACK_NEVER_OVERWRITE")) + { + AddAttribute("NeverOverwrite", "yes"); + } + if(installedFile->GetPropertyAsBool("CPACK_PERMANENT")) + { + AddAttribute("Permanent", "yes"); + } + } + BeginElement("File"); AddAttribute("Id", fileId); AddAttribute("Source", filePath); diff --git a/Source/CPack/WiX/cmWIXFilesSourceWriter.h b/Source/CPack/WiX/cmWIXFilesSourceWriter.h index 13122c2..23ef561 100644 --- a/Source/CPack/WiX/cmWIXFilesSourceWriter.h +++ b/Source/CPack/WiX/cmWIXFilesSourceWriter.h @@ -53,7 +53,8 @@ public: std::string const& directoryId, std::string const& id, std::string const& filePath, - cmWIXPatch &patch); + cmWIXPatch &patch, + cmInstalledFile const* installedFile); private: void EmitInstallRegistryValue( diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx index 9cdf5aa..91f92c5 100644 --- a/Source/CPack/cmCPackGenerator.cxx +++ b/Source/CPack/cmCPackGenerator.cxx @@ -1314,6 +1314,14 @@ int cmCPackGenerator::CleanTemporaryDirectory() } //---------------------------------------------------------------------- +cmInstalledFile const* cmCPackGenerator::GetInstalledFile( + std::string const& name) const +{ + cmake const* cm = this->MakefileMap->GetCMakeInstance(); + return cm->GetInstalledFile(name); +} + +//---------------------------------------------------------------------- int cmCPackGenerator::PrepareGroupingKind() { // find a component package method specified by the user diff --git a/Source/CPack/cmCPackGenerator.h b/Source/CPack/cmCPackGenerator.h index e780f0e..ed89b53 100644 --- a/Source/CPack/cmCPackGenerator.h +++ b/Source/CPack/cmCPackGenerator.h @@ -47,6 +47,7 @@ class cmMakefile; class cmCPackLog; +class cmInstalledFile; /** \class cmCPackGenerator * \brief A superclass of all CPack Generators @@ -129,6 +130,8 @@ protected: int CleanTemporaryDirectory(); + cmInstalledFile const* GetInstalledFile(std::string const& name) const; + virtual const char* GetOutputExtension() { return ".cpack"; } virtual const char* GetOutputPostfix() { return 0; } diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx index 9eabdca..2aa5991 100644 --- a/Source/CPack/cpack.cxx +++ b/Source/CPack/cpack.cxx @@ -257,6 +257,11 @@ int main (int argc, char const* const* argv) return 1; } + if ( !cpackBuildConfig.empty() ) + { + globalMF->AddDefinition("CPACK_BUILD_CONFIG", cpackBuildConfig.c_str()); + } + if ( cmSystemTools::FileExists(cpackConfigFile.c_str()) ) { cpackConfigFile = @@ -317,10 +322,6 @@ int main (int argc, char const* const* argv) cpackProjectDirectory.c_str()); } } - if ( !cpackBuildConfig.empty() ) - { - globalMF->AddDefinition("CPACK_BUILD_CONFIG", cpackBuildConfig.c_str()); - } cpackDefinitions::MapType::iterator cdit; for ( cdit = definitions.Map.begin(); cdit != definitions.Map.end(); diff --git a/Source/CTest/cmParsePythonCoverage.cxx b/Source/CTest/cmParsePythonCoverage.cxx index 2578bb8..817b8dc 100644 --- a/Source/CTest/cmParsePythonCoverage.cxx +++ b/Source/CTest/cmParsePythonCoverage.cxx @@ -33,19 +33,25 @@ protected: << atts[tagCount+1] << std::endl); this->CurFileName = this->Coverage.SourceDir + "/" + atts[tagCount+1]; - FileLinesType& curFileLines = - this->Coverage.TotalCoverage[this->CurFileName]; cmsys::ifstream fin(this->CurFileName.c_str()); if(!fin) { - cmCTestLog(this->CTest, ERROR_MESSAGE, - "Python Coverage: Error opening " << this->CurFileName - << std::endl); - this->Coverage.Error++; - break; + this->CurFileName = this->Coverage.BinaryDir + "/" + + atts[tagCount+1]; + fin.open(this->CurFileName.c_str()); + if (!fin) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Python Coverage: Error opening " << this->CurFileName + << std::endl); + this->Coverage.Error++; + break; + } } std::string line; + FileLinesType& curFileLines = + this->Coverage.TotalCoverage[this->CurFileName]; curFileLines.push_back(-1); while(cmSystemTools::GetLineFromStream(fin, line)) { @@ -73,11 +79,11 @@ protected: curNumber = atoi(atts[tagCount+1]); } - if(curHits > -1 && curNumber > -1) + if(curHits > -1 && curNumber > 0) { FileLinesType& curFileLines = this->Coverage.TotalCoverage[this->CurFileName]; - curFileLines[curNumber] = curHits; + curFileLines[curNumber-1] = curHits; break; } ++tagCount; diff --git a/Source/cmCPackPropertiesGenerator.cxx b/Source/cmCPackPropertiesGenerator.cxx new file mode 100644 index 0000000..cf24c13 --- /dev/null +++ b/Source/cmCPackPropertiesGenerator.cxx @@ -0,0 +1,45 @@ +#include "cmCPackPropertiesGenerator.h" + +#include "cmLocalGenerator.h" + +cmCPackPropertiesGenerator::cmCPackPropertiesGenerator( + cmMakefile* mf, + cmInstalledFile const& installedFile, + std::vector<std::string> const& configurations): + cmScriptGenerator("CPACK_BUILD_CONFIG", configurations), + Makefile(mf), + InstalledFile(installedFile) +{ + this->ActionsPerConfig = true; +} + +void cmCPackPropertiesGenerator::GenerateScriptForConfig(std::ostream& os, + const std::string& config, Indent const& indent) +{ + std::string const& expandedFileName = + this->InstalledFile.GetNameExpression().Evaluate(this->Makefile, config); + + cmInstalledFile::PropertyMapType const& properties = + this->InstalledFile.GetProperties(); + + for(cmInstalledFile::PropertyMapType::const_iterator i = properties.begin(); + i != properties.end(); ++i) + { + std::string const& name = i->first; + cmInstalledFile::Property const& property = i->second; + + os << indent << "set_property(INSTALL " << + cmLocalGenerator::EscapeForCMake(expandedFileName) << " PROPERTY " << + cmLocalGenerator::EscapeForCMake(name); + + for(cmInstalledFile::ExpressionVectorType::const_iterator + j = property.ValueExpressions.begin(); + j != property.ValueExpressions.end(); ++j) + { + std::string value = (*j)->Evaluate(this->Makefile, config); + os << " " << cmLocalGenerator::EscapeForCMake(value); + } + + os << ")\n"; + } +} diff --git a/Source/cmCPackPropertiesGenerator.h b/Source/cmCPackPropertiesGenerator.h new file mode 100644 index 0000000..71e2eaa --- /dev/null +++ b/Source/cmCPackPropertiesGenerator.h @@ -0,0 +1,38 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2014 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmCPackPropertiesGenerator_h +#define cmCPackPropertiesGenerator_h + +#include "cmScriptGenerator.h" +#include "cmInstalledFile.h" + +/** \class cmCPackPropertiesGenerator + * \brief Support class for generating CPackProperties.cmake. + * + */ +class cmCPackPropertiesGenerator: public cmScriptGenerator +{ +public: + cmCPackPropertiesGenerator( + cmMakefile* mf, + cmInstalledFile const& installedFile, + std::vector<std::string> const& configurations); + +protected: + virtual void GenerateScriptForConfig(std::ostream& os, + const std::string& config, Indent const& indent); + + cmMakefile* Makefile; + cmInstalledFile const& InstalledFile; +}; + +#endif diff --git a/Source/cmCacheManager.cxx b/Source/cmCacheManager.cxx index 8f352b1..d6b84a0 100644 --- a/Source/cmCacheManager.cxx +++ b/Source/cmCacheManager.cxx @@ -751,11 +751,7 @@ void cmCacheManager::AddCacheEntry(const std::string& key, } e.SetProperty("HELPSTRING", helpString? helpString : "(This variable does not exist and should not be used)"); - if (this->Cache[key].Value == e.Value) - { - this->CMakeInstance->UnwatchUnusedCli(key); - } - this->Cache[key] = e; + this->CMakeInstance->UnwatchUnusedCli(key); } bool cmCacheManager::CacheIterator::IsAtEnd() const diff --git a/Source/cmGetPropertyCommand.cxx b/Source/cmGetPropertyCommand.cxx index 512d789..9a88191 100644 --- a/Source/cmGetPropertyCommand.cxx +++ b/Source/cmGetPropertyCommand.cxx @@ -67,12 +67,16 @@ bool cmGetPropertyCommand { scope = cmProperty::CACHE; } + else if(args[1] == "INSTALL") + { + scope = cmProperty::INSTALL; + } else { cmOStringStream e; e << "given invalid scope " << args[1] << ". " << "Valid scopes are " - << "GLOBAL, DIRECTORY, TARGET, SOURCE, TEST, VARIABLE, CACHE."; + << "GLOBAL, DIRECTORY, TARGET, SOURCE, TEST, VARIABLE, CACHE, INSTALL."; this->SetError(e.str()); return false; } @@ -190,6 +194,7 @@ bool cmGetPropertyCommand case cmProperty::TEST: return this->HandleTestMode(); case cmProperty::VARIABLE: return this->HandleVariableMode(); case cmProperty::CACHE: return this->HandleCacheMode(); + case cmProperty::INSTALL: return this->HandleInstallMode(); case cmProperty::CACHED_VARIABLE: break; // should never happen @@ -395,3 +400,33 @@ bool cmGetPropertyCommand::HandleCacheMode() this->StoreResult(value); return true; } + +//---------------------------------------------------------------------------- +bool cmGetPropertyCommand::HandleInstallMode() +{ + if(this->Name.empty()) + { + this->SetError("not given name for INSTALL scope."); + return false; + } + + // Get the installed file. + cmake* cm = this->Makefile->GetCMakeInstance(); + + if(cmInstalledFile* file = cm->GetOrCreateInstalledFile( + this->Makefile, this->Name)) + { + std::string value; + bool isSet = file->GetProperty(this->PropertyName, value); + + return this->StoreResult(isSet ? value.c_str() : 0); + } + else + { + cmOStringStream e; + e << "given INSTALL name that could not be found or created: " + << this->Name; + this->SetError(e.str()); + return false; + } +} diff --git a/Source/cmGetPropertyCommand.h b/Source/cmGetPropertyCommand.h index 8c3738f..40b7dbc 100644 --- a/Source/cmGetPropertyCommand.h +++ b/Source/cmGetPropertyCommand.h @@ -60,6 +60,7 @@ private: bool HandleTestMode(); bool HandleVariableMode(); bool HandleCacheMode(); + bool HandleInstallMode(); }; #endif diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 2a30593..dba4f46 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -28,6 +28,7 @@ #include "cmGeneratorExpression.h" #include "cmGeneratorExpressionEvaluationFile.h" #include "cmExportBuildFileGenerator.h" +#include "cmCPackPropertiesGenerator.h" #include <cmsys/Directory.hxx> #include <cmsys/FStream.hxx> @@ -1269,6 +1270,13 @@ void cmGlobalGenerator::Generate() } this->SetCurrentLocalGenerator(0); + if(!this->GenerateCPackPropertiesFile()) + { + this->GetCMakeInstance()->IssueMessage( + cmake::FATAL_ERROR, "Could not write CPack properties file.", + cmListFileBacktrace()); + } + for (std::map<std::string, cmExportBuildFileGenerator*>::iterator it = this->BuildExportSets.begin(); it != this->BuildExportSets.end(); ++it) @@ -3014,3 +3022,39 @@ std::string cmGlobalGenerator::ExpandCFGIntDir(const std::string& str, { return str; } + +//---------------------------------------------------------------------------- +bool cmGlobalGenerator::GenerateCPackPropertiesFile() +{ + cmake::InstalledFilesMap const& installedFiles = + this->CMakeInstance->GetInstalledFiles(); + + cmMakefile* mf = this->LocalGenerators[0]->GetMakefile(); + + std::vector<std::string> configs; + std::string config = mf->GetConfigurations(configs, false); + + std::string path = this->CMakeInstance->GetStartOutputDirectory(); + path += "/CPackProperties.cmake"; + + if(!cmSystemTools::FileExists(path.c_str()) && installedFiles.empty()) + { + return true; + } + + cmGeneratedFileStream file(path.c_str()); + file << "# CPack properties\n"; + + for(cmake::InstalledFilesMap::const_iterator i = installedFiles.begin(); + i != installedFiles.end(); ++i) + { + cmInstalledFile const& installedFile = i->second; + + cmCPackPropertiesGenerator cpackPropertiesGenerator( + mf, installedFile, configs); + + cpackPropertiesGenerator.Generate(file, config, configs); + } + + return true; +} diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 14ec99a..617e708 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -329,6 +329,8 @@ public: virtual void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const; + bool GenerateCPackPropertiesFile(); + protected: typedef std::vector<cmLocalGenerator*> GeneratorVector; // for a project collect all its targets by following depend diff --git a/Source/cmInstalledFile.cxx b/Source/cmInstalledFile.cxx new file mode 100644 index 0000000..7e78ec0 --- /dev/null +++ b/Source/cmInstalledFile.cxx @@ -0,0 +1,115 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2014 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include "cmInstalledFile.h" +#include "cmSystemTools.h" +#include "cmMakefile.h" + +//---------------------------------------------------------------------------- +cmInstalledFile::cmInstalledFile(): + NameExpression(0) +{ + +} + +//---------------------------------------------------------------------------- +cmInstalledFile::~cmInstalledFile() +{ + if(NameExpression) + { + delete NameExpression; + } +} + +//---------------------------------------------------------------------------- +void cmInstalledFile::SetName(cmMakefile* mf, const std::string& name) +{ + cmListFileBacktrace backtrace; + mf->GetBacktrace(backtrace); + cmGeneratorExpression ge(backtrace); + + this->Name = name; + this->NameExpression = ge.Parse(name).release(); +} + +//---------------------------------------------------------------------------- +std::string const& cmInstalledFile::GetName() const +{ + return this->Name; +} + +//---------------------------------------------------------------------------- +cmCompiledGeneratorExpression const& cmInstalledFile::GetNameExpression() const +{ + return *(this->NameExpression); +} + +//---------------------------------------------------------------------------- +void cmInstalledFile::RemoveProperty(const std::string& prop) +{ + this->Properties.erase(prop); +} + +//---------------------------------------------------------------------------- +void cmInstalledFile::SetProperty(cmMakefile const* mf, + const std::string& prop, const char* value) +{ + this->RemoveProperty(prop); + this->AppendProperty(mf, prop, value); +} + +//---------------------------------------------------------------------------- +void cmInstalledFile::AppendProperty(cmMakefile const* mf, + const std::string& prop, const char* value, bool /*asString*/) +{ + cmListFileBacktrace backtrace; + mf->GetBacktrace(backtrace); + cmGeneratorExpression ge(backtrace); + + Property& property = this->Properties[prop]; + property.ValueExpressions.push_back(ge.Parse(value).release()); +} + +//---------------------------------------------------------------------------- +bool cmInstalledFile::GetProperty( + const std::string& prop, std::string& value) const +{ + PropertyMapType::const_iterator i = this->Properties.find(prop); + if(i == this->Properties.end()) + { + return false; + } + + Property const& property = i->second; + + std::string output; + std::string separator; + + for(ExpressionVectorType::const_iterator + j = property.ValueExpressions.begin(); + j != property.ValueExpressions.end(); ++j) + { + output += separator; + output += (*j)->GetInput(); + separator = ";"; + } + + value = output; + return true; +} + +//---------------------------------------------------------------------------- +bool cmInstalledFile::GetPropertyAsBool(const std::string& prop) const +{ + std::string value; + bool isSet = this->GetProperty(prop, value); + return isSet && cmSystemTools::IsOn(value.c_str()); +} diff --git a/Source/cmInstalledFile.h b/Source/cmInstalledFile.h new file mode 100644 index 0000000..df28221 --- /dev/null +++ b/Source/cmInstalledFile.h @@ -0,0 +1,83 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2014 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmInstalledFile_h +#define cmInstalledFile_h + +#include "cmGeneratorExpression.h" + +/** \class cmInstalledFile + * \brief Represents a file intended for installation. + * + * cmInstalledFile represents a file intended for installation. + */ +class cmInstalledFile +{ +public: + + typedef cmsys::auto_ptr<cmCompiledGeneratorExpression> + CompiledGeneratorExpressionPtrType; + + typedef std::vector<cmCompiledGeneratorExpression*> + ExpressionVectorType; + + struct Property + { + Property() + { + + } + + ~Property() + { + for(ExpressionVectorType::iterator i = ValueExpressions.begin(); + i != ValueExpressions.end(); ++i) + { + delete *i; + } + } + + ExpressionVectorType ValueExpressions; + }; + + typedef std::map<std::string, Property> PropertyMapType; + + cmInstalledFile(); + + ~cmInstalledFile(); + + void RemoveProperty(const std::string& prop); + + void SetProperty(cmMakefile const* mf, + const std::string& prop, const char *value); + + void AppendProperty(cmMakefile const* mf, + const std::string& prop, const char* value,bool asString=false); + + bool GetProperty(const std::string& prop, std::string& value) const; + + bool GetPropertyAsBool(const std::string& prop) const; + + void SetName(cmMakefile* mf, const std::string& name); + + std::string const& GetName() const; + + cmCompiledGeneratorExpression const& GetNameExpression() const; + + PropertyMapType const& GetProperties() const { return this->Properties; } + +private: + std::string Name; + cmCompiledGeneratorExpression* NameExpression; + PropertyMapType Properties; +}; + +#endif diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 9e72fb8..2620471 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 6a72663..e3b83af 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/cmProperty.h b/Source/cmProperty.h index 34897e8..659c4c3 100644 --- a/Source/cmProperty.h +++ b/Source/cmProperty.h @@ -18,7 +18,7 @@ class cmProperty { public: enum ScopeType { TARGET, SOURCE_FILE, DIRECTORY, GLOBAL, CACHE, - TEST, VARIABLE, CACHED_VARIABLE }; + TEST, VARIABLE, CACHED_VARIABLE, INSTALL }; // set this property void Set(const std::string& name, const char *value); diff --git a/Source/cmRST.cxx b/Source/cmRST.cxx index 7ff12dd..cca995b 100644 --- a/Source/cmRST.cxx +++ b/Source/cmRST.cxx @@ -39,7 +39,8 @@ cmRST::cmRST(std::ostream& os, std::string const& docroot): ModuleRST("^#\\[(=*)\\[\\.rst:$"), CMakeRole("(:cmake)?:(" "command|generator|variable|module|policy|" - "prop_cache|prop_dir|prop_gbl|prop_sf|prop_test|prop_tgt|" + "prop_cache|prop_dir|prop_gbl|prop_inst|prop_sf|" + "prop_test|prop_tgt|" "manual" "):`(<*([^`<]|[^` \t]<)*)([ \t]+<[^`]*>)?`"), Substitution("(^|[^A-Za-z0-9_])" diff --git a/Source/cmSetPropertyCommand.cxx b/Source/cmSetPropertyCommand.cxx index 5f970f8..c624d17 100644 --- a/Source/cmSetPropertyCommand.cxx +++ b/Source/cmSetPropertyCommand.cxx @@ -61,11 +61,16 @@ bool cmSetPropertyCommand { scope = cmProperty::CACHE; } + else if(*arg == "INSTALL") + { + scope = cmProperty::INSTALL; + } else { cmOStringStream e; e << "given invalid scope " << *arg << ". " - << "Valid scopes are GLOBAL, DIRECTORY, TARGET, SOURCE, TEST, CACHE."; + << "Valid scopes are GLOBAL, DIRECTORY, " + "TARGET, SOURCE, TEST, CACHE, INSTALL."; this->SetError(e.str()); return false; } @@ -135,6 +140,7 @@ bool cmSetPropertyCommand case cmProperty::SOURCE_FILE: return this->HandleSourceMode(); case cmProperty::TEST: return this->HandleTestMode(); case cmProperty::CACHE: return this->HandleCacheMode(); + case cmProperty::INSTALL: return this->HandleInstallMode(); case cmProperty::VARIABLE: case cmProperty::CACHED_VARIABLE: @@ -488,3 +494,54 @@ bool cmSetPropertyCommand::HandleCacheEntry(cmCacheManager::CacheIterator& it) return true; } + +//---------------------------------------------------------------------------- +bool cmSetPropertyCommand::HandleInstallMode() +{ + cmake* cm = this->Makefile->GetCMakeInstance(); + + for(std::set<std::string>::const_iterator i = this->Names.begin(); + i != this->Names.end(); ++i) + { + if(cmInstalledFile* file = cm->GetOrCreateInstalledFile( + this->Makefile, *i)) + { + if(!this->HandleInstall(file)) + { + return false; + } + } + else + { + cmOStringStream e; + e << "given INSTALL name that could not be found or created: " << *i; + this->SetError(e.str()); + return false; + } + } + return true; +} + +//---------------------------------------------------------------------------- +bool cmSetPropertyCommand::HandleInstall(cmInstalledFile* file) +{ + // Set or append the property. + std::string const& name = this->PropertyName; + + cmMakefile* mf = this->Makefile; + + const char *value = this->PropertyValue.c_str(); + if (this->Remove) + { + file->RemoveProperty(name); + } + else if(this->AppendMode) + { + file->AppendProperty(mf, name, value, this->AppendAsString); + } + else + { + file->SetProperty(mf, name, value); + } + return true; +} diff --git a/Source/cmSetPropertyCommand.h b/Source/cmSetPropertyCommand.h index eaa0233..b06cb68 100644 --- a/Source/cmSetPropertyCommand.h +++ b/Source/cmSetPropertyCommand.h @@ -62,6 +62,8 @@ private: bool HandleTest(cmTest* test); bool HandleCacheMode(); bool HandleCacheEntry(cmCacheManager::CacheIterator&); + bool HandleInstallMode(); + bool HandleInstall(cmInstalledFile* file); }; 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/Source/cmake.cxx b/Source/cmake.cxx index a83ebd5..60e92a0 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -1236,7 +1236,10 @@ int cmake::HandleDeleteCacheVariables(const std::string& var) if(ci.Find(save.key)) { save.type = ci.GetType(); - save.help = ci.GetProperty("HELPSTRING"); + if(const char* help = ci.GetProperty("HELPSTRING")) + { + save.help = help; + } } saved.push_back(save); } @@ -2291,6 +2294,41 @@ bool cmake::GetPropertyAsBool(const std::string& prop) return cmSystemTools::IsOn(this->GetProperty(prop)); } +cmInstalledFile *cmake::GetOrCreateInstalledFile( + cmMakefile* mf, const std::string& name) +{ + std::map<std::string, cmInstalledFile>::iterator i = + this->InstalledFiles.find(name); + + if(i != this->InstalledFiles.end()) + { + cmInstalledFile &file = i->second; + return &file; + } + else + { + cmInstalledFile &file = this->InstalledFiles[name]; + file.SetName(mf, name); + return &file; + } +} + +cmInstalledFile const* cmake::GetInstalledFile(const std::string& name) const +{ + std::map<std::string, cmInstalledFile>::const_iterator i = + this->InstalledFiles.find(name); + + if(i != this->InstalledFiles.end()) + { + cmInstalledFile const& file = i->second; + return &file; + } + else + { + return 0; + } +} + int cmake::GetSystemInformation(std::vector<std::string>& args) { // so create the directory diff --git a/Source/cmake.h b/Source/cmake.h index 3992a9e..329b439 100644 --- a/Source/cmake.h +++ b/Source/cmake.h @@ -16,6 +16,7 @@ #include "cmSystemTools.h" #include "cmPropertyDefinitionMap.h" #include "cmPropertyMap.h" +#include "cmInstalledFile.h" class cmGlobalGeneratorFactory; class cmGlobalGenerator; @@ -92,6 +93,7 @@ class cmake FIND_PACKAGE_MODE }; typedef std::map<std::string, cmCommand*> RegisteredCommandsMap; + typedef std::map<std::string, cmInstalledFile> InstalledFilesMap; /// Default constructor cmake(); @@ -280,6 +282,15 @@ class cmake // Get the properties cmPropertyMap &GetProperties() { return this->Properties; } + ///! Get or create an cmInstalledFile instance and return a pointer to it + cmInstalledFile *GetOrCreateInstalledFile( + cmMakefile* mf, const std::string& name); + + cmInstalledFile const* GetInstalledFile(const std::string& name) const; + + InstalledFilesMap const& GetInstalledFiles() const + { return this->InstalledFiles; } + ///! Do all the checks before running configure int DoPreConfigureChecks(); @@ -445,6 +456,7 @@ private: cmFileTimeComparison* FileComparison; std::string GraphVizFile; std::vector<std::string> DebugConfigs; + InstalledFilesMap InstalledFiles; void UpdateConversionPathTable(); }; diff --git a/Templates/CPackConfig.cmake.in b/Templates/CPackConfig.cmake.in index 79b8d93..c00ea2a 100644 --- a/Templates/CPackConfig.cmake.in +++ b/Templates/CPackConfig.cmake.in @@ -10,3 +10,11 @@ # usually begin with CPACK_<GENNAME>_xxxx. @_CPACK_OTHER_VARIABLES_@ + +if(NOT CPACK_PROPERTIES_FILE) + set(CPACK_PROPERTIES_FILE "@CMAKE_BINARY_DIR@/CPackProperties.cmake") +endif() + +if(EXISTS ${CPACK_PROPERTIES_FILE}) + include(${CPACK_PROPERTIES_FILE}) +endif() 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..d5af542 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) @@ -137,3 +138,4 @@ add_RunCMake_test(CheckModules) add_RunCMake_test(CommandLine) add_RunCMake_test(install) +add_RunCMake_test(CPackInstallProperties) diff --git a/Tests/RunCMake/CPackInstallProperties/Append-check.cmake b/Tests/RunCMake/CPackInstallProperties/Append-check.cmake new file mode 100644 index 0000000..017b30d --- /dev/null +++ b/Tests/RunCMake/CPackInstallProperties/Append-check.cmake @@ -0,0 +1,3 @@ +include(${RunCMake_SOURCE_DIR}/check.cmake) + +test_property("append.txt" CPACK_TEST_PROP "value1;value2;value3") diff --git a/Tests/RunCMake/CPackInstallProperties/Append.cmake b/Tests/RunCMake/CPackInstallProperties/Append.cmake new file mode 100644 index 0000000..cecc45f --- /dev/null +++ b/Tests/RunCMake/CPackInstallProperties/Append.cmake @@ -0,0 +1,2 @@ +set_property(INSTALL append.txt PROPERTY CPACK_TEST_PROP value1) +set_property(INSTALL append.txt PROPERTY CPACK_TEST_PROP value2 value3 APPEND) diff --git a/Tests/RunCMake/CPackInstallProperties/CMakeLists.txt b/Tests/RunCMake/CPackInstallProperties/CMakeLists.txt new file mode 100644 index 0000000..89ff7c4 --- /dev/null +++ b/Tests/RunCMake/CPackInstallProperties/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.0) + +project(${RunCMake_TEST} CXX) +include(${RunCMake_TEST}.cmake) + +include(CPack) diff --git a/Tests/RunCMake/CPackInstallProperties/FilenameGenex-check.cmake b/Tests/RunCMake/CPackInstallProperties/FilenameGenex-check.cmake new file mode 100644 index 0000000..8c9e967 --- /dev/null +++ b/Tests/RunCMake/CPackInstallProperties/FilenameGenex-check.cmake @@ -0,0 +1,3 @@ +include(${RunCMake_SOURCE_DIR}/check.cmake) + +test_property(${EXPECTED_MYTEST_NAME} CPACK_TEST_PROP2 PROP_VALUE2) diff --git a/Tests/RunCMake/CPackInstallProperties/FilenameGenex.cmake b/Tests/RunCMake/CPackInstallProperties/FilenameGenex.cmake new file mode 100644 index 0000000..1a373b9 --- /dev/null +++ b/Tests/RunCMake/CPackInstallProperties/FilenameGenex.cmake @@ -0,0 +1,7 @@ +add_executable(mytest test.cpp) + +file(GENERATE OUTPUT runtest_info.cmake CONTENT [[ +set(EXPECTED_MYTEST_NAME "$<TARGET_FILE_NAME:mytest>") +]]) + +set_property(INSTALL $<TARGET_FILE_NAME:mytest> PROPERTY CPACK_TEST_PROP2 PROP_VALUE2) diff --git a/Tests/RunCMake/CPackInstallProperties/MultipleValues-check.cmake b/Tests/RunCMake/CPackInstallProperties/MultipleValues-check.cmake new file mode 100644 index 0000000..91278ba --- /dev/null +++ b/Tests/RunCMake/CPackInstallProperties/MultipleValues-check.cmake @@ -0,0 +1,3 @@ +include(${RunCMake_SOURCE_DIR}/check.cmake) + +test_property("multiple_values.txt" CPACK_TEST_PROP "value1;value2;value3") diff --git a/Tests/RunCMake/CPackInstallProperties/MultipleValues.cmake b/Tests/RunCMake/CPackInstallProperties/MultipleValues.cmake new file mode 100644 index 0000000..26db52a --- /dev/null +++ b/Tests/RunCMake/CPackInstallProperties/MultipleValues.cmake @@ -0,0 +1 @@ +set_property(INSTALL multiple_values.txt PROPERTY CPACK_TEST_PROP value1 value2 value3) diff --git a/Tests/RunCMake/CPackInstallProperties/PerConfigValue-check.cmake b/Tests/RunCMake/CPackInstallProperties/PerConfigValue-check.cmake new file mode 100644 index 0000000..2966d88 --- /dev/null +++ b/Tests/RunCMake/CPackInstallProperties/PerConfigValue-check.cmake @@ -0,0 +1,13 @@ +include(${RunCMake_SOURCE_DIR}/check.cmake) + +file(GLOB INFO_FILES ${RunCMake_TEST_BINARY_DIR}/runtest_info_*.cmake) + +if(NOT INFO_FILES) + message(FATAL_ERROR "missing expected info files") +endif() + +foreach(INFO_FILE IN LISTS INFO_FILES) + include(${INFO_FILE}) + include(${RunCMake_TEST_BINARY_DIR}/CPackProperties.cmake) + test_property("config.cpp" FOO ${EXPECTED_MYTEST_NAME}) +endforeach() diff --git a/Tests/RunCMake/CPackInstallProperties/PerConfigValue.cmake b/Tests/RunCMake/CPackInstallProperties/PerConfigValue.cmake new file mode 100644 index 0000000..77fe8ed --- /dev/null +++ b/Tests/RunCMake/CPackInstallProperties/PerConfigValue.cmake @@ -0,0 +1,14 @@ +add_executable(mytest test.cpp) + +foreach(CONFIG IN LISTS CMAKE_CONFIGURATION_TYPES) + string(TOUPPER ${CONFIG} UPPER_CONFIG) + set_property(TARGET mytest PROPERTY + OUTPUT_NAME_${UPPER_CONFIG} bar_${CONFIG}) +endforeach() + +file(GENERATE OUTPUT runtest_info_$<CONFIG>.cmake CONTENT [[ +set(CPACK_BUILD_CONFIG "$<CONFIG>") +set(EXPECTED_MYTEST_NAME "$<TARGET_FILE_NAME:mytest>") +]]) + +set_property(INSTALL config.cpp PROPERTY FOO $<TARGET_FILE_NAME:mytest>) diff --git a/Tests/RunCMake/CPackInstallProperties/Replace-check.cmake b/Tests/RunCMake/CPackInstallProperties/Replace-check.cmake new file mode 100644 index 0000000..6e492e7 --- /dev/null +++ b/Tests/RunCMake/CPackInstallProperties/Replace-check.cmake @@ -0,0 +1,3 @@ +include(${RunCMake_SOURCE_DIR}/check.cmake) + +test_property("replace.txt" CPACK_TEST_PROP "value2") diff --git a/Tests/RunCMake/CPackInstallProperties/Replace.cmake b/Tests/RunCMake/CPackInstallProperties/Replace.cmake new file mode 100644 index 0000000..104d5a4 --- /dev/null +++ b/Tests/RunCMake/CPackInstallProperties/Replace.cmake @@ -0,0 +1,2 @@ +set_property(INSTALL replace.txt PROPERTY CPACK_TEST_PROP value1) +set_property(INSTALL replace.txt PROPERTY CPACK_TEST_PROP value2) diff --git a/Tests/RunCMake/CPackInstallProperties/RunCMakeTest.cmake b/Tests/RunCMake/CPackInstallProperties/RunCMakeTest.cmake new file mode 100644 index 0000000..d244ac5 --- /dev/null +++ b/Tests/RunCMake/CPackInstallProperties/RunCMakeTest.cmake @@ -0,0 +1,9 @@ +include(RunCMake) + +run_cmake(Simple) +run_cmake(FilenameGenex) +run_cmake(ValueGenex) +run_cmake(MultipleValues) +run_cmake(Append) +run_cmake(Replace) +run_cmake(PerConfigValue) diff --git a/Tests/RunCMake/CPackInstallProperties/Simple-check.cmake b/Tests/RunCMake/CPackInstallProperties/Simple-check.cmake new file mode 100644 index 0000000..6a7ee2a --- /dev/null +++ b/Tests/RunCMake/CPackInstallProperties/Simple-check.cmake @@ -0,0 +1,3 @@ +include(${RunCMake_SOURCE_DIR}/check.cmake) + +test_property("foo/test.cpp" CPACK_TEST_PROP PROP_VALUE) diff --git a/Tests/RunCMake/CPackInstallProperties/Simple.cmake b/Tests/RunCMake/CPackInstallProperties/Simple.cmake new file mode 100644 index 0000000..2eb8755 --- /dev/null +++ b/Tests/RunCMake/CPackInstallProperties/Simple.cmake @@ -0,0 +1 @@ +set_property(INSTALL foo/test.cpp PROPERTY CPACK_TEST_PROP PROP_VALUE) diff --git a/Tests/RunCMake/CPackInstallProperties/ValueGenex-check.cmake b/Tests/RunCMake/CPackInstallProperties/ValueGenex-check.cmake new file mode 100644 index 0000000..cdfbcda --- /dev/null +++ b/Tests/RunCMake/CPackInstallProperties/ValueGenex-check.cmake @@ -0,0 +1,3 @@ +include(${RunCMake_SOURCE_DIR}/check.cmake) + +test_property("bar/test.cpp" CPACK_TEST_PROP ${EXPECTED_MYTEST_NAME}) diff --git a/Tests/RunCMake/CPackInstallProperties/ValueGenex.cmake b/Tests/RunCMake/CPackInstallProperties/ValueGenex.cmake new file mode 100644 index 0000000..2e1d465 --- /dev/null +++ b/Tests/RunCMake/CPackInstallProperties/ValueGenex.cmake @@ -0,0 +1,7 @@ +add_executable(mytest test.cpp) + +file(GENERATE OUTPUT runtest_info.cmake CONTENT [[ +set(EXPECTED_MYTEST_NAME "$<TARGET_FILE_NAME:mytest>") +]]) + +set_property(INSTALL bar/test.cpp PROPERTY CPACK_TEST_PROP $<TARGET_FILE_NAME:mytest>) diff --git a/Tests/RunCMake/CPackInstallProperties/check.cmake b/Tests/RunCMake/CPackInstallProperties/check.cmake new file mode 100644 index 0000000..65aa467 --- /dev/null +++ b/Tests/RunCMake/CPackInstallProperties/check.cmake @@ -0,0 +1,12 @@ +function(test_property FILE NAME EXPECTED_VALUE) + get_property(ACTUAL_VALUE INSTALL "${FILE}" PROPERTY "${NAME}") + + if(NOT "${ACTUAL_VALUE}" STREQUAL "${EXPECTED_VALUE}") + message(FATAL_ERROR "${NAME}@${FILE}: property mismatch expected [${EXPECTED_VALUE}] actual [${ACTUAL_VALUE}] (Config:${CPACK_BUILD_CONFIG})") + endif() +endfunction() + +set(CPACK_BUILD_CONFIG Debug) +include(${RunCMake_TEST_BINARY_DIR}/CPackProperties.cmake) + +include(${RunCMake_TEST_BINARY_DIR}/runtest_info.cmake OPTIONAL) diff --git a/Tests/RunCMake/CPackInstallProperties/test.cpp b/Tests/RunCMake/CPackInstallProperties/test.cpp new file mode 100644 index 0000000..237c8ce --- /dev/null +++ b/Tests/RunCMake/CPackInstallProperties/test.cpp @@ -0,0 +1 @@ +int main() {} diff --git a/Utilities/Sphinx/cmake.py b/Utilities/Sphinx/cmake.py index 6e6e48a..2629bb3 100644 --- a/Utilities/Sphinx/cmake.py +++ b/Utilities/Sphinx/cmake.py @@ -142,6 +142,7 @@ _cmake_index_objs = { 'prop_cache': _cmake_index_entry('cache property'), 'prop_dir': _cmake_index_entry('directory property'), 'prop_gbl': _cmake_index_entry('global property'), + 'prop_inst': _cmake_index_entry('installed file property'), 'prop_sf': _cmake_index_entry('source file property'), 'prop_test': _cmake_index_entry('test property'), 'prop_tgt': _cmake_index_entry('target property'), @@ -269,6 +270,7 @@ class CMakeDomain(Domain): 'prop_cache': ObjType('prop_cache', 'prop_cache'), 'prop_dir': ObjType('prop_dir', 'prop_dir'), 'prop_gbl': ObjType('prop_gbl', 'prop_gbl'), + 'prop_inst': ObjType('prop_inst', 'prop_inst'), 'prop_sf': ObjType('prop_sf', 'prop_sf'), 'prop_test': ObjType('prop_test', 'prop_test'), 'prop_tgt': ObjType('prop_tgt', 'prop_tgt'), @@ -284,6 +286,7 @@ class CMakeDomain(Domain): # 'prop_cache': CMakeObject, # 'prop_dir': CMakeObject, # 'prop_gbl': CMakeObject, + # 'prop_inst': CMakeObject, # 'prop_sf': CMakeObject, # 'prop_test': CMakeObject, # 'prop_tgt': CMakeObject, @@ -298,6 +301,7 @@ class CMakeDomain(Domain): 'prop_cache': CMakeXRefRole(), 'prop_dir': CMakeXRefRole(), 'prop_gbl': CMakeXRefRole(), + 'prop_inst': CMakeXRefRole(), 'prop_sf': CMakeXRefRole(), 'prop_test': CMakeXRefRole(), 'prop_tgt': CMakeXRefRole(), @@ -232,6 +232,7 @@ CMAKE_CXX_SOURCES="\ cmCommandArgumentLexer \ cmCommandArgumentParser \ cmCommandArgumentParserHelper \ + cmCPackPropertiesGenerator \ cmDefinitions \ cmDepends \ cmDependsC \ @@ -258,6 +259,7 @@ CMAKE_CXX_SOURCES="\ cmGeneratorExpression \ cmGlobalGenerator \ cmLocalGenerator \ + cmInstalledFile \ cmInstallGenerator \ cmInstallExportGenerator \ cmInstallFilesGenerator \ |