summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Auxiliary/vim/syntax/cmake.vim7
-rw-r--r--Help/command/file.rst27
-rw-r--r--Help/envvar/SWIFTC.rst11
-rw-r--r--Help/manual/cmake-buildsystem.7.rst1
-rw-r--r--Help/manual/cmake-env-variables.7.rst1
-rw-r--r--Help/manual/cmake-generator-expressions.7.rst56
-rw-r--r--Help/manual/cmake-language.7.rst6
-rw-r--r--Help/manual/cmake-properties.7.rst5
-rw-r--r--Help/manual/cmake-variables.7.rst1
-rw-r--r--Help/prop_sf/Swift_DEPENDENCIES_FILE.rst5
-rw-r--r--Help/prop_sf/Swift_DIAGNOSTICS_FILE.rst4
-rw-r--r--Help/prop_tgt/AUTOGEN_BUILD_DIR.rst2
-rw-r--r--Help/prop_tgt/Swift_DEPENDENCIES_FILE.rst5
-rw-r--r--Help/prop_tgt/Swift_MODULE_DIRECTORY.rst10
-rw-r--r--Help/prop_tgt/Swift_MODULE_NAME.rst5
-rw-r--r--Help/release/dev/file-install-follow-symlink-chain.rst6
-rw-r--r--Help/release/dev/genex-COMPILE_LANG_AND_ID.rst7
-rw-r--r--Help/release/dev/swift-support.rst23
-rw-r--r--Help/variable/CMAKE_Swift_MODULE_DIRECTORY.rst8
-rw-r--r--Modules/CMakeDetermineCompilerId.cmake39
-rw-r--r--Modules/CMakeDetermineSwiftCompiler.cmake49
-rw-r--r--Modules/CMakeSwiftCompiler.cmake.in9
-rw-r--r--Modules/CMakeSwiftInformation.cmake57
-rw-r--r--Modules/CMakeTestSwiftCompiler.cmake7
-rw-r--r--Modules/FindBLAS.cmake17
-rw-r--r--Modules/FindDoxygen.cmake2
-rw-r--r--Modules/FindPNG.cmake5
-rw-r--r--Modules/UseEcos.cmake8
-rw-r--r--Modules/UseJava.cmake3
-rw-r--r--Modules/UseSWIG.cmake4
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/cmCoreTryCompile.cxx10
-rw-r--r--Source/cmExtraCodeBlocksGenerator.cxx47
-rw-r--r--Source/cmExtraCodeBlocksGenerator.h7
-rw-r--r--Source/cmFileCopier.cxx71
-rw-r--r--Source/cmFileCopier.h2
-rw-r--r--Source/cmGeneratorExpressionNode.cxx46
-rw-r--r--Source/cmGlobalMSYSMakefileGenerator.cxx6
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx4
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.cxx131
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.h3
-rw-r--r--Source/cmGlobalVisualStudio7Generator.cxx16
-rw-r--r--Source/cmGlobalVisualStudio7Generator.h4
-rw-r--r--Source/cmGlobalVisualStudio8Generator.cxx4
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx29
-rw-r--r--Source/cmLocalNinjaGenerator.cxx2
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx60
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.h1
-rw-r--r--Source/cmMakefileExecutableTargetGenerator.cxx2
-rw-r--r--Source/cmMakefileTargetGenerator.cxx17
-rw-r--r--Source/cmNinjaNormalTargetGenerator.cxx104
-rw-r--r--Source/cmNinjaTargetGenerator.cxx133
-rw-r--r--Source/cmNinjaTargetGenerator.h7
-rw-r--r--Source/cmOutputRequiredFilesCommand.cxx6
-rw-r--r--Source/cmQtAutoGenInitializer.cxx20
-rw-r--r--Source/cmQtAutoGenInitializer.h1
-rw-r--r--Source/cmRulePlaceholderExpander.cxx65
-rw-r--r--Source/cmRulePlaceholderExpander.h11
-rw-r--r--Source/cmTarget.cxx1
-rw-r--r--Source/cmTargetPropertyComputer.cxx1
-rw-r--r--Source/cmTryRunCommand.cxx18
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx6
-rw-r--r--Tests/CMakeCommands/target_compile_options/CMakeLists.txt2
-rw-r--r--Tests/CMakeLists.txt39
-rw-r--r--Tests/CheckSwift.cmake61
-rw-r--r--Tests/CompileOptions/CMakeLists.txt1
-rw-r--r--Tests/CompileOptions/main.cpp3
-rw-r--r--Tests/ExportImport/Export/Interface/CMakeLists.txt2
-rw-r--r--Tests/ExportImport/Import/Interface/CMakeLists.txt8
-rw-r--r--Tests/MakeClean/ToClean/CMakeLists.txt82
-rw-r--r--Tests/MakeClean/ToClean/EmptySubDir/CMakeLists.txt17
-rw-r--r--Tests/RunCMake/CMakeLists.txt2
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_custom_command-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_custom_command-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_custom_command.cmake4
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_custom_target-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_custom_target-stderr.txt11
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_custom_target.cmake4
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_executable-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_executable-stderr.txt11
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_executable.cmake5
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_library-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_library-stderr.txt11
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_library.cmake2
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_test-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_test-stderr.txt11
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_test.cmake5
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-install-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-install-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-install.cmake5
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-target_sources-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-target_sources-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-target_sources.cmake2
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-unknown-lang.cmake4
-rw-r--r--Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake8
-rw-r--r--Tests/RunCMake/Swift/RunCMakeTest.cmake4
-rw-r--r--Tests/RunCMake/file/INSTALL-FOLLOW_SYMLINK_CHAIN.cmake168
-rw-r--r--Tests/RunCMake/file/RunCMakeTest.cmake1
-rw-r--r--Tests/WarnUnusedCliUnused/CMakeLists.txt8
99 files changed, 1290 insertions, 452 deletions
diff --git a/Auxiliary/vim/syntax/cmake.vim b/Auxiliary/vim/syntax/cmake.vim
index 7fcdc72..877a033 100644
--- a/Auxiliary/vim/syntax/cmake.vim
+++ b/Auxiliary/vim/syntax/cmake.vim
@@ -96,6 +96,7 @@ syn keyword cmakeProperty contained
\ CMAKE_CONFIGURE_DEPENDS
\ CMAKE_CXX_KNOWN_FEATURES
\ CMAKE_C_KNOWN_FEATURES
+ \ CMAKE_Swift_MODULE_DIRECTORY
\ COMMON_LANGUAGE_RUNTIME
\ COMPATIBLE_INTERFACE_BOOL
\ COMPATIBLE_INTERFACE_NUMBER_MAX
@@ -287,6 +288,11 @@ syn keyword cmakeProperty contained
\ STRINGS
\ SUBDIRECTORIES
\ SUFFIX
+ \ Swift_DEPENDENCIES_FILE
+ \ Swift_DIAGNOSTICS_FILE
+ \ Swift_MODULE
+ \ Swift_MODULE_DIRECTORY
+ \ Swift_MODULE_NAME
\ SYMBOLIC
\ TARGET_ARCHIVES_MAY_BE_SHARED_LIBS
\ TARGET_MESSAGES
@@ -2199,6 +2205,7 @@ syn keyword cmakeGeneratorExpressions contained
\ COMPILE_DEFINITIONS
\ COMPILE_FEATURES
\ COMPILE_LANGUAGE
+ \ COMPILE_LANG_AND_ID
\ COMPILING_CUDA
\ COMPILING_CXX
\ CONFIG
diff --git a/Help/command/file.rst b/Help/command/file.rst
index 465e567..0664e7c 100644
--- a/Help/command/file.rst
+++ b/Help/command/file.rst
@@ -311,6 +311,7 @@ Create the given directories and their parents as needed.
[FILE_PERMISSIONS <permissions>...]
[DIRECTORY_PERMISSIONS <permissions>...]
[NO_SOURCE_PERMISSIONS] [USE_SOURCE_PERMISSIONS]
+ [FOLLOW_SYMLINK_CHAIN]
[FILES_MATCHING]
[[PATTERN <pattern> | REGEX <regex>]
[EXCLUDE] [PERMISSIONS <permissions>...]] [...])
@@ -324,6 +325,32 @@ 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``).
+If ``FOLLOW_SYMLINK_CHAIN`` is specified, ``COPY`` will recursively resolve
+the symlinks at the paths given until a real file is found, and install
+a corresponding symlink in the destination for each symlink encountered. For
+each symlink that is installed, the resolution is stripped of the directory,
+leaving only the filename, meaning that the new symlink points to a file in
+the same directory as the symlink. This feature is useful on some Unix systems,
+where libraries are installed as a chain of symlinks with version numbers, with
+less specific versions pointing to more specific versions.
+``FOLLOW_SYMLINK_CHAIN`` will install all of these symlinks and the library
+itself into the destination directory. For example, if you have the following
+directory structure:
+
+* ``/opt/foo/lib/libfoo.so.1.2.3``
+* ``/opt/foo/lib/libfoo.so.1.2 -> libfoo.so.1.2.3``
+* ``/opt/foo/lib/libfoo.so.1 -> libfoo.so.1.2``
+* ``/opt/foo/lib/libfoo.so -> libfoo.so.1``
+
+and you do:
+
+.. code-block:: cmake
+
+ file(COPY /opt/foo/lib/libfoo.so DESTINATION lib FOLLOW_SYMLINK_CHAIN)
+
+This will install all of the symlinks and ``libfoo.so.1.2.3`` itself into
+``lib``.
+
See the :command:`install(DIRECTORY)` command for documentation of
permissions, ``FILES_MATCHING``, ``PATTERN``, ``REGEX``, and
``EXCLUDE`` options. Copying directories preserves the structure
diff --git a/Help/envvar/SWIFTC.rst b/Help/envvar/SWIFTC.rst
new file mode 100644
index 0000000..b12e51d
--- /dev/null
+++ b/Help/envvar/SWIFTC.rst
@@ -0,0 +1,11 @@
+SWIFTC
+------
+
+.. include:: ENV_VAR.txt
+
+Preferred executable for compiling ``Swift`` language files. Will only be used by
+CMake on the first configuration to determine ``Swift`` compiler, after which the
+value for ``SWIFTC`` is stored in the cache as
+:variable:`CMAKE_Swift_COMPILER <CMAKE_<LANG>_COMPILER>`. For any configuration run
+(including the first), the environment variable will be ignored if the
+:variable:`CMAKE_Swift_COMPILER <CMAKE_<LANG>_COMPILER>` variable is defined.
diff --git a/Help/manual/cmake-buildsystem.7.rst b/Help/manual/cmake-buildsystem.7.rst
index 1ad3453..8cd6e68 100644
--- a/Help/manual/cmake-buildsystem.7.rst
+++ b/Help/manual/cmake-buildsystem.7.rst
@@ -977,6 +977,7 @@ are:
* Properties matching ``INTERFACE_*``
* Built-in properties matching ``COMPATIBLE_INTERFACE_*``
* ``EXPORT_NAME``
+* ``EXPORT_PROPERTIES``
* ``IMPORTED``
* ``MANUALLY_ADDED_DEPENDENCIES``
* ``NAME``
diff --git a/Help/manual/cmake-env-variables.7.rst b/Help/manual/cmake-env-variables.7.rst
index c433412..f106f28 100644
--- a/Help/manual/cmake-env-variables.7.rst
+++ b/Help/manual/cmake-env-variables.7.rst
@@ -52,6 +52,7 @@ Environment Variables for Languages
/envvar/FFLAGS
/envvar/RC
/envvar/RCFLAGS
+ /envvar/SWIFTC
Environment Variables for CTest
===============================
diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst
index ce62893..f2e6597 100644
--- a/Help/manual/cmake-generator-expressions.7.rst
+++ b/Help/manual/cmake-generator-expressions.7.rst
@@ -111,22 +111,22 @@ Variable Queries
this expression when it is evaluated on a property on an :prop_tgt:`IMPORTED`
target.
``$<PLATFORM_ID:platform_id>``
- ``1`` if the CMake-id of the platform matches ``platform_id``
+ ``1`` if the CMake's platform id matches ``platform_id``
otherwise ``0``.
See also the :variable:`CMAKE_SYSTEM_NAME` variable.
``$<C_COMPILER_ID:compiler_id>``
- ``1`` if the CMake-id of the C compiler matches ``compiler_id``,
+ ``1`` if the CMake's compiler id of the C compiler matches ``compiler_id``,
otherwise ``0``.
See also the :variable:`CMAKE_<LANG>_COMPILER_ID` variable.
``$<CXX_COMPILER_ID:compiler_id>``
- ``1`` if the CMake-id of the CXX compiler matches ``compiler_id``,
+ ``1`` if the CMake's compiler id of the CXX compiler matches ``compiler_id``,
otherwise ``0``.
``$<CUDA_COMPILER_ID:compiler_id>``
- ``1`` if the CMake-id of the CUDA compiler matches ``compiler_id``,
+ ``1`` if the CMake's compiler id of the CUDA compiler matches ``compiler_id``,
otherwise ``0``.
See also the :variable:`CMAKE_<LANG>_COMPILER_ID` variable.
``$<Fortran_COMPILER_ID:compiler_id>``
- ``1`` if the CMake-id of the Fortran compiler matches ``compiler_id``,
+ ``1`` if the CMake's compiler id of the Fortran compiler matches ``compiler_id``,
otherwise ``0``.
See also the :variable:`CMAKE_<LANG>_COMPILER_ID` variable.
``$<C_COMPILER_VERSION:version>``
@@ -158,6 +158,42 @@ Variable Queries
.. _`Boolean COMPILE_LANGUAGE Generator Expression`:
+``$<COMPILE_LANG_AND_ID:language,compiler_id>``
+ ``1`` when the language used for compilation unit matches ``language`` and
+ the CMake's compiler id of the language compiler matches ``compiler_id``,
+ otherwise ``0``. This expression is a short form for the combination of
+ ``$<COMPILE_LANGUAGE:language>`` and ``$<LANG_COMPILER_ID:compiler_id>``.
+ This expression may be used to specify compile options,
+ compile definitions, and include directories for source files of a
+ particular language and compiler combination in a target. For example:
+
+ .. code-block:: cmake
+
+ add_executable(myapp main.cpp foo.c bar.cpp zot.cu)
+ target_compile_definitions(myapp
+ PRIVATE $<$<COMPILE_LANG_AND_ID:CXX,Clang>:COMPILING_CXX_WITH_CLANG>
+ $<$<COMPILE_LANG_AND_ID:CXX,Intel>:COMPILING_CXX_WITH_INTEL>
+ $<$<COMPILE_LANG_AND_ID:C,Clang>:COMPILING_C_WITH_CLANG>
+ )
+
+ This specifies the use of different compile definitions based on both
+ the compiler id and compilation language. This example will have a
+ ``COMPILING_CXX_WITH_CLANG`` compile definition when Clang is the CXX
+ compiler, and ``COMPILING_CXX_WITH_INTEL`` when Intel is the CXX compiler.
+ Likewise when the C compiler is Clang it will only see the ``COMPILING_C_WITH_CLANG``
+ definition.
+
+ Without the ``COMPILE_LANG_AND_ID`` generator expression the same logic
+ would be expressed as:
+
+ .. code-block:: cmake
+
+ target_compile_definitions(myapp
+ PRIVATE $<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CXX_COMPILER_ID:Clang>>:COMPILING_CXX_WITH_CLANG>
+ $<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CXX_COMPILER_ID:Intel>>:COMPILING_CXX_WITH_INTEL>
+ $<$<AND:$<COMPILE_LANGUAGE:C>,$<C_COMPILER_ID:Clang>>:COMPILING_C_WITH_CLANG>
+ )
+
``$<COMPILE_LANGUAGE:language>``
``1`` when the language used for compilation unit matches ``language``,
otherwise ``0``. This expression may be used to specify compile options,
@@ -348,19 +384,19 @@ Variable Queries
``$<CONFIGURATION>``
Configuration name. Deprecated since CMake 3.0. Use ``CONFIG`` instead.
``$<PLATFORM_ID>``
- The CMake-id of the platform.
+ The current system's CMake platform id.
See also the :variable:`CMAKE_SYSTEM_NAME` variable.
``$<C_COMPILER_ID>``
- The CMake-id of the C compiler used.
+ The CMake's compiler id of the C compiler used.
See also the :variable:`CMAKE_<LANG>_COMPILER_ID` variable.
``$<CXX_COMPILER_ID>``
- The CMake-id of the CXX compiler used.
+ The CMake's compiler id of the CXX compiler used.
See also the :variable:`CMAKE_<LANG>_COMPILER_ID` variable.
``$<CUDA_COMPILER_ID>``
- The CMake-id of the CUDA compiler used.
+ The CMake's compiler id of the CUDA compiler used.
See also the :variable:`CMAKE_<LANG>_COMPILER_ID` variable.
``$<Fortran_COMPILER_ID>``
- The CMake-id of the Fortran compiler used.
+ The CMake's compiler id of the Fortran compiler used.
See also the :variable:`CMAKE_<LANG>_COMPILER_ID` variable.
``$<C_COMPILER_VERSION>``
The version of the C compiler used.
diff --git a/Help/manual/cmake-language.7.rst b/Help/manual/cmake-language.7.rst
index 5e5cfff..4ca8e3a 100644
--- a/Help/manual/cmake-language.7.rst
+++ b/Help/manual/cmake-language.7.rst
@@ -430,7 +430,7 @@ comments: a `Bracket Comment`_ and a `Line Comment`_.
Bracket Comment
^^^^^^^^^^^^^^^
-A ``#`` immediately followed by a `Bracket Argument`_ forms a
+A ``#`` immediately followed by a :token:`bracket_open` forms a
*bracket comment* consisting of the entire bracket enclosure:
.. raw:: latex
@@ -461,7 +461,7 @@ For example:
Line Comment
^^^^^^^^^^^^
-A ``#`` not immediately followed by a `Bracket Argument`_ forms a
+A ``#`` not immediately followed by a :token:`bracket_open` forms a
*line comment* that runs until the end of the line:
.. raw:: latex
@@ -469,7 +469,7 @@ A ``#`` not immediately followed by a `Bracket Argument`_ forms a
\begin{small}
.. productionlist::
- line_comment: '#' <any text not starting in a `bracket_argument`
+ line_comment: '#' <any text not starting in a `bracket_open`
: and not containing a `newline`>
.. raw:: latex
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index 70974c0..9d2ad90 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -315,6 +315,9 @@ Properties on Targets
/prop_tgt/STATIC_LIBRARY_FLAGS
/prop_tgt/STATIC_LIBRARY_OPTIONS
/prop_tgt/SUFFIX
+ /prop_tgt/Swift_DEPENDENCIES_FILE
+ /prop_tgt/Swift_MODULE_DIRECTORY
+ /prop_tgt/Swift_MODULE_NAME
/prop_tgt/TYPE
/prop_tgt/VERSION
/prop_tgt/VISIBILITY_INLINES_HIDDEN
@@ -439,6 +442,8 @@ Properties on Source Files
/prop_sf/SKIP_AUTOMOC
/prop_sf/SKIP_AUTORCC
/prop_sf/SKIP_AUTOUIC
+ /prop_sf/Swift_DEPENDENCIES_FILE
+ /prop_sf/Swift_DIAGNOSTICS_FILE
/prop_sf/SYMBOLIC
/prop_sf/VS_COPY_TO_OUT_DIR
/prop_sf/VS_CSHARP_tagname
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index e5669d8..fd5e28f 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -97,6 +97,7 @@ Variables that Provide Information
/variable/CMAKE_SOURCE_DIR
/variable/CMAKE_STATIC_LIBRARY_PREFIX
/variable/CMAKE_STATIC_LIBRARY_SUFFIX
+ /variable/CMAKE_Swift_MODULE_DIRECTORY
/variable/CMAKE_TOOLCHAIN_FILE
/variable/CMAKE_TWEAK_VERSION
/variable/CMAKE_VERBOSE_MAKEFILE
diff --git a/Help/prop_sf/Swift_DEPENDENCIES_FILE.rst b/Help/prop_sf/Swift_DEPENDENCIES_FILE.rst
new file mode 100644
index 0000000..a8cf063
--- /dev/null
+++ b/Help/prop_sf/Swift_DEPENDENCIES_FILE.rst
@@ -0,0 +1,5 @@
+Swift_DEPENDENCIES_FILE
+-----------------------
+
+This property sets the path for the Swift dependency file (swiftdeps) for the
+source.
diff --git a/Help/prop_sf/Swift_DIAGNOSTICS_FILE.rst b/Help/prop_sf/Swift_DIAGNOSTICS_FILE.rst
new file mode 100644
index 0000000..5bf5d59
--- /dev/null
+++ b/Help/prop_sf/Swift_DIAGNOSTICS_FILE.rst
@@ -0,0 +1,4 @@
+Swift_DIAGNOSTICS_FILE
+----------------------
+
+This property controls where the Swift diagnostics are serialized.
diff --git a/Help/prop_tgt/AUTOGEN_BUILD_DIR.rst b/Help/prop_tgt/AUTOGEN_BUILD_DIR.rst
index 8db6ede..909b14c 100644
--- a/Help/prop_tgt/AUTOGEN_BUILD_DIR.rst
+++ b/Help/prop_tgt/AUTOGEN_BUILD_DIR.rst
@@ -5,7 +5,7 @@ Directory where :prop_tgt:`AUTOMOC`, :prop_tgt:`AUTOUIC` and :prop_tgt:`AUTORCC`
generate files for the target.
The directory is created on demand and automatically added to the
-:prop_dir:`ADDITIONAL_MAKE_CLEAN_FILES`.
+:prop_tgt:`ADDITIONAL_CLEAN_FILES` target property.
When unset or empty the directory ``<dir>/<target-name>_autogen`` is used where
``<dir>`` is :variable:`CMAKE_CURRENT_BINARY_DIR` and ``<target-name>``
diff --git a/Help/prop_tgt/Swift_DEPENDENCIES_FILE.rst b/Help/prop_tgt/Swift_DEPENDENCIES_FILE.rst
new file mode 100644
index 0000000..93cdd2c
--- /dev/null
+++ b/Help/prop_tgt/Swift_DEPENDENCIES_FILE.rst
@@ -0,0 +1,5 @@
+Swift_DEPENDENCIES_FILE
+-----------------------
+
+This property sets the path for the Swift dependency file (swiftdep) for the
+target.
diff --git a/Help/prop_tgt/Swift_MODULE_DIRECTORY.rst b/Help/prop_tgt/Swift_MODULE_DIRECTORY.rst
new file mode 100644
index 0000000..d404251
--- /dev/null
+++ b/Help/prop_tgt/Swift_MODULE_DIRECTORY.rst
@@ -0,0 +1,10 @@
+Swift_MODULE_DIRECTORY
+----------------------
+
+Specify output directory for Swift modules provided by the target.
+
+If the target contains Swift source files, this specifies the directory in which
+the modules will be placed. When this property is not set, the modules will be
+placed in the build directory corresponding to the target's source directory.
+If the variable :variable:`CMAKE_Swift_MODULE_DIRECTORY` is set when a target is
+created its value is used to initialise this property.
diff --git a/Help/prop_tgt/Swift_MODULE_NAME.rst b/Help/prop_tgt/Swift_MODULE_NAME.rst
new file mode 100644
index 0000000..2866020
--- /dev/null
+++ b/Help/prop_tgt/Swift_MODULE_NAME.rst
@@ -0,0 +1,5 @@
+Swift_MODULE_NAME
+-----------------
+
+This property specifies the name of the Swift module. It is defaulted to the
+name of the target.
diff --git a/Help/release/dev/file-install-follow-symlink-chain.rst b/Help/release/dev/file-install-follow-symlink-chain.rst
new file mode 100644
index 0000000..8d22512
--- /dev/null
+++ b/Help/release/dev/file-install-follow-symlink-chain.rst
@@ -0,0 +1,6 @@
+file-install-follow-symlink-chain
+---------------------------------
+
+* The :command:`file(INSTALL)` command learned a new argument,
+ ``FOLLOW_SYMLINK_CHAIN``, which can be used to recursively resolve and
+ install symlinks.
diff --git a/Help/release/dev/genex-COMPILE_LANG_AND_ID.rst b/Help/release/dev/genex-COMPILE_LANG_AND_ID.rst
new file mode 100644
index 0000000..27e0ebd
--- /dev/null
+++ b/Help/release/dev/genex-COMPILE_LANG_AND_ID.rst
@@ -0,0 +1,7 @@
+genex-COMPILE_LANG_AND_ID
+--------------------------
+
+* A new ``COMPILE_LANG_AND_ID`` generator expression was introduced to
+ allow specification of compile options for target files based on the
+ :variable:`CMAKE_<LANG>_COMPILER_ID` and :prop_sf:`LANGUAGE` and of
+ each source file.
diff --git a/Help/release/dev/swift-support.rst b/Help/release/dev/swift-support.rst
new file mode 100644
index 0000000..49784e2
--- /dev/null
+++ b/Help/release/dev/swift-support.rst
@@ -0,0 +1,23 @@
+Swift Language Support
+----------------------
+
+* Preliminary support for the Swift language with the :generator:`Ninja`
+ generator was added. Use the :envvar:`SWIFTC` environment variable to
+ specify a compiler.
+
+* Support to emit an output file map was added to enable Swift compilation.
+
+* A target property :prop_tgt:`Swift_DEPENDENCIES_FILE` was added to targets to
+ indicate where to save the target swift dependencies file. If one is not
+ specified, it will default to `<TARGET>.swiftdeps`.
+
+* A target property :prop_tgt:`Swift_MODULE_NAME` was added to targets to
+ indicate the Swift module name. If it is not specified, it will default to
+ the name of the target.
+
+* A source property :prop_sf:`Swift_DEPENDENCIES_FILE` was added to sources to
+ indicate where to save the target swift dependencies file. If one is not
+ specified, it will default to `<OBJECT>.swiftdeps`.
+
+* A source property :prop_sf:`Swift_DIAGNOSTICS_FILE` was added to sources to
+ indicate where to write the serialised Swift diagnostics.
diff --git a/Help/variable/CMAKE_Swift_MODULE_DIRECTORY.rst b/Help/variable/CMAKE_Swift_MODULE_DIRECTORY.rst
new file mode 100644
index 0000000..b11253b
--- /dev/null
+++ b/Help/variable/CMAKE_Swift_MODULE_DIRECTORY.rst
@@ -0,0 +1,8 @@
+CMAKE_Swift_MODULE_DIRECTORY
+----------------------------
+
+Swift module output directory.
+
+This variable is used to initialise the :prop_tgt:`Swift_MODULE_DIRECTORY`
+property on all the targets. See the target property for additional
+information.
diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake
index 1cd919a..7036b93 100644
--- a/Modules/CMakeDetermineCompilerId.cmake
+++ b/Modules/CMakeDetermineCompilerId.cmake
@@ -46,6 +46,14 @@ function(CMAKE_DETERMINE_COMPILER_ID lang flagvar src)
endif()
endforeach()
+ # Check if compiler id detection gave us the compiler tool.
+ if(CMAKE_${lang}_COMPILER_ID_TOOL)
+ set(CMAKE_${lang}_COMPILER "${CMAKE_${lang}_COMPILER_ID_TOOL}")
+ set(CMAKE_${lang}_COMPILER "${CMAKE_${lang}_COMPILER_ID_TOOL}" PARENT_SCOPE)
+ elseif(NOT CMAKE_${lang}_COMPILER)
+ set(CMAKE_${lang}_COMPILER "CMAKE_${lang}_COMPILER-NOTFOUND" PARENT_SCOPE)
+ endif()
+
# If the compiler is still unknown, try to query its vendor.
if(CMAKE_${lang}_COMPILER AND NOT CMAKE_${lang}_COMPILER_ID)
foreach(userflags "${CMAKE_${lang}_COMPILER_ID_FLAGS_LIST}" "")
@@ -76,6 +84,30 @@ function(CMAKE_DETERMINE_COMPILER_ID lang flagvar src)
endif()
endif()
+ # For Swift we need to explicitly query the version.
+ if(lang STREQUAL "Swift"
+ AND CMAKE_${lang}_COMPILER
+ AND NOT CMAKE_${lang}_COMPILER_VERSION)
+ execute_process(
+ COMMAND "${CMAKE_${lang}_COMPILER}"
+ -version
+ OUTPUT_VARIABLE output ERROR_VARIABLE output
+ RESULT_VARIABLE result
+ TIMEOUT 10
+ )
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "Running the ${lang} compiler: \"${CMAKE_${lang}_COMPILER}\" -version\n"
+ "${output}\n"
+ )
+
+ if(output MATCHES [[Swift version ([0-9]+\.[0-9]+(\.[0-9]+)?)]])
+ set(CMAKE_${lang}_COMPILER_VERSION "${CMAKE_MATCH_1}")
+ if(NOT CMAKE_${lang}_COMPILER_ID)
+ set(CMAKE_Swift_COMPILER_ID "Apple")
+ endif()
+ endif()
+ endif()
+
if (COMPILER_QNXNTO AND CMAKE_${lang}_COMPILER_ID STREQUAL "GNU")
execute_process(
COMMAND "${CMAKE_${lang}_COMPILER}"
@@ -124,13 +156,6 @@ function(CMAKE_DETERMINE_COMPILER_ID lang flagvar src)
message(STATUS "The ${lang} compiler identification is unknown")
endif()
- # Check if compiler id detection gave us the compiler tool.
- if(CMAKE_${lang}_COMPILER_ID_TOOL)
- set(CMAKE_${lang}_COMPILER "${CMAKE_${lang}_COMPILER_ID_TOOL}" PARENT_SCOPE)
- elseif(NOT CMAKE_${lang}_COMPILER)
- set(CMAKE_${lang}_COMPILER "CMAKE_${lang}_COMPILER-NOTFOUND" PARENT_SCOPE)
- endif()
-
set(CMAKE_${lang}_COMPILER_ID "${CMAKE_${lang}_COMPILER_ID}" PARENT_SCOPE)
set(CMAKE_${lang}_PLATFORM_ID "${CMAKE_${lang}_PLATFORM_ID}" PARENT_SCOPE)
set(CMAKE_${lang}_COMPILER_ARCHITECTURE_ID "${CMAKE_${lang}_COMPILER_ARCHITECTURE_ID}" PARENT_SCOPE)
diff --git a/Modules/CMakeDetermineSwiftCompiler.cmake b/Modules/CMakeDetermineSwiftCompiler.cmake
index dd02d54..2fcf7b0 100644
--- a/Modules/CMakeDetermineSwiftCompiler.cmake
+++ b/Modules/CMakeDetermineSwiftCompiler.cmake
@@ -1,15 +1,46 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
-
include(${CMAKE_ROOT}/Modules/CMakeDetermineCompiler.cmake)
+# Local system-specific compiler preferences for this language.
+include(Platform/${CMAKE_SYSTEM_NAME}-Determine-Swift OPTIONAL)
+include(Platform/${CMAKE_SYSTEM_NAME}-Swift OPTIONAL)
+if(NOT CMAKE_Swift_COMPILER_NAMES)
+ set(CMAKE_Swift_COMPILER_NAMES swiftc)
+endif()
+
if("${CMAKE_GENERATOR}" STREQUAL "Xcode")
if(XCODE_VERSION VERSION_LESS 6.1)
message(FATAL_ERROR "Swift language not supported by Xcode ${XCODE_VERSION}")
endif()
set(CMAKE_Swift_COMPILER_XCODE_TYPE sourcecode.swift)
_cmake_find_compiler_path(Swift)
+elseif("${CMAKE_GENERATOR}" STREQUAL "Ninja")
+ if(CMAKE_Swift_COMPILER)
+ _cmake_find_compiler_path(Swift)
+ else()
+ set(CMAKE_Swift_COMPILER_INIT NOTFOUND)
+
+ if(NOT $ENV{SWIFTC} STREQUAL "")
+ get_filename_component(CMAKE_Swift_COMPILER_INIT $ENV{SWIFTC} PROGRAM
+ PROGRAM_ARGS CMAKE_Swift_FLAGS_ENV_INIT)
+ if(CMAKE_Swift_FLAGS_ENV_INIT)
+ set(CMAKE_Swift_COMPILER_ARG1 "${CMAKE_Swift_FLAGS_ENV_INIT}" CACHE
+ STRING "First argument to the Swift compiler")
+ endif()
+ if(NOT EXISTS ${CMAKE_Swift_COMPILER_INIT})
+ message(FATAL_ERROR "Could not find compiler set in environment variable SWIFTC\n$ENV{SWIFTC}.\n${CMAKE_Swift_COMPILER_INIT}")
+ endif()
+ endif()
+
+ if(NOT CMAKE_Swift_COMPILER_INIT)
+ set(CMAKE_Swift_COMPILER_LIST swiftc ${_CMAKE_TOOLCHAIN_PREFIX}swiftc)
+ endif()
+
+ _cmake_find_compiler(Swift)
+ endif()
+ mark_as_advanced(CMAKE_Swift_COMPILER)
else()
message(FATAL_ERROR "Swift language not supported by \"${CMAKE_GENERATOR}\" generator")
endif()
@@ -18,11 +49,13 @@ endif()
if(NOT CMAKE_Swift_COMPILER_ID_RUN)
set(CMAKE_Swift_COMPILER_ID_RUN 1)
- list(APPEND CMAKE_Swift_COMPILER_ID_MATCH_VENDORS Apple)
- set(CMAKE_Swift_COMPILER_ID_MATCH_VENDOR_REGEX_Apple "com.apple.xcode.tools.swift.compiler")
+ if("${CMAKE_GENERATOR}" STREQUAL "Xcode")
+ list(APPEND CMAKE_Swift_COMPILER_ID_MATCH_VENDORS Apple)
+ set(CMAKE_Swift_COMPILER_ID_MATCH_VENDOR_REGEX_Apple "com.apple.xcode.tools.swift.compiler")
- set(CMAKE_Swift_COMPILER_ID_TOOL_MATCH_REGEX "\nCompileSwiftSources[^\n]*(\n[ \t]+[^\n]*)*\n[ \t]+([^ \t\r\n]+)[^\r\n]* -c[^\r\n]*CompilerIdSwift/CompilerId/main.swift")
- set(CMAKE_Swift_COMPILER_ID_TOOL_MATCH_INDEX 2)
+ set(CMAKE_Swift_COMPILER_ID_TOOL_MATCH_REGEX "\nCompileSwiftSources[^\n]*(\n[ \t]+[^\n]*)*\n[ \t]+([^ \t\r\n]+)[^\r\n]* -c[^\r\n]*CompilerIdSwift/CompilerId/main.swift")
+ set(CMAKE_Swift_COMPILER_ID_TOOL_MATCH_INDEX 2)
+ endif()
# Try to identify the compiler.
set(CMAKE_Swift_COMPILER_ID)
@@ -40,6 +73,6 @@ unset(_CMAKE_PROCESSING_LANGUAGE)
# configure variables set in this file for fast reload later on
configure_file(${CMAKE_ROOT}/Modules/CMakeSwiftCompiler.cmake.in
- ${CMAKE_PLATFORM_INFO_DIR}/CMakeSwiftCompiler.cmake
- @ONLY
- )
+ ${CMAKE_PLATFORM_INFO_DIR}/CMakeSwiftCompiler.cmake @ONLY)
+
+set(CMAKE_Swift_COMPILER_ENV_VAR "SWIFTC")
diff --git a/Modules/CMakeSwiftCompiler.cmake.in b/Modules/CMakeSwiftCompiler.cmake.in
index 45f0a31..7c8d1c1 100644
--- a/Modules/CMakeSwiftCompiler.cmake.in
+++ b/Modules/CMakeSwiftCompiler.cmake.in
@@ -1,5 +1,14 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
set(CMAKE_Swift_COMPILER "@CMAKE_Swift_COMPILER@")
set(CMAKE_Swift_COMPILER_ID "@CMAKE_Swift_COMPILER_ID@")
+set(CMAKE_Swift_COMPILER_VERSION "@CMAKE_Swift_COMPILER_VERSION@")
+
+set(CMAKE_Swift_COMPILER_LOADED 1)
+set(CMAKE_Swift_COMPILER_WORKS "@CMAKE_Swift_COMPILER_WORKS@")
+
+set(CMAKE_Swift_COMPILER_ENV_VAR "SWIFTC")
set(CMAKE_Swift_COMPILER_ID_RUN 1)
set(CMAKE_Swift_SOURCE_FILE_EXTENSIONS swift)
diff --git a/Modules/CMakeSwiftInformation.cmake b/Modules/CMakeSwiftInformation.cmake
index 07ba6d0..64e7f99 100644
--- a/Modules/CMakeSwiftInformation.cmake
+++ b/Modules/CMakeSwiftInformation.cmake
@@ -1,32 +1,61 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
-
-set(CMAKE_Swift_OUTPUT_EXTENSION .o)
-set(CMAKE_INCLUDE_FLAG_Swift "-I")
+if(UNIX)
+ set(CMAKE_Swift_OUTPUT_EXTENSION .o)
+else()
+ set(CMAKE_Swift_OUTPUT_EXTENSION .obj)
+endif()
# Load compiler-specific information.
if(CMAKE_Swift_COMPILER_ID)
include(Compiler/${CMAKE_Swift_COMPILER_ID}-Swift OPTIONAL)
-endif()
-# load the system- and compiler specific files
-if(CMAKE_Swift_COMPILER_ID)
- # load a hardware specific file, mostly useful for embedded compilers
if(CMAKE_SYSTEM_PROCESSOR)
include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_Swift_COMPILER_ID}-Swift-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL)
endif()
include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_Swift_COMPILER_ID}-Swift OPTIONAL)
endif()
-# for most systems a module is the same as a shared library
-# so unless the variable CMAKE_MODULE_EXISTS is set just
-# copy the values from the LIBRARY variables
-if(NOT CMAKE_MODULE_EXISTS)
- set(CMAKE_SHARED_MODULE_Swift_FLAGS ${CMAKE_SHARED_LIBRARY_Swift_FLAGS})
- set(CMAKE_SHARED_MODULE_CREATE_Swift_FLAGS ${CMAKE_SHARED_LIBRARY_CREATE_Swift_FLAGS})
+set(CMAKE_INCLUDE_FLAG_Swift "-I")
+set(CMAKE_INCLUDE_FLAG_SEP_Swift " ")
+set(CMAKE_Swift_DEFINE_FLAG -D)
+set(CMAKE_Swift_COMPILE_OPTIONS_TARGET "-target ")
+set(CMAKE_Swift_COMPILER_ARG1 -frontend)
+
+set(CMAKE_Swift_FLAGS_DEBUG_INIT "-g")
+set(CMAKE_Swift_FLAGS_RELEASE_INIT "-O")
+set(CMAKE_Swift_FLAGS_RELWITHDEBINFO_INIT "-O -g")
+set(CMAKE_Swift_FLAGS_MINSIZEREL_INIT "-Osize")
+
+# NOTE(compnerd) we do not have an object compile rule since we build the objects as part of the link step
+if(NOT CMAKE_Swift_COMPILE_OBJECT)
+ set(CMAKE_Swift_COMPILE_OBJECT ":")
endif()
-include(CMakeCommonLanguageInclude)
+if(NOT CMAKE_Swift_CREATE_SHARED_LIBRARY)
+ if(CMAKE_Swift_COMPILER_TARGET)
+ set(CMAKE_Swift_CREATE_SHARED_LIBRARY "${CMAKE_Swift_COMPILER} -target <CMAKE_Swift_COMPILER_TARGET> -output-file-map <SWIFT_OUTPUT_FILE_MAP> -incremental -emit-library -o <TARGET> -module-name <SWIFT_MODULE_NAME> -module-link-name <SWIFT_LIBRARY_NAME> -emit-module -emit-module-path <SWIFT_MODULE> -emit-dependencies <FLAGS> <SWIFT_SOURCES> <LINK_FLAGS> <LINK_LIBRARIES>")
+ else()
+ set(CMAKE_Swift_CREATE_SHARED_LIBRARY "${CMAKE_Swift_COMPILER} -output-file-map <SWIFT_OUTPUT_FILE_MAP> -incremental -emit-library -o <TARGET> -module-name <SWIFT_MODULE_NAME> -module-link-name <SWIFT_LIBRARY_NAME> -emit-module -emit-module-path <SWIFT_MODULE> -emit-dependencies <FLAGS> <SWIFT_SOURCES> <LINK_FLAGS> <LINK_LIBRARIES>")
+ endif()
+endif()
+
+if(NOT CMAKE_Swift_CREATE_SHARED_MODULE)
+ set(CMAKE_Swift_CREATE_SHARED_MODULE ${CMAKE_Swift_CREATE_SHARED_LIBRARY})
+endif()
+
+if(NOT CMAKE_Swift_LINK_EXECUTABLE)
+ if(CMAKE_Swift_COMPILER_TARGET)
+ set(CMAKE_Swift_LINK_EXECUTABLE "${CMAKE_Swift_COMPILER} -target <CMAKE_Swift_COMPILER_TARGET> -output-file-map <SWIFT_OUTPUT_FILE_MAP> -incremental -emit-executable -o <TARGET> -emit-module -emit-module-path <SWIFT_MODULE> -emit-dependencies <FLAGS> <SWIFT_SOURCES> <LINK_FLAGS> <LINK_LIBRARIES>")
+ else()
+ set(CMAKE_Swift_LINK_EXECUTABLE "${CMAKE_Swift_COMPILER} -output-file-map <SWIFT_OUTPUT_FILE_MAP> -incremental -emit-executable -o <TARGET> -emit-module -emit-module-path <SWIFT_MODULE> -emit-dependencies <FLAGS> <SWIFT_SOURCES> <LINK_FLAGS> <LINK_LIBRARIES>")
+ endif()
+endif()
+
+if(NOT CMAKE_Swift_CREATE_STATIC_LIBRARY)
+ set(CMAKE_Swift_ARCHIVE_CREATE "<CMAKE_AR> crs <TARGET> <OBJECTS>")
+ set(CMAKE_Swift_ARCHIVE_FINISH "")
+endif()
set(CMAKE_Swift_INFORMATION_LOADED 1)
diff --git a/Modules/CMakeTestSwiftCompiler.cmake b/Modules/CMakeTestSwiftCompiler.cmake
index 858c1be..841aee6 100644
--- a/Modules/CMakeTestSwiftCompiler.cmake
+++ b/Modules/CMakeTestSwiftCompiler.cmake
@@ -1,7 +1,6 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
-
if(CMAKE_Swift_COMPILER_FORCED)
# The compiler configuration was forced by the user.
# Assume the user has configured all compiler information.
@@ -23,7 +22,6 @@ unset(CMAKE_Swift_COMPILER_WORKS CACHE)
if(NOT CMAKE_Swift_COMPILER_WORKS)
PrintTestCompilerStatus("Swift" "")
file(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/main.swift
- "import Foundation\n"
"print(\"CMake\")\n")
try_compile(CMAKE_Swift_COMPILER_WORKS ${CMAKE_BINARY_DIR}
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/main.swift
@@ -51,6 +49,11 @@ else()
"Determining if the Swift compiler works passed with "
"the following output:\n${__CMAKE_Swift_COMPILER_OUTPUT}\n\n")
endif()
+
+ # Re-configure to save learned information.
+ configure_file(${CMAKE_ROOT}/Modules/CMakeSwiftCompiler.cmake.in
+ ${CMAKE_PLATFORM_INFO_DIR}/CMakeSwiftCompiler.cmake @ONLY)
+ include(${CMAKE_PLATFORM_INFO_DIR}/CMakeSwiftCompiler.cmake)
endif()
unset(__CMAKE_Swift_COMPILER_OUTPUT)
diff --git a/Modules/FindBLAS.cmake b/Modules/FindBLAS.cmake
index 8d55ac7..65e5d1c 100644
--- a/Modules/FindBLAS.cmake
+++ b/Modules/FindBLAS.cmake
@@ -403,20 +403,19 @@ if (BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All")
endif ()
if (DEFINED ENV{MKLROOT})
- set(_BLAS_MKLROOT_LIB_DIR "$ENV{MKLROOT}")
+ if (BLA_VENDOR STREQUAL "Intel10_32")
+ set(_BLAS_MKLROOT_LIB_DIR "$ENV{MKLROOT}/lib/ia32")
+ elseif (BLA_VENDOR MATCHES "^Intel10_64i?lp$" OR BLA_VENDOR MATCHES "^Intel10_64i?lp_seq$")
+ set(_BLAS_MKLROOT_LIB_DIR "$ENV{MKLROOT}/lib/intel64")
+ endif ()
endif ()
if (_BLAS_MKLROOT_LIB_DIR)
- if( SIZEOF_INTEGER EQUAL 8 )
- set( _BLAS_MKL_PATH_PREFIX "intel64" )
- else()
- set( _BLAS_MKL_PATH_PREFIX "ia32" )
- endif()
if (WIN32)
- string(APPEND _BLAS_MKLROOT_LIB_DIR "/lib/${_BLAS_MKL_PATH_PREFIX}_win")
+ string(APPEND _BLAS_MKLROOT_LIB_DIR "_win")
elseif (APPLE)
- string(APPEND _BLAS_MKLROOT_LIB_DIR "/lib/${_BLAS_MKL_PATH_PREFIX}_mac")
+ string(APPEND _BLAS_MKLROOT_LIB_DIR "_mac")
else ()
- string(APPEND _BLAS_MKLROOT_LIB_DIR "/lib/${_BLAS_MKL_PATH_PREFIX}_lin")
+ string(APPEND _BLAS_MKLROOT_LIB_DIR "_lin")
endif ()
endif ()
diff --git a/Modules/FindDoxygen.cmake b/Modules/FindDoxygen.cmake
index 32b4aa2..ebd0b24 100644
--- a/Modules/FindDoxygen.cmake
+++ b/Modules/FindDoxygen.cmake
@@ -974,7 +974,7 @@ doxygen_add_docs() for target ${targetName}")
"${DOXYGEN_OUTPUT_DIRECTORY}/${DOXYGEN_HTML_OUTPUT}")
endif()
set_property(DIRECTORY APPEND PROPERTY
- ADDITIONAL_MAKE_CLEAN_FILES "${_args_clean_html_dir}")
+ ADDITIONAL_CLEAN_FILES "${_args_clean_html_dir}")
endif()
# Build up a list of files we can identify from the inputs so we can list
diff --git a/Modules/FindPNG.cmake b/Modules/FindPNG.cmake
index 2208b48..a7908c5 100644
--- a/Modules/FindPNG.cmake
+++ b/Modules/FindPNG.cmake
@@ -100,13 +100,14 @@ if(ZLIB_FOUND)
# No need to define PNG_USE_DLL here, because it's default for Cygwin.
else()
set (PNG_DEFINITIONS -DPNG_STATIC)
+ set(_PNG_COMPILE_DEFINITIONS PNG_STATIC)
endif()
endif ()
if(NOT TARGET PNG::PNG)
add_library(PNG::PNG UNKNOWN IMPORTED)
set_target_properties(PNG::PNG PROPERTIES
- INTERFACE_COMPILE_DEFINITIONS "${PNG_DEFINITIONS}"
+ INTERFACE_COMPILE_DEFINITIONS "${_PNG_COMPILE_DEFINITIONS}"
INTERFACE_INCLUDE_DIRECTORIES "${PNG_INCLUDE_DIRS}"
INTERFACE_LINK_LIBRARIES ZLIB::ZLIB)
if(EXISTS "${PNG_LIBRARY}")
@@ -129,6 +130,8 @@ if(ZLIB_FOUND)
IMPORTED_LOCATION_DEBUG "${PNG_LIBRARY_DEBUG}")
endif()
endif()
+
+ unset(_PNG_COMPILE_DEFINITIONS)
endif ()
if (PNG_PNG_INCLUDE_DIR AND EXISTS "${PNG_PNG_INCLUDE_DIR}/png.h")
diff --git a/Modules/UseEcos.cmake b/Modules/UseEcos.cmake
index 1e82f16..60324b1 100644
--- a/Modules/UseEcos.cmake
+++ b/Modules/UseEcos.cmake
@@ -214,10 +214,10 @@ macro(ECOS_ADD_EXECUTABLE _exe_NAME )
)
#add the created files to the clean-files
- set_directory_properties(
- PROPERTIES
- ADDITIONAL_MAKE_CLEAN_FILES "${CMAKE_CURRENT_BINARY_DIR}/${_exe_NAME}.bin;${CMAKE_CURRENT_BINARY_DIR}/${_exe_NAME}.srec;${CMAKE_CURRENT_BINARY_DIR}/${_exe_NAME}.lst;"
- )
+ set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_CLEAN_FILES
+ "${CMAKE_CURRENT_BINARY_DIR}/${_exe_NAME}.bin"
+ "${CMAKE_CURRENT_BINARY_DIR}/${_exe_NAME}.srec"
+ "${CMAKE_CURRENT_BINARY_DIR}/${_exe_NAME}.lst")
add_custom_target(ecosclean ${CMAKE_COMMAND} -DECOS_DIR=${CMAKE_CURRENT_BINARY_DIR}/ecos/ -P ${ECOS_CMAKE_MODULE_DIR}/ecos_clean.cmake )
add_custom_target(normalclean ${CMAKE_MAKE_PROGRAM} clean WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
diff --git a/Modules/UseJava.cmake b/Modules/UseJava.cmake
index b0315b2..0798488 100644
--- a/Modules/UseJava.cmake
+++ b/Modules/UseJava.cmake
@@ -735,7 +735,8 @@ function(add_jar _TARGET_NAME)
# this INTERFACE library depends on jar generation
add_dependencies (${_GENERATE_NATIVE_HEADERS_TARGET} ${_TARGET_NAME})
- set_property (DIRECTORY PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${_GENERATE_NATIVE_HEADERS_OUTPUT_DIR}")
+ set_property (DIRECTORY APPEND PROPERTY ADDITIONAL_CLEAN_FILES
+ "${_GENERATE_NATIVE_HEADERS_OUTPUT_DIR}")
endif()
endfunction()
diff --git a/Modules/UseSWIG.cmake b/Modules/UseSWIG.cmake
index c136b05..78522da 100644
--- a/Modules/UseSWIG.cmake
+++ b/Modules/UseSWIG.cmake
@@ -708,9 +708,9 @@ function(SWIG_ADD_LIBRARY name)
endif()
endforeach()
set_property (DIRECTORY APPEND PROPERTY
- ADDITIONAL_MAKE_CLEAN_FILES ${swig_generated_sources} ${swig_generated_timestamps})
+ ADDITIONAL_CLEAN_FILES ${swig_generated_sources} ${swig_generated_timestamps})
if (UseSWIG_MODULE_VERSION VERSION_GREATER 1)
- set_property (DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${outputdir}")
+ set_property (DIRECTORY APPEND PROPERTY ADDITIONAL_CLEAN_FILES "${outputdir}")
endif()
add_library(${target_name}
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 8c3fa94..4303c25 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 14)
-set(CMake_VERSION_PATCH 20190516)
+set(CMake_VERSION_PATCH 20190521)
#set(CMake_VERSION_RC 1)
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index 2f62db1..f12ef0b 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -122,8 +122,8 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
}
}
- const char* sourceDirectory = argv[2].c_str();
- const char* projectName = nullptr;
+ std::string sourceDirectory = argv[2];
+ std::string projectName;
std::string targetName;
std::vector<std::string> cmakeFlags(1, "CMAKE_FLAGS"); // fake argv[0]
std::vector<std::string> compileDefs;
@@ -309,7 +309,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
doing = DoingNone;
} else if (i == 3) {
this->SrcFileSignature = false;
- projectName = argv[i].c_str();
+ projectName = argv[i];
} else if (i == 4 && !this->SrcFileSignature) {
targetName = argv[i];
} else {
@@ -480,7 +480,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
// we need to create a directory and CMakeLists file etc...
// first create the directories
- sourceDirectory = this->BinaryDirectory.c_str();
+ sourceDirectory = this->BinaryDirectory;
// now create a CMakeLists.txt file in that directory
FILE* fout = cmsys::SystemTools::Fopen(outFileName, "w");
@@ -950,7 +950,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
<< " '" << copyFile << "'\n";
/* clang-format on */
if (!this->FindErrorMessage.empty()) {
- emsg << this->FindErrorMessage.c_str();
+ emsg << this->FindErrorMessage;
}
if (copyFileError.empty()) {
this->Makefile->IssueMessage(MessageType::FATAL_ERROR, emsg.str());
diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx
index 93ff8f4..c6e44e3 100644
--- a/Source/cmExtraCodeBlocksGenerator.cxx
+++ b/Source/cmExtraCodeBlocksGenerator.cxx
@@ -280,8 +280,7 @@ void cmExtraCodeBlocksGenerator::CreateNewProjectFile(
xml.StartElement("Build");
- this->AppendTarget(xml, "all", nullptr, make.c_str(), lgs[0],
- compiler.c_str(), makeArgs);
+ this->AppendTarget(xml, "all", nullptr, make, lgs[0], compiler, makeArgs);
// add all executable and library targets and some of the GLOBAL
// and UTILITY targets
@@ -294,8 +293,8 @@ void cmExtraCodeBlocksGenerator::CreateNewProjectFile(
// Only add the global targets from CMAKE_BINARY_DIR,
// not from the subdirs
if (lg->GetCurrentBinaryDirectory() == lg->GetBinaryDirectory()) {
- this->AppendTarget(xml, targetName, nullptr, make.c_str(), lg,
- compiler.c_str(), makeArgs);
+ this->AppendTarget(xml, targetName, nullptr, make, lg, compiler,
+ makeArgs);
}
} break;
case cmStateEnums::UTILITY:
@@ -310,8 +309,8 @@ void cmExtraCodeBlocksGenerator::CreateNewProjectFile(
break;
}
- this->AppendTarget(xml, targetName, nullptr, make.c_str(), lg,
- compiler.c_str(), makeArgs);
+ this->AppendTarget(xml, targetName, nullptr, make, lg, compiler,
+ makeArgs);
break;
case cmStateEnums::EXECUTABLE:
case cmStateEnums::STATIC_LIBRARY:
@@ -319,12 +318,12 @@ void cmExtraCodeBlocksGenerator::CreateNewProjectFile(
case cmStateEnums::MODULE_LIBRARY:
case cmStateEnums::OBJECT_LIBRARY: {
cmGeneratorTarget* gt = target;
- this->AppendTarget(xml, targetName, gt, make.c_str(), lg,
- compiler.c_str(), makeArgs);
+ this->AppendTarget(xml, targetName, gt, make, lg, compiler,
+ makeArgs);
std::string fastTarget = targetName;
fastTarget += "/fast";
- this->AppendTarget(xml, fastTarget, gt, make.c_str(), lg,
- compiler.c_str(), makeArgs);
+ this->AppendTarget(xml, fastTarget, gt, make, lg, compiler,
+ makeArgs);
} break;
default:
break;
@@ -378,7 +377,7 @@ void cmExtraCodeBlocksGenerator::CreateNewProjectFile(
std::string const& fullPath = s->GetFullPath();
// Check file position relative to project root dir.
- const std::string& relative =
+ const std::string relative =
cmSystemTools::RelativePath(lg->GetSourceDirectory(), fullPath);
// Do not add this file if it has ".." in relative path and
// if CMAKE_CODEBLOCKS_EXCLUDE_EXTERNAL_FILES variable is on.
@@ -454,7 +453,7 @@ void cmExtraCodeBlocksGenerator::CreateNewProjectFile(
}
// Add CMakeLists.txt
- tree.BuildUnit(xml, std::string(mf->GetHomeDirectory()) + "/");
+ tree.BuildUnit(xml, mf->GetHomeDirectory() + "/");
xml.EndElement(); // Project
xml.EndElement(); // CodeBlocks_project_file
@@ -489,8 +488,8 @@ std::string cmExtraCodeBlocksGenerator::CreateDummyTargetFile(
// Generate the xml code for one target.
void cmExtraCodeBlocksGenerator::AppendTarget(
cmXMLWriter& xml, const std::string& targetName, cmGeneratorTarget* target,
- const char* make, const cmLocalGenerator* lg, const char* compiler,
- const std::string& makeFlags)
+ const std::string& make, const cmLocalGenerator* lg,
+ const std::string& compiler, const std::string& makeFlags)
{
cmMakefile const* makefile = lg->GetMakefile();
std::string makefileName = lg->GetCurrentBinaryDirectory();
@@ -613,25 +612,23 @@ void cmExtraCodeBlocksGenerator::AppendTarget(
xml.StartElement("Build");
xml.Attribute(
"command",
- this->BuildMakeCommand(make, makefileName.c_str(), targetName, makeFlags));
+ this->BuildMakeCommand(make, makefileName, targetName, makeFlags));
xml.EndElement();
xml.StartElement("CompileFile");
- xml.Attribute("command",
- this->BuildMakeCommand(make, makefileName.c_str(), "\"$file\"",
- makeFlags));
+ xml.Attribute(
+ "command",
+ this->BuildMakeCommand(make, makefileName, "\"$file\"", makeFlags));
xml.EndElement();
xml.StartElement("Clean");
xml.Attribute(
- "command",
- this->BuildMakeCommand(make, makefileName.c_str(), "clean", makeFlags));
+ "command", this->BuildMakeCommand(make, makefileName, "clean", makeFlags));
xml.EndElement();
xml.StartElement("DistClean");
xml.Attribute(
- "command",
- this->BuildMakeCommand(make, makefileName.c_str(), "clean", makeFlags));
+ "command", this->BuildMakeCommand(make, makefileName, "clean", makeFlags));
xml.EndElement();
xml.EndElement(); // MakeCommands
@@ -725,8 +722,8 @@ int cmExtraCodeBlocksGenerator::GetCBTargetType(cmGeneratorTarget* target)
// Create the command line for building the given target using the selected
// make
std::string cmExtraCodeBlocksGenerator::BuildMakeCommand(
- const std::string& make, const char* makefile, const std::string& target,
- const std::string& makeFlags)
+ const std::string& make, const std::string& makefile,
+ const std::string& target, const std::string& makeFlags)
{
std::string command = make;
if (!makeFlags.empty()) {
@@ -747,7 +744,7 @@ std::string cmExtraCodeBlocksGenerator::BuildMakeCommand(
} else if (generator == "MinGW Makefiles") {
// no escaping of spaces in this case, see
// https://gitlab.kitware.com/cmake/cmake/issues/10014
- std::string makefileName = makefile;
+ std::string const& makefileName = makefile;
command += " -f \"";
command += makefileName;
command += "\" ";
diff --git a/Source/cmExtraCodeBlocksGenerator.h b/Source/cmExtraCodeBlocksGenerator.h
index be3af25..173e284 100644
--- a/Source/cmExtraCodeBlocksGenerator.h
+++ b/Source/cmExtraCodeBlocksGenerator.h
@@ -42,12 +42,13 @@ private:
std::string GetCBCompilerId(const cmMakefile* mf);
int GetCBTargetType(cmGeneratorTarget* target);
- std::string BuildMakeCommand(const std::string& make, const char* makefile,
+ std::string BuildMakeCommand(const std::string& make,
+ const std::string& makefile,
const std::string& target,
const std::string& makeFlags);
void AppendTarget(cmXMLWriter& xml, const std::string& targetName,
- cmGeneratorTarget* target, const char* make,
- const cmLocalGenerator* lg, const char* compiler,
+ cmGeneratorTarget* target, const std::string& make,
+ const cmLocalGenerator* lg, const std::string& compiler,
const std::string& makeFlags);
};
diff --git a/Source/cmFileCopier.cxx b/Source/cmFileCopier.cxx
index 8913e6d..972cd6e 100644
--- a/Source/cmFileCopier.cxx
+++ b/Source/cmFileCopier.cxx
@@ -31,6 +31,7 @@ cmFileCopier::cmFileCopier(cmFileCommand* command, const char* name)
, UseGivenPermissionsFile(false)
, UseGivenPermissionsDir(false)
, UseSourcePermissions(true)
+ , FollowSymlinkChain(false)
, Doing(DoingNone)
{
}
@@ -249,6 +250,9 @@ bool cmFileCopier::CheckKeyword(std::string const& arg)
this->Doing = DoingPattern;
} else if (arg == "REGEX") {
this->Doing = DoingRegex;
+ } else if (arg == "FOLLOW_SYMLINK_CHAIN") {
+ this->FollowSymlinkChain = true;
+ this->Doing = DoingNone;
} else if (arg == "EXCLUDE") {
// Add this property to the current match rule.
if (this->CurrentMatchRule) {
@@ -464,16 +468,69 @@ bool cmFileCopier::Install(const std::string& fromFile,
if (cmSystemTools::SameFile(fromFile, toFile)) {
return true;
}
- if (cmSystemTools::FileIsSymlink(fromFile)) {
- return this->InstallSymlink(fromFile, toFile);
+
+ std::string newFromFile = fromFile;
+ std::string newToFile = toFile;
+
+ if (this->FollowSymlinkChain &&
+ !this->InstallSymlinkChain(newFromFile, newToFile)) {
+ return false;
}
- if (cmSystemTools::FileIsDirectory(fromFile)) {
- return this->InstallDirectory(fromFile, toFile, match_properties);
+
+ if (cmSystemTools::FileIsSymlink(newFromFile)) {
+ return this->InstallSymlink(newFromFile, newToFile);
}
- if (cmSystemTools::FileExists(fromFile)) {
- return this->InstallFile(fromFile, toFile, match_properties);
+ if (cmSystemTools::FileIsDirectory(newFromFile)) {
+ return this->InstallDirectory(newFromFile, newToFile, match_properties);
}
- return this->ReportMissing(fromFile);
+ if (cmSystemTools::FileExists(newFromFile)) {
+ return this->InstallFile(newFromFile, newToFile, match_properties);
+ }
+ return this->ReportMissing(newFromFile);
+}
+
+bool cmFileCopier::InstallSymlinkChain(std::string& fromFile,
+ std::string& toFile)
+{
+ std::string newFromFile;
+ std::string toFilePath = cmSystemTools::GetFilenamePath(toFile);
+ while (cmSystemTools::ReadSymlink(fromFile, newFromFile)) {
+ if (!cmSystemTools::FileIsFullPath(newFromFile)) {
+ std::string fromFilePath = cmSystemTools::GetFilenamePath(fromFile);
+ newFromFile = fromFilePath + "/" + newFromFile;
+ }
+
+ std::string symlinkTarget = cmSystemTools::GetFilenameName(newFromFile);
+
+ bool copy = true;
+ if (!this->Always) {
+ std::string oldSymlinkTarget;
+ if (cmSystemTools::ReadSymlink(toFile, oldSymlinkTarget)) {
+ if (symlinkTarget == oldSymlinkTarget) {
+ copy = false;
+ }
+ }
+ }
+
+ this->ReportCopy(toFile, TypeLink, copy);
+
+ if (copy) {
+ cmSystemTools::RemoveFile(toFile);
+ cmSystemTools::MakeDirectory(toFilePath);
+
+ if (!cmSystemTools::CreateSymlink(symlinkTarget, toFile)) {
+ std::ostringstream e;
+ e << this->Name << " cannot create symlink \"" << toFile << "\".";
+ this->FileCommand->SetError(e.str());
+ return false;
+ }
+ }
+
+ fromFile = newFromFile;
+ toFile = toFilePath + "/" + symlinkTarget;
+ }
+
+ return true;
}
bool cmFileCopier::InstallSymlink(const std::string& fromFile,
diff --git a/Source/cmFileCopier.h b/Source/cmFileCopier.h
index 003b8f6..a79a60b 100644
--- a/Source/cmFileCopier.h
+++ b/Source/cmFileCopier.h
@@ -64,6 +64,7 @@ protected:
// Translate an argument to a permissions bit.
bool CheckPermissions(std::string const& arg, mode_t& permissions);
+ bool InstallSymlinkChain(std::string& fromFile, std::string& toFile);
bool InstallSymlink(const std::string& fromFile, const std::string& toFile);
bool InstallFile(const std::string& fromFile, const std::string& toFile,
MatchProperties match_properties);
@@ -86,6 +87,7 @@ protected:
bool UseGivenPermissionsFile;
bool UseGivenPermissionsDir;
bool UseSourcePermissions;
+ bool FollowSymlinkChain;
std::string Destination;
std::string FilesFromDir;
std::vector<std::string> Files;
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index 8c6fb34..709355a 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -981,6 +981,51 @@ static const struct CompileLanguageNode : public cmGeneratorExpressionNode
}
} languageNode;
+static const struct CompileLanguageAndIdNode : public cmGeneratorExpressionNode
+{
+ CompileLanguageAndIdNode() {} // NOLINT(modernize-use-equals-default)
+
+ int NumExpectedParameters() const override { return 2; }
+
+ std::string Evaluate(
+ const std::vector<std::string>& parameters,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* content,
+ cmGeneratorExpressionDAGChecker* dagChecker) const override
+ {
+ if (!context->HeadTarget || context->Language.empty()) {
+ // reportError(context, content->GetOriginalExpression(), "");
+ reportError(
+ context, content->GetOriginalExpression(),
+ "$<COMPILE_LANG_AND_ID:lang,id> may only be used with binary targets "
+ "to specify include directories, compile definitions, and compile "
+ "options. It may not be used with the add_custom_command, "
+ "add_custom_target, or file(GENERATE) commands.");
+ return std::string();
+ }
+ cmGlobalGenerator* gg = context->LG->GetGlobalGenerator();
+ std::string genName = gg->GetName();
+ if (genName.find("Makefiles") == std::string::npos &&
+ genName.find("Ninja") == std::string::npos &&
+ genName.find("Visual Studio") == std::string::npos &&
+ genName.find("Xcode") == std::string::npos &&
+ genName.find("Watcom WMake") == std::string::npos) {
+ reportError(
+ context, content->GetOriginalExpression(),
+ "$<COMPILE_LANG_AND_ID:lang,id> not supported for this generator.");
+ return std::string();
+ }
+
+ const std::string& lang = context->Language;
+ if (lang == parameters.front()) {
+ std::vector<std::string> idParameter = { parameters[1] };
+ return CompilerIdNode{ lang.c_str() }.EvaluateWithLanguage(
+ idParameter, context, content, dagChecker, lang);
+ }
+ return "0";
+ }
+} languageAndIdNode;
+
#define TRANSITIVE_PROPERTY_NAME(PROPERTY) , "INTERFACE_" #PROPERTY
static const char* targetPropertyTransitiveWhitelist[] = {
@@ -2285,6 +2330,7 @@ const cmGeneratorExpressionNode* cmGeneratorExpressionNode::GetNode(
{ "INSTALL_PREFIX", &installPrefixNode },
{ "JOIN", &joinNode },
{ "LINK_ONLY", &linkOnlyNode },
+ { "COMPILE_LANG_AND_ID", &languageAndIdNode },
{ "COMPILE_LANGUAGE", &languageNode },
{ "SHELL_PATH", &shellPathNode }
};
diff --git a/Source/cmGlobalMSYSMakefileGenerator.cxx b/Source/cmGlobalMSYSMakefileGenerator.cxx
index 606febe..7b58389 100644
--- a/Source/cmGlobalMSYSMakefileGenerator.cxx
+++ b/Source/cmGlobalMSYSMakefileGenerator.cxx
@@ -48,7 +48,7 @@ void cmGlobalMSYSMakefileGenerator::EnableLanguage(
const std::string& makeProgram =
mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM");
std::vector<std::string> locations;
- std::string makeloc = cmSystemTools::GetProgramPath(makeProgram.c_str());
+ std::string makeloc = cmSystemTools::GetProgramPath(makeProgram);
locations.push_back(this->FindMinGW(makeloc));
locations.push_back(makeloc);
locations.push_back("/mingw/bin");
@@ -77,8 +77,8 @@ void cmGlobalMSYSMakefileGenerator::EnableLanguage(
if (!mf->IsSet("CMAKE_AR") && !this->CMakeInstance->GetIsInTryCompile() &&
!(1 == l.size() && l[0] == "NONE")) {
cmSystemTools::Error(
- "CMAKE_AR was not found, please set to archive program. ",
- mf->GetDefinition("CMAKE_AR"));
+ "CMAKE_AR was not found, please set to archive program. " +
+ mf->GetSafeDefinition("CMAKE_AR"));
}
}
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index 00276f8..5ddaaa3 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -574,7 +574,7 @@ void cmGlobalNinjaGenerator::CheckNinjaFeatures()
static std::string const k_DYNDEP_ = ".dyndep-";
std::string::size_type pos = this->NinjaVersion.find(k_DYNDEP_);
if (pos != std::string::npos) {
- const char* fv = this->NinjaVersion.c_str() + pos + k_DYNDEP_.size();
+ const char* fv = &this->NinjaVersion[pos + k_DYNDEP_.size()];
cmSystemTools::StringToULong(fv, &this->NinjaSupportsDyndeps);
}
}
@@ -1254,7 +1254,7 @@ void cmGlobalNinjaGenerator::WriteUnknownExplicitDependencies(std::ostream& os)
for (std::string const& i : unknownExplicitDepends) {
// verify the file is in the build directory
std::string const absDepPath =
- cmSystemTools::CollapseFullPath(i, rootBuildDirectory.c_str());
+ cmSystemTools::CollapseFullPath(i, rootBuildDirectory);
bool const inBuildDir =
cmSystemTools::IsSubDirectory(absDepPath, rootBuildDirectory);
if (inBuildDir) {
diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx
index 65d816e..8053f61 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.cxx
+++ b/Source/cmGlobalUnixMakefileGenerator3.cxx
@@ -169,7 +169,7 @@ void cmGlobalUnixMakefileGenerator3::AddCXXCompileCommand(
{
if (this->CommandDatabase == nullptr) {
std::string commandDatabaseName =
- std::string(this->GetCMakeInstance()->GetHomeOutputDirectory()) +
+ this->GetCMakeInstance()->GetHomeOutputDirectory() +
"/compile_commands.json";
this->CommandDatabase = new cmGeneratedFileStream(commandDatabaseName);
*this->CommandDatabase << "[" << std::endl;
@@ -232,28 +232,16 @@ void cmGlobalUnixMakefileGenerator3::WriteMainMakefile2()
depends.push_back(this->EmptyRuleHackDepends);
}
- // Write and empty all:
- lg->WriteMakeRule(makefileStream, "The main recursive all target", "all",
- depends, no_commands, true);
-
- // Write an empty preinstall:
- lg->WriteMakeRule(makefileStream, "The main recursive preinstall target",
- "preinstall", depends, no_commands, true);
-
- // Write an empty clean:
- lg->WriteMakeRule(makefileStream, "The main recursive clean target", "clean",
- depends, no_commands, true);
-
// Write out the "special" stuff
lg->WriteSpecialTargetsTop(makefileStream);
- // write the target convenience rules
+ // Write the target convenience rules
for (cmLocalGenerator* localGen : this->LocalGenerators) {
- lg = static_cast<cmLocalUnixMakefileGenerator3*>(localGen);
- this->WriteConvenienceRules2(makefileStream, lg);
+ this->WriteConvenienceRules2(
+ makefileStream, static_cast<cmLocalUnixMakefileGenerator3*>(localGen));
}
- lg = static_cast<cmLocalUnixMakefileGenerator3*>(this->LocalGenerators[0]);
+ // Write special bottom targets
lg->WriteSpecialTargetsBottom(makefileStream);
}
@@ -354,9 +342,7 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile()
{
cmakefileStream << "# Byproducts of CMake generate step:\n"
<< "set(CMAKE_MAKEFILE_PRODUCTS\n";
- const std::vector<std::string>& outfiles =
- lg->GetMakefile()->GetOutputFiles();
- for (std::string const& outfile : outfiles) {
+ for (std::string const& outfile : lg->GetMakefile()->GetOutputFiles()) {
cmakefileStream << " \""
<< lg->MaybeConvertToRelativePath(binDir, outfile)
<< "\"\n";
@@ -392,8 +378,7 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefileLanguageRules(
for (cmLocalGenerator* lGenerator : lGenerators) {
lg = static_cast<cmLocalUnixMakefileGenerator3*>(lGenerator);
// for all of out targets
- const std::vector<cmGeneratorTarget*>& tgts = lg->GetGeneratorTargets();
- for (cmGeneratorTarget* tgt : tgts) {
+ for (cmGeneratorTarget* tgt : lg->GetGeneratorTargets()) {
if ((tgt->GetType() == cmStateEnums::EXECUTABLE) ||
(tgt->GetType() == cmStateEnums::STATIC_LIBRARY) ||
(tgt->GetType() == cmStateEnums::SHARED_LIBRARY) ||
@@ -413,18 +398,18 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefileLanguageRules(
void cmGlobalUnixMakefileGenerator3::WriteDirectoryRule2(
std::ostream& ruleFileStream, cmLocalUnixMakefileGenerator3* lg,
- const char* pass, bool check_all, bool check_relink)
+ const char* pass, bool check_all, bool check_relink,
+ std::vector<std::string> const& commands)
{
// Get the relative path to the subdirectory from the top.
std::string makeTarget = lg->GetCurrentBinaryDirectory();
- makeTarget += "/";
+ makeTarget += '/';
makeTarget += pass;
// The directory-level rule should depend on the target-level rules
// for all targets in the directory.
std::vector<std::string> depends;
- const std::vector<cmGeneratorTarget*>& targets = lg->GetGeneratorTargets();
- for (cmGeneratorTarget* gtarget : targets) {
+ for (cmGeneratorTarget* gtarget : lg->GetGeneratorTargets()) {
int type = gtarget->GetType();
if ((type == cmStateEnums::EXECUTABLE) ||
(type == cmStateEnums::STATIC_LIBRARY) ||
@@ -446,10 +431,9 @@ void cmGlobalUnixMakefileGenerator3::WriteDirectoryRule2(
// The directory-level rule should depend on the directory-level
// rules of the subdirectories.
- std::vector<cmStateSnapshot> children = lg->GetStateSnapshot().GetChildren();
- for (cmStateSnapshot const& c : children) {
+ for (cmStateSnapshot const& c : lg->GetStateSnapshot().GetChildren()) {
std::string subdir = c.GetDirectory().GetCurrentBinary();
- subdir += "/";
+ subdir += '/';
subdir += pass;
depends.push_back(std::move(subdir));
}
@@ -461,34 +445,46 @@ void cmGlobalUnixMakefileGenerator3::WriteDirectoryRule2(
}
// Write the rule.
- std::string doc = "Convenience name for \"";
- doc += pass;
- doc += "\" pass in the directory.";
- std::vector<std::string> no_commands;
- lg->WriteMakeRule(ruleFileStream, doc.c_str(), makeTarget, depends,
- no_commands, true);
+ std::string doc;
+ if (lg->IsRootMakefile()) {
+ doc = "The main recursive \"";
+ doc += pass;
+ doc += "\" target.";
+ } else {
+ doc = "Recursive \"";
+ doc += pass;
+ doc += "\" directory target.";
+ }
+ lg->WriteMakeRule(ruleFileStream, doc.c_str(), makeTarget, depends, commands,
+ true);
}
void cmGlobalUnixMakefileGenerator3::WriteDirectoryRules2(
std::ostream& ruleFileStream, cmLocalUnixMakefileGenerator3* lg)
{
- // Only subdirectories need these rules.
- if (lg->IsRootMakefile()) {
- return;
- }
-
// Begin the directory-level rules section.
- std::string dir =
- cmSystemTools::ConvertToOutputPath(lg->MaybeConvertToRelativePath(
- lg->GetBinaryDirectory(), lg->GetCurrentBinaryDirectory()));
- lg->WriteDivider(ruleFileStream);
- ruleFileStream << "# Directory level rules for directory " << dir << "\n\n";
+ {
+ std::string dir =
+ cmSystemTools::ConvertToOutputPath(lg->MaybeConvertToRelativePath(
+ lg->GetBinaryDirectory(), lg->GetCurrentBinaryDirectory()));
+ lg->WriteDivider(ruleFileStream);
+ if (lg->IsRootMakefile()) {
+ ruleFileStream << "# Directory level rules for the build root directory";
+ } else {
+ ruleFileStream << "# Directory level rules for directory " << dir;
+ }
+ ruleFileStream << "\n\n";
+ }
// Write directory-level rules for "all".
this->WriteDirectoryRule2(ruleFileStream, lg, "all", true, false);
// Write directory-level rules for "clean".
- this->WriteDirectoryRule2(ruleFileStream, lg, "clean", false, false);
+ {
+ std::vector<std::string> cmds;
+ lg->AppendDirectoryCleanCommand(cmds);
+ this->WriteDirectoryRule2(ruleFileStream, lg, "clean", false, false, cmds);
+ }
// Write directory-level rules for "preinstall".
this->WriteDirectoryRule2(ruleFileStream, lg, "preinstall", true, true);
@@ -567,8 +563,7 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules(
cmLocalUnixMakefileGenerator3* lg =
static_cast<cmLocalUnixMakefileGenerator3*>(localGen);
// for each target Generate the rule files for each target.
- const std::vector<cmGeneratorTarget*>& targets = lg->GetGeneratorTargets();
- for (cmGeneratorTarget* gtarget : targets) {
+ for (cmGeneratorTarget* gtarget : lg->GetGeneratorTargets()) {
// Don't emit the same rule twice (e.g. two targets with the same
// simple name)
int type = gtarget->GetType();
@@ -652,8 +647,7 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2(
}
// for each target Generate the rule files for each target.
- const std::vector<cmGeneratorTarget*>& targets = lg->GetGeneratorTargets();
- for (cmGeneratorTarget* gtarget : targets) {
+ for (cmGeneratorTarget* gtarget : lg->GetGeneratorTargets()) {
int type = gtarget->GetType();
std::string name = gtarget->GetName();
if (!name.empty() &&
@@ -693,9 +687,7 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2(
{
std::ostringstream progressArg;
const char* sep = "";
- std::vector<unsigned long> const& progFiles =
- this->ProgressMap[gtarget].Marks;
- for (unsigned long progFile : progFiles) {
+ for (unsigned long progFile : this->ProgressMap[gtarget].Marks) {
progressArg << sep << progFile;
sep = ",";
}
@@ -718,15 +710,6 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2(
lg->WriteMakeRule(ruleFileStream, "All Build rule for target.",
localName, depends, commands, true);
- // add the all/all dependency
- if (!this->IsExcluded(gtarget)) {
- depends.clear();
- depends.push_back(localName);
- commands.clear();
- lg->WriteMakeRule(ruleFileStream, "Include target in all.", "all",
- depends, commands, true);
- }
-
// Write the rule.
commands.clear();
@@ -803,9 +786,6 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2(
lg->WriteMakeRule(ruleFileStream, "clean rule for target.",
makeTargetName, depends, commands, true);
commands.clear();
- depends.push_back(makeTargetName);
- lg->WriteMakeRule(ruleFileStream, "clean rule for target.", "clean",
- depends, commands, true);
}
}
}
@@ -817,8 +797,7 @@ void cmGlobalUnixMakefileGenerator3::InitializeProgressMarks()
this->DirectoryTargetsMap.clear();
// Loop over all targets in all local generators.
for (cmLocalGenerator* lg : this->LocalGenerators) {
- const std::vector<cmGeneratorTarget*>& targets = lg->GetGeneratorTargets();
- for (cmGeneratorTarget* gt : targets) {
+ for (cmGeneratorTarget* gt : lg->GetGeneratorTargets()) {
cmLocalGenerator* tlg = gt->GetLocalGenerator();
if (gt->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
@@ -841,8 +820,7 @@ void cmGlobalUnixMakefileGenerator3::InitializeProgressMarks()
// Add dependencies of the included target. An excluded
// target may still be included if it is a dependency of a
// non-excluded target.
- TargetDependSet const& tgtdeps = this->GetTargetDirectDepends(gt);
- for (cmTargetDepend const& tgtdep : tgtdeps) {
+ for (cmTargetDepend const& tgtdep : this->GetTargetDirectDepends(gt)) {
targetSet.insert(tgtdep);
}
}
@@ -856,8 +834,7 @@ size_t cmGlobalUnixMakefileGenerator3::CountProgressMarksInTarget(
size_t count = 0;
if (emitted.insert(target).second) {
count = this->ProgressMap[target].Marks.size();
- TargetDependSet const& depends = this->GetTargetDirectDepends(target);
- for (cmTargetDepend const& depend : depends) {
+ for (cmTargetDepend const& depend : this->GetTargetDirectDepends(target)) {
if (depend->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
}
@@ -872,9 +849,8 @@ size_t cmGlobalUnixMakefileGenerator3::CountProgressMarksInAll(
{
size_t count = 0;
std::set<cmGeneratorTarget const*> emitted;
- std::set<cmGeneratorTarget const*> const& targets =
- this->DirectoryTargetsMap[lg->GetStateSnapshot()];
- for (cmGeneratorTarget const* target : targets) {
+ for (cmGeneratorTarget const* target :
+ this->DirectoryTargetsMap[lg->GetStateSnapshot()]) {
count += this->CountProgressMarksInTarget(target, emitted);
}
return count;
@@ -913,8 +889,7 @@ void cmGlobalUnixMakefileGenerator3::TargetProgress::WriteProgressVariables(
void cmGlobalUnixMakefileGenerator3::AppendGlobalTargetDepends(
std::vector<std::string>& depends, cmGeneratorTarget* target)
{
- TargetDependSet const& depends_set = this->GetTargetDirectDepends(target);
- for (cmTargetDepend const& i : depends_set) {
+ for (cmTargetDepend const& i : this->GetTargetDirectDepends(target)) {
// Create the target-level dependency.
cmGeneratorTarget const* dep = i;
if (dep->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
@@ -956,9 +931,7 @@ void cmGlobalUnixMakefileGenerator3::WriteHelpRule(
// the targets
if (lg2 == lg || lg->IsRootMakefile()) {
// for each target Generate the rule files for each target.
- const std::vector<cmGeneratorTarget*>& targets =
- lg2->GetGeneratorTargets();
- for (cmGeneratorTarget* target : targets) {
+ for (cmGeneratorTarget* target : lg2->GetGeneratorTargets()) {
cmStateEnums::TargetType type = target->GetType();
if ((type == cmStateEnums::EXECUTABLE) ||
(type == cmStateEnums::STATIC_LIBRARY) ||
diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h
index e919d38..287472c 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.h
+++ b/Source/cmGlobalUnixMakefileGenerator3.h
@@ -165,7 +165,8 @@ protected:
void WriteDirectoryRule2(std::ostream& ruleFileStream,
cmLocalUnixMakefileGenerator3* lg, const char* pass,
- bool check_all, bool check_relink);
+ bool check_all, bool check_relink,
+ std::vector<std::string> const& commands = {});
void WriteDirectoryRules2(std::ostream& ruleFileStream,
cmLocalUnixMakefileGenerator3* lg);
diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx
index c31dbf4..8764ee4 100644
--- a/Source/cmGlobalVisualStudio7Generator.cxx
+++ b/Source/cmGlobalVisualStudio7Generator.cxx
@@ -45,7 +45,6 @@ cmGlobalVisualStudio7Generator::cmGlobalVisualStudio7Generator(
cmake* cm, std::string const& platformInGeneratorName)
: cmGlobalVisualStudioGenerator(cm, platformInGeneratorName)
{
- this->IntelProjectVersion = 0;
this->DevEnvCommandInitialized = false;
this->MasmEnabled = false;
this->NasmEnabled = false;
@@ -54,21 +53,20 @@ cmGlobalVisualStudio7Generator::cmGlobalVisualStudio7Generator(
cmGlobalVisualStudio7Generator::~cmGlobalVisualStudio7Generator()
{
- free(this->IntelProjectVersion);
}
// Package GUID of Intel Visual Fortran plugin to VS IDE
#define CM_INTEL_PLUGIN_GUID "{B68A201D-CB9B-47AF-A52F-7EEC72E217E4}"
-const char* cmGlobalVisualStudio7Generator::GetIntelProjectVersion()
+const std::string& cmGlobalVisualStudio7Generator::GetIntelProjectVersion()
{
- if (!this->IntelProjectVersion) {
+ if (this->IntelProjectVersion.empty()) {
// Compute the version of the Intel plugin to the VS IDE.
// If the key does not exist then use a default guess.
std::string intelVersion;
std::string vskey = this->GetRegistryBase();
vskey += "\\Packages\\" CM_INTEL_PLUGIN_GUID ";ProductVersion";
- cmSystemTools::ReadRegistryValue(vskey.c_str(), intelVersion,
+ cmSystemTools::ReadRegistryValue(vskey, intelVersion,
cmSystemTools::KeyWOW64_32);
unsigned int intelVersionNumber = ~0u;
sscanf(intelVersion.c_str(), "%u", &intelVersionNumber);
@@ -81,7 +79,7 @@ const char* cmGlobalVisualStudio7Generator::GetIntelProjectVersion()
} else {
// Version <= 9: use ProductVersion from registry.
}
- this->IntelProjectVersion = strdup(intelVersion.c_str());
+ this->IntelProjectVersion = intelVersion;
}
return this->IntelProjectVersion;
}
@@ -237,7 +235,7 @@ cmGlobalVisualStudio7Generator::GenerateBuildCommand(
GeneratedMakeCommand makeCommand;
makeCommand.RequiresOutputForward = requiresOutputForward;
makeCommand.Add(makeProgramSelected);
- makeCommand.Add(std::string(projectName) + ".sln");
+ makeCommand.Add(projectName + ".sln");
makeCommand.Add((clean ? "/clean" : "/build"));
makeCommand.Add((config.empty() ? "Debug" : config));
makeCommand.Add("/project");
@@ -270,7 +268,7 @@ bool cmGlobalVisualStudio7Generator::SetSystemName(std::string const& s,
cmMakefile* mf)
{
mf->AddDefinition("CMAKE_VS_INTEL_Fortran_PROJECT_VERSION",
- this->GetIntelProjectVersion());
+ this->GetIntelProjectVersion().c_str());
return this->cmGlobalVisualStudioGenerator::SetSystemName(s, mf);
}
@@ -615,7 +613,7 @@ std::string cmGlobalVisualStudio7Generator::GetGUID(std::string const& name)
{
std::string const& guidStoreName = name + "_GUID_CMAKE";
if (const char* storedGUID =
- this->CMakeInstance->GetCacheDefinition(guidStoreName.c_str())) {
+ this->CMakeInstance->GetCacheDefinition(guidStoreName)) {
return std::string(storedGUID);
}
// Compute a GUID that is deterministic but unique to the build tree.
diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h
index 1e76383..f004afb 100644
--- a/Source/cmGlobalVisualStudio7Generator.h
+++ b/Source/cmGlobalVisualStudio7Generator.h
@@ -86,7 +86,7 @@ public:
return false;
}
- const char* GetIntelProjectVersion();
+ const std::string& GetIntelProjectVersion();
bool FindMakeProgram(cmMakefile* mf) override;
@@ -163,7 +163,7 @@ protected:
bool NasmEnabled;
private:
- char* IntelProjectVersion;
+ std::string IntelProjectVersion;
std::string DevEnvCommand;
bool DevEnvCommandInitialized;
std::string GetVSMakeProgram() override { return this->GetDevEnvCommand(); }
diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx
index 21abdf7..0da9986 100644
--- a/Source/cmGlobalVisualStudio8Generator.cxx
+++ b/Source/cmGlobalVisualStudio8Generator.cxx
@@ -188,8 +188,8 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
commandLine.push_back("--check-stamp-list");
commandLine.push_back(stampList.c_str());
commandLine.push_back("--vs-solution-file");
- std::string const sln = std::string(lg->GetBinaryDirectory()) + "/" +
- lg->GetProjectName() + ".sln";
+ std::string const sln =
+ lg->GetBinaryDirectory() + "/" + lg->GetProjectName() + ".sln";
commandLine.push_back(sln);
cmCustomCommandLines commandLines;
commandLines.push_back(commandLine);
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index d5a59c7..f2eb0ce 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -202,7 +202,7 @@ cmGlobalGenerator* cmGlobalXCodeGenerator::Factory::CreateGlobalGenerator(
}
}
}
- if (!versionFile.empty() && cmSystemTools::FileExists(versionFile.c_str())) {
+ if (!versionFile.empty() && cmSystemTools::FileExists(versionFile)) {
parser.ParseFile(versionFile.c_str());
} else if (cmSystemTools::FileExists(
"/Applications/Xcode.app/Contents/version.plist")) {
@@ -479,7 +479,7 @@ void cmGlobalXCodeGenerator::SetGenerationRoot(cmLocalGenerator* root)
this->CurrentXCodeHackMakefile = root->GetCurrentBinaryDirectory();
this->CurrentXCodeHackMakefile += "/CMakeScripts";
- cmSystemTools::MakeDirectory(this->CurrentXCodeHackMakefile.c_str());
+ cmSystemTools::MakeDirectory(this->CurrentXCodeHackMakefile);
this->CurrentXCodeHackMakefile += "/XCODE_DEPEND_HELPER.make";
}
@@ -600,7 +600,7 @@ void cmGlobalXCodeGenerator::CreateReRunCMakeFile(
this->CurrentReRunCMakeMakefile = root->GetCurrentBinaryDirectory();
this->CurrentReRunCMakeMakefile += "/CMakeScripts";
- cmSystemTools::MakeDirectory(this->CurrentReRunCMakeMakefile.c_str());
+ cmSystemTools::MakeDirectory(this->CurrentReRunCMakeMakefile);
this->CurrentReRunCMakeMakefile += "/ReRunCMake.make";
cmGeneratedFileStream makefileStream(this->CurrentReRunCMakeMakefile);
makefileStream.SetCopyIfDifferent(true);
@@ -1026,8 +1026,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeFileReferenceFromPath(
std::string path = this->RelativeToSource(fullpath);
std::string name = cmSystemTools::GetFilenameName(path);
const char* sourceTree =
- (cmSystemTools::FileIsFullPath(path.c_str()) ? "<absolute>"
- : "SOURCE_ROOT");
+ cmSystemTools::FileIsFullPath(path) ? "<absolute>" : "SOURCE_ROOT";
fileRef->AddAttribute("name", this->CreateString(name));
fileRef->AddAttribute("path", this->CreateString(path));
fileRef->AddAttribute("sourceTree", this->CreateString(sourceTree));
@@ -1588,7 +1587,7 @@ std::string cmGlobalXCodeGenerator::ExtractFlagRegex(const char* exp,
std::string::size_type offset = 0;
- while (regex.find(flags.c_str() + offset)) {
+ while (regex.find(&flags[offset])) {
const std::string::size_type startPos = offset + regex.start(matchIndex);
const std::string::size_type endPos = offset + regex.end(matchIndex);
const std::string::size_type size = endPos - startPos;
@@ -1641,7 +1640,7 @@ void cmGlobalXCodeGenerator::AddCommandsToBuildPhase(
{
std::string dir = this->CurrentLocalGenerator->GetCurrentBinaryDirectory();
dir += "/CMakeScripts";
- cmSystemTools::MakeDirectory(dir.c_str());
+ cmSystemTools::MakeDirectory(dir);
std::string makefile = dir;
makefile += "/";
makefile += target->GetName();
@@ -1700,7 +1699,7 @@ void cmGlobalXCodeGenerator::CreateCustomRulesMakefile(
} else {
std::ostringstream str;
str << "_buildpart_" << count++;
- tname[&ccg.GetCC()] = std::string(target->GetName()) + str.str();
+ tname[&ccg.GetCC()] = target->GetName() + str.str();
makefileStream << "\\\n\t" << tname[&ccg.GetCC()];
}
}
@@ -1824,8 +1823,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
std::string llang = gtgt->GetLinkerLanguage(configName);
if (binary && llang.empty()) {
cmSystemTools::Error(
- "CMake can not determine linker language for target: ",
- gtgt->GetName().c_str());
+ "CMake can not determine linker language for target: " +
+ gtgt->GetName());
return;
}
std::string const& langForPreprocessor = llang;
@@ -3014,10 +3013,11 @@ bool cmGlobalXCodeGenerator::CreateXCodeObjects(
cmXCodeObject* group = this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
group->AddAttribute("COPY_PHASE_STRIP", this->CreateString("NO"));
cmXCodeObject* listObjs = this->CreateObject(cmXCodeObject::OBJECT_LIST);
- for (auto& CurrentConfigurationType : this->CurrentConfigurationTypes) {
+ for (const std::string& CurrentConfigurationType :
+ this->CurrentConfigurationTypes) {
cmXCodeObject* buildStyle =
this->CreateObject(cmXCodeObject::PBXBuildStyle);
- const char* name = CurrentConfigurationType.c_str();
+ const std::string& name = CurrentConfigurationType;
buildStyle->AddAttribute("name", this->CreateString(name));
buildStyle->SetComment(name);
cmXCodeObject* sgroup = this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
@@ -3263,8 +3263,7 @@ void cmGlobalXCodeGenerator::CreateXCodeDependHackTarget(
{
cmGeneratedFileStream makefileStream(this->CurrentXCodeHackMakefile);
if (!makefileStream) {
- cmSystemTools::Error("Could not create",
- this->CurrentXCodeHackMakefile.c_str());
+ cmSystemTools::Error("Could not create " + this->CurrentXCodeHackMakefile);
return;
}
makefileStream.SetCopyIfDifferent(true);
@@ -3401,7 +3400,7 @@ void cmGlobalXCodeGenerator::OutputXCodeProject(
xcodeDir += "/";
xcodeDir += root->GetProjectName();
xcodeDir += ".xcodeproj";
- cmSystemTools::MakeDirectory(xcodeDir.c_str());
+ cmSystemTools::MakeDirectory(xcodeDir);
std::string xcodeProjFile = xcodeDir + "/project.pbxproj";
cmGeneratedFileStream fout(xcodeProjFile);
fout.SetCopyIfDifferent(true);
diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx
index 7f7ee71..9b651a4 100644
--- a/Source/cmLocalNinjaGenerator.cxx
+++ b/Source/cmLocalNinjaGenerator.cxx
@@ -70,7 +70,7 @@ void cmLocalNinjaGenerator::Generate()
this->WritePools(this->GetRulesFileStream());
- const std::string showIncludesPrefix =
+ const std::string& showIncludesPrefix =
this->GetMakefile()->GetSafeDefinition("CMAKE_CL_SHOWINCLUDES_PREFIX");
if (!showIncludesPrefix.empty()) {
cmGlobalNinjaGenerator::WriteComment(this->GetRulesFileStream(),
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index 88966c8..6a08840 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -15,6 +15,7 @@
#include "cmCustomCommandGenerator.h"
#include "cmFileTimeCache.h"
#include "cmGeneratedFileStream.h"
+#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmGlobalUnixMakefileGenerator3.h"
@@ -115,10 +116,9 @@ void cmLocalUnixMakefileGenerator3::Generate()
this->Makefile->IsOn("CMAKE_SKIP_ASSEMBLY_SOURCE_RULES");
// Generate the rule files for each target.
- const std::vector<cmGeneratorTarget*>& targets = this->GetGeneratorTargets();
cmGlobalUnixMakefileGenerator3* gg =
static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator);
- for (cmGeneratorTarget* target : targets) {
+ for (cmGeneratorTarget* target : this->GetGeneratorTargets()) {
if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
}
@@ -154,8 +154,7 @@ void cmLocalUnixMakefileGenerator3::ComputeHomeRelativeOutputPath()
void cmLocalUnixMakefileGenerator3::GetLocalObjectFiles(
std::map<std::string, LocalObjectInfo>& localObjectFiles)
{
- const std::vector<cmGeneratorTarget*>& targets = this->GetGeneratorTargets();
- for (cmGeneratorTarget* gt : targets) {
+ for (cmGeneratorTarget* gt : this->GetGeneratorTargets()) {
if (gt->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
}
@@ -353,9 +352,8 @@ void cmLocalUnixMakefileGenerator3::WriteLocalMakefileTargets(
// for each target we just provide a rule to cd up to the top and do a make
// on the target
- const std::vector<cmGeneratorTarget*>& targets = this->GetGeneratorTargets();
std::string localName;
- for (cmGeneratorTarget* target : targets) {
+ for (cmGeneratorTarget* target : this->GetGeneratorTargets()) {
if ((target->GetType() == cmStateEnums::EXECUTABLE) ||
(target->GetType() == cmStateEnums::STATIC_LIBRARY) ||
(target->GetType() == cmStateEnums::SHARED_LIBRARY) ||
@@ -1092,6 +1090,56 @@ void cmLocalUnixMakefileGenerator3::AppendCleanCommand(
}
}
+void cmLocalUnixMakefileGenerator3::AppendDirectoryCleanCommand(
+ std::vector<std::string>& commands)
+{
+ std::vector<std::string> cleanFiles;
+ // Look for additional files registered for cleaning in this directory.
+ if (const char* prop_value =
+ this->Makefile->GetProperty("ADDITIONAL_CLEAN_FILES")) {
+ cmGeneratorExpression ge;
+ std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop_value);
+ cmSystemTools::ExpandListArgument(
+ cge->Evaluate(this,
+ this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE")),
+ cleanFiles);
+ }
+ if (cleanFiles.empty()) {
+ return;
+ }
+
+ cmLocalGenerator* rootLG =
+ this->GetGlobalGenerator()->GetLocalGenerators().at(0);
+ std::string const& binaryDir = rootLG->GetCurrentBinaryDirectory();
+ std::string const& currentBinaryDir = this->GetCurrentBinaryDirectory();
+ std::string cleanfile = currentBinaryDir;
+ cleanfile += "/CMakeFiles/cmake_directory_clean.cmake";
+ // Write clean script
+ {
+ std::string cleanfilePath = cmSystemTools::CollapseFullPath(cleanfile);
+ cmsys::ofstream fout(cleanfilePath.c_str());
+ if (!fout) {
+ cmSystemTools::Error("Could not create " + cleanfilePath);
+ return;
+ }
+ fout << "file(REMOVE_RECURSE\n";
+ for (std::string const& cfl : cleanFiles) {
+ std::string fc = rootLG->MaybeConvertToRelativePath(
+ binaryDir, cmSystemTools::CollapseFullPath(cfl, currentBinaryDir));
+ fout << " " << cmOutputConverter::EscapeForCMake(fc) << "\n";
+ }
+ fout << ")\n";
+ }
+ // Create command
+ {
+ std::string remove = "$(CMAKE_COMMAND) -P ";
+ remove += this->ConvertToOutputFormat(
+ rootLG->MaybeConvertToRelativePath(binaryDir, cleanfile),
+ cmOutputConverter::SHELL);
+ commands.push_back(std::move(remove));
+ }
+}
+
void cmLocalUnixMakefileGenerator3::AppendEcho(
std::vector<std::string>& commands, std::string const& text, EchoColor color,
EchoProgress const* progress)
diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h
index fed25e1..c8e4b0e 100644
--- a/Source/cmLocalUnixMakefileGenerator3.h
+++ b/Source/cmLocalUnixMakefileGenerator3.h
@@ -227,6 +227,7 @@ protected:
const std::set<std::string>& files,
cmGeneratorTarget* target,
const char* filename = nullptr);
+ void AppendDirectoryCleanCommand(std::vector<std::string>& commands);
// Helper methods for dependency updates.
bool ScanDependencies(std::string const& targetDir,
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index beabf91..9b21739 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -108,7 +108,7 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule(
// Get the language to use for linking this library.
std::string linkLanguage = "CUDA";
- std::string const objExt =
+ std::string const& objExt =
this->Makefile->GetSafeDefinition("CMAKE_CUDA_OUTPUT_EXTENSION");
// Build list of dependencies.
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index a751b24..3a89d75 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -172,18 +172,6 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
this->CleanFiles.insert(files.begin(), files.end());
}
- // Look for additional files registered for cleaning in this directory.
- if (const char* prop_value =
- this->Makefile->GetProperty("ADDITIONAL_CLEAN_FILES")) {
- std::vector<std::string> const files = evaluatedFiles(prop_value);
- // For relative path support
- std::string const& binaryDir =
- this->LocalGenerator->GetCurrentBinaryDirectory();
- for (std::string const& cfl : files) {
- this->CleanFiles.insert(cmSystemTools::CollapseFullPath(cfl, binaryDir));
- }
- }
-
// Look for additional files registered for cleaning in this target.
if (const char* prop_value =
this->GeneratorTarget->GetProperty("ADDITIONAL_CLEAN_FILES")) {
@@ -1430,7 +1418,7 @@ void cmMakefileTargetGenerator::AppendTargetDepends(
}
// Loop over all library dependencies.
- const char* cfg = this->LocalGenerator->GetConfigName().c_str();
+ const std::string& cfg = this->LocalGenerator->GetConfigName();
if (cmComputeLinkInformation* cli =
this->GeneratorTarget->GetLinkInformation(cfg)) {
std::vector<std::string> const& libDeps = cli->GetDepends();
@@ -1635,7 +1623,8 @@ void cmMakefileTargetGenerator::CreateLinkLibs(
{
std::string frameworkPath;
std::string linkPath;
- std::string config = this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
+ const std::string& config =
+ this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
cmComputeLinkInformation* pcli =
this->GeneratorTarget->GetLinkInformation(config);
this->LocalGenerator->OutputLinkLibraries(pcli, linkLineComputer, linkLibs,
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index 680f881..06063b2 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -281,10 +281,13 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile)
cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType());
vars.Language = this->TargetLinkLanguage.c_str();
+
if (this->TargetLinkLanguage == "Swift") {
- vars.SwiftPartialModules = "$SWIFT_PARTIAL_MODULES";
- vars.TargetSwiftModule = "$TARGET_SWIFT_MODULE";
- vars.TargetSwiftDoc = "$TARGET_SWIFT_DOC";
+ vars.SwiftLibraryName = "$SWIFT_LIBRARY_NAME";
+ vars.SwiftModule = "$SWIFT_MODULE";
+ vars.SwiftModuleName = "$SWIFT_MODULE_NAME";
+ vars.SwiftOutputFileMap = "$SWIFT_OUTPUT_FILE_MAP";
+ vars.SwiftSources = "$SWIFT_SOURCES";
}
std::string responseFlag;
@@ -605,7 +608,7 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement()
// First and very important step is to make sure while inside this
// step our link language is set to CUDA
std::string cudaLinkLanguage = "CUDA";
- std::string const objExt =
+ std::string const& objExt =
this->Makefile->GetSafeDefinition("CMAKE_CUDA_OUTPUT_EXTENSION");
std::string const cfgName = this->GetConfigName();
@@ -805,35 +808,82 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
outputs.push_back(targetOutputReal);
if (this->TargetLinkLanguage == "Swift") {
- if (const char* name = gt.GetProperty("SWIFT_MODULE_NAME")) {
- vars["TARGET_SWIFT_DOC"] = std::string(name) + ".swiftdoc";
- vars["TARGET_SWIFT_MODULE"] = std::string(name) + ".swiftmodule";
- } else {
- vars["TARGET_SWIFT_DOC"] = gt.GetName() + ".swiftdoc";
- vars["TARGET_SWIFT_MODULE"] = gt.GetName() + ".swiftmodule";
- }
- outputs.push_back(vars["TARGET_SWIFT_DOC"]);
- outputs.push_back(vars["TARGET_SWIFT_MODULE"]);
+ vars["SWIFT_LIBRARY_NAME"] = [this]() -> std::string {
+ cmGeneratorTarget::Names targetNames =
+ this->GetGeneratorTarget()->GetLibraryNames(this->GetConfigName());
+ return targetNames.Base;
+ }();
+
+ vars["SWIFT_MODULE"] = [this]() -> std::string {
+ cmGeneratorTarget::Names targetNames =
+ this->GetGeneratorTarget()->GetLibraryNames(this->GetConfigName());
+
+ std::string directory =
+ this->GetLocalGenerator()->GetCurrentBinaryDirectory();
+ if (const char* prop = this->GetGeneratorTarget()->GetProperty(
+ "Swift_MODULE_DIRECTORY")) {
+ directory = prop;
+ }
+
+ std::string name = targetNames.Base + ".swiftmodule";
+ if (const char* prop =
+ this->GetGeneratorTarget()->GetProperty("Swift_MODULE")) {
+ name = prop;
+ }
- cmLocalNinjaGenerator& localGen = *this->GetLocalGenerator();
+ return this->GetLocalGenerator()->ConvertToOutputFormat(
+ this->ConvertToNinjaPath(directory + "/" + name),
+ cmOutputConverter::SHELL);
+ }();
- std::string partials;
- std::vector<cmSourceFile const*> sources;
- gt.GetObjectSources(sources, this->GetConfigName());
- for (cmSourceFile const* source : sources) {
- partials += " ";
- if (const char* partial = source->GetProperty("SWIFT_PARTIAL_MODULE")) {
- partials += partial;
- } else {
- partials += localGen.GetTargetDirectory(&gt) + "/" +
- gt.GetObjectName(source) + ".swiftmodule";
+ vars["SWIFT_MODULE_NAME"] = [this]() -> std::string {
+ if (const char* name =
+ this->GetGeneratorTarget()->GetProperty("Swift_MODULE_NAME")) {
+ return name;
}
- }
- vars["SWIFT_PARTIAL_MODULES"] = partials;
+ return this->GetGeneratorTarget()->GetName();
+ }();
+
+ vars["SWIFT_OUTPUT_FILE_MAP"] =
+ this->GetLocalGenerator()->ConvertToOutputFormat(
+ this->ConvertToNinjaPath(gt.GetSupportDirectory() +
+ "/output-file-map.json"),
+ cmOutputConverter::SHELL);
+
+ vars["SWIFT_SOURCES"] = [this]() -> std::string {
+ std::vector<cmSourceFile const*> sources;
+ std::stringstream oss;
+
+ this->GetGeneratorTarget()->GetObjectSources(sources,
+ this->GetConfigName());
+ cmLocalGenerator const* LocalGen = this->GetLocalGenerator();
+ for (const auto& source : sources) {
+ oss << " "
+ << LocalGen->ConvertToOutputFormat(
+ this->ConvertToNinjaPath(this->GetSourceFilePath(source)),
+ cmOutputConverter::SHELL);
+ }
+ return oss.str();
+ }();
}
// Compute specific libraries to link with.
- cmNinjaDeps explicitDeps = this->GetObjects();
+ cmNinjaDeps explicitDeps;
+ if (this->TargetLinkLanguage == "Swift") {
+ std::vector<cmSourceFile const*> sources;
+ this->GetGeneratorTarget()->GetObjectSources(sources,
+ this->GetConfigName());
+ for (const auto& source : sources) {
+ outputs.push_back(
+ this->ConvertToNinjaPath(this->GetObjectFilePath(source)));
+ explicitDeps.push_back(
+ this->ConvertToNinjaPath(this->GetSourceFilePath(source)));
+ }
+
+ outputs.push_back(vars["SWIFT_MODULE"]);
+ } else {
+ explicitDeps = this->GetObjects();
+ }
cmNinjaDeps implicitDeps = this->ComputeLinkDeps(this->TargetLinkLanguage);
if (!this->DeviceLinkObject.empty()) {
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 8afac70..9deaa13 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -19,7 +19,6 @@
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalNinjaGenerator.h"
-#include "cmListFileCache.h" // for BT
#include "cmLocalGenerator.h"
#include "cmLocalNinjaGenerator.h"
#include "cmMakefile.h"
@@ -455,13 +454,6 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
vars.TargetCompilePDB = "$TARGET_COMPILE_PDB";
vars.ObjectDir = "$OBJECT_DIR";
vars.ObjectFileDir = "$OBJECT_FILE_DIR";
- if (lang == "Swift") {
- vars.SwiftAuxiliarySources = "$SWIFT_AUXILIARY_SOURCES";
- vars.SwiftModuleName = "$SWIFT_MODULE_NAME";
- vars.SwiftLibraryName = "$SWIFT_LIBRARY_NAME";
- vars.SwiftPartialModule = "$SWIFT_PARTIAL_MODULE";
- vars.SwiftPartialDoc = "$SWIFT_PARTIAL_DOC";
- }
// For some cases we do an explicit preprocessor invocation.
bool const explicitPP = this->NeedExplicitPreprocessing(lang);
@@ -813,7 +805,8 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements()
<< cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType())
<< " target " << this->GetTargetName() << "\n\n";
- std::string config = this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
+ const std::string& config =
+ this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
std::vector<cmSourceFile const*> customCommands;
this->GeneratorTarget->GetCustomCommands(customCommands, config);
for (cmSourceFile const* sf : customCommands) {
@@ -923,6 +916,28 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements()
}
this->GetBuildFileStream() << "\n";
+
+ if (!this->SwiftOutputMap.empty()) {
+ std::string const mapFilePath = this->ConvertToNinjaPath(
+ this->GeneratorTarget->GetSupportDirectory() + "/output-file-map.json");
+ std::string const targetSwiftDepsPath = [this]() -> std::string {
+ cmGeneratorTarget const* target = this->GeneratorTarget;
+ if (const char* name = target->GetProperty("Swift_DEPENDENCIES_FILE")) {
+ return name;
+ }
+ return this->ConvertToNinjaPath(target->GetSupportDirectory() + "/" +
+ target->GetName() + ".swiftdeps");
+ }();
+
+ // build the global target dependencies
+ // https://github.com/apple/swift/blob/master/docs/Driver.md#output-file-maps
+ Json::Value deps(Json::objectValue);
+ deps["swift-dependencies"] = targetSwiftDepsPath;
+ this->SwiftOutputMap[""] = deps;
+
+ cmGeneratedFileStream output(mapFilePath);
+ output << this->SwiftOutputMap;
+ }
}
void cmNinjaTargetGenerator::WriteObjectBuildStatement(
@@ -947,43 +962,6 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
vars["FLAGS"] = this->ComputeFlagsForObject(source, language);
vars["DEFINES"] = this->ComputeDefines(source, language);
vars["INCLUDES"] = this->ComputeIncludes(source, language);
- if (language == "Swift") {
- // The swift compiler needs all the sources besides the one being compiled
- // in order to do the type checking. List all these "auxiliary" sources.
- std::string aux_sources;
- cmGeneratorTarget::KindedSources const& sources =
- this->GeneratorTarget->GetKindedSources(this->GetConfigName());
- for (cmGeneratorTarget::SourceAndKind const& src : sources.Sources) {
- if (src.Source.Value == source) {
- continue;
- }
- aux_sources += " " + this->GetSourceFilePath(src.Source.Value);
- }
- vars["SWIFT_AUXILIARY_SOURCES"] = aux_sources;
-
- if (const char* name =
- this->GeneratorTarget->GetProperty("SWIFT_MODULE_NAME")) {
- vars["SWIFT_MODULE_NAME"] = name;
- } else {
- vars["SWIFT_MODULE_NAME"] = this->GeneratorTarget->GetName();
- }
-
- cmGeneratorTarget::Names targetNames =
- this->GeneratorTarget->GetLibraryNames(this->GetConfigName());
- vars["SWIFT_LIBRARY_NAME"] = targetNames.Base;
-
- if (const char* partial = source->GetProperty("SWIFT_PARTIAL_MODULE")) {
- vars["SWIFT_PARTIAL_MODULE"] = partial;
- } else {
- vars["SWIFT_PARTIAL_MODULE"] = objectFileName + ".swiftmodule";
- }
-
- if (const char* partial = source->GetProperty("SWIFT_PARTIAL_DOC")) {
- vars["SWIFT_PARTIAL_DOC"] = partial;
- } else {
- vars["SWIFT_PARTIAL_DOC"] = objectFileName + ".swiftdoc";
- }
- }
if (!this->NeedDepTypeMSVC(language)) {
bool replaceExt(false);
@@ -1093,7 +1071,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
if (compilePP) {
// In case compilation requires flags that are incompatible with
// preprocessing, include them here.
- std::string const postFlag = this->Makefile->GetSafeDefinition(
+ std::string const& postFlag = this->Makefile->GetSafeDefinition(
"CMAKE_" + language + "_POSTPROCESS_FLAG");
this->LocalGenerator->AppendFlags(vars["FLAGS"], postFlag);
}
@@ -1176,10 +1154,14 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
std::string const rspfile = objectFileName + ".rsp";
- this->GetGlobalGenerator()->WriteBuild(
- this->GetBuildFileStream(), comment, rule, outputs,
- /*implicitOuts=*/cmNinjaDeps(), explicitDeps, implicitDeps, orderOnlyDeps,
- vars, rspfile, commandLineLengthLimit);
+ if (language == "Swift") {
+ this->EmitSwiftDependencyInfo(source);
+ } else {
+ this->GetGlobalGenerator()->WriteBuild(
+ this->GetBuildFileStream(), comment, rule, outputs,
+ /*implicitOuts=*/cmNinjaDeps(), explicitDeps, implicitDeps,
+ orderOnlyDeps, vars, rspfile, commandLineLengthLimit);
+ }
if (const char* objectOutputs = source->GetProperty("OBJECT_OUTPUTS")) {
std::vector<std::string> outputList;
@@ -1238,6 +1220,52 @@ void cmNinjaTargetGenerator::WriteTargetDependInfo(std::string const& lang)
tdif << tdi;
}
+void cmNinjaTargetGenerator::EmitSwiftDependencyInfo(
+ cmSourceFile const* source)
+{
+ std::string const sourceFilePath =
+ this->ConvertToNinjaPath(this->GetSourceFilePath(source));
+ std::string const objectFilePath =
+ this->ConvertToNinjaPath(this->GetObjectFilePath(source));
+ std::string const swiftDepsPath = [source, objectFilePath]() -> std::string {
+ if (const char* name = source->GetProperty("Swift_DEPENDENCIES_FILE")) {
+ return name;
+ }
+ return objectFilePath + ".swiftdeps";
+ }();
+ std::string const swiftDiaPath = [source, objectFilePath]() -> std::string {
+ if (const char* name = source->GetProperty("Swift_DIAGNOSTICS_FILE")) {
+ return name;
+ }
+ return objectFilePath + ".dia";
+ }();
+ std::string const makeDepsPath = [this, source]() -> std::string {
+ cmLocalNinjaGenerator const* local = this->GetLocalGenerator();
+ std::string const objectFileName =
+ this->ConvertToNinjaPath(this->GetObjectFilePath(source));
+ std::string const objectFileDir =
+ cmSystemTools::GetFilenamePath(objectFileName);
+
+ if (this->Makefile->IsOn("CMAKE_Swift_DEPFLE_EXTNSION_REPLACE")) {
+ std::string dependFileName =
+ cmSystemTools::GetFilenameWithoutLastExtension(objectFileName) + ".d";
+ return local->ConvertToOutputFormat(objectFileDir + "/" + dependFileName,
+ cmOutputConverter::SHELL);
+ }
+ return local->ConvertToOutputFormat(objectFileName + ".d",
+ cmOutputConverter::SHELL);
+ }();
+
+ // build the source file mapping
+ // https://github.com/apple/swift/blob/master/docs/Driver.md#output-file-maps
+ Json::Value entry = Json::Value(Json::objectValue);
+ entry["object"] = objectFilePath;
+ entry["dependencies"] = makeDepsPath;
+ entry["swift-dependencies"] = swiftDepsPath;
+ entry["diagnostics"] = swiftDiaPath;
+ SwiftOutputMap[sourceFilePath] = entry;
+}
+
void cmNinjaTargetGenerator::ExportObjectCompileCommand(
std::string const& language, std::string const& sourceFileName,
std::string const& objectDir, std::string const& objectFileName,
@@ -1342,8 +1370,7 @@ void cmNinjaTargetGenerator::EnsureDirectoryExists(
cmSystemTools::MakeDirectory(path);
} else {
cmGlobalNinjaGenerator* gg = this->GetGlobalGenerator();
- std::string fullPath =
- std::string(gg->GetCMakeInstance()->GetHomeOutputDirectory());
+ std::string fullPath = gg->GetCMakeInstance()->GetHomeOutputDirectory();
// Also ensures their is a trailing slash.
gg->StripNinjaOutputPathPrefixAsSuffix(fullPath);
fullPath += path;
diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h
index 235c60c..3055e18 100644
--- a/Source/cmNinjaTargetGenerator.h
+++ b/Source/cmNinjaTargetGenerator.h
@@ -5,6 +5,8 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include "cm_jsoncpp_value.h"
+
#include "cmCommonTargetGenerator.h"
#include "cmGlobalNinjaGenerator.h"
#include "cmNinjaTypes.h"
@@ -128,6 +130,8 @@ protected:
void WriteObjectBuildStatement(cmSourceFile const* source);
void WriteTargetDependInfo(std::string const& lang);
+ void EmitSwiftDependencyInfo(cmSourceFile const* source);
+
void ExportObjectCompileCommand(
std::string const& language, std::string const& sourceFileName,
std::string const& objectDir, std::string const& objectFileName,
@@ -171,7 +175,10 @@ private:
cmLocalNinjaGenerator* LocalGenerator;
/// List of object files for this target.
cmNinjaDeps Objects;
+ // Fortran Support
std::map<std::string, cmNinjaDeps> DDIFiles;
+ // Swift Support
+ Json::Value SwiftOutputMap;
std::vector<cmCustomCommand const*> CustomCommands;
cmNinjaDeps ExtraFiles;
};
diff --git a/Source/cmOutputRequiredFilesCommand.cxx b/Source/cmOutputRequiredFilesCommand.cxx
index cb9433f..4ed5581 100644
--- a/Source/cmOutputRequiredFilesCommand.cxx
+++ b/Source/cmOutputRequiredFilesCommand.cxx
@@ -293,8 +293,8 @@ protected:
// Make sure we don't visit the same file more than once.
info->DependDone = true;
- const char* path = info->FullPath.c_str();
- if (!path) {
+ const std::string& path = info->FullPath;
+ if (path.empty()) {
cmSystemTools::Error(
"Attempt to find dependencies for file without path!");
return;
@@ -356,7 +356,7 @@ protected:
if (!found) {
// Couldn't find any dependency information.
if (this->ComplainFileRegularExpression.find(info->IncludeName)) {
- cmSystemTools::Error("error cannot find dependencies for ", path);
+ cmSystemTools::Error("error cannot find dependencies for " + path);
} else {
// Destroy the name of the file so that it won't be output as a
// dependency.
diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx
index 38f39fb..a5e0f32 100644
--- a/Source/cmQtAutoGenInitializer.cxx
+++ b/Source/cmQtAutoGenInitializer.cxx
@@ -52,12 +52,6 @@ static std::size_t GetParallelCPUCount()
return count;
}
-static void AddCleanFile(cmMakefile* makefile, std::string const& fileName)
-{
- makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES", fileName.c_str(),
- false);
-}
-
static std::string FileProjectRelativePath(cmMakefile* makefile,
std::string const& fileName)
{
@@ -320,7 +314,7 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
}
cmSystemTools::ConvertToUnixSlashes(this->Dir.Build);
// Cleanup build directory
- AddCleanFile(makefile, this->Dir.Build);
+ this->AddCleanFile(this->Dir.Build);
// Working directory
this->Dir.Work = cbd;
@@ -381,15 +375,15 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
std::string& filename = this->AutogenTarget.ConfigSettingsFile[cfg];
filename =
AppendFilenameSuffix(this->AutogenTarget.SettingsFile, "_" + cfg);
- AddCleanFile(makefile, filename);
+ this->AddCleanFile(filename);
}
} else {
- AddCleanFile(makefile, this->AutogenTarget.SettingsFile);
+ this->AddCleanFile(this->AutogenTarget.SettingsFile);
}
this->AutogenTarget.ParseCacheFile = this->Dir.Info;
this->AutogenTarget.ParseCacheFile += "/ParseCache.txt";
- AddCleanFile(makefile, this->AutogenTarget.ParseCacheFile);
+ this->AddCleanFile(this->AutogenTarget.ParseCacheFile);
}
// Autogen target: Compute user defined dependencies
@@ -1528,6 +1522,12 @@ bool cmQtAutoGenInitializer::AddToSourceGroup(std::string const& fileName,
return true;
}
+void cmQtAutoGenInitializer::AddCleanFile(std::string const& fileName)
+{
+ Target->Target->AppendProperty("ADDITIONAL_CLEAN_FILES", fileName.c_str(),
+ false);
+}
+
static unsigned int CharPtrToUInt(const char* const input)
{
unsigned long tmp = 0;
diff --git a/Source/cmQtAutoGenInitializer.h b/Source/cmQtAutoGenInitializer.h
index 153f56d..6d2dcb6 100644
--- a/Source/cmQtAutoGenInitializer.h
+++ b/Source/cmQtAutoGenInitializer.h
@@ -145,6 +145,7 @@ private:
bool prepend = false);
bool AddToSourceGroup(std::string const& fileName,
std::string const& genNameUpper);
+ void AddCleanFile(std::string const& fileName);
bool GetQtExecutable(GenVarsT& genVars, const std::string& executable,
bool ignoreMissingTarget, std::string* output) const;
diff --git a/Source/cmRulePlaceholderExpander.cxx b/Source/cmRulePlaceholderExpander.cxx
index 309ee30..33389ca 100644
--- a/Source/cmRulePlaceholderExpander.cxx
+++ b/Source/cmRulePlaceholderExpander.cxx
@@ -91,6 +91,31 @@ std::string cmRulePlaceholderExpander::ExpandRuleVariable(
if (replaceValues.Includes && variable == "INCLUDES") {
return replaceValues.Includes;
}
+ if (replaceValues.SwiftLibraryName) {
+ if (variable == "SWIFT_LIBRARY_NAME") {
+ return replaceValues.SwiftLibraryName;
+ }
+ }
+ if (replaceValues.SwiftModule) {
+ if (variable == "SWIFT_MODULE") {
+ return replaceValues.SwiftModule;
+ }
+ }
+ if (replaceValues.SwiftModuleName) {
+ if (variable == "SWIFT_MODULE_NAME") {
+ return replaceValues.SwiftModuleName;
+ }
+ }
+ if (replaceValues.SwiftOutputFileMap) {
+ if (variable == "SWIFT_OUTPUT_FILE_MAP") {
+ return replaceValues.SwiftOutputFileMap;
+ }
+ }
+ if (replaceValues.SwiftSources) {
+ if (variable == "SWIFT_SOURCES") {
+ return replaceValues.SwiftSources;
+ }
+ }
if (replaceValues.TargetPDB) {
if (variable == "TARGET_PDB") {
return replaceValues.TargetPDB;
@@ -162,46 +187,6 @@ std::string cmRulePlaceholderExpander::ExpandRuleVariable(
}
}
}
- if (replaceValues.SwiftAuxiliarySources) {
- if (variable == "SWIFT_AUXILIARY_SOURCES") {
- return replaceValues.SwiftAuxiliarySources;
- }
- }
- if (replaceValues.SwiftModuleName) {
- if (variable == "SWIFT_MODULE_NAME") {
- return replaceValues.SwiftModuleName;
- }
- }
- if (replaceValues.SwiftLibraryName) {
- if (variable == "SWIFT_LIBRARY_NAME") {
- return replaceValues.SwiftLibraryName;
- }
- }
- if (replaceValues.SwiftPartialDoc) {
- if (variable == "SWIFT_PARTIAL_DOC") {
- return replaceValues.SwiftPartialDoc;
- }
- }
- if (replaceValues.SwiftPartialModule) {
- if (variable == "SWIFT_PARTIAL_MODULE") {
- return replaceValues.SwiftPartialModule;
- }
- }
- if (replaceValues.SwiftPartialModules) {
- if (variable == "SWIFT_PARTIAL_MODULES") {
- return replaceValues.SwiftPartialModules;
- }
- }
- if (replaceValues.TargetSwiftDoc) {
- if (variable == "TARGET_SWIFT_DOC") {
- return replaceValues.TargetSwiftDoc;
- }
- }
- if (replaceValues.TargetSwiftModule) {
- if (variable == "TARGET_SWIFT_MODULE") {
- return replaceValues.TargetSwiftModule;
- }
- }
if (variable == "TARGET_SONAME" || variable == "SONAME_FLAG" ||
variable == "TARGET_INSTALLNAME_DIR") {
// All these variables depend on TargetSOName
diff --git a/Source/cmRulePlaceholderExpander.h b/Source/cmRulePlaceholderExpander.h
index ebd4d41..8f36196 100644
--- a/Source/cmRulePlaceholderExpander.h
+++ b/Source/cmRulePlaceholderExpander.h
@@ -58,14 +58,11 @@ public:
const char* Includes;
const char* DependencyFile;
const char* FilterPrefix;
- const char* SwiftAuxiliarySources;
- const char* SwiftModuleName;
const char* SwiftLibraryName;
- const char* SwiftPartialModule;
- const char* SwiftPartialDoc;
- const char* TargetSwiftModule;
- const char* TargetSwiftDoc;
- const char* SwiftPartialModules;
+ const char* SwiftModule;
+ const char* SwiftModuleName;
+ const char* SwiftOutputFileMap;
+ const char* SwiftSources;
};
// Expand rule variables in CMake of the type found in language rules
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index d6d463b..2de8950 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -335,6 +335,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
InitProperty("LINK_SEARCH_START_STATIC", nullptr);
InitProperty("LINK_SEARCH_END_STATIC", nullptr);
InitProperty("FOLDER", nullptr);
+ InitProperty("Swift_MODULE_DIRECTORY", nullptr);
InitProperty("VS_JUST_MY_CODE_DEBUGGING", nullptr);
#ifdef __APPLE__
if (this->GetGlobalGenerator()->IsXcode()) {
diff --git a/Source/cmTargetPropertyComputer.cxx b/Source/cmTargetPropertyComputer.cxx
index 994fcf7..3f763af 100644
--- a/Source/cmTargetPropertyComputer.cxx
+++ b/Source/cmTargetPropertyComputer.cxx
@@ -63,6 +63,7 @@ bool cmTargetPropertyComputer::WhiteListedInterfaceProperty(
builtIns.insert("COMPATIBLE_INTERFACE_NUMBER_MIN");
builtIns.insert("COMPATIBLE_INTERFACE_STRING");
builtIns.insert("EXPORT_NAME");
+ builtIns.insert("EXPORT_PROPERTIES");
builtIns.insert("IMPORTED");
builtIns.insert("IMPORTED_GLOBAL");
builtIns.insert("MANUALLY_ADDED_DEPENDENCIES");
diff --git a/Source/cmTryRunCommand.cxx b/Source/cmTryRunCommand.cxx
index 4b0707b..a92c2a0 100644
--- a/Source/cmTryRunCommand.cxx
+++ b/Source/cmTryRunCommand.cxx
@@ -146,7 +146,7 @@ bool cmTryRunCommand::InitialPass(std::vector<std::string> const& argv,
const char* compileOutput =
this->Makefile->GetDefinition(this->OutputVariable);
if (compileOutput) {
- runOutputContents = std::string(compileOutput) + runOutputContents;
+ runOutputContents = compileOutput + runOutputContents;
}
this->Makefile->AddDefinition(this->OutputVariable,
runOutputContents.c_str());
@@ -167,7 +167,7 @@ void cmTryRunCommand::RunExecutable(const std::string& runArgs,
int retVal = -1;
std::string finalCommand;
- const std::string emulator =
+ const std::string& emulator =
this->Makefile->GetSafeDefinition("CMAKE_CROSSCOMPILING_EMULATOR");
if (!emulator.empty()) {
std::vector<std::string> emulatorWithArgs;
@@ -233,7 +233,7 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs,
this->RunResultVariable + "__TRYRUN_OUTPUT";
bool error = false;
- if (this->Makefile->GetDefinition(this->RunResultVariable) == nullptr) {
+ if (!this->Makefile->GetDefinition(this->RunResultVariable)) {
// if the variables doesn't exist, create it with a helpful error text
// and mark it as advanced
std::string comment;
@@ -255,8 +255,8 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs,
}
// is the output from the executable used ?
- if (out != nullptr) {
- if (this->Makefile->GetDefinition(internalRunOutputName) == nullptr) {
+ if (out) {
+ if (!this->Makefile->GetDefinition(internalRunOutputName)) {
// if the variables doesn't exist, create it with a helpful error text
// and mark it as advanced
std::string comment;
@@ -304,7 +304,7 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs,
comment += " to\n"
" the exit code (in many cases 0 for success), otherwise "
"enter \"FAILED_TO_RUN\".\n";
- if (out != nullptr) {
+ if (out) {
comment += internalRunOutputName;
comment +=
"\n contains the text the executable "
@@ -335,7 +335,7 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs,
<< this->Makefile->GetDefinition(this->RunResultVariable)
<< "\"\n CACHE STRING \"Result from TRY_RUN\" FORCE)\n\n";
- if (out != nullptr) {
+ if (out) {
file << "set( " << internalRunOutputName << " \n \""
<< this->Makefile->GetDefinition(internalRunOutputName)
<< "\"\n CACHE STRING \"Output from TRY_RUN\" FORCE)\n\n";
@@ -348,7 +348,7 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs,
"please set the following cache variables "
"appropriately:\n";
errorMessage += " " + this->RunResultVariable + " (advanced)\n";
- if (out != nullptr) {
+ if (out) {
errorMessage += " " + internalRunOutputName + " (advanced)\n";
}
errorMessage += detailsString;
@@ -356,7 +356,7 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs,
return;
}
- if (out != nullptr) {
+ if (out) {
(*out) = this->Makefile->GetDefinition(internalRunOutputName);
}
}
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index c60706d..ab9ef79 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -2858,7 +2858,7 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaOptions(
// Get compile flags for CUDA in this directory.
std::string CONFIG = cmSystemTools::UpperCase(configName);
- std::string configFlagsVar = std::string("CMAKE_CUDA_FLAGS_") + CONFIG;
+ std::string configFlagsVar = "CMAKE_CUDA_FLAGS_" + CONFIG;
std::string flags = this->Makefile->GetSafeDefinition("CMAKE_CUDA_FLAGS") +
" " + this->Makefile->GetSafeDefinition(configFlagsVar);
this->LocalGenerator->AddCompileOptions(flags, this->GeneratorTarget, "CUDA",
@@ -3075,7 +3075,7 @@ bool cmVisualStudio10TargetGenerator::ComputeMasmOptions(
Options& masmOptions = *pOptions;
std::string CONFIG = cmSystemTools::UpperCase(configName);
- std::string configFlagsVar = std::string("CMAKE_ASM_MASM_FLAGS_") + CONFIG;
+ std::string configFlagsVar = "CMAKE_ASM_MASM_FLAGS_" + CONFIG;
std::string flags =
this->Makefile->GetSafeDefinition("CMAKE_ASM_MASM_FLAGS") + " " +
this->Makefile->GetSafeDefinition(configFlagsVar);
@@ -3428,7 +3428,7 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions(
std::string standardLibsVar = "CMAKE_";
standardLibsVar += linkLanguage;
standardLibsVar += "_STANDARD_LIBRARIES";
- std::string const libs = this->Makefile->GetSafeDefinition(standardLibsVar);
+ std::string const& libs = this->Makefile->GetSafeDefinition(standardLibsVar);
cmSystemTools::ParseWindowsCommandLine(libs.c_str(), libVec);
linkOptions.AddFlag("AdditionalDependencies", libVec);
diff --git a/Tests/CMakeCommands/target_compile_options/CMakeLists.txt b/Tests/CMakeCommands/target_compile_options/CMakeLists.txt
index 1dedbae..a24cd53 100644
--- a/Tests/CMakeCommands/target_compile_options/CMakeLists.txt
+++ b/Tests/CMakeCommands/target_compile_options/CMakeLists.txt
@@ -8,7 +8,7 @@ add_executable(target_compile_options
)
target_compile_options(target_compile_options
PRIVATE $<$<CXX_COMPILER_ID:GNU>:-DMY_PRIVATE_DEFINE>
- PUBLIC $<$<CXX_COMPILER_ID:GNU>:-DMY_PUBLIC_DEFINE>
+ PUBLIC $<$<COMPILE_LANG_AND_ID:CXX,GNU>:-DMY_PUBLIC_DEFINE>
INTERFACE $<$<CXX_COMPILER_ID:GNU>:-DMY_INTERFACE_DEFINE>
)
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index d992986..698cb1d 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -22,6 +22,7 @@ macro(ADD_TEST_MACRO NAME)
endmacro()
include(${CMAKE_CURRENT_SOURCE_DIR}/CheckFortran.cmake)
+include(${CMAKE_CURRENT_SOURCE_DIR}/CheckSwift.cmake)
# Fake a user home directory to avoid polluting the real one.
if(DEFINED ENV{HOME} AND NOT CTEST_NO_TEST_HOME)
@@ -365,11 +366,16 @@ if(BUILD_TESTING)
((NOT CMAKE_OSX_SDKPRODUCT STREQUAL "Mac OS X") OR
(NOT CMAKE_OSX_SDKVERSION VERSION_LESS 10.10)))
if(CMAKE_GENERATOR STREQUAL "Xcode")
- ADD_TEST_MACRO(SwiftMix SwiftMix)
- ADD_TEST_MACRO(SwiftOnly SwiftOnly)
+ set(CMake_TEST_XCODE_SWIFT 1)
endif()
endif()
endif()
+ if(CMAKE_Swift_COMPILER OR CMake_TEST_XCODE_SWIFT)
+ ADD_TEST_MACRO(SwiftOnly SwiftOnly)
+ if(CMake_TEST_XCODE_SWIFT)
+ ADD_TEST_MACRO(SwiftMix SwiftMix)
+ endif()
+ endif()
if(CMAKE_Fortran_COMPILER)
ADD_TEST_MACRO(FortranOnly FortranOnly)
endif()
@@ -2525,24 +2531,17 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
FAIL_REGULAR_EXPRESSION "CMakeLists.txt:5 \\(set\\):")
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/WarnUnusedUnusedViaUnset")
- if("${CMAKE_GENERATOR}" MATCHES "Makefile" AND NOT WIN32)
- # Ninja does not support ADDITIONAL_MAKE_CLEAN_FILES and therefore fails
- # this test. (See #13371)
- # Apparently Visual Studio does not support it either. As the MakeClean
- # test above is only run with the Makefiles generator, only run this
- # test with the Makefiles generator also.
- add_test(WarnUnusedCliUnused ${CMAKE_CTEST_COMMAND}
- --build-and-test
- "${CMake_SOURCE_DIR}/Tests/WarnUnusedCliUnused"
- "${CMake_BINARY_DIR}/Tests/WarnUnusedCliUnused"
- ${build_generator_args}
- --build-project WarnUnusedCliUnused
- --build-options ${build_options}
- "-DUNUSED_CLI_VARIABLE=Unused")
- set_tests_properties(WarnUnusedCliUnused PROPERTIES
- PASS_REGULAR_EXPRESSION "CMake Warning:.*Manually-specified variables were not used by the project:.* UNUSED_CLI_VARIABLE")
- list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/WarnUnusedCliUnused")
- endif()
+ add_test(WarnUnusedCliUnused ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/WarnUnusedCliUnused"
+ "${CMake_BINARY_DIR}/Tests/WarnUnusedCliUnused"
+ ${build_generator_args}
+ --build-project WarnUnusedCliUnused
+ --build-options ${build_options}
+ "-DUNUSED_CLI_VARIABLE=Unused")
+ set_tests_properties(WarnUnusedCliUnused PROPERTIES
+ PASS_REGULAR_EXPRESSION "CMake Warning:.*Manually-specified variables were not used by the project:.* UNUSED_CLI_VARIABLE")
+ list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/WarnUnusedCliUnused")
add_test(WarnUnusedCliUsed ${CMAKE_CTEST_COMMAND}
--build-and-test
diff --git a/Tests/CheckSwift.cmake b/Tests/CheckSwift.cmake
new file mode 100644
index 0000000..fcbae7e
--- /dev/null
+++ b/Tests/CheckSwift.cmake
@@ -0,0 +1,61 @@
+if(NOT CMAKE_GENERATOR MATCHES "Xcode|Ninja")
+ set(CMAKE_Swift_COMPILER "")
+ return()
+endif()
+
+if(NOT DEFINED CMAKE_Swift_COMPILER)
+ set(_desc "Looking for a Swift compiler")
+ message(STATUS ${_desc})
+
+ file(REMOVE_RECURSE ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CheckSwift)
+
+ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CheckSwift/CMakeLists.txt"
+ "cmake_minimum_required(VERSION 3.14)
+project(CheckSwift Swift)
+file(WRITE \"\${CMAKE_CURRENT_BINARY_DIR}/result.cmake\"
+ \"set(CMAKE_Swift_COMPILER \\\"\${CMAKE_Swift_COMPILER}\\\")\\n\"
+ \"set(CMAKE_Swift_FLAGS \\\"\${CMAKE_Swift_FLAGS}\\\")\\n\")
+")
+
+ if(CMAKE_GENERATOR_INSTANCE)
+ set(_D_CMAKE_GENERATOR_INSTANCE "-DCMAKE_GENERATOR_INSTANCE:INTERNAL=${CMAKE_GENERATOR_INSTANCE}")
+ else()
+ set(_D_CMAKE_GENERATOR_INSTANCE "")
+ endif()
+
+ execute_process(WORKING_DIRECTORY
+ ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CheckSwift
+ COMMAND
+ ${CMAKE_COMMAND} . -G ${CMAKE_GENERATOR}
+ -A "${CMAKE_GENERATOR_PLATFORM}"
+ -T "${CMAKE_GENERATOR_TOOLSET}"
+ ${_D_CMAKE_GENERATOR_INSTANCE}
+ TIMEOUT
+ 60
+ OUTPUT_VARIABLE
+ output
+ ERROR_VARIABLE
+ output
+ RESULT_VARIABLE
+ result)
+
+ include(${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CheckSwift/result.cmake
+ OPTIONAL)
+ if(CMAKE_Swift_COMPILER AND "${result}" STREQUAL "0")
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "${_desc} passed with the following output:\n"
+ "${output}\n")
+ else()
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "${_desc} failed with the following output:\n"
+ "${output}\n")
+ endif()
+
+ message(STATUS "${_desc} - ${CMAKE_Swift_COMPILER}")
+
+ set(CMAKE_Swift_COMPILER "${CMAKE_Swift_COMPILER}" CACHE FILEPATH "Swift compiler")
+ set(CMAKE_Swift_FLAGS "${CMAKE_Swift_FLAGS}" CACHE STRING "Swift flags")
+
+ mark_as_advanced(CMAKE_Swift_COMPILER)
+ mark_as_advanced(CMAKE_Swift_FLAGS)
+endif()
diff --git a/Tests/CompileOptions/CMakeLists.txt b/Tests/CompileOptions/CMakeLists.txt
index 15a993c..18896bf 100644
--- a/Tests/CompileOptions/CMakeLists.txt
+++ b/Tests/CompileOptions/CMakeLists.txt
@@ -25,6 +25,7 @@ set_property(TARGET CompileOptions PROPERTY COMPILE_OPTIONS
"-DTEST_DEFINE"
"-DNEEDS_ESCAPE=\"E$CAPE\""
"$<$<CXX_COMPILER_ID:GNU>:-DTEST_DEFINE_GNU>"
+ "$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-DTEST_DEFINE_CXX_AND_GNU>"
"SHELL:" # produces no options
${c_tests}
${cxx_tests}
diff --git a/Tests/CompileOptions/main.cpp b/Tests/CompileOptions/main.cpp
index d94a169..ebc1017 100644
--- a/Tests/CompileOptions/main.cpp
+++ b/Tests/CompileOptions/main.cpp
@@ -10,6 +10,9 @@
# ifndef TEST_DEFINE_GNU
# error Expected definition TEST_DEFINE_GNU
# endif
+# ifndef TEST_DEFINE_CXX_AND_GNU
+# error Expected definition TEST_DEFINE_CXX_AND_GNU
+# endif
#endif
#ifndef NO_DEF_TESTS
diff --git a/Tests/ExportImport/Export/Interface/CMakeLists.txt b/Tests/ExportImport/Export/Interface/CMakeLists.txt
index fd55c42..22a4ef6 100644
--- a/Tests/ExportImport/Export/Interface/CMakeLists.txt
+++ b/Tests/ExportImport/Export/Interface/CMakeLists.txt
@@ -41,6 +41,8 @@ install(FILES
add_library(cmakeonly INTERFACE)
set_property(TARGET cmakeonly PROPERTY INTERFACE_COMPILE_DEFINITIONS [[DEF="\"\$\B"]])
+set_property(TARGET cmakeonly PROPERTY custom_property CustomPropertyValue)
+set_property(TARGET cmakeonly PROPERTY EXPORT_PROPERTIES custom_property)
install(TARGETS headeronly sharediface use_auto_type use_c_restrict source_target
cmakeonly
diff --git a/Tests/ExportImport/Import/Interface/CMakeLists.txt b/Tests/ExportImport/Import/Interface/CMakeLists.txt
index c850508..a07a5b3 100644
--- a/Tests/ExportImport/Import/Interface/CMakeLists.txt
+++ b/Tests/ExportImport/Import/Interface/CMakeLists.txt
@@ -109,4 +109,12 @@ foreach(ns exp bld)
"not\n"
" " [[DEF="\"\$\B"]] "\n")
endif()
+ get_property(custom TARGET ${ns}::cmakeonly PROPERTY custom_property)
+ if(NOT custom STREQUAL "CustomPropertyValue")
+ message(SEND_ERROR
+ "${ns}::cmakeonly property custom_property is:\n"
+ " ${custom}\n"
+ "not\n"
+ " CustomPropertyValue\n")
+ endif()
endforeach()
diff --git a/Tests/MakeClean/ToClean/CMakeLists.txt b/Tests/MakeClean/ToClean/CMakeLists.txt
index 5d84e6c..6f16d12 100644
--- a/Tests/MakeClean/ToClean/CMakeLists.txt
+++ b/Tests/MakeClean/ToClean/CMakeLists.txt
@@ -2,45 +2,56 @@ cmake_minimum_required(VERSION 3.14)
project(ToClean)
# Utility variables
-set(TSD ${ToClean_SOURCE_DIR})
-set(TBD ${ToClean_BINARY_DIR})
+set(CSD ${CMAKE_CURRENT_SOURCE_DIR})
+set(CBD ${CMAKE_CURRENT_BINARY_DIR})
set(CLEAN_FILE_CONTENT "File registered for cleaning.\n")
# Lists build-time-generated files that should be cleaned away
-set(TOCLEAN_FILES)
+set_property(GLOBAL PROPERTY TOCLEAN_FILES "")
+function(addCleanFile FILENAME)
+ set_property(GLOBAL APPEND PROPERTY TOCLEAN_FILES "${FILENAME}")
+endfunction()
+function(writeCleanFile FILENAME)
+ file(WRITE "${FILENAME}" ${CLEAN_FILE_CONTENT})
+endfunction()
# Build a simple project whose compiled objects should be cleaned.
add_executable(toclean toclean.cxx)
-list(APPEND TOCLEAN_FILES
- "${TBD}${CMAKE_FILES_DIRECTORY}/toclean.dir/toclean.cxx${CMAKE_CXX_OUTPUT_EXTENSION}")
+addCleanFile("${CBD}${CMAKE_FILES_DIRECTORY}/toclean.dir/toclean.cxx${CMAKE_CXX_OUTPUT_EXTENSION}")
+
+# Create a post build custom command that copies the toclean output executable
+# to a custom location
+function(addToCleanPostBuildCopy FILENAME)
+ add_custom_command(TARGET toclean POST_BUILD
+ COMMAND ${CMAKE_COMMAND}
+ ARGS -E copy $<TARGET_FILE:toclean> ${FILENAME})
+endfunction()
# Create a custom command whose output should be cleaned.
-set(CustomCommandFile "${TBD}/CustomCommandFile.txt")
+set(CustomCommandFile "${CBD}/CustomCommandFile.txt")
add_custom_command(OUTPUT ${CustomCommandFile}
- DEPENDS ${TSD}/toclean.cxx
+ DEPENDS ${CSD}/toclean.cxx
COMMAND ${CMAKE_COMMAND}
- ARGS -E copy ${TSD}/toclean.cxx ${CustomCommandFile})
+ ARGS -E copy ${CSD}/toclean.cxx ${CustomCommandFile})
add_custom_target(generate ALL DEPENDS ${CustomCommandFile})
-list(APPEND TOCLEAN_FILES ${CustomCommandFile})
+addCleanFile(${CustomCommandFile})
### Tests ADDITIONAL_MAKE_CLEAN_FILES directory property
if("${CMAKE_GENERATOR}" MATCHES "Makefile")
# Create a file that must be registered for cleaning.
- set(MakeDirPropFile "${TBD}/MakeDirPropFile.txt")
- file(WRITE "${MakeDirPropFile}" ${CLEAN_FILE_CONTENT})
+ set(MakeDirPropFile "${CBD}/MakeDirPropFile.txt")
+ writeCleanFile("${MakeDirPropFile}")
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${MakeDirPropFile}")
- list(APPEND TOCLEAN_FILES "${MakeDirPropFile}")
+ addCleanFile(${MakeDirPropFile})
# Create a custom command whose output should be cleaned, but whose name
# is not known until generate-time
set(MakeDirPropExpFileRel "MakeDirProp_copy${CMAKE_EXECUTABLE_SUFFIX}")
set(MakeDirPropExpFile "$<TARGET_FILE_DIR:toclean>/${MakeDirPropExpFileRel}")
- add_custom_command(TARGET toclean POST_BUILD
- COMMAND ${CMAKE_COMMAND}
- ARGS -E copy $<TARGET_FILE:toclean> ${MakeDirPropExpFile})
+ addToCleanPostBuildCopy("${MakeDirPropExpFile}")
set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${MakeDirPropExpFile})
- list(APPEND TOCLEAN_FILES "${TBD}/${MakeDirPropExpFileRel}")
+ addCleanFile("${CBD}/${MakeDirPropExpFileRel}")
endif()
@@ -48,51 +59,52 @@ endif()
# Register a file path relative to the build directory
set(DirPropFileRel "DirPropFileRel.txt")
-file(WRITE "${TBD}/${DirPropFileRel}" ${CLEAN_FILE_CONTENT})
+writeCleanFile("${CBD}/${DirPropFileRel}")
set_directory_properties(PROPERTIES ADDITIONAL_CLEAN_FILES ${DirPropFileRel})
-list(APPEND TOCLEAN_FILES "${TBD}/${DirPropFileRel}")
+addCleanFile("${CBD}/${DirPropFileRel}")
# Register an absolute file path
-set(DirPropFileAbs "${TBD}/DirPropFileAbs.txt")
-file(WRITE "${DirPropFileAbs}" ${CLEAN_FILE_CONTENT})
+set(DirPropFileAbs "${CBD}/DirPropFileAbs.txt")
+writeCleanFile("${DirPropFileAbs}")
set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_CLEAN_FILES ${DirPropFileAbs})
-list(APPEND TOCLEAN_FILES "${DirPropFileAbs}")
+addCleanFile("${DirPropFileAbs}")
# Create a custom command whose output should be cleaned, but whose name
# is not known until generate-time
set(DirPropExpFileRel "DirProp_copy${CMAKE_EXECUTABLE_SUFFIX}")
set(DirPropExpFile "$<TARGET_FILE_DIR:toclean>/${DirPropExpFileRel}")
-add_custom_command(TARGET toclean POST_BUILD
- COMMAND ${CMAKE_COMMAND}
- ARGS -E copy $<TARGET_FILE:toclean> ${DirPropExpFile})
+addToCleanPostBuildCopy("${DirPropExpFile}")
set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_CLEAN_FILES ${DirPropExpFile})
-list(APPEND TOCLEAN_FILES "${TBD}/${DirPropExpFileRel}")
+addCleanFile("${CBD}/${DirPropExpFileRel}")
### Tests ADDITIONAL_CLEAN_FILES target property
# Register a file path relative to the build directory
set(TgtPropFileRel "TargetPropFileRel.txt")
-file(WRITE "${TBD}/${TgtPropFileRel}" ${CLEAN_FILE_CONTENT})
+writeCleanFile("${CBD}/${TgtPropFileRel}")
set_target_properties(toclean PROPERTIES ADDITIONAL_CLEAN_FILES ${TgtPropFileRel})
-list(APPEND TOCLEAN_FILES "${TBD}/${TgtPropFileRel}")
+addCleanFile("${CBD}/${TgtPropFileRel}")
# Register an absolute file path
-set(TgtPropFileAbs "${TBD}/TargetPropFileAbs.txt")
-file(WRITE "${TgtPropFileAbs}" ${CLEAN_FILE_CONTENT})
+set(TgtPropFileAbs "${CBD}/TargetPropFileAbs.txt")
+writeCleanFile("${TgtPropFileAbs}")
set_property(TARGET toclean APPEND PROPERTY ADDITIONAL_CLEAN_FILES ${TgtPropFileAbs})
-list(APPEND TOCLEAN_FILES "${TgtPropFileAbs}")
+addCleanFile("${TgtPropFileAbs}")
# Create a custom command whose output should be cleaned, but whose name
# is not known until generate-time
set(TgtPropExpFileRel "TgtProp_copy${CMAKE_EXECUTABLE_SUFFIX}")
set(TgtPropExpFile "$<TARGET_FILE_DIR:toclean>/${TgtPropExpFileRel}")
-add_custom_command(TARGET toclean POST_BUILD
- COMMAND ${CMAKE_COMMAND}
- ARGS -E copy $<TARGET_FILE:toclean> ${TgtPropExpFile})
+addToCleanPostBuildCopy("${TgtPropExpFile}")
set_property(TARGET toclean APPEND PROPERTY ADDITIONAL_CLEAN_FILES ${TgtPropExpFile})
-list(APPEND TOCLEAN_FILES "${TBD}/${TgtPropExpFileRel}")
+addCleanFile("${CBD}/${TgtPropExpFileRel}")
+
+
+# Process subdirectory without targets
+add_subdirectory(EmptySubDir)
# Configure a file listing these build-time-generated files.
-configure_file(${TSD}/ToCleanFiles.cmake.in ${TBD}/ToCleanFiles.cmake @ONLY)
+get_property(TOCLEAN_FILES GLOBAL PROPERTY TOCLEAN_FILES)
+configure_file(${CSD}/ToCleanFiles.cmake.in ${CBD}/ToCleanFiles.cmake @ONLY)
diff --git a/Tests/MakeClean/ToClean/EmptySubDir/CMakeLists.txt b/Tests/MakeClean/ToClean/EmptySubDir/CMakeLists.txt
new file mode 100644
index 0000000..55893ae
--- /dev/null
+++ b/Tests/MakeClean/ToClean/EmptySubDir/CMakeLists.txt
@@ -0,0 +1,17 @@
+cmake_minimum_required(VERSION 3.14)
+
+# Subdirectory CMakeLists.txt without targets
+set(CSD ${CMAKE_CURRENT_SOURCE_DIR})
+set(CBD ${CMAKE_CURRENT_BINARY_DIR})
+
+# Register a file path relative to the build directory
+set(DirPropFileRel "DirPropFileRel.txt")
+writeCleanFile("${CBD}/${DirPropFileRel}")
+set_directory_properties(PROPERTIES ADDITIONAL_CLEAN_FILES ${DirPropFileRel})
+addCleanFile("${CBD}/${DirPropFileRel}")
+
+# Register an absolute file path
+set(DirPropFileAbs "${CBD}/DirPropFileAbs.txt")
+writeCleanFile("${DirPropFileAbs}")
+set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_CLEAN_FILES ${DirPropFileAbs})
+addCleanFile("${DirPropFileAbs}")
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index d57138b..0ccfca8 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -205,7 +205,7 @@ if(UNIX AND CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG AND CMAKE_EXECUTABLE_FORMAT STRE
add_RunCMake_test(RuntimePath)
endif()
add_RunCMake_test(ScriptMode)
-add_RunCMake_test(Swift)
+add_RunCMake_test(Swift -DCMAKE_Swift_COMPILER=${CMAKE_Swift_COMPILER})
add_RunCMake_test(TargetObjects)
add_RunCMake_test(TargetSources)
add_RunCMake_test(ToolchainFile)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_custom_command-result.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_custom_command-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_custom_command-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_custom_command-stderr.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_custom_command-stderr.txt
new file mode 100644
index 0000000..fc3c3de
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_custom_command-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at COMPILE_LANG_AND_ID-add_custom_command.cmake:2 \(add_custom_command\):
+ Error evaluating generator expression:
+
+ \$<COMPILE_LANG_AND_ID>
+
+ \$<COMPILE_LANG_AND_ID> expression requires 2 comma separated parameters,
+ but got 0 instead.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_custom_command.cmake b/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_custom_command.cmake
new file mode 100644
index 0000000..9bd5e8e
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_custom_command.cmake
@@ -0,0 +1,4 @@
+add_custom_target(drive)
+add_custom_command(TARGET drive PRE_BUILD
+ COMMAND ${CMAKE_COMMAND} -E echo $<COMPILE_LANG_AND_ID>
+)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_custom_target-result.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_custom_target-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_custom_target-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_custom_target-stderr.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_custom_target-stderr.txt
new file mode 100644
index 0000000..589e64b
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_custom_target-stderr.txt
@@ -0,0 +1,11 @@
+CMake Error at COMPILE_LANG_AND_ID-add_custom_target.cmake:2 \(add_custom_target\):
+ Error evaluating generator expression:
+
+ \$<COMPILE_LANG_AND_ID:LANG,ID>
+
+ \$<COMPILE_LANG_AND_ID:lang,id> may only be used with binary targets to
+ specify include directories, compile definitions, and compile options. It
+ may not be used with the add_custom_command, add_custom_target, or
+ file\(GENERATE\) commands.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_custom_target.cmake b/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_custom_target.cmake
new file mode 100644
index 0000000..398db19
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_custom_target.cmake
@@ -0,0 +1,4 @@
+
+add_custom_target(drive
+ COMMAND ${CMAKE_COMMAND} -E echo $<COMPILE_LANG_AND_ID:LANG,ID>
+)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_executable-result.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_executable-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_executable-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_executable-stderr.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_executable-stderr.txt
new file mode 100644
index 0000000..3b3f38d
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_executable-stderr.txt
@@ -0,0 +1,11 @@
+CMake Error at COMPILE_LANG_AND_ID-add_executable.cmake:1 \(add_executable\):
+ Error evaluating generator expression:
+
+ \$<COMPILE_LANG_AND_ID:C,MSVC>
+
+ \$<COMPILE_LANG_AND_ID:lang,id> may only be used with binary targets to
+ specify include directories, compile definitions, and compile options. It
+ may not be used with the add_custom_command, add_custom_target, or
+ file\(GENERATE\) commands.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_executable.cmake b/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_executable.cmake
new file mode 100644
index 0000000..2245f50
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_executable.cmake
@@ -0,0 +1,5 @@
+add_executable(empty main.c
+ $<$<COMPILE_LANG_AND_ID:C,MSVC>:empty.c>
+ $<$<COMPILE_LANG_AND_ID:C,GNU>:empty2.c>
+ $<$<COMPILE_LANG_AND_ID:C,Clang>:empty3.c>
+ )
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_library-result.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_library-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_library-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_library-stderr.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_library-stderr.txt
new file mode 100644
index 0000000..4cbf000
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_library-stderr.txt
@@ -0,0 +1,11 @@
+CMake Error at COMPILE_LANG_AND_ID-add_library.cmake:2 \(add_library\):
+ Error evaluating generator expression:
+
+ \$<COMPILE_LANG_AND_ID:C,MSVC>
+
+ \$<COMPILE_LANG_AND_ID:lang,id> may only be used with binary targets to
+ specify include directories, compile definitions, and compile options. It
+ may not be used with the add_custom_command, add_custom_target, or
+ file\(GENERATE\) commands.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_library.cmake b/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_library.cmake
new file mode 100644
index 0000000..044962a
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_library.cmake
@@ -0,0 +1,2 @@
+
+add_library(empty empty.$<COMPILE_LANG_AND_ID:C,MSVC>)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_test-result.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_test-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_test-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_test-stderr.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_test-stderr.txt
new file mode 100644
index 0000000..26a5940
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_test-stderr.txt
@@ -0,0 +1,11 @@
+CMake Error at COMPILE_LANG_AND_ID-add_test.cmake:5 \(add_test\):
+ Error evaluating generator expression:
+
+ \$<COMPILE_LANG_AND_ID:CXX,GNU>
+
+ \$<COMPILE_LANG_AND_ID:lang,id> may only be used with binary targets to
+ specify include directories, compile definitions, and compile options. It
+ may not be used with the add_custom_command, add_custom_target, or
+ file\(GENERATE\) commands.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_test.cmake b/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_test.cmake
new file mode 100644
index 0000000..b5b6c2b
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_test.cmake
@@ -0,0 +1,5 @@
+
+include(CTest)
+enable_testing()
+
+add_test(NAME dummy COMMAND ${CMAKE_COMMAND} -E echo $<COMPILE_LANG_AND_ID:CXX,GNU>)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-install-result.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-install-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-install-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-install-stderr.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-install-stderr.txt
new file mode 100644
index 0000000..0c4ecd0
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-install-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error:
+ Error evaluating generator expression:
+
+ \$<COMPILE_LANG_AND_ID:C,MSVC>
+
+ \$<COMPILE_LANG_AND_ID:lang,id> may only be used with binary targets to
+ specify include directories, compile definitions, and compile options. It
+ may not be used with the add_custom_command, add_custom_target, or
+ file\(GENERATE\) commands.
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-install.cmake b/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-install.cmake
new file mode 100644
index 0000000..c13eda6
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-install.cmake
@@ -0,0 +1,5 @@
+
+install(FILES
+ empty.$<COMPILE_LANG_AND_ID:C,MSVC>
+ DESTINATION src
+)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-target_sources-result.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-target_sources-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-target_sources-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-target_sources-stderr.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-target_sources-stderr.txt
new file mode 100644
index 0000000..44d8684
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-target_sources-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at COMPILE_LANG_AND_ID-target_sources.cmake:2 \(target_sources\):
+ Error evaluating generator expression:
+
+ \$<COMPILE_LANG_AND_ID>
+
+ \$<COMPILE_LANG_AND_ID> expression requires 2 comma separated parameters,
+ but got 0 instead.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-target_sources.cmake b/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-target_sources.cmake
new file mode 100644
index 0000000..a2c9b03
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-target_sources.cmake
@@ -0,0 +1,2 @@
+add_library(empty)
+target_sources(empty PRIVATE empty.$<COMPILE_LANG_AND_ID>)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-unknown-lang.cmake b/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-unknown-lang.cmake
new file mode 100644
index 0000000..b9e840b
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-unknown-lang.cmake
@@ -0,0 +1,4 @@
+
+enable_language(C)
+add_executable(empty empty.c)
+target_compile_options(empty PRIVATE $<$<COMPILE_LANG_AND_ID:CXX,GNU>:$<TARGET_EXISTS:too,many,parameters>>)
diff --git a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
index a491e99..8abf70d 100644
--- a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
@@ -31,6 +31,14 @@ run_cmake(COMPILE_LANGUAGE-add_executable)
run_cmake(COMPILE_LANGUAGE-add_library)
run_cmake(COMPILE_LANGUAGE-add_test)
run_cmake(COMPILE_LANGUAGE-unknown-lang)
+run_cmake(COMPILE_LANG_AND_ID-add_custom_target)
+run_cmake(COMPILE_LANG_AND_ID-add_custom_command)
+run_cmake(COMPILE_LANG_AND_ID-install)
+run_cmake(COMPILE_LANG_AND_ID-target_sources)
+run_cmake(COMPILE_LANG_AND_ID-add_executable)
+run_cmake(COMPILE_LANG_AND_ID-add_library)
+run_cmake(COMPILE_LANG_AND_ID-add_test)
+run_cmake(COMPILE_LANG_AND_ID-unknown-lang)
run_cmake(TARGET_FILE-recursion)
run_cmake(OUTPUT_NAME-recursion)
run_cmake(TARGET_FILE_PREFIX)
diff --git a/Tests/RunCMake/Swift/RunCMakeTest.cmake b/Tests/RunCMake/Swift/RunCMakeTest.cmake
index 4864295..de99042 100644
--- a/Tests/RunCMake/Swift/RunCMakeTest.cmake
+++ b/Tests/RunCMake/Swift/RunCMakeTest.cmake
@@ -4,6 +4,10 @@ if(RunCMake_GENERATOR STREQUAL Xcode)
if(XCODE_BELOW_6_1)
run_cmake(XcodeTooOld)
endif()
+elseif(RunCMake_GENERATOR STREQUAL Ninja)
+ if(CMAKE_Swift_COMPILER)
+ # Add Ninja-specific Swift tests here.
+ endif()
else()
run_cmake(NotSupported)
endif()
diff --git a/Tests/RunCMake/file/INSTALL-FOLLOW_SYMLINK_CHAIN.cmake b/Tests/RunCMake/file/INSTALL-FOLLOW_SYMLINK_CHAIN.cmake
new file mode 100644
index 0000000..d8a12eb
--- /dev/null
+++ b/Tests/RunCMake/file/INSTALL-FOLLOW_SYMLINK_CHAIN.cmake
@@ -0,0 +1,168 @@
+file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/dest1")
+
+file(TOUCH "${CMAKE_BINARY_DIR}/file1.txt")
+file(CREATE_LINK file1.txt "${CMAKE_BINARY_DIR}/file1.txt.sym" SYMBOLIC)
+file(TOUCH "${CMAKE_BINARY_DIR}/dest1/file1.txt.sym")
+
+file(TOUCH "${CMAKE_BINARY_DIR}/file2.txt")
+file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/file2")
+file(CREATE_LINK ../file2.txt "${CMAKE_BINARY_DIR}/file2/file2.txt.sym" SYMBOLIC)
+
+file(TOUCH "${CMAKE_BINARY_DIR}/file3.txt")
+file(CREATE_LINK "${CMAKE_BINARY_DIR}/file3.txt" "${CMAKE_BINARY_DIR}/file3.txt.sym" SYMBOLIC)
+
+file(TOUCH "${CMAKE_BINARY_DIR}/file4.txt")
+file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/file4")
+file(CREATE_LINK "${CMAKE_BINARY_DIR}/file4.txt" "${CMAKE_BINARY_DIR}/file4/file4.txt.sym" SYMBOLIC)
+
+file(TOUCH "${CMAKE_BINARY_DIR}/file5.txt")
+
+file(TOUCH "${CMAKE_BINARY_DIR}/file6.txt")
+file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/file6/file6")
+file(CREATE_LINK file6.txt "${CMAKE_BINARY_DIR}/file6.txt.sym.1" SYMBOLIC)
+file(CREATE_LINK ../file6.txt.sym.1 "${CMAKE_BINARY_DIR}/file6/file6.txt.sym.2" SYMBOLIC)
+file(CREATE_LINK "${CMAKE_BINARY_DIR}/file6/file6.txt.sym.2" "${CMAKE_BINARY_DIR}/file6/file6/file6.txt.sym.3" SYMBOLIC)
+file(CREATE_LINK file6.txt.sym.3 "${CMAKE_BINARY_DIR}/file6/file6/file6.txt.sym.4" SYMBOLIC)
+
+file(TOUCH "${CMAKE_BINARY_DIR}/file7.txt")
+file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/file7")
+
+file(TOUCH "${CMAKE_BINARY_DIR}/file8.txt")
+file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/file8")
+file(CREATE_LINK "${CMAKE_BINARY_DIR}/file8/../file8.txt" "${CMAKE_BINARY_DIR}/file8/file8.txt.sym" SYMBOLIC)
+
+file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/file9")
+file(TOUCH "${CMAKE_BINARY_DIR}/file9/file9.txt")
+file(CREATE_LINK "${CMAKE_BINARY_DIR}/file9" "${CMAKE_BINARY_DIR}/file9.sym" SYMBOLIC)
+
+file(TOUCH "${CMAKE_BINARY_DIR}/file10.txt")
+file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/file10")
+file(CREATE_LINK "." "${CMAKE_BINARY_DIR}/file10/file10" SYMBOLIC)
+file(CREATE_LINK "${CMAKE_BINARY_DIR}/file10/file10/../file10.txt" "${CMAKE_BINARY_DIR}/file10/file10.txt.sym" SYMBOLIC)
+
+file(INSTALL
+ "${CMAKE_BINARY_DIR}/file1.txt.sym"
+ DESTINATION "${CMAKE_BINARY_DIR}/dest1"
+ FOLLOW_SYMLINK_CHAIN
+ )
+
+file(INSTALL
+ "${CMAKE_BINARY_DIR}/file1.txt.sym"
+ "${CMAKE_BINARY_DIR}/file2/file2.txt.sym"
+ "${CMAKE_BINARY_DIR}/file3.txt.sym"
+ "${CMAKE_BINARY_DIR}/file4/file4.txt.sym"
+ "${CMAKE_BINARY_DIR}/file5.txt"
+ "${CMAKE_BINARY_DIR}/file6/file6/file6.txt.sym.4"
+ "${CMAKE_BINARY_DIR}/file8/file8.txt.sym"
+ "${CMAKE_BINARY_DIR}/file7/../file7.txt"
+ "${CMAKE_BINARY_DIR}/file8.txt"
+ "${CMAKE_BINARY_DIR}/file9.sym/file9.txt"
+ "${CMAKE_BINARY_DIR}/file10/file10/file10.txt.sym"
+ DESTINATION "${CMAKE_BINARY_DIR}/dest2"
+ FOLLOW_SYMLINK_CHAIN
+ )
+
+set(resolved_file1.txt.sym file1.txt)
+set(resolved_file10.txt.sym file10.txt)
+set(resolved_file2.txt.sym file2.txt)
+set(resolved_file3.txt.sym file3.txt)
+set(resolved_file4.txt.sym file4.txt)
+set(resolved_file6.txt.sym.1 file6.txt)
+set(resolved_file6.txt.sym.2 file6.txt.sym.1)
+set(resolved_file6.txt.sym.3 file6.txt.sym.2)
+set(resolved_file6.txt.sym.4 file6.txt.sym.3)
+set(resolved_file8.txt.sym file8.txt)
+set(syms)
+foreach(f
+ file1.txt
+ file1.txt.sym
+ file10.txt
+ file10.txt.sym
+ file2.txt
+ file2.txt.sym
+ file3.txt
+ file3.txt.sym
+ file4.txt
+ file4.txt.sym
+ file5.txt
+ file6.txt
+ file6.txt.sym.1
+ file6.txt.sym.2
+ file6.txt.sym.3
+ file6.txt.sym.4
+ file7.txt
+ file8.txt
+ file8.txt.sym
+ file9.txt
+ )
+ string(REPLACE "." "\\." r "${f}")
+ list(APPEND syms "[^;]*/Tests/RunCMake/file/INSTALL-FOLLOW_SYMLINK_CHAIN-build/dest2/${r}")
+ set(filename "${CMAKE_BINARY_DIR}/dest2/${f}")
+ if(DEFINED resolved_${f})
+ file(READ_SYMLINK "${filename}" resolved)
+ if(NOT resolved STREQUAL "${resolved_${f}}")
+ message(SEND_ERROR "Expected symlink resolution for ${f}: ${resolved_${f}}\nActual resolution: ${resolved}")
+ endif()
+ elseif(NOT EXISTS "${filename}" OR IS_SYMLINK "${filename}" OR IS_DIRECTORY "${filename}")
+ message(SEND_ERROR "${f} should be a regular file")
+ endif()
+endforeach()
+
+file(GLOB_RECURSE actual_syms LIST_DIRECTORIES true "${CMAKE_BINARY_DIR}/dest2/*")
+if(NOT actual_syms MATCHES "^${syms}$")
+ message(SEND_ERROR "Expected files:\n\n ^${syms}$\n\nActual files:\n\n ${actual_syms}")
+endif()
+
+file(INSTALL
+ "${CMAKE_BINARY_DIR}/file1.txt.sym"
+ "${CMAKE_BINARY_DIR}/file2/file2.txt.sym"
+ "${CMAKE_BINARY_DIR}/file3.txt.sym"
+ "${CMAKE_BINARY_DIR}/file4/file4.txt.sym"
+ "${CMAKE_BINARY_DIR}/file5.txt"
+ "${CMAKE_BINARY_DIR}/file6/file6/file6.txt.sym.4"
+ "${CMAKE_BINARY_DIR}/file8/file8.txt.sym"
+ "${CMAKE_BINARY_DIR}/file7/../file7.txt"
+ "${CMAKE_BINARY_DIR}/file8.txt"
+ "${CMAKE_BINARY_DIR}/file9.sym/file9.txt"
+ "${CMAKE_BINARY_DIR}/file10/file10/file10.txt.sym"
+ DESTINATION "${CMAKE_BINARY_DIR}/dest3"
+ )
+
+set(resolved_file1.txt.sym [[^file1\.txt$]])
+set(resolved_file10.txt.sym [[/Tests/RunCMake/file/INSTALL-FOLLOW_SYMLINK_CHAIN-build/file10/file10/\.\./file10\.txt$]])
+set(resolved_file2.txt.sym [[^\.\./file2\.txt$]])
+set(resolved_file3.txt.sym [[/Tests/RunCMake/file/INSTALL-FOLLOW_SYMLINK_CHAIN-build/file3\.txt$]])
+set(resolved_file4.txt.sym [[/Tests/RunCMake/file/INSTALL-FOLLOW_SYMLINK_CHAIN-build/file4\.txt$]])
+set(resolved_file6.txt.sym.4 [[^file6\.txt\.sym\.3$]])
+set(resolved_file8.txt.sym [[/Tests/RunCMake/file/INSTALL-FOLLOW_SYMLINK_CHAIN-build/file8/\.\./file8\.txt$]])
+set(syms)
+foreach(f
+ file1.txt.sym
+ file10.txt.sym
+ file2.txt.sym
+ file3.txt.sym
+ file4.txt.sym
+ file5.txt
+ file6.txt.sym.4
+ file7.txt
+ file8.txt
+ file8.txt.sym
+ file9.txt
+ )
+ string(REPLACE "." "\\." r "${f}")
+ list(APPEND syms "[^;]*/Tests/RunCMake/file/INSTALL-FOLLOW_SYMLINK_CHAIN-build/dest3/${r}")
+ set(filename "${CMAKE_BINARY_DIR}/dest3/${f}")
+ if(DEFINED resolved_${f})
+ file(READ_SYMLINK "${filename}" resolved)
+ if(NOT resolved MATCHES "${resolved_${f}}")
+ message(SEND_ERROR "Expected symlink resolution for ${f}: ${resolved_${f}}\nActual resolution: ${resolved}")
+ endif()
+ elseif(NOT EXISTS "${filename}" OR IS_SYMLINK "${filename}" OR IS_DIRECTORY "${filename}")
+ message(SEND_ERROR "${f} should be a regular file")
+ endif()
+endforeach()
+
+file(GLOB_RECURSE actual_syms LIST_DIRECTORIES true "${CMAKE_BINARY_DIR}/dest3/*")
+if(NOT actual_syms MATCHES "^${syms}$")
+ message(SEND_ERROR "Expected files:\n\n ^${syms}$\n\nActual files:\n\n ${actual_syms}")
+endif()
diff --git a/Tests/RunCMake/file/RunCMakeTest.cmake b/Tests/RunCMake/file/RunCMakeTest.cmake
index 128e8f3..996d1c5 100644
--- a/Tests/RunCMake/file/RunCMakeTest.cmake
+++ b/Tests/RunCMake/file/RunCMakeTest.cmake
@@ -64,6 +64,7 @@ if(NOT WIN32 OR CYGWIN)
run_cmake(READ_SYMLINK)
run_cmake(READ_SYMLINK-noexist)
run_cmake(READ_SYMLINK-notsymlink)
+ run_cmake(INSTALL-FOLLOW_SYMLINK_CHAIN)
endif()
if(RunCMake_GENERATOR STREQUAL "Ninja")
diff --git a/Tests/WarnUnusedCliUnused/CMakeLists.txt b/Tests/WarnUnusedCliUnused/CMakeLists.txt
index 7ed69bf..a149f04 100644
--- a/Tests/WarnUnusedCliUnused/CMakeLists.txt
+++ b/Tests/WarnUnusedCliUnused/CMakeLists.txt
@@ -1,9 +1,9 @@
-cmake_minimum_required(VERSION 2.8)
+cmake_minimum_required(VERSION 3.14)
project(WarnUnusedCliUnused)
-set_directory_properties(PROPERTIES
- ADDITIONAL_MAKE_CLEAN_FILES "${CMAKE_BINARY_DIR}/CMakeCache.txt"
-)
+# Remove UNUSED_CLI_VARIABLE from the cache to trigger the
+# CMake warning message on re-builds as well.
+unset(UNUSED_CLI_VARIABLE CACHE)
add_library(dummy empty.cpp)