summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTING.rst14
-rw-r--r--CompileFlags.cmake4
-rw-r--r--Help/command/FIND_XXX.txt5
-rw-r--r--Help/command/add_custom_command.rst2
-rw-r--r--Help/command/add_library.rst9
-rw-r--r--Help/command/find_package.rst5
-rw-r--r--Help/command/if.rst3
-rw-r--r--Help/command/install.rst23
-rw-r--r--Help/command/string.rst52
-rw-r--r--Help/dev/README.rst9
-rw-r--r--Help/dev/source.rst42
-rw-r--r--Help/generator/Visual Studio 7 .NET 2003.rst10
-rw-r--r--Help/manual/cmake-buildsystem.7.rst12
-rw-r--r--Help/manual/cmake-developer.7.rst24
-rw-r--r--Help/manual/cmake-generator-expressions.7.rst4
-rw-r--r--Help/manual/cmake-properties.7.rst2
-rw-r--r--Help/manual/cmake-variables.7.rst2
-rw-r--r--Help/prop_dir/VS_GLOBAL_SECTION_POST_section.rst2
-rw-r--r--Help/prop_dir/VS_GLOBAL_SECTION_PRE_section.rst2
-rw-r--r--Help/prop_tgt/EXCLUDE_FROM_DEFAULT_BUILD.rst2
-rw-r--r--Help/prop_tgt/IMPORTED_OBJECTS.rst11
-rw-r--r--Help/prop_tgt/IMPORTED_OBJECTS_CONFIG.rst7
-rw-r--r--Help/prop_tgt/INTERPROCEDURAL_OPTIMIZATION_CONFIG.rst4
-rw-r--r--Help/release/dev/FindMPI-add-imported-targets.rst4
-rw-r--r--Help/release/dev/add_custom_command-TARGET_OBJECTS.rst6
-rw-r--r--Help/release/dev/add_library-TARGET_OBJECTS.rst5
-rw-r--r--Help/release/dev/cpackifw-search-algorithm.rst7
-rw-r--r--Help/release/dev/file-GENERATE-TARGET_OBJECTS.rst6
-rw-r--r--Help/release/dev/install-TARGET_OBJECTS.rst8
-rw-r--r--Help/release/dev/remove-vs7.1-generator.rst4
-rw-r--r--Help/variable/CMAKE_CFG_INTDIR.rst2
-rw-r--r--Help/variable/CMAKE_INTERPROCEDURAL_OPTIMIZATION_CONFIG.rst8
-rw-r--r--Help/variable/CMAKE_MATCH_COUNT.rst7
-rw-r--r--Help/variable/CMAKE_MATCH_n.rst10
-rw-r--r--Help/variable/CMAKE_MFC_FLAG.rst2
-rw-r--r--Help/variable/CMAKE_VS_DEVENV_COMMAND.rst2
-rw-r--r--Help/variable/CMAKE_VS_INTEL_Fortran_PROJECT_VERSION.rst2
-rw-r--r--Modules/AutogenInfo.cmake.in1
-rw-r--r--Modules/CMakeBackwardCompatibilityC.cmake6
-rw-r--r--Modules/CMakeDetermineCSharpCompiler.cmake2
-rw-r--r--Modules/CMakeDetermineCUDACompiler.cmake2
-rw-r--r--Modules/CMakeVS7BackwardCompatibility.cmake16
-rw-r--r--Modules/CPackIFW.cmake53
-rw-r--r--Modules/CTest.cmake6
-rw-r--r--Modules/Compiler/Intel.cmake2
-rw-r--r--Modules/FindBoost.cmake5
-rw-r--r--Modules/FindMPI.cmake30
-rw-r--r--Modules/FindOpenSSL.cmake4
-rw-r--r--Modules/FindwxWidgets.cmake22
-rw-r--r--Modules/Platform/Linux-GNU.cmake1
-rw-r--r--Modules/Platform/Linux-TinyCC-C.cmake1
-rw-r--r--Modules/Platform/Windows-df.cmake2
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/CPack/OSXScriptLauncher.cxx2
-rw-r--r--Source/QtDialog/CMakeLists.txt2
-rw-r--r--Source/QtDialog/cmake-gui.desktop (renamed from Source/QtDialog/CMake.desktop)0
-rw-r--r--Source/cmAddLibraryCommand.cxx13
-rw-r--r--Source/cmExportBuildFileGenerator.cxx60
-rw-r--r--Source/cmExportCommand.cxx14
-rw-r--r--Source/cmExportFileGenerator.cxx8
-rw-r--r--Source/cmExportInstallFileGenerator.cxx19
-rw-r--r--Source/cmFileCommand.cxx61
-rw-r--r--Source/cmGeneratorExpressionEvaluationFile.cxx6
-rw-r--r--Source/cmGeneratorExpressionNode.cxx86
-rw-r--r--Source/cmGeneratorTarget.cxx114
-rw-r--r--Source/cmGeneratorTarget.h31
-rw-r--r--Source/cmGlobalGenerator.h5
-rw-r--r--Source/cmGlobalVisualStudio71Generator.cxx68
-rw-r--r--Source/cmGlobalVisualStudio71Generator.h29
-rw-r--r--Source/cmGlobalVisualStudio7Generator.cxx14
-rw-r--r--Source/cmGlobalVisualStudio8Generator.cxx7
-rw-r--r--Source/cmGlobalVisualStudio8Generator.h3
-rw-r--r--Source/cmGlobalVisualStudioGenerator.h2
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx96
-rw-r--r--Source/cmGlobalXCodeGenerator.h2
-rw-r--r--Source/cmInstallCommand.cxx50
-rw-r--r--Source/cmInstallTargetGenerator.cxx88
-rw-r--r--Source/cmInstallTargetGenerator.h6
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx113
-rw-r--r--Source/cmLocalVisualStudio7Generator.h3
-rw-r--r--Source/cmQtAutoGeneratorInitializer.cxx45
-rw-r--r--Source/cmQtAutoGenerators.cxx63
-rw-r--r--Source/cmQtAutoGenerators.h8
-rw-r--r--Source/cmSystemTools.cxx2
-rw-r--r--Source/cmTarget.cxx41
-rw-r--r--Source/cmTargetExport.h1
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx69
-rw-r--r--Source/cmVisualStudio10TargetGenerator.h1
-rw-r--r--Source/cmVisualStudioGeneratorOptions.cxx4
-rw-r--r--Source/cmake.cxx5
-rw-r--r--Source/kwsys/CMakeLists.txt1
-rw-r--r--Source/kwsys/Encoding.hxx.in11
-rw-r--r--Source/kwsys/EncodingCXX.cxx58
-rw-r--r--Source/kwsys/FStream.hxx.in4
-rw-r--r--Source/kwsys/SystemTools.cxx138
-rw-r--r--Source/kwsys/SystemTools.hxx.in8
-rw-r--r--Source/kwsys/testEncoding.cxx83
-rw-r--r--Source/kwsys/testSystemTools.cxx79
-rw-r--r--Tests/BuildDepends/CMakeLists.txt2
-rw-r--r--Tests/CMakeLists.txt31
-rw-r--r--Tests/CMakeOnly/CMakeLists.txt2
-rw-r--r--Tests/CMakeTestAllGenerators/RunCMake.cmake57
-rw-r--r--Tests/ExportImport/Export/CMakeLists.txt13
-rw-r--r--Tests/ExportImport/Export/sub/testLib8C.c4
-rw-r--r--Tests/ExportImport/Export/testLib8A.c4
-rw-r--r--Tests/ExportImport/Export/testLib8B.c4
-rw-r--r--Tests/ExportImport/Import/A/CMakeLists.txt10
-rw-r--r--Tests/ExportImport/Import/A/imp_testExe1.c24
-rw-r--r--Tests/ExportImport/Import/A/imp_testLib8.c8
-rw-r--r--Tests/FindMPI/CMakeLists.txt21
-rw-r--r--Tests/FindMPI/Test/CMakeLists.txt41
-rw-r--r--Tests/FindMPI/Test/main.c7
-rw-r--r--Tests/FindMPI/Test/main.f907
-rw-r--r--Tests/GeneratorExpression/CMakeLists.txt16
-rw-r--r--Tests/GeneratorExpression/check_object_files.cmake26
-rw-r--r--Tests/GeneratorExpression/objlib1.c4
-rw-r--r--Tests/GeneratorExpression/objlib2.c4
-rw-r--r--Tests/Module/CheckIPOSupported-C/CMakeLists.txt19
-rw-r--r--Tests/Module/CheckIPOSupported-C/foo.c4
-rw-r--r--Tests/Module/CheckIPOSupported-C/main.c9
-rw-r--r--Tests/Module/CheckIPOSupported-CXX/CMakeLists.txt19
-rw-r--r--Tests/Module/CheckIPOSupported-CXX/foo.cpp4
-rw-r--r--Tests/Module/CheckIPOSupported-CXX/main.cpp9
-rw-r--r--Tests/Module/CheckIPOSupported-Fortran/CMakeLists.txt19
-rw-r--r--Tests/Module/CheckIPOSupported-Fortran/foo.f2
-rw-r--r--Tests/Module/CheckIPOSupported-Fortran/main.f3
-rw-r--r--Tests/ObjectLibrary/CMakeLists.txt6
-rw-r--r--Tests/Preprocess/CMakeLists.txt10
-rw-r--r--Tests/RunCMake/BuildDepends/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/CMP0026/CMP0026-OLD.cmake12
-rw-r--r--Tests/RunCMake/CMP0026/RunCMakeTest.cmake1
-rw-r--r--Tests/RunCMake/CMakeLists.txt4
-rw-r--r--Tests/RunCMake/CommandLine/DeprecateVS71-WARN-ON-stderr.txt5
-rw-r--r--Tests/RunCMake/CommandLine/RunCMakeTest.cmake7
-rw-r--r--Tests/RunCMake/File_Generate/OutputConflict-stderr.txt5
-rw-r--r--Tests/RunCMake/File_Generate/OutputNameMatchesObjects-stderr.txt7
-rw-r--r--Tests/RunCMake/File_Generate/OutputNameMatchesObjects.cmake1
-rw-r--r--Tests/RunCMake/ObjectLibrary/Export-stderr.txt4
-rw-r--r--Tests/RunCMake/ObjectLibrary/ExportNotSupported-result.txt (renamed from Tests/RunCMake/TargetObjects/BadContext-result.txt)0
-rw-r--r--Tests/RunCMake/ObjectLibrary/ExportNotSupported-stderr.txt5
-rw-r--r--Tests/RunCMake/ObjectLibrary/ExportNotSupported.cmake2
-rw-r--r--Tests/RunCMake/ObjectLibrary/Import.cmake11
-rw-r--r--Tests/RunCMake/ObjectLibrary/ImportNotSupported-result.txt (renamed from Tests/RunCMake/ObjectLibrary/Install-result.txt)0
-rw-r--r--Tests/RunCMake/ObjectLibrary/ImportNotSupported-stderr.txt (renamed from Tests/RunCMake/ObjectLibrary/Import-stderr.txt)5
-rw-r--r--Tests/RunCMake/ObjectLibrary/ImportNotSupported.cmake1
-rw-r--r--Tests/RunCMake/ObjectLibrary/InstallNotSupported-result.txt (renamed from Tests/RunCMake/ObjectLibrary/Import-result.txt)0
-rw-r--r--Tests/RunCMake/ObjectLibrary/InstallNotSupported-stderr.txt (renamed from Tests/RunCMake/ObjectLibrary/Install-stderr.txt)5
-rw-r--r--Tests/RunCMake/ObjectLibrary/InstallNotSupported.cmake2
-rw-r--r--Tests/RunCMake/ObjectLibrary/RunCMakeTest.cmake12
-rw-r--r--Tests/RunCMake/ObjectLibrary/b.c4
-rw-r--r--Tests/RunCMake/RunCMake.cmake3
-rw-r--r--Tests/RunCMake/TargetObjects/BadContext-stderr.txt27
-rw-r--r--Tests/RunCMake/TargetObjects/NoTarget-result.txt (renamed from Tests/RunCMake/ObjectLibrary/Export-result.txt)0
-rw-r--r--Tests/RunCMake/TargetObjects/NoTarget-stderr.txt24
-rw-r--r--Tests/RunCMake/TargetObjects/NoTarget.cmake (renamed from Tests/RunCMake/TargetObjects/BadContext.cmake)0
-rw-r--r--Tests/RunCMake/TargetObjects/NotObjlibTarget-result.txt1
-rw-r--r--Tests/RunCMake/TargetObjects/NotObjlibTarget-stderr.txt8
-rw-r--r--Tests/RunCMake/TargetObjects/NotObjlibTarget.cmake3
-rw-r--r--Tests/RunCMake/TargetObjects/RunCMakeTest.cmake3
-rw-r--r--Tests/RunCMake/TargetObjects/empty.cpp4
-rw-r--r--Tests/RunCMake/VSSolution/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/file/INSTALL-FILES_FROM_DIR-bad-result.txt1
-rw-r--r--Tests/RunCMake/file/INSTALL-FILES_FROM_DIR-bad-stderr.txt15
-rw-r--r--Tests/RunCMake/file/INSTALL-FILES_FROM_DIR-bad.cmake5
-rw-r--r--Tests/RunCMake/file/INSTALL-FILES_FROM_DIR-stdout.txt8
-rw-r--r--Tests/RunCMake/file/INSTALL-FILES_FROM_DIR.cmake7
-rw-r--r--Tests/RunCMake/file/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/file/from/a.txt (renamed from Tests/RunCMake/CommandLine/DeprecateVS71-WARN-ON.cmake)0
-rw-r--r--Tests/RunCMake/file/from/a/b.txt (renamed from Tests/RunCMake/CommandLine/DeprecateVS71-WARN-OFF.cmake)0
-rw-r--r--Tests/RunCMake/file/from/a/b/c.txt0
170 files changed, 1746 insertions, 852 deletions
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
index 434f0f4..e219763 100644
--- a/CONTRIBUTING.rst
+++ b/CONTRIBUTING.rst
@@ -25,6 +25,7 @@ To contribute patches:
#. Fork the upstream `CMake Repository`_ into a personal account.
#. Run `Utilities/SetupForDevelopment.sh`_ for local configuration.
+#. See the `CMake Source Code Guide`_ for coding guidelines.
#. Base all new work on the upstream ``master`` branch.
#. Create commits making incremental, distinct, logically complete changes.
#. Push a topic branch to a personal repository fork on GitLab.
@@ -35,20 +36,9 @@ The merge request will enter the `CMake Review Process`_ for consideration.
.. _`Kitware's GitLab Instance`: https://gitlab.kitware.com
.. _`CMake Repository`: https://gitlab.kitware.com/cmake/cmake
.. _`Utilities/SetupForDevelopment.sh`: Utilities/SetupForDevelopment.sh
+.. _`CMake Source Code Guide`: Help/dev/source.rst
.. _`CMake Review Process`: Help/dev/review.rst
-Code Style
-==========
-
-We use `clang-format`_ to define our style for C++ code in the CMake source
-tree. See the `.clang-format`_ configuration file for our style settings.
-Use ``clang-format`` version 3.8 or higher to format source files.
-See also the `Utilities/Scripts/clang-format.bash`_ script.
-
-.. _`clang-format`: http://clang.llvm.org/docs/ClangFormat.html
-.. _`.clang-format`: .clang-format
-.. _`Utilities/Scripts/clang-format.bash`: Utilities/Scripts/clang-format.bash
-
License
=======
diff --git a/CompileFlags.cmake b/CompileFlags.cmake
index c875e6f..d70e3af 100644
--- a/CompileFlags.cmake
+++ b/CompileFlags.cmake
@@ -4,10 +4,6 @@
#-----------------------------------------------------------------------------
# set some special flags for different compilers
#
-if(CMAKE_GENERATOR MATCHES "Visual Studio 7")
- set(CMAKE_SKIP_COMPATIBILITY_TESTS 1)
-endif()
-
if(WIN32 AND CMAKE_C_COMPILER_ID STREQUAL "Intel")
set(_INTEL_WINDOWS 1)
endif()
diff --git a/Help/command/FIND_XXX.txt b/Help/command/FIND_XXX.txt
index bd4d295..2f27764 100644
--- a/Help/command/FIND_XXX.txt
+++ b/Help/command/FIND_XXX.txt
@@ -73,6 +73,7 @@ If ``NO_DEFAULT_PATH`` is not specified, the search process is as follows:
1. Search paths specified in cmake-specific cache variables.
These are intended to be used on the command line with a ``-DVAR=value``.
+ The values are interpreted as :ref:`;-lists <CMake Language Lists>`.
This can be skipped if ``NO_CMAKE_PATH`` is passed.
* |CMAKE_PREFIX_PATH_XXX|
@@ -80,7 +81,9 @@ If ``NO_DEFAULT_PATH`` is not specified, the search process is as follows:
* |CMAKE_XXX_MAC_PATH|
2. Search paths specified in cmake-specific environment variables.
- These are intended to be set in the user's shell configuration.
+ These are intended to be set in the user's shell configuration,
+ and therefore use the host's native path separator
+ (``;`` on Windows and ``:`` on UNIX).
This can be skipped if ``NO_CMAKE_ENVIRONMENT_PATH`` is passed.
* |CMAKE_PREFIX_PATH_XXX|
diff --git a/Help/command/add_custom_command.rst b/Help/command/add_custom_command.rst
index 80e7edf..d038406 100644
--- a/Help/command/add_custom_command.rst
+++ b/Help/command/add_custom_command.rst
@@ -215,7 +215,7 @@ of the following is specified:
``PRE_BUILD``
Run before any other rules are executed within the target.
- This is supported only on Visual Studio 7 or later.
+ This is supported only on Visual Studio 8 or later.
For all other generators ``PRE_BUILD`` will be treated as
``PRE_LINK``.
``PRE_LINK``
diff --git a/Help/command/add_library.rst b/Help/command/add_library.rst
index af75a39..3a76040 100644
--- a/Help/command/add_library.rst
+++ b/Help/command/add_library.rst
@@ -64,7 +64,7 @@ Imported Libraries
::
- add_library(<name> <SHARED|STATIC|MODULE|UNKNOWN> IMPORTED
+ add_library(<name> <SHARED|STATIC|MODULE|OBJECT|UNKNOWN> IMPORTED
[GLOBAL])
An :ref:`IMPORTED library target <Imported Targets>` references a library
@@ -106,10 +106,9 @@ may contain only sources that compile, header files, and other files
that would not affect linking of a normal library (e.g. ``.txt``).
They may contain custom commands generating such sources, but not
``PRE_BUILD``, ``PRE_LINK``, or ``POST_BUILD`` commands. Object libraries
-cannot be imported, exported, installed, or linked. Some native build
-systems may not like targets that have only object files, so consider
-adding at least one real source file to any target that references
-``$<TARGET_OBJECTS:objlib>``.
+cannot be linked. Some native build systems may not like targets that
+have only object files, so consider adding at least one real source file
+to any target that references ``$<TARGET_OBJECTS:objlib>``.
Alias Libraries
^^^^^^^^^^^^^^^
diff --git a/Help/command/find_package.rst b/Help/command/find_package.rst
index 2cb1e5f..60a77b8 100644
--- a/Help/command/find_package.rst
+++ b/Help/command/find_package.rst
@@ -251,6 +251,7 @@ enabled.
1. Search paths specified in cmake-specific cache variables. These
are intended to be used on the command line with a ``-DVAR=value``.
+ The values are interpreted as :ref:`;-lists <CMake Language Lists>`.
This can be skipped if ``NO_CMAKE_PATH`` is passed::
CMAKE_PREFIX_PATH
@@ -258,7 +259,9 @@ enabled.
CMAKE_APPBUNDLE_PATH
2. Search paths specified in cmake-specific environment variables.
- These are intended to be set in the user's shell configuration.
+ These are intended to be set in the user's shell configuration,
+ and therefore use the host's native path separator
+ (``;`` on Windows and ``:`` on UNIX).
This can be skipped if ``NO_CMAKE_ENVIRONMENT_PATH`` is passed::
<package>_DIR
diff --git a/Help/command/if.rst b/Help/command/if.rst
index 2a087d0..edd343d 100644
--- a/Help/command/if.rst
+++ b/Help/command/if.rst
@@ -103,7 +103,8 @@ Possible expressions are:
``if(<variable|string> MATCHES regex)``
True if the given string or variable's value matches the given regular
- expression.
+ expression. See :ref:`Regex Specification` for regex format.
+ ``()`` groups are captured in :variable:`CMAKE_MATCH_<n>` variables.
``if(<variable|string> LESS <variable|string>)``
True if the given string or variable's value is a valid number and less
diff --git a/Help/command/install.rst b/Help/command/install.rst
index 70087a4..58438b7 100644
--- a/Help/command/install.rst
+++ b/Help/command/install.rst
@@ -73,7 +73,7 @@ Installing Targets
::
install(TARGETS targets... [EXPORT <export-name>]
- [[ARCHIVE|LIBRARY|RUNTIME|FRAMEWORK|BUNDLE|
+ [[ARCHIVE|LIBRARY|RUNTIME|OBJECTS|FRAMEWORK|BUNDLE|
PRIVATE_HEADER|PUBLIC_HEADER|RESOURCE]
[DESTINATION <dir>]
[PERMISSIONS permissions...]
@@ -86,10 +86,10 @@ Installing Targets
)
The ``TARGETS`` form specifies rules for installing targets from a
-project. There are five kinds of target files that may be installed:
-``ARCHIVE``, ``LIBRARY``, ``RUNTIME``, ``FRAMEWORK``, and ``BUNDLE``.
-Executables are treated as ``RUNTIME`` targets, except that those
-marked with the ``MACOSX_BUNDLE`` property are treated as ``BUNDLE``
+project. There are six kinds of target files that may be installed:
+``ARCHIVE``, ``LIBRARY``, ``RUNTIME``, ``OBJECTS``, ``FRAMEWORK``, and
+``BUNDLE``. Executables are treated as ``RUNTIME`` targets, except that
+those marked with the ``MACOSX_BUNDLE`` property are treated as ``BUNDLE``
targets on OS X. Static libraries are treated as ``ARCHIVE`` targets,
except that those marked with the ``FRAMEWORK`` property are treated
as ``FRAMEWORK`` targets on OS X.
@@ -99,10 +99,11 @@ targets, except that those marked with the ``FRAMEWORK`` property are
treated as ``FRAMEWORK`` targets on OS X. For DLL platforms the DLL
part of a shared library is treated as a ``RUNTIME`` target and the
corresponding import library is treated as an ``ARCHIVE`` target.
-All Windows-based systems including Cygwin are DLL platforms.
-The ``ARCHIVE``, ``LIBRARY``, ``RUNTIME``, and ``FRAMEWORK`` arguments
-change the type of target to which the subsequent properties apply.
-If none is given the installation properties apply to all target
+All Windows-based systems including Cygwin are DLL platforms. Object
+libraries are always treated as ``OBJECTS`` targets.
+The ``ARCHIVE``, ``LIBRARY``, ``RUNTIME``, ``OBJECTS``, and ``FRAMEWORK``
+arguments change the type of target to which the subsequent properties
+apply. If none is given the installation properties apply to all target
types. If only one is given then only targets of that type will be
installed (which can be used to install just a DLL or just an import
library).
@@ -165,8 +166,8 @@ the ``mySharedLib`` DLL will be installed to ``<prefix>/bin`` and
The ``EXPORT`` option associates the installed target files with an
export called ``<export-name>``. It must appear before any ``RUNTIME``,
-``LIBRARY``, or ``ARCHIVE`` options. To actually install the export
-file itself, call ``install(EXPORT)``, documented below.
+``LIBRARY``, ``ARCHIVE``, or ``OBJECTS`` options. To actually install the
+export file itself, call ``install(EXPORT)``, documented below.
Installing a target with the :prop_tgt:`EXCLUDE_FROM_ALL` target property
set to ``TRUE`` has undefined behavior.
diff --git a/Help/command/string.rst b/Help/command/string.rst
index 698a91d..4f0c45c 100644
--- a/Help/command/string.rst
+++ b/Help/command/string.rst
@@ -77,31 +77,43 @@ The replace expression may refer to paren-delimited subexpressions of the
match using ``\1``, ``\2``, ..., ``\9``. Note that two backslashes (``\\1``)
are required in CMake code to get a backslash through argument parsing.
+.. _`Regex Specification`:
+
Regex Specification
"""""""""""""""""""
The following characters have special meaning in regular expressions:
-::
-
- ^ Matches at beginning of input
- $ Matches at end of input
- . Matches any single character
- [ ] Matches any character(s) inside the brackets
- [^ ] Matches any character(s) not inside the brackets
- - Inside brackets, specifies an inclusive range between
- characters on either side e.g. [a-f] is [abcdef]
- To match a literal - using brackets, make it the first
- or the last character e.g. [+*/-] matches basic
- mathematical operators.
- * Matches preceding pattern zero or more times
- + Matches preceding pattern one or more times
- ? Matches preceding pattern zero or once only
- | Matches a pattern on either side of the |
- () Saves a matched subexpression, which can be referenced
- in the REGEX REPLACE operation. Additionally it is saved
- by all regular expression-related commands, including
- e.g. if( MATCHES ), in the variables CMAKE_MATCH_(0..9).
+``^``
+ Matches at beginning of input
+``$``
+ Matches at end of input
+``.``
+ Matches any single character
+``[ ]``
+ Matches any character(s) inside the brackets
+``[^ ]``
+ Matches any character(s) not inside the brackets
+``-``
+ Inside brackets, specifies an inclusive range between
+ characters on either side e.g. ``[a-f]`` is ``[abcdef]``
+ To match a literal ``-`` using brackets, make it the first
+ or the last character e.g. ``[+*/-]`` matches basic
+ mathematical operators.
+``*``
+ Matches preceding pattern zero or more times
+``+``
+ Matches preceding pattern one or more times
+``?``
+ Matches preceding pattern zero or once only
+``|``
+ Matches a pattern on either side of the ``|``
+``()``
+ Saves a matched subexpression, which can be referenced
+ in the ``REGEX REPLACE`` operation. Additionally it is saved
+ by all regular expression-related commands, including
+ e.g. :command:`if(MATCHES)`, in the variables
+ :variable:`CMAKE_MATCH_<n>` for ``<n>`` 0..9.
``*``, ``+`` and ``?`` have higher precedence than concatenation. ``|``
has lower precedence than concatenation. This means that the regular
diff --git a/Help/dev/README.rst b/Help/dev/README.rst
index 0dc512a..163be97 100644
--- a/Help/dev/README.rst
+++ b/Help/dev/README.rst
@@ -29,3 +29,12 @@ following documents:
.. _`CMake Repository`: https://gitlab.kitware.com/cmake/cmake
.. _`CMake Review Process`: review.rst
.. _`CMake Testing Process`: testing.rst
+
+Developer Documentation
+=======================
+
+CMake developer documentation is provided by the following documents:
+
+* The `CMake Source Code Guide`_.
+
+.. _`CMake Source Code Guide`: source.rst
diff --git a/Help/dev/source.rst b/Help/dev/source.rst
new file mode 100644
index 0000000..3ac9aca
--- /dev/null
+++ b/Help/dev/source.rst
@@ -0,0 +1,42 @@
+CMake Source Code Guide
+***********************
+
+The following is a guide to the CMake source code for developers.
+See documentation on `CMake Development`_ for more information.
+
+.. _`CMake Development`: README.rst
+
+C++ Code Style
+==============
+
+We use `clang-format`_ version **3.8** to define our style for C++ code in
+the CMake source tree. See the `.clang-format`_ configuration file for our
+style settings. Use the `Utilities/Scripts/clang-format.bash`_ script to
+format source code. It automatically runs ``clang-format`` on the set of
+source files for which we enforce style. The script also has options to
+format only a subset of files, such as those that are locally modified.
+
+.. _`clang-format`: http://clang.llvm.org/docs/ClangFormat.html
+.. _`.clang-format`: ../../.clang-format
+.. _`Utilities/Scripts/clang-format.bash`: ../../Utilities/Scripts/clang-format.bash
+
+C++ Subset Permitted
+====================
+
+CMake supports compiling as C++98 in addition to C++11 and C++14.
+In order to support building on older toolchains some constructs
+need to be handled with care:
+
+* Use ``CM_AUTO_PTR`` instead of ``std::auto_ptr``.
+
+ The ``std::auto_ptr`` template is deprecated in C++11. We want to use it
+ so we can build on C++98 compilers but we do not want to turn off compiler
+ warnings about deprecated interfaces in general. Use the ``CM_AUTO_PTR``
+ macro instead.
+
+* Use ``size_t`` instead of ``std::size_t``.
+
+ Various implementations have differing implementation of ``size_t``.
+ When assigning the result of ``.size()`` on a container for example,
+ the result should be assigned to ``size_t`` not to ``std::size_t``,
+ ``unsigned int`` or similar types.
diff --git a/Help/generator/Visual Studio 7 .NET 2003.rst b/Help/generator/Visual Studio 7 .NET 2003.rst
index 1c086a0..d4c7869 100644
--- a/Help/generator/Visual Studio 7 .NET 2003.rst
+++ b/Help/generator/Visual Studio 7 .NET 2003.rst
@@ -1,10 +1,6 @@
Visual Studio 7 .NET 2003
-------------------------
-Deprecated. Generates Visual Studio .NET 2003 project files.
-
-.. note::
- This generator is deprecated and will be removed
- in a future version of CMake. It will still be
- possible to build with VS 7.1 tools using the
- :generator:`NMake Makefiles` generator.
+Removed. This once generated Visual Studio .NET 2003 project files, but
+the generator has been removed since CMake 3.9. It is still possible to
+build with VS 7.1 tools using the :generator:`NMake Makefiles` generator.
diff --git a/Help/manual/cmake-buildsystem.7.rst b/Help/manual/cmake-buildsystem.7.rst
index 2e6a803..95f5b87 100644
--- a/Help/manual/cmake-buildsystem.7.rst
+++ b/Help/manual/cmake-buildsystem.7.rst
@@ -125,10 +125,10 @@ The object files collection can be used as source inputs to other targets:
add_executable(test_exe $<TARGET_OBJECTS:archive> test.cpp)
-``OBJECT`` libraries may only be used locally as sources in a buildsystem --
-they may not be installed, exported, or used in the right hand side of
+``OBJECT`` libraries may not be used in the right hand side of
:command:`target_link_libraries`. They also may not be used as the ``TARGET``
-in a use of the :command:`add_custom_command(TARGET)` command signature.
+in a use of the :command:`add_custom_command(TARGET)` command signature. They
+may be installed, and will be exported as an INTERFACE library.
Although object libraries may not be named directly in calls to
the :command:`target_link_libraries` command, they can be "linked"
@@ -136,6 +136,12 @@ indirectly by using an :ref:`Interface Library <Interface Libraries>`
whose :prop_tgt:`INTERFACE_SOURCES` target property is set to name
``$<TARGET_OBJECTS:objlib>``.
+Although object libraries may not be used as the ``TARGET``
+in a use of the :command:`add_custom_command(TARGET)` command signature,
+the list of objects can be used by :command:`add_custom_command(OUTPUT)` or
+:command:`file(GENERATE)` by using ``$<TARGET_OBJECTS:objlib>``.
+
+
Build Specification and Usage Requirements
==========================================
diff --git a/Help/manual/cmake-developer.7.rst b/Help/manual/cmake-developer.7.rst
index f77d8c0..cd509ac 100644
--- a/Help/manual/cmake-developer.7.rst
+++ b/Help/manual/cmake-developer.7.rst
@@ -13,30 +13,6 @@ Introduction
This manual is intended for reference by developers modifying the CMake
source tree itself, and by those authoring externally-maintained modules.
-
-Permitted C++ Subset
-====================
-
-CMake is required to build with ancient C++ compilers and standard library
-implementations. Some common C++ constructs may not be used in CMake in order
-to build with such toolchains.
-
-std::auto_ptr
--------------
-
-The ``std::auto_ptr`` template is deprecated in C++11. We want to use it
-so we can build on C++98 compilers but we do not want to turn off compiler
-warnings about deprecated interfaces in general. Use the ``CM_AUTO_PTR``
-macro instead.
-
-size_t
-------
-
-Various implementations have differing implementation of ``size_t``. When
-assigning the result of ``.size()`` on a container for example, the result
-should be assigned to ``size_t`` not to ``std::size_t``, ``unsigned int`` or
-similar types.
-
Adding Compile Features
=======================
diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst
index 3eac45f..bddb174 100644
--- a/Help/manual/cmake-generator-expressions.7.rst
+++ b/Help/manual/cmake-generator-expressions.7.rst
@@ -290,9 +290,7 @@ Available output expressions are:
Content of ``...`` converted to a C identifier.
``$<TARGET_OBJECTS:objLib>``
List of objects resulting from build of ``objLib``. ``objLib`` must be an
- object of type ``OBJECT_LIBRARY``. This expression may only be used in
- the sources of :command:`add_library` and :command:`add_executable`
- commands.
+ object of type ``OBJECT_LIBRARY``.
``$<SHELL_PATH:...>``
Content of ``...`` converted to shell path style. For example, slashes are
converted to backslashes in Windows shells and drive letters are converted
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index 27c75dc..31b2389 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -194,6 +194,8 @@ Properties on Targets
/prop_tgt/IMPORTED_LOCATION
/prop_tgt/IMPORTED_NO_SONAME_CONFIG
/prop_tgt/IMPORTED_NO_SONAME
+ /prop_tgt/IMPORTED_OBJECTS_CONFIG
+ /prop_tgt/IMPORTED_OBJECTS
/prop_tgt/IMPORTED
/prop_tgt/IMPORTED_SONAME_CONFIG
/prop_tgt/IMPORTED_SONAME
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index 0a68815..4317f67 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -56,6 +56,7 @@ Variables that Provide Information
/variable/CMAKE_MAJOR_VERSION
/variable/CMAKE_MAKE_PROGRAM
/variable/CMAKE_MATCH_COUNT
+ /variable/CMAKE_MATCH_n
/variable/CMAKE_MINIMUM_REQUIRED_VERSION
/variable/CMAKE_MINOR_VERSION
/variable/CMAKE_PARENT_LIST_FILE
@@ -292,6 +293,7 @@ Variables that Control the Build
/variable/CMAKE_INSTALL_RPATH
/variable/CMAKE_INSTALL_RPATH_USE_LINK_PATH
/variable/CMAKE_INTERPROCEDURAL_OPTIMIZATION
+ /variable/CMAKE_INTERPROCEDURAL_OPTIMIZATION_CONFIG
/variable/CMAKE_IOS_INSTALL_COMBINED
/variable/CMAKE_LANG_CLANG_TIDY
/variable/CMAKE_LANG_COMPILER_LAUNCHER
diff --git a/Help/prop_dir/VS_GLOBAL_SECTION_POST_section.rst b/Help/prop_dir/VS_GLOBAL_SECTION_POST_section.rst
index eb91832..dcd2a4e 100644
--- a/Help/prop_dir/VS_GLOBAL_SECTION_POST_section.rst
+++ b/Help/prop_dir/VS_GLOBAL_SECTION_POST_section.rst
@@ -17,7 +17,7 @@ pairs. Each such pair will be transformed into an entry in the
solution global section. Whitespace around key and value is ignored.
List elements which do not contain an equal sign are skipped.
-This property only works for Visual Studio 7 and above; it is ignored
+This property only works for Visual Studio 8 and above; it is ignored
on other generators. The property only applies when set on a
directory whose CMakeLists.txt contains a project() command.
diff --git a/Help/prop_dir/VS_GLOBAL_SECTION_PRE_section.rst b/Help/prop_dir/VS_GLOBAL_SECTION_PRE_section.rst
index fbcd9e6..200e8e6 100644
--- a/Help/prop_dir/VS_GLOBAL_SECTION_PRE_section.rst
+++ b/Help/prop_dir/VS_GLOBAL_SECTION_PRE_section.rst
@@ -17,6 +17,6 @@ pairs. Each such pair will be transformed into an entry in the
solution global section. Whitespace around key and value is ignored.
List elements which do not contain an equal sign are skipped.
-This property only works for Visual Studio 7 and above; it is ignored
+This property only works for Visual Studio 8 and above; it is ignored
on other generators. The property only applies when set on a
directory whose CMakeLists.txt contains a project() command.
diff --git a/Help/prop_tgt/EXCLUDE_FROM_DEFAULT_BUILD.rst b/Help/prop_tgt/EXCLUDE_FROM_DEFAULT_BUILD.rst
index 19270a5..a14e48c 100644
--- a/Help/prop_tgt/EXCLUDE_FROM_DEFAULT_BUILD.rst
+++ b/Help/prop_tgt/EXCLUDE_FROM_DEFAULT_BUILD.rst
@@ -3,6 +3,6 @@ EXCLUDE_FROM_DEFAULT_BUILD
Exclude target from "Build Solution".
-This property is only used by Visual Studio generators 7 and above.
+This property is only used by Visual Studio generators.
When set to TRUE, the target will not be built when you press "Build
Solution".
diff --git a/Help/prop_tgt/IMPORTED_OBJECTS.rst b/Help/prop_tgt/IMPORTED_OBJECTS.rst
new file mode 100644
index 0000000..222e6cc
--- /dev/null
+++ b/Help/prop_tgt/IMPORTED_OBJECTS.rst
@@ -0,0 +1,11 @@
+IMPORTED_OBJECTS
+----------------
+
+:ref:`;-list <CMake Language Lists>` of absolute paths to the object
+files on disk for an :ref:`imported <Imported targets>`
+:ref:`object library <object libraries>`.
+
+Ignored for non-imported targets.
+
+Projects may skip ``IMPORTED_OBJECTS`` if the configuration-specific
+property :prop_tgt:`IMPORTED_OBJECTS_<CONFIG>` is set instead.
diff --git a/Help/prop_tgt/IMPORTED_OBJECTS_CONFIG.rst b/Help/prop_tgt/IMPORTED_OBJECTS_CONFIG.rst
new file mode 100644
index 0000000..4419ed1
--- /dev/null
+++ b/Help/prop_tgt/IMPORTED_OBJECTS_CONFIG.rst
@@ -0,0 +1,7 @@
+IMPORTED_OBJECTS_<CONFIG>
+-------------------------
+
+<CONFIG>-specific version of :prop_tgt:`IMPORTED_OBJECTS` property.
+
+Configuration names correspond to those provided by the project from
+which the target is imported.
diff --git a/Help/prop_tgt/INTERPROCEDURAL_OPTIMIZATION_CONFIG.rst b/Help/prop_tgt/INTERPROCEDURAL_OPTIMIZATION_CONFIG.rst
index 492fee0..782b0f0 100644
--- a/Help/prop_tgt/INTERPROCEDURAL_OPTIMIZATION_CONFIG.rst
+++ b/Help/prop_tgt/INTERPROCEDURAL_OPTIMIZATION_CONFIG.rst
@@ -6,3 +6,7 @@ Per-configuration interprocedural optimization for a target.
This is a per-configuration version of INTERPROCEDURAL_OPTIMIZATION.
If set, this property overrides the generic property for the named
configuration.
+
+This property is initialized by the
+:variable:`CMAKE_INTERPROCEDURAL_OPTIMIZATION_<CONFIG>` variable if it is set
+when a target is created.
diff --git a/Help/release/dev/FindMPI-add-imported-targets.rst b/Help/release/dev/FindMPI-add-imported-targets.rst
new file mode 100644
index 0000000..c0a7bfc
--- /dev/null
+++ b/Help/release/dev/FindMPI-add-imported-targets.rst
@@ -0,0 +1,4 @@
+FindMPI-add-imported-targets
+------------------------------
+
+* The :module:`FindMPI` module now provides imported targets.
diff --git a/Help/release/dev/add_custom_command-TARGET_OBJECTS.rst b/Help/release/dev/add_custom_command-TARGET_OBJECTS.rst
new file mode 100644
index 0000000..c4a9ee8
--- /dev/null
+++ b/Help/release/dev/add_custom_command-TARGET_OBJECTS.rst
@@ -0,0 +1,6 @@
+add_custom_command-TARGET_OBJECTS
+---------------------------------
+
+* The :command:`add_custom_command` command learned to evaluate the
+ ``TARGET_OBJECTS``
+ :manual:`generator expression <cmake-generator-expressions(7)>`.
diff --git a/Help/release/dev/add_library-TARGET_OBJECTS.rst b/Help/release/dev/add_library-TARGET_OBJECTS.rst
new file mode 100644
index 0000000..964064e
--- /dev/null
+++ b/Help/release/dev/add_library-TARGET_OBJECTS.rst
@@ -0,0 +1,5 @@
+add_library-TARGET_OBJECTS
+--------------------------
+
+* The :command:`add_library` command ``IMPORTED`` option learned to support
+ :ref:`Object Libraries`.
diff --git a/Help/release/dev/cpackifw-search-algorithm.rst b/Help/release/dev/cpackifw-search-algorithm.rst
new file mode 100644
index 0000000..f2e9985
--- /dev/null
+++ b/Help/release/dev/cpackifw-search-algorithm.rst
@@ -0,0 +1,7 @@
+cpackifw-search-algorithm
+-------------------------
+
+* The :module:`CPackIFW` module learned the new hint :variable:`CPACK_IFW_ROOT`
+ variable for finding the QtIFW tool suite installed in a non-standard place.
+* The :module:`CPackIFW` module tries to find and use QtIFW tools of the `3.0`
+ and `3.1` versions.
diff --git a/Help/release/dev/file-GENERATE-TARGET_OBJECTS.rst b/Help/release/dev/file-GENERATE-TARGET_OBJECTS.rst
new file mode 100644
index 0000000..853a803
--- /dev/null
+++ b/Help/release/dev/file-GENERATE-TARGET_OBJECTS.rst
@@ -0,0 +1,6 @@
+file-GENERATE-TARGET_OBJECTS
+----------------------------
+
+* The :command:`file(GENERATE)` subcommand learned to evaluate the
+ ``TARGET_OBJECTS``
+ :manual:`generator expression <cmake-generator-expressions(7)>`.
diff --git a/Help/release/dev/install-TARGET_OBJECTS.rst b/Help/release/dev/install-TARGET_OBJECTS.rst
new file mode 100644
index 0000000..dbcf635
--- /dev/null
+++ b/Help/release/dev/install-TARGET_OBJECTS.rst
@@ -0,0 +1,8 @@
+install-TARGET_OBJECTS
+----------------------
+
+* The :command:`install(TARGETS)` command learned a new ``OBJECTS`` option to
+ specify where to install :ref:`Object Libraries`.
+
+* The :command:`install(EXPORT)` command learned how to export
+ :ref:`Object Libraries`.
diff --git a/Help/release/dev/remove-vs7.1-generator.rst b/Help/release/dev/remove-vs7.1-generator.rst
new file mode 100644
index 0000000..72ffafb
--- /dev/null
+++ b/Help/release/dev/remove-vs7.1-generator.rst
@@ -0,0 +1,4 @@
+remove-vs7.1-generator
+----------------------
+
+* The :generator:`Visual Studio 7 .NET 2003` generator has been removed.
diff --git a/Help/variable/CMAKE_CFG_INTDIR.rst b/Help/variable/CMAKE_CFG_INTDIR.rst
index ba25a35..c36599a 100644
--- a/Help/variable/CMAKE_CFG_INTDIR.rst
+++ b/Help/variable/CMAKE_CFG_INTDIR.rst
@@ -12,7 +12,7 @@ Example values:
::
- $(ConfigurationName) = Visual Studio 7, 8, 9
+ $(ConfigurationName) = Visual Studio 8, 9
$(Configuration) = Visual Studio 10
$(CONFIGURATION) = Xcode
. = Make-based tools
diff --git a/Help/variable/CMAKE_INTERPROCEDURAL_OPTIMIZATION_CONFIG.rst b/Help/variable/CMAKE_INTERPROCEDURAL_OPTIMIZATION_CONFIG.rst
new file mode 100644
index 0000000..b291102
--- /dev/null
+++ b/Help/variable/CMAKE_INTERPROCEDURAL_OPTIMIZATION_CONFIG.rst
@@ -0,0 +1,8 @@
+CMAKE_INTERPROCEDURAL_OPTIMIZATION_<CONFIG>
+-------------------------------------------
+
+Default value for :prop_tgt:`INTERPROCEDURAL_OPTIMIZATION_<CONFIG>` of targets.
+
+This variable is used to initialize the :prop_tgt:`INTERPROCEDURAL_OPTIMIZATION_<CONFIG>`
+property on all the targets. See that target property for additional
+information.
diff --git a/Help/variable/CMAKE_MATCH_COUNT.rst b/Help/variable/CMAKE_MATCH_COUNT.rst
index 8b1c036..355e834 100644
--- a/Help/variable/CMAKE_MATCH_COUNT.rst
+++ b/Help/variable/CMAKE_MATCH_COUNT.rst
@@ -3,6 +3,7 @@ CMAKE_MATCH_COUNT
The number of matches with the last regular expression.
-When a regular expression match is used, CMake fills in ``CMAKE_MATCH_<n>``
-variables with the match contents. The ``CMAKE_MATCH_COUNT`` variable holds
-the number of match expressions when these are filled.
+When a regular expression match is used, CMake fills in
+:variable:`CMAKE_MATCH_<n>` variables with the match contents.
+The ``CMAKE_MATCH_COUNT`` variable holds the number of match
+expressions when these are filled.
diff --git a/Help/variable/CMAKE_MATCH_n.rst b/Help/variable/CMAKE_MATCH_n.rst
new file mode 100644
index 0000000..c7dd623
--- /dev/null
+++ b/Help/variable/CMAKE_MATCH_n.rst
@@ -0,0 +1,10 @@
+CMAKE_MATCH_<n>
+---------------
+
+Capture group ``<n>`` matched by the last regular expression, for groups
+0 through 9. Group 0 is the entire match. Groups 1 through 9 are the
+subexpressions captured by ``()`` syntax.
+
+When a regular expression match is used, CMake fills in ``CMAKE_MATCH_<n>``
+variables with the match contents. The :variable:`CMAKE_MATCH_COUNT`
+variable holds the number of match expressions when these are filled.
diff --git a/Help/variable/CMAKE_MFC_FLAG.rst b/Help/variable/CMAKE_MFC_FLAG.rst
index 1543677..5a392bf 100644
--- a/Help/variable/CMAKE_MFC_FLAG.rst
+++ b/Help/variable/CMAKE_MFC_FLAG.rst
@@ -5,7 +5,7 @@ Tell cmake to use MFC for an executable or dll.
This can be set in a ``CMakeLists.txt`` file and will enable MFC in the
application. It should be set to ``1`` for the static MFC library, and ``2``
-for the shared MFC library. This is used in Visual Studio 7
+for the shared MFC library. This is used in Visual Studio
project files. The CMakeSetup dialog used MFC and the ``CMakeLists.txt``
looks like this:
diff --git a/Help/variable/CMAKE_VS_DEVENV_COMMAND.rst b/Help/variable/CMAKE_VS_DEVENV_COMMAND.rst
index 14cc50a..51b42dd 100644
--- a/Help/variable/CMAKE_VS_DEVENV_COMMAND.rst
+++ b/Help/variable/CMAKE_VS_DEVENV_COMMAND.rst
@@ -1,7 +1,7 @@
CMAKE_VS_DEVENV_COMMAND
-----------------------
-The generators for :generator:`Visual Studio 7` and above set this
+The generators for :generator:`Visual Studio 8 2005` and above set this
variable to the ``devenv.com`` command installed with the corresponding
Visual Studio version. Note that this variable may be empty on
Visual Studio Express editions because they do not provide this tool.
diff --git a/Help/variable/CMAKE_VS_INTEL_Fortran_PROJECT_VERSION.rst b/Help/variable/CMAKE_VS_INTEL_Fortran_PROJECT_VERSION.rst
index 0be10e5..6d196f9 100644
--- a/Help/variable/CMAKE_VS_INTEL_Fortran_PROJECT_VERSION.rst
+++ b/Help/variable/CMAKE_VS_INTEL_Fortran_PROJECT_VERSION.rst
@@ -1,7 +1,7 @@
CMAKE_VS_INTEL_Fortran_PROJECT_VERSION
--------------------------------------
-When generating for :generator:`Visual Studio 7` or greater with the Intel
+When generating for :generator:`Visual Studio 8 2005` or greater with the Intel
Fortran plugin installed, this specifies the ``.vfproj`` project file format
version. This is intended for internal use by CMake and should not be
used by project code.
diff --git a/Modules/AutogenInfo.cmake.in b/Modules/AutogenInfo.cmake.in
index fcecb6c..5e945bc 100644
--- a/Modules/AutogenInfo.cmake.in
+++ b/Modules/AutogenInfo.cmake.in
@@ -21,6 +21,7 @@ set(AM_MOC_INCLUDES @_moc_incs@)
set(AM_MOC_OPTIONS @_moc_options@)
set(AM_MOC_RELAXED_MODE @_moc_relaxed_mode@)
set(AM_MOC_DEPEND_FILTERS @_moc_depend_filters@)
+set(AM_MOC_PREDEFS_CMD @_moc_predefs_cmd@)
# UIC settings
set(AM_UIC_SKIP @_uic_skip@)
set(AM_UIC_TARGET_OPTIONS @_uic_target_options@)
diff --git a/Modules/CMakeBackwardCompatibilityC.cmake b/Modules/CMakeBackwardCompatibilityC.cmake
index 228e063..5d86d73 100644
--- a/Modules/CMakeBackwardCompatibilityC.cmake
+++ b/Modules/CMakeBackwardCompatibilityC.cmake
@@ -2,12 +2,6 @@
# file Copyright.txt or https://cmake.org/licensing for details.
-# Nothing here yet
-if(CMAKE_GENERATOR MATCHES "Visual Studio 7")
- include(CMakeVS7BackwardCompatibility)
- set(CMAKE_SKIP_COMPATIBILITY_TESTS 1)
-endif()
-
if(NOT CMAKE_SKIP_COMPATIBILITY_TESTS)
# Old CMake versions did not support OS X universal binaries anyway,
# so just get through this with at least some size for the types.
diff --git a/Modules/CMakeDetermineCSharpCompiler.cmake b/Modules/CMakeDetermineCSharpCompiler.cmake
index 1b8dd02..55b2fb3 100644
--- a/Modules/CMakeDetermineCSharpCompiler.cmake
+++ b/Modules/CMakeDetermineCSharpCompiler.cmake
@@ -1,7 +1,7 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
-if(NOT ${CMAKE_GENERATOR} MATCHES "Visual Studio ([^789]|[789][0-9])")
+if(NOT ${CMAKE_GENERATOR} MATCHES "Visual Studio ([^89]|[89][0-9])")
message(FATAL_ERROR
"C# is currently only supported for Microsoft Visual Studio 2010 and later.")
endif()
diff --git a/Modules/CMakeDetermineCUDACompiler.cmake b/Modules/CMakeDetermineCUDACompiler.cmake
index 55a6f0c..89ac9fa 100644
--- a/Modules/CMakeDetermineCUDACompiler.cmake
+++ b/Modules/CMakeDetermineCUDACompiler.cmake
@@ -6,7 +6,7 @@ include(${CMAKE_ROOT}/Modules//CMakeParseImplicitLinkInfo.cmake)
if( NOT ( ("${CMAKE_GENERATOR}" MATCHES "Make") OR
("${CMAKE_GENERATOR}" MATCHES "Ninja") OR
- ("${CMAKE_GENERATOR}" MATCHES "Visual Studio (1|[7-9][0-9])") ) )
+ ("${CMAKE_GENERATOR}" MATCHES "Visual Studio (1|[89][0-9])") ) )
message(FATAL_ERROR "CUDA language not currently supported by \"${CMAKE_GENERATOR}\" generator")
endif()
diff --git a/Modules/CMakeVS7BackwardCompatibility.cmake b/Modules/CMakeVS7BackwardCompatibility.cmake
deleted file mode 100644
index cf477c8..0000000
--- a/Modules/CMakeVS7BackwardCompatibility.cmake
+++ /dev/null
@@ -1,16 +0,0 @@
-# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
-# file Copyright.txt or https://cmake.org/licensing for details.
-
-
-# hard code these for fast backwards compatibility tests
-set (CMAKE_SIZEOF_INT 4 CACHE INTERNAL "Size of int data type")
-set (CMAKE_SIZEOF_LONG 4 CACHE INTERNAL "Size of long data type")
-set (CMAKE_SIZEOF_VOID_P 4 CACHE INTERNAL "Size of void* data type")
-set (CMAKE_SIZEOF_CHAR 1 CACHE INTERNAL "Size of char data type")
-set (CMAKE_SIZEOF_SHORT 2 CACHE INTERNAL "Size of short data type")
-set (CMAKE_SIZEOF_FLOAT 4 CACHE INTERNAL "Size of float data type")
-set (CMAKE_SIZEOF_DOUBLE 8 CACHE INTERNAL "Size of double data type")
-set (CMAKE_NO_ANSI_FOR_SCOPE 0 CACHE INTERNAL
- "Does the compiler support ansi for scope.")
-set (CMAKE_USE_WIN32_THREADS TRUE CACHE BOOL "Use the win32 thread library.")
-set (CMAKE_WORDS_BIGENDIAN 0 CACHE INTERNAL "endianness of bytes")
diff --git a/Modules/CPackIFW.cmake b/Modules/CPackIFW.cmake
index deb724c..099dd1c 100644
--- a/Modules/CPackIFW.cmake
+++ b/Modules/CPackIFW.cmake
@@ -28,8 +28,32 @@
# and Mac OS X.
#
# You should also install QtIFW_ to use CPack ``IFW`` generator.
-# If you don't use a default path for the installation, please set
-# the used path in the variable ``QTIFWDIR``.
+#
+# Hints
+# ^^^^^
+#
+# Generally, the CPack ``IFW`` generator automatically finds QtIFW_ tools,
+# but if you don't use a default path for installation of the QtIFW_ tools,
+# the path may be specified in either a CMake or an environment variable:
+#
+# .. variable:: CPACK_IFW_ROOT
+#
+# An CMake variable which specifies the location of the QtIFW_ tool suite.
+#
+# The variable will be cached in the ``CPackConfig.cmake`` file and used at
+# CPack runtime.
+#
+# .. variable:: QTIFWDIR
+#
+# An environment variable which specifies the location of the QtIFW_ tool
+# suite.
+#
+# .. note::
+# The specified path should not contain "bin" at the end
+# (for example: "D:\\DevTools\\QtIFW2.0.5").
+#
+# The :variable:`CPACK_IFW_ROOT` variable has a higher priority and overrides
+# the value of the :variable:`QTIFWDIR` variable.
#
# Variables
# ^^^^^^^^^
@@ -197,7 +221,7 @@
# dependent components.
#
# Tools
-# """"""""
+# """""
#
# .. variable:: CPACK_IFW_FRAMEWORK_VERSION
#
@@ -207,13 +231,25 @@
#
# The path to "binarycreator" command line client.
#
-# This variable is cached and can be configured user if need.
+# This variable is cached and may be configured if needed.
#
# .. variable:: CPACK_IFW_REPOGEN_EXECUTABLE
#
# The path to "repogen" command line client.
#
-# This variable is cached and can be configured user if need.
+# This variable is cached and may be configured if needed.
+#
+# .. variable:: CPACK_IFW_INSTALLERBASE_EXECUTABLE
+#
+# The path to "installerbase" installer executable base.
+#
+# This variable is cached and may be configured if needed.
+#
+# .. variable:: CPACK_IFW_DEVTOOL_EXECUTABLE
+#
+# The path to "devtool" command line client.
+#
+# This variable is cached and may be configured if needed.
#
# Commands
# ^^^^^^^^^
@@ -568,7 +604,7 @@
# Default path
-foreach(_CPACK_IFW_PATH_VAR "QTIFWDIR" "QTDIR")
+foreach(_CPACK_IFW_PATH_VAR "CPACK_IFW_ROOT" "QTIFWDIR" "QTDIR")
if(DEFINED ${_CPACK_IFW_PATH_VAR}
AND NOT "${${_CPACK_IFW_PATH_VAR}}" STREQUAL "")
list(APPEND _CPACK_IFW_PATHS "${${_CPACK_IFW_PATH_VAR}}")
@@ -597,6 +633,10 @@ set(_CPACK_IFW_PREFIXES
"QtIFW-")
set(_CPACK_IFW_VERSIONS
+ "3.1"
+ "3.1.0"
+ "3.0"
+ "3.0.0"
"2.3"
"2.3.0"
"2.2"
@@ -604,6 +644,7 @@ set(_CPACK_IFW_VERSIONS
"2.1"
"2.1.0"
"2.0"
+ "2.0.5"
"2.0.3"
"2.0.2"
"2.0.1"
diff --git a/Modules/CTest.cmake b/Modules/CTest.cmake
index 7aeb5be..9370596 100644
--- a/Modules/CTest.cmake
+++ b/Modules/CTest.cmake
@@ -54,15 +54,11 @@ in the ``CTestConfig.cmake`` file.
option(BUILD_TESTING "Build the testing tree." ON)
# function to turn generator name into a version string
-# like vs7 vs71 vs8 vs9
+# like vs8 vs9
function(GET_VS_VERSION_STRING generator var)
string(REGEX REPLACE "Visual Studio ([0-9][0-9]?)($|.*)" "\\1"
NUMBER "${generator}")
- if("${generator}" MATCHES "Visual Studio 7 .NET 2003")
- set(ver_string "vs71")
- else()
set(ver_string "vs${NUMBER}")
- endif()
set(${var} ${ver_string} PARENT_SCOPE)
endfunction()
diff --git a/Modules/Compiler/Intel.cmake b/Modules/Compiler/Intel.cmake
index 02968b4..06d01f1 100644
--- a/Modules/Compiler/Intel.cmake
+++ b/Modules/Compiler/Intel.cmake
@@ -22,5 +22,7 @@ else()
string(APPEND CMAKE_${lang}_FLAGS_MINSIZEREL_INIT " -Os")
string(APPEND CMAKE_${lang}_FLAGS_RELEASE_INIT " -O3")
string(APPEND CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT " -O2 -g")
+
+ set(CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "${CMAKE_${lang}_COMPILER}" "-QdM" "-P" "-Za" "${CMAKE_ROOT}/Modules/CMakeCXXCompilerABI.cpp")
endmacro()
endif()
diff --git a/Modules/FindBoost.cmake b/Modules/FindBoost.cmake
index c3cf341..093d8c9 100644
--- a/Modules/FindBoost.cmake
+++ b/Modules/FindBoost.cmake
@@ -896,7 +896,7 @@ endfunction()
# This function would append corresponding directories if MSVC is a current compiler,
# so having `BOOST_ROOT` would be enough to specify to find everything.
#
-macro(_Boost_UPDATE_WINDOWS_LIBRARY_SEARCH_DIRS_WITH_PREBUILT_PATHS componentlibvar basedir)
+function(_Boost_UPDATE_WINDOWS_LIBRARY_SEARCH_DIRS_WITH_PREBUILT_PATHS componentlibvar basedir)
if("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC")
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(_arch_suffix 64)
@@ -919,8 +919,9 @@ macro(_Boost_UPDATE_WINDOWS_LIBRARY_SEARCH_DIRS_WITH_PREBUILT_PATHS componentlib
elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 14)
list(APPEND ${componentlibvar} ${basedir}/lib${_arch_suffix}-msvc-8.0)
endif()
+ set(${componentlibvar} ${${componentlibvar}} PARENT_SCOPE)
endif()
-endmacro()
+endfunction()
#
# End functions/macros
diff --git a/Modules/FindMPI.cmake b/Modules/FindMPI.cmake
index ff2c4de..3e8be5b 100644
--- a/Modules/FindMPI.cmake
+++ b/Modules/FindMPI.cmake
@@ -29,6 +29,12 @@
# MPI_<lang>_LINK_FLAGS Linking flags for MPI programs
# MPI_<lang>_LIBRARIES All libraries to link MPI programs against
#
+# Additionally, the following :prop_tgt:`IMPORTED` targets are defined:
+#
+# ::
+#
+# MPI::MPI_<lang> Target for using MPI from <lang>
+#
# Additionally, FindMPI sets the following variables for running MPI
# programs from the command line:
#
@@ -621,6 +627,29 @@ foreach (lang C CXX Fortran)
else()
find_package_handle_standard_args(MPI_${lang} DEFAULT_MSG MPI_${lang}_LIBRARIES MPI_${lang}_INCLUDE_PATH)
endif()
+
+ if(MPI_${lang}_FOUND)
+ if(NOT TARGET MPI::MPI_${lang})
+ add_library(MPI::MPI_${lang} INTERFACE IMPORTED)
+ endif()
+ if(MPI_${lang}_COMPILE_FLAGS)
+ set(_MPI_${lang}_COMPILE_OPTIONS "${MPI_${lang}_COMPILE_FLAGS}")
+ separate_arguments(_MPI_${lang}_COMPILE_OPTIONS)
+ set_property(TARGET MPI::MPI_${lang} PROPERTY
+ INTERFACE_COMPILE_OPTIONS "${_MPI_${lang}_COMPILE_OPTIONS}")
+ endif()
+
+ unset(_MPI_${lang}_LINK_LINE)
+ if(MPI_${lang}_LINK_FLAGS)
+ list(APPEND _MPI_${lang}_LINK_LINE "${MPI_${lang}_LINK_FLAGS}")
+ endif()
+ list(APPEND _MPI_${lang}_LINK_LINE "${MPI_${lang}_LIBRARIES}")
+ set_property(TARGET MPI::MPI_${lang} PROPERTY
+ INTERFACE_LINK_LIBRARIES "${_MPI_${lang}_LINK_LINE}")
+
+ set_property(TARGET MPI::MPI_${lang} PROPERTY
+ INTERFACE_INCLUDE_DIRECTORIES "${MPI_${lang}_INCLUDE_PATH}")
+ endif()
endif()
endforeach()
@@ -660,6 +689,7 @@ if (MPI_NUMLIBS GREATER 1)
else()
set(MPI_EXTRA_LIBRARY "MPI_EXTRA_LIBRARY-NOTFOUND" CACHE STRING "Extra MPI libraries to link against" FORCE)
endif()
+mark_as_advanced(MPI_LIBRARY MPI_EXTRA_LIBRARY)
#=============================================================================
# unset these vars to cleanup namespace
diff --git a/Modules/FindOpenSSL.cmake b/Modules/FindOpenSSL.cmake
index 117811c..1209560 100644
--- a/Modules/FindOpenSSL.cmake
+++ b/Modules/FindOpenSSL.cmake
@@ -145,6 +145,7 @@ if(WIN32 AND NOT CYGWIN)
find_library(LIB_EAY_DEBUG
NAMES
libcrypto${_OPENSSL_MSVC_ARCH_SUFFIX}${_OPENSSL_MSVC_RT_MODE}d
+ libcrypto${_OPENSSL_MSVC_RT_MODE}d
libcryptod
libeay32${_OPENSSL_MSVC_RT_MODE}d
libeay32d
@@ -157,6 +158,7 @@ if(WIN32 AND NOT CYGWIN)
find_library(LIB_EAY_RELEASE
NAMES
libcrypto${_OPENSSL_MSVC_ARCH_SUFFIX}${_OPENSSL_MSVC_RT_MODE}
+ libcrypto${_OPENSSL_MSVC_RT_MODE}
libcrypto
libeay32${_OPENSSL_MSVC_RT_MODE}
libeay32
@@ -170,6 +172,7 @@ if(WIN32 AND NOT CYGWIN)
find_library(SSL_EAY_DEBUG
NAMES
libssl${_OPENSSL_MSVC_ARCH_SUFFIX}${_OPENSSL_MSVC_RT_MODE}d
+ libssl${_OPENSSL_MSVC_RT_MODE}d
libssld
ssleay32${_OPENSSL_MSVC_RT_MODE}d
ssleay32d
@@ -182,6 +185,7 @@ if(WIN32 AND NOT CYGWIN)
find_library(SSL_EAY_RELEASE
NAMES
libssl${_OPENSSL_MSVC_ARCH_SUFFIX}${_OPENSSL_MSVC_RT_MODE}
+ libssl${_OPENSSL_MSVC_RT_MODE}
libssl
ssleay32${_OPENSSL_MSVC_RT_MODE}
ssleay32
diff --git a/Modules/FindwxWidgets.cmake b/Modules/FindwxWidgets.cmake
index bc906e5..af4daf0 100644
--- a/Modules/FindwxWidgets.cmake
+++ b/Modules/FindwxWidgets.cmake
@@ -893,6 +893,28 @@ else()
endif()
endif()
+# Check that all libraries are present, as wx-config does not check it
+set(_wx_lib_missing "")
+foreach(_wx_lib_ ${wxWidgets_LIBRARIES})
+ if("${_wx_lib_}" MATCHES "^-l(.*)")
+ set(_wx_lib_name "${CMAKE_MATCH_1}")
+ unset(_wx_lib_found CACHE)
+ find_library(_wx_lib_found NAMES ${_wx_lib_name} HINTS ${wxWidgets_LIBRARY_DIRS})
+ if(_wx_lib_found STREQUAL _wx_lib_found-NOTFOUND)
+ list(APPEND _wx_lib_missing ${_wx_lib_name})
+ endif()
+ unset(_wx_lib_found CACHE)
+ endif()
+endforeach()
+
+if (_wx_lib_missing)
+ string(REPLACE ";" " " _wx_lib_missing "${_wx_lib_missing}")
+ DBG_MSG_V("wxWidgets not found due to following missing libraries: ${_wx_lib_missing}")
+ set(wxWidgets_FOUND FALSE)
+ unset(wxWidgets_LIBRARIES)
+endif()
+unset(_wx_lib_missing)
+
# Check if a specfic version was requested by find_package().
if(wxWidgets_FOUND)
find_file(_filename wx/version.h PATHS ${wxWidgets_INCLUDE_DIRS} NO_DEFAULT_PATH)
diff --git a/Modules/Platform/Linux-GNU.cmake b/Modules/Platform/Linux-GNU.cmake
index 6878254..ce30a26 100644
--- a/Modules/Platform/Linux-GNU.cmake
+++ b/Modules/Platform/Linux-GNU.cmake
@@ -12,4 +12,5 @@ macro(__linux_compiler_gnu lang)
# We pass this for historical reasons. Projects may have
# executables that use dlopen but do not set ENABLE_EXPORTS.
set(CMAKE_SHARED_LIBRARY_LINK_${lang}_FLAGS "-rdynamic")
+ set(CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "${CMAKE_${lang}_COMPILER}" "-dM" "-E" "-c" "${CMAKE_ROOT}/Modules/CMakeCXXCompilerABI.cpp")
endmacro()
diff --git a/Modules/Platform/Linux-TinyCC-C.cmake b/Modules/Platform/Linux-TinyCC-C.cmake
index f78e708..9409d8b 100644
--- a/Modules/Platform/Linux-TinyCC-C.cmake
+++ b/Modules/Platform/Linux-TinyCC-C.cmake
@@ -2,3 +2,4 @@ set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "")
set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG_SEP "")
set(CMAKE_SHARED_LIBRARY_RPATH_LINK_C_FLAG "")
set(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG "-soname ")
+set(CMAKE_EXE_EXPORTS_C_FLAG "-rdynamic ")
diff --git a/Modules/Platform/Windows-df.cmake b/Modules/Platform/Windows-df.cmake
index b31cb11..c59be45 100644
--- a/Modules/Platform/Windows-df.cmake
+++ b/Modules/Platform/Windows-df.cmake
@@ -30,7 +30,7 @@ set(CMAKE_Fortran_LINK_EXECUTABLE
set(CMAKE_CREATE_WIN32_EXE /winapp)
set(CMAKE_CREATE_CONSOLE_EXE )
-if(CMAKE_GENERATOR MATCHES "Visual Studio 7" OR CMAKE_GENERATOR MATCHES "Visual Studio 8")
+if(CMAKE_GENERATOR MATCHES "Visual Studio 8")
set (CMAKE_NO_BUILD_TYPE 1)
endif()
# does the compiler support pdbtype and is it the newer compiler
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 3556ee2..ea6e0e2 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 8)
-set(CMake_VERSION_PATCH 20170417)
+set(CMake_VERSION_PATCH 20170421)
#set(CMake_VERSION_RC 1)
diff --git a/Source/CPack/OSXScriptLauncher.cxx b/Source/CPack/OSXScriptLauncher.cxx
index 701481d..b48bf12 100644
--- a/Source/CPack/OSXScriptLauncher.cxx
+++ b/Source/CPack/OSXScriptLauncher.cxx
@@ -85,8 +85,6 @@ int main(int argc, char* argv[])
int length;
while (cmsysProcess_WaitForData(cp, &data, &length, 0)) {
// Translate NULL characters in the output into valid text.
- // Visual Studio 7 puts these characters in the output of its
- // build process.
for (int i = 0; i < length; ++i) {
if (data[i] == '\0') {
data[i] = ' ';
diff --git a/Source/QtDialog/CMakeLists.txt b/Source/QtDialog/CMakeLists.txt
index 10fd718..2e11a8a 100644
--- a/Source/QtDialog/CMakeLists.txt
+++ b/Source/QtDialog/CMakeLists.txt
@@ -198,7 +198,7 @@ if(UNIX AND NOT APPLE)
# install a desktop file so CMake appears in the application start menu
# with an icon
- install(FILES CMake.desktop
+ install(FILES cmake-gui.desktop
DESTINATION "${CMAKE_XDGDATA_DIR}/applications"
${COMPONENT})
install(FILES cmakecache.xml
diff --git a/Source/QtDialog/CMake.desktop b/Source/QtDialog/cmake-gui.desktop
index 842091f..842091f 100644
--- a/Source/QtDialog/CMake.desktop
+++ b/Source/QtDialog/cmake-gui.desktop
diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx
index 9ae4ace..0bdf963 100644
--- a/Source/cmAddLibraryCommand.cxx
+++ b/Source/cmAddLibraryCommand.cxx
@@ -297,10 +297,15 @@ bool cmAddLibraryCommand::InitialPass(std::vector<std::string> const& args,
return false;
}
if (type == cmStateEnums::OBJECT_LIBRARY) {
- this->Makefile->IssueMessage(
- cmake::FATAL_ERROR,
- "The OBJECT library type may not be used for IMPORTED libraries.");
- return true;
+ std::string reason;
+ if (!this->Makefile->GetGlobalGenerator()->HasKnownObjectFileLocation(
+ &reason)) {
+ this->Makefile->IssueMessage(
+ cmake::FATAL_ERROR,
+ "The OBJECT library type may not be used for IMPORTED libraries" +
+ reason + ".");
+ return true;
+ }
}
if (type == cmStateEnums::INTERFACE_LIBRARY) {
if (!cmGeneratorExpression::IsValidTargetName(libName)) {
diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx
index 539d854..978a7a1 100644
--- a/Source/cmExportBuildFileGenerator.cxx
+++ b/Source/cmExportBuildFileGenerator.cxx
@@ -2,6 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmExportBuildFileGenerator.h"
+#include "cmAlgorithms.h"
#include "cmExportSet.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
@@ -21,6 +22,8 @@
#include <sstream>
#include <utility>
+class cmSourceFile;
+
cmExportBuildFileGenerator::cmExportBuildFileGenerator()
{
this->LG = CM_NULLPTR;
@@ -171,27 +174,48 @@ void cmExportBuildFileGenerator::SetImportLocationProperty(
// Get the makefile in which to lookup target information.
cmMakefile* mf = target->Makefile;
- // Add the main target file.
- {
- std::string prop = "IMPORTED_LOCATION";
+ if (target->GetType() == cmStateEnums::OBJECT_LIBRARY) {
+ std::string prop = "IMPORTED_OBJECTS";
prop += suffix;
- std::string value;
- if (target->IsAppBundleOnApple()) {
- value = target->GetFullPath(config, false);
- } else {
- value = target->GetFullPath(config, false, true);
+
+ // Compute all the object files inside this target and setup
+ // IMPORTED_OBJECTS as a list of object files
+ std::vector<cmSourceFile const*> objectSources;
+ target->GetObjectSources(objectSources, config);
+ std::string const obj_dir = target->GetObjectDirectory(config);
+ std::vector<std::string> objects;
+ for (std::vector<cmSourceFile const*>::const_iterator si =
+ objectSources.begin();
+ si != objectSources.end(); ++si) {
+ const std::string& obj = target->GetObjectName(*si);
+ objects.push_back(obj_dir + obj);
}
- properties[prop] = value;
- }
- // Add the import library for windows DLLs.
- if (target->HasImportLibrary() &&
- mf->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX")) {
- std::string prop = "IMPORTED_IMPLIB";
- prop += suffix;
- std::string value = target->GetFullPath(config, true);
- target->GetImplibGNUtoMS(value, value, "${CMAKE_IMPORT_LIBRARY_SUFFIX}");
- properties[prop] = value;
+ // Store the property.
+ properties[prop] = cmJoin(objects, ";");
+ } else {
+ // Add the main target file.
+ {
+ std::string prop = "IMPORTED_LOCATION";
+ prop += suffix;
+ std::string value;
+ if (target->IsAppBundleOnApple()) {
+ value = target->GetFullPath(config, false);
+ } else {
+ value = target->GetFullPath(config, false, true);
+ }
+ properties[prop] = value;
+ }
+
+ // Add the import library for windows DLLs.
+ if (target->HasImportLibrary() &&
+ mf->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX")) {
+ std::string prop = "IMPORTED_IMPLIB";
+ prop += suffix;
+ std::string value = target->GetFullPath(config, true);
+ target->GetImplibGNUtoMS(value, value, "${CMAKE_IMPORT_LIBRARY_SUFFIX}");
+ properties[prop] = value;
+ }
}
}
diff --git a/Source/cmExportCommand.cxx b/Source/cmExportCommand.cxx
index 691048b..38cd511 100644
--- a/Source/cmExportCommand.cxx
+++ b/Source/cmExportCommand.cxx
@@ -149,11 +149,15 @@ bool cmExportCommand::InitialPass(std::vector<std::string> const& args,
if (cmTarget* target = gg->FindTarget(*currentTarget)) {
if (target->GetType() == cmStateEnums::OBJECT_LIBRARY) {
- std::ostringstream e;
- e << "given OBJECT library \"" << *currentTarget
- << "\" which may not be exported.";
- this->SetError(e.str());
- return false;
+ std::string reason;
+ if (!this->Makefile->GetGlobalGenerator()
+ ->HasKnownObjectFileLocation(&reason)) {
+ std::ostringstream e;
+ e << "given OBJECT library \"" << *currentTarget
+ << "\" which may not be exported" << reason << ".";
+ this->SetError(e.str());
+ return false;
+ }
}
if (target->GetType() == cmStateEnums::UTILITY) {
this->SetError("given custom target \"" + *currentTarget +
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index 5875f9e..ae3ec3b 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -441,6 +441,11 @@ void getCompatibleInterfaceProperties(cmGeneratorTarget* target,
std::set<std::string>& ifaceProperties,
const std::string& config)
{
+ if (target->GetType() == cmStateEnums::OBJECT_LIBRARY) {
+ // object libraries have no link information, so nothing to compute
+ return;
+ }
+
cmComputeLinkInformation* info = target->GetLinkInformation(config);
if (!info) {
@@ -927,6 +932,9 @@ void cmExportFileGenerator::GenerateImportTargetCode(
case cmStateEnums::UNKNOWN_LIBRARY:
os << "add_library(" << targetName << " UNKNOWN IMPORTED)\n";
break;
+ case cmStateEnums::OBJECT_LIBRARY:
+ os << "add_library(" << targetName << " OBJECT IMPORTED)\n";
+ break;
case cmStateEnums::INTERFACE_LIBRARY:
os << "add_library(" << targetName << " INTERFACE IMPORTED)\n";
break;
diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx
index 3b76a87..16bd5e8 100644
--- a/Source/cmExportInstallFileGenerator.cxx
+++ b/Source/cmExportInstallFileGenerator.cxx
@@ -331,6 +331,8 @@ void cmExportInstallFileGenerator::GenerateImportTargetsConfig(
properties, importedLocations);
this->SetImportLocationProperty(config, suffix, te->RuntimeGenerator,
properties, importedLocations);
+ this->SetImportLocationProperty(config, suffix, te->ObjectsGenerator,
+ properties, importedLocations);
this->SetImportLocationProperty(config, suffix, te->FrameworkGenerator,
properties, importedLocations);
this->SetImportLocationProperty(config, suffix, te->BundleGenerator,
@@ -397,6 +399,23 @@ void cmExportInstallFileGenerator::SetImportLocationProperty(
// Store the property.
properties[prop] = value;
importedLocations.insert(prop);
+ } else if (itgen->GetTarget()->GetType() == cmStateEnums::OBJECT_LIBRARY) {
+ // Construct the property name.
+ std::string prop = "IMPORTED_OBJECTS";
+ prop += suffix;
+
+ // Compute all the object files inside this target and setup
+ // IMPORTED_OBJECTS as a list of object files
+ std::vector<std::string> objects;
+ itgen->GetInstallObjectNames(config, objects);
+ for (std::vector<std::string>::iterator i = objects.begin();
+ i != objects.end(); ++i) {
+ *i = value + *i;
+ }
+
+ // Store the property.
+ properties[prop] = cmJoin(objects, ";");
+ importedLocations.insert(prop);
} else {
// Construct the property name.
std::string prop = "IMPORTED_LOCATION";
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index deb7187..034a266 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -1147,6 +1147,7 @@ protected:
bool UseGivenPermissionsDir;
bool UseSourcePermissions;
std::string Destination;
+ std::string FilesFromDir;
std::vector<std::string> Files;
int Doing;
@@ -1156,6 +1157,7 @@ protected:
DoingNone,
DoingError,
DoingDestination,
+ DoingFilesFromDir,
DoingFiles,
DoingPattern,
DoingRegex,
@@ -1251,6 +1253,12 @@ bool cmFileCopier::CheckKeyword(std::string const& arg)
} else {
this->Doing = DoingDestination;
}
+ } else if (arg == "FILES_FROM_DIR") {
+ if (this->CurrentMatchRule) {
+ this->NotAfterMatch(arg);
+ } else {
+ this->Doing = DoingFilesFromDir;
+ }
} else if (arg == "PATTERN") {
this->Doing = DoingPattern;
} else if (arg == "REGEX") {
@@ -1314,13 +1322,7 @@ bool cmFileCopier::CheckValue(std::string const& arg)
{
switch (this->Doing) {
case DoingFiles:
- if (arg.empty() || cmSystemTools::FileIsFullPath(arg.c_str())) {
- this->Files.push_back(arg);
- } else {
- std::string file = this->Makefile->GetCurrentSourceDirectory();
- file += "/" + arg;
- this->Files.push_back(file);
- }
+ this->Files.push_back(arg);
break;
case DoingDestination:
if (arg.empty() || cmSystemTools::FileIsFullPath(arg.c_str())) {
@@ -1331,6 +1333,16 @@ bool cmFileCopier::CheckValue(std::string const& arg)
}
this->Doing = DoingNone;
break;
+ case DoingFilesFromDir:
+ if (cmSystemTools::FileIsFullPath(arg.c_str())) {
+ this->FilesFromDir = arg;
+ } else {
+ this->FilesFromDir = this->Makefile->GetCurrentSourceDirectory();
+ this->FilesFromDir += "/" + arg;
+ }
+ cmSystemTools::ConvertToUnixSlashes(this->FilesFromDir);
+ this->Doing = DoingNone;
+ break;
case DoingPattern: {
// Convert the pattern to a regular expression. Require a
// leading slash and trailing end-of-string in the matched
@@ -1390,17 +1402,41 @@ bool cmFileCopier::Run(std::vector<std::string> const& args)
return false;
}
- std::vector<std::string> const& files = this->Files;
- for (std::vector<std::string>::size_type i = 0; i < files.size(); ++i) {
+ for (std::vector<std::string>::const_iterator i = this->Files.begin();
+ i != this->Files.end(); ++i) {
+ std::string file;
+ if (!i->empty() && !cmSystemTools::FileIsFullPath(*i)) {
+ if (!this->FilesFromDir.empty()) {
+ file = this->FilesFromDir;
+ } else {
+ file = this->Makefile->GetCurrentSourceDirectory();
+ }
+ file += "/";
+ file += *i;
+ } else if (!this->FilesFromDir.empty()) {
+ this->FileCommand->SetError("option FILES_FROM_DIR requires all files "
+ "to be specified as relative paths.");
+ return false;
+ } else {
+ file = *i;
+ }
+
// Split the input file into its directory and name components.
std::vector<std::string> fromPathComponents;
- cmSystemTools::SplitPath(files[i], fromPathComponents);
+ cmSystemTools::SplitPath(file, fromPathComponents);
std::string fromName = *(fromPathComponents.end() - 1);
std::string fromDir = cmSystemTools::JoinPath(
fromPathComponents.begin(), fromPathComponents.end() - 1);
// Compute the full path to the destination file.
std::string toFile = this->Destination;
+ if (!this->FilesFromDir.empty()) {
+ std::string dir = cmSystemTools::GetFilenamePath(*i);
+ if (!dir.empty()) {
+ toFile += "/";
+ toFile += dir;
+ }
+ }
std::string const& toName = this->ToName(fromName);
if (!toName.empty()) {
toFile += "/";
@@ -1751,6 +1787,11 @@ bool cmFileInstaller::Parse(std::vector<std::string> const& args)
}
if (!this->Rename.empty()) {
+ if (!this->FilesFromDir.empty()) {
+ this->FileCommand->SetError("INSTALL option RENAME may not be "
+ "combined with FILES_FROM_DIR.");
+ return false;
+ }
if (this->InstallType != cmInstallType_FILES &&
this->InstallType != cmInstallType_PROGRAMS) {
this->FileCommand->SetError("INSTALL option RENAME may be used "
diff --git a/Source/cmGeneratorExpressionEvaluationFile.cxx b/Source/cmGeneratorExpressionEvaluationFile.cxx
index dc54488..1526454 100644
--- a/Source/cmGeneratorExpressionEvaluationFile.cxx
+++ b/Source/cmGeneratorExpressionEvaluationFile.cxx
@@ -64,8 +64,10 @@ void cmGeneratorExpressionEvaluationFile::Generate(
return;
}
std::ostringstream e;
- e << "Evaluation file to be written multiple times for different "
- "configurations or languages with different content:\n "
+ e << "Evaluation file to be written multiple times with different "
+ "content. "
+ "This is generally caused by the content evaluating the "
+ "configuration type, language, or location of object files:\n "
<< outputFileName;
lg->IssueMessage(cmake::FATAL_ERROR, e.str());
return;
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index 8fee119..77a4962 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -33,8 +33,6 @@
#include <string.h>
#include <utility>
-class cmSourceFile;
-
std::string cmGeneratorExpressionNode::EvaluateDependentExpression(
std::string const& prop, cmLocalGenerator* lg,
cmGeneratorExpressionContext* context, cmGeneratorTarget const* headTarget,
@@ -1228,15 +1226,6 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const
CM_OVERRIDE
{
- if (!context->EvaluateForBuildsystem) {
- std::ostringstream e;
- e << "The evaluation of the TARGET_OBJECTS generator expression "
- "is only suitable for consumption by CMake. It is not suitable "
- "for writing out elsewhere.";
- reportError(context, content->GetOriginalExpression(), e.str());
- return std::string();
- }
-
std::string tgtName = parameters.front();
cmGeneratorTarget* gt = context->LG->FindGeneratorTargetToUse(tgtName);
if (!gt) {
@@ -1253,39 +1242,60 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode
reportError(context, content->GetOriginalExpression(), e.str());
return std::string();
}
+ if (!context->EvaluateForBuildsystem) {
+ cmGlobalGenerator* gg = context->LG->GetGlobalGenerator();
+ std::string reason;
+ if (!gg->HasKnownObjectFileLocation(&reason)) {
+ std::ostringstream e;
+ e << "The evaluation of the TARGET_OBJECTS generator expression "
+ "is only suitable for consumption by CMake (limited"
+ << reason << "). "
+ "It is not suitable for writing out elsewhere.";
+ reportError(context, content->GetOriginalExpression(), e.str());
+ return std::string();
+ }
+ }
- std::vector<cmSourceFile const*> objectSources;
- gt->GetObjectSources(objectSources, context->Config);
- std::map<cmSourceFile const*, std::string> mapping;
+ std::vector<std::string> objects;
- for (std::vector<cmSourceFile const*>::const_iterator it =
- objectSources.begin();
- it != objectSources.end(); ++it) {
- mapping[*it];
- }
+ if (gt->IsImported()) {
+ const char* loc = CM_NULLPTR;
+ const char* imp = CM_NULLPTR;
+ std::string suffix;
+ if (gt->Target->GetMappedConfig(context->Config, &loc, &imp, suffix)) {
+ cmSystemTools::ExpandListArgument(loc, objects);
+ }
+ context->HadContextSensitiveCondition = true;
+ } else {
+ gt->GetTargetObjectNames(context->Config, objects);
+
+ std::string obj_dir;
+ if (context->EvaluateForBuildsystem) {
+ // Use object file directory with buildsystem placeholder.
+ obj_dir = gt->ObjectDirectory;
+ // Here we assume that the set of object files produced
+ // by an object library does not vary with configuration
+ // and do not set HadContextSensitiveCondition to true.
+ } else {
+ // Use object file directory with per-config location.
+ obj_dir = gt->GetObjectDirectory(context->Config);
+ context->HadContextSensitiveCondition = true;
+ }
- gt->LocalGenerator->ComputeObjectFilenames(mapping, gt);
+ for (std::vector<std::string>::iterator oi = objects.begin();
+ oi != objects.end(); ++oi) {
+ *oi = obj_dir + *oi;
+ }
+ }
+ // Create the cmSourceFile instances in the referencing directory.
cmMakefile* mf = context->LG->GetMakefile();
-
- std::string obj_dir = gt->ObjectDirectory;
- std::string result;
- const char* sep = "";
- for (std::vector<cmSourceFile const*>::const_iterator it =
- objectSources.begin();
- it != objectSources.end(); ++it) {
- // Find the object file name corresponding to this source file.
- std::map<cmSourceFile const*, std::string>::const_iterator map_it =
- mapping.find(*it);
- // It must exist because we populated the mapping just above.
- assert(!map_it->second.empty());
- result += sep;
- std::string objFile = obj_dir + map_it->second;
- mf->AddTargetObject(tgtName, objFile);
- result += objFile;
- sep = ";";
+ for (std::vector<std::string>::iterator oi = objects.begin();
+ oi != objects.end(); ++oi) {
+ mf->AddTargetObject(tgtName, *oi);
}
- return result;
+
+ return cmJoin(objects, ";");
}
} targetObjectsNode;
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 5e4259d..2799505 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -941,6 +941,26 @@ void cmGeneratorTarget::GetSourceFiles(std::vector<std::string>& files,
void cmGeneratorTarget::GetSourceFiles(std::vector<cmSourceFile*>& files,
const std::string& config) const
{
+ if (!this->GlobalGenerator->GetConfigureDoneCMP0026()) {
+ // Since we are still configuring not all sources may exist yet,
+ // so we need to avoid full source classification because that
+ // requires the absolute paths to all sources to be determined.
+ // Since this is only for compatibility with old policies that
+ // projects should not depend on anymore, just compute the files
+ // without memoizing them.
+ std::vector<std::string> srcs;
+ this->GetSourceFiles(srcs, config);
+ std::set<cmSourceFile*> emitted;
+ for (std::vector<std::string>::const_iterator i = srcs.begin();
+ i != srcs.end(); ++i) {
+ cmSourceFile* sf = this->Makefile->GetOrCreateSource(*i);
+ if (emitted.insert(sf).second) {
+ files.push_back(sf);
+ }
+ }
+ return;
+ }
+
KindedSources const& kinded = this->GetKindedSources(config);
files.reserve(kinded.Sources.size());
for (std::vector<SourceAndKind>::const_iterator si = kinded.Sources.begin();
@@ -949,6 +969,19 @@ void cmGeneratorTarget::GetSourceFiles(std::vector<cmSourceFile*>& files,
}
}
+void cmGeneratorTarget::GetSourceFilesWithoutObjectLibraries(
+ std::vector<cmSourceFile*>& files, const std::string& config) const
+{
+ KindedSources const& kinded = this->GetKindedSources(config);
+ files.reserve(kinded.Sources.size());
+ for (std::vector<SourceAndKind>::const_iterator si = kinded.Sources.begin();
+ si != kinded.Sources.end(); ++si) {
+ if (si->Source->GetObjectLibrary().empty()) {
+ files.push_back(si->Source);
+ }
+ }
+}
+
cmGeneratorTarget::KindedSources const& cmGeneratorTarget::GetKindedSources(
std::string const& config) const
{
@@ -1069,6 +1102,43 @@ void cmGeneratorTarget::ComputeKindedSources(KindedSources& files,
}
}
+std::vector<cmGeneratorTarget::AllConfigSource> const&
+cmGeneratorTarget::GetAllConfigSources() const
+{
+ if (this->AllConfigSources.empty()) {
+ this->ComputeAllConfigSources();
+ }
+ return this->AllConfigSources;
+}
+
+void cmGeneratorTarget::ComputeAllConfigSources() const
+{
+ std::vector<std::string> configs;
+ this->Makefile->GetConfigurations(configs);
+
+ std::map<cmSourceFile const*, size_t> index;
+
+ for (size_t ci = 0; ci < configs.size(); ++ci) {
+ KindedSources const& sources = this->GetKindedSources(configs[ci]);
+ for (std::vector<cmGeneratorTarget::SourceAndKind>::const_iterator si =
+ sources.Sources.begin();
+ si != sources.Sources.end(); ++si) {
+ std::map<cmSourceFile const*, size_t>::iterator mi =
+ index.find(si->Source);
+ if (mi == index.end()) {
+ AllConfigSource acs;
+ acs.Source = si->Source;
+ acs.Kind = si->Kind;
+ this->AllConfigSources.push_back(acs);
+ std::map<cmSourceFile const*, size_t>::value_type entry(
+ si->Source, this->AllConfigSources.size() - 1);
+ mi = index.insert(entry).first;
+ }
+ this->AllConfigSources[mi->second].Configs.push_back(ci);
+ }
+ }
+}
+
std::string cmGeneratorTarget::GetCompilePDBName(
const std::string& config) const
{
@@ -3204,6 +3274,46 @@ std::string cmGeneratorTarget::GetPDBName(const std::string& config) const
return prefix + base + ".pdb";
}
+std::string cmGeneratorTarget::GetObjectDirectory(
+ std::string const& config) const
+{
+ std::string obj_dir =
+ this->GlobalGenerator->ExpandCFGIntDir(this->ObjectDirectory, config);
+#if defined(__APPLE__)
+ // find and replace $(PROJECT_NAME) xcode placeholder
+ const std::string projectName = this->LocalGenerator->GetProjectName();
+ cmSystemTools::ReplaceString(obj_dir, "$(PROJECT_NAME)", projectName);
+#endif
+ return obj_dir;
+}
+
+void cmGeneratorTarget::GetTargetObjectNames(
+ std::string const& config, std::vector<std::string>& objects) const
+{
+ std::vector<cmSourceFile const*> objectSources;
+ this->GetObjectSources(objectSources, config);
+ std::map<cmSourceFile const*, std::string> mapping;
+
+ for (std::vector<cmSourceFile const*>::const_iterator it =
+ objectSources.begin();
+ it != objectSources.end(); ++it) {
+ mapping[*it];
+ }
+
+ this->LocalGenerator->ComputeObjectFilenames(mapping, this);
+
+ for (std::vector<cmSourceFile const*>::const_iterator it =
+ objectSources.begin();
+ it != objectSources.end(); ++it) {
+ // Find the object file name corresponding to this source file.
+ std::map<cmSourceFile const*, std::string>::const_iterator map_it =
+ mapping.find(*it);
+ // It must exist because we populated the mapping just above.
+ assert(!map_it->second.empty());
+ objects.push_back(map_it->second);
+ }
+}
+
bool cmGeneratorTarget::StrictTargetComparison::operator()(
cmGeneratorTarget const* t1, cmGeneratorTarget const* t2) const
{
@@ -4900,11 +5010,11 @@ bool cmGeneratorTarget::GetConfigCommonSourceFiles(
std::vector<std::string>::const_iterator it = configs.begin();
const std::string& firstConfig = *it;
- this->GetSourceFiles(files, firstConfig);
+ this->GetSourceFilesWithoutObjectLibraries(files, firstConfig);
for (; it != configs.end(); ++it) {
std::vector<cmSourceFile*> configFiles;
- this->GetSourceFiles(configFiles, *it);
+ this->GetSourceFilesWithoutObjectLibraries(configFiles, *it);
if (configFiles != files) {
std::string firstConfigFiles;
const char* sep = "";
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 7c86d30..5b903de 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -12,6 +12,7 @@
#include <map>
#include <set>
+#include <stddef.h>
#include <string>
#include <utility>
#include <vector>
@@ -69,6 +70,8 @@ public:
bool GetPropertyAsBool(const std::string& prop) const;
void GetSourceFiles(std::vector<cmSourceFile*>& files,
const std::string& config) const;
+ void GetSourceFilesWithoutObjectLibraries(std::vector<cmSourceFile*>& files,
+ const std::string& config) const;
/** Source file kinds (classifications).
Generators use this to decide how to treat a source file. */
@@ -107,6 +110,17 @@ public:
/** Get all sources needed for a configuration with kinds assigned. */
KindedSources const& GetKindedSources(std::string const& config) const;
+ struct AllConfigSource
+ {
+ cmSourceFile const* Source;
+ cmGeneratorTarget::SourceKind Kind;
+ std::vector<size_t> Configs;
+ };
+
+ /** Get all sources needed for all configurations with kinds and
+ per-source configurations assigned. */
+ std::vector<AllConfigSource> const& GetAllConfigSources() const;
+
void GetObjectSources(std::vector<cmSourceFile const*>&,
const std::string& config) const;
const std::string& GetObjectName(cmSourceFile const* file);
@@ -195,6 +209,11 @@ public:
bool realname) const;
std::string NormalGetRealName(const std::string& config) const;
+ /** Get the names of an object library's object files underneath
+ its object file directory. */
+ void GetTargetObjectNames(std::string const& config,
+ std::vector<std::string>& objects) const;
+
/** What hierarchy level should the reported directory contain */
enum BundleDirectoryLevel
{
@@ -338,6 +357,9 @@ public:
std::string GetFullNameImported(const std::string& config,
bool implib) const;
+ /** Get source files common to all configurations and diagnose cases
+ with per-config sources. Excludes sources added by a TARGET_OBJECTS
+ generator expression. */
bool GetConfigCommonSourceFiles(std::vector<cmSourceFile*>& files) const;
bool HaveBuildTreeRPATH(const std::string& config) const;
@@ -347,6 +369,10 @@ public:
time config name placeholder if needed for the generator. */
std::string ObjectDirectory;
+ /** Full path with trailing slash to the top-level directory
+ holding object files for the given configuration. */
+ std::string GetObjectDirectory(std::string const& config) const;
+
void GetAppleArchs(const std::string& config,
std::vector<std::string>& archVec) const;
@@ -517,7 +543,7 @@ public:
std::string GetPDBDirectory(const std::string& config) const;
///! Return the preferred linker language for this target
- std::string GetLinkerLanguage(const std::string& config = "") const;
+ std::string GetLinkerLanguage(const std::string& config) const;
/** Does this target have a GNU implib to convert to MS format? */
bool HasImplibGNUtoMS() const;
@@ -731,6 +757,9 @@ private:
void ComputeKindedSources(KindedSources& files,
std::string const& config) const;
+ mutable std::vector<AllConfigSource> AllConfigSources;
+ void ComputeAllConfigSources() const;
+
std::vector<TargetPropertyEntry*> IncludeDirectoriesEntries;
std::vector<TargetPropertyEntry*> CompileOptionsEntries;
std::vector<TargetPropertyEntry*> CompileFeaturesEntries;
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index 4200b21..aa2dd22 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -331,6 +331,11 @@ public:
i.e. "Can I build Debug and Release in the same tree?" */
virtual bool IsMultiConfig() const { return false; }
+ /** Return true if we know the exact location of object files.
+ If false, store the reason in the given string.
+ This is meaningful only after EnableLanguage has been called. */
+ virtual bool HasKnownObjectFileLocation(std::string*) const { return true; }
+
virtual bool UseFolderProperty() const;
virtual bool IsIPOSupported() const { return false; }
diff --git a/Source/cmGlobalVisualStudio71Generator.cxx b/Source/cmGlobalVisualStudio71Generator.cxx
index 3f8d381..aeceb8d 100644
--- a/Source/cmGlobalVisualStudio71Generator.cxx
+++ b/Source/cmGlobalVisualStudio71Generator.cxx
@@ -13,58 +13,6 @@ cmGlobalVisualStudio71Generator::cmGlobalVisualStudio71Generator(
: cmGlobalVisualStudio7Generator(cm, platformName)
{
this->ProjectConfigurationSectionName = "ProjectConfiguration";
- this->Version = VS71;
-}
-
-std::string cmGlobalVisualStudio71Generator::GetUserMacrosDirectory()
-{
- // Macros not supported on Visual Studio 7.1 and earlier because
- // they do not appear to work *during* a build when called by an
- // outside agent...
- //
- return "";
-
-#if 0
- //
- // The COM result from calling a Visual Studio macro with 7.1 indicates
- // that the call succeeds, but the macro does not appear to execute...
- //
- // So, I am leaving this code here to show how to do it, but have not
- // yet figured out what the issue is in terms of why the macro does not
- // appear to execute...
- //
- std::string base;
- std::string path;
-
- // base begins with the VisualStudioProjectsLocation reg value...
- if (cmSystemTools::ReadRegistryValue(
- "HKEY_CURRENT_USER\\Software\\Microsoft\\VisualStudio\\7.1;"
- "VisualStudioProjectsLocation",
- base))
- {
- cmSystemTools::ConvertToUnixSlashes(base);
-
- // 7.1 macros folder:
- path = base + "/VSMacros71";
- }
-
- // path is (correctly) still empty if we did not read the base value from
- // the Registry value
- return path;
-#endif
-}
-
-std::string cmGlobalVisualStudio71Generator::GetUserMacrosRegKeyBase()
-{
- // Macros not supported on Visual Studio 7.1 and earlier because
- // they do not appear to work *during* a build when called by an
- // outside agent...
- //
- return "";
-
-#if 0
- return "Software\\Microsoft\\VisualStudio\\7.1\\vsmacros";
-#endif
}
void cmGlobalVisualStudio71Generator::WriteSLNFile(
@@ -91,11 +39,6 @@ void cmGlobalVisualStudio71Generator::WriteSLNFile(
std::ostringstream targetsSlnString;
this->WriteTargetsToSolution(targetsSlnString, root, orderedProjectTargets);
- // VS 7 does not support folders specified first.
- if (this->GetVersion() <= VS71) {
- fout << targetsSlnString.str();
- }
-
// Generate folder specification.
bool useFolderProperty = this->UseFolderProperty();
if (useFolderProperty) {
@@ -103,9 +46,7 @@ void cmGlobalVisualStudio71Generator::WriteSLNFile(
}
// Now write the actual target specification content.
- if (this->GetVersion() > VS71) {
- fout << targetsSlnString.str();
- }
+ fout << targetsSlnString.str();
// Write out the configurations information for the solution
fout << "Global\n";
@@ -280,10 +221,3 @@ void cmGlobalVisualStudio71Generator::WriteSLNHeader(std::ostream& fout)
{
fout << "Microsoft Visual Studio Solution File, Format Version 8.00\n";
}
-
-void cmGlobalVisualStudio71Generator::GetDocumentation(
- cmDocumentationEntry& entry)
-{
- entry.Name = cmGlobalVisualStudio71Generator::GetActualName();
- entry.Brief = "Deprecated. Generates Visual Studio .NET 2003 project files.";
-}
diff --git a/Source/cmGlobalVisualStudio71Generator.h b/Source/cmGlobalVisualStudio71Generator.h
index c65a84a..0ce02aa 100644
--- a/Source/cmGlobalVisualStudio71Generator.h
+++ b/Source/cmGlobalVisualStudio71Generator.h
@@ -15,37 +15,8 @@ class cmGlobalVisualStudio71Generator : public cmGlobalVisualStudio7Generator
public:
cmGlobalVisualStudio71Generator(cmake* cm,
const std::string& platformName = "");
- static cmGlobalGeneratorFactory* NewFactory()
- {
- return new cmGlobalGeneratorSimpleFactory<
- cmGlobalVisualStudio71Generator>();
- }
-
- ///! Get the name for the generator.
- virtual std::string GetName() const
- {
- return cmGlobalVisualStudio71Generator::GetActualName();
- }
- static std::string GetActualName() { return "Visual Studio 7 .NET 2003"; }
-
- /** Get the documentation entry for this generator. */
- static void GetDocumentation(cmDocumentationEntry& entry);
-
- /**
- * Where does this version of Visual Studio look for macros for the
- * current user? Returns the empty string if this version of Visual
- * Studio does not implement support for VB macros.
- */
- virtual std::string GetUserMacrosDirectory();
-
- /**
- * What is the reg key path to "vsmacros" for this version of Visual
- * Studio?
- */
- virtual std::string GetUserMacrosRegKeyBase();
protected:
- virtual const char* GetIDEVersion() { return "7.1"; }
virtual void WriteSLNFile(std::ostream& fout, cmLocalGenerator* root,
std::vector<cmLocalGenerator*>& generators);
virtual void WriteSolutionConfigurations(
diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx
index 3849175..14ec72f 100644
--- a/Source/cmGlobalVisualStudio7Generator.cxx
+++ b/Source/cmGlobalVisualStudio7Generator.cxx
@@ -54,7 +54,6 @@ cmGlobalVisualStudio7Generator::cmGlobalVisualStudio7Generator(
this->DefaultPlatformName = platformName;
}
this->ExtraFlagTable = cmVS7ExtraFlagTable;
- this->Version = VS7;
}
cmGlobalVisualStudio7Generator::~cmGlobalVisualStudio7Generator()
@@ -294,19 +293,6 @@ void cmGlobalVisualStudio7Generator::Generate()
if (!cmSystemTools::GetErrorOccuredFlag()) {
this->CallVisualStudioMacro(MacroReload);
}
-
- if (this->Version == VS71 && !this->CMakeInstance->GetIsInTryCompile()) {
- const char* cmakeWarnVS71 =
- this->CMakeInstance->GetState()->GetCacheEntryValue("CMAKE_WARN_VS71");
- if (!cmakeWarnVS71 || !cmSystemTools::IsOff(cmakeWarnVS71)) {
- this->CMakeInstance->IssueMessage(
- cmake::WARNING,
- "The \"Visual Studio 7 .NET 2003\" generator is deprecated "
- "and will be removed in a future version of CMake."
- "\n"
- "Add CMAKE_WARN_VS71=OFF to the cache to disable this warning.");
- }
- }
}
void cmGlobalVisualStudio7Generator::OutputSLNFile(
diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx
index 634db7f..1fcb5ac 100644
--- a/Source/cmGlobalVisualStudio8Generator.cxx
+++ b/Source/cmGlobalVisualStudio8Generator.cxx
@@ -153,13 +153,6 @@ void cmGlobalVisualStudio8Generator::WriteSLNHeader(std::ostream& fout)
fout << "# Visual Studio 2005\n";
}
-void cmGlobalVisualStudio8Generator::GetDocumentation(
- cmDocumentationEntry& entry)
-{
- entry.Name = cmGlobalVisualStudio8Generator::GetActualName();
- entry.Brief = "Generates Visual Studio 8 2005 project files.";
-}
-
std::string cmGlobalVisualStudio8Generator::GetGenerateStampList()
{
return "generate.stamp.list";
diff --git a/Source/cmGlobalVisualStudio8Generator.h b/Source/cmGlobalVisualStudio8Generator.h
index 03fa077..4723b83 100644
--- a/Source/cmGlobalVisualStudio8Generator.h
+++ b/Source/cmGlobalVisualStudio8Generator.h
@@ -20,9 +20,6 @@ public:
///! Get the name for the generator.
virtual std::string GetName() const { return this->Name; }
- /** Get the documentation entry for this generator. */
- static void GetDocumentation(cmDocumentationEntry& entry);
-
/** Get the name of the main stamp list file. */
static std::string GetGenerateStampList();
diff --git a/Source/cmGlobalVisualStudioGenerator.h b/Source/cmGlobalVisualStudioGenerator.h
index 60344f3..c12a933 100644
--- a/Source/cmGlobalVisualStudioGenerator.h
+++ b/Source/cmGlobalVisualStudioGenerator.h
@@ -32,8 +32,6 @@ public:
/** Known versions of Visual Studio. */
enum VSVersion
{
- VS7 = 70,
- VS71 = 71,
VS8 = 80,
VS9 = 90,
VS10 = 100,
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 10343fd..6118c73 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -651,11 +651,6 @@ std::string GetGroupMapKeyFromPath(cmGeneratorTarget* target,
return key;
}
-std::string GetGroupMapKey(cmGeneratorTarget* target, cmSourceFile* sf)
-{
- return GetGroupMapKeyFromPath(target, sf->GetFullPath());
-}
-
cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFileFromPath(
const std::string& fullpath, cmGeneratorTarget* target,
const std::string& lang, cmSourceFile* sf)
@@ -2014,6 +2009,10 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
BuildObjectListOrString dirs(this, this->XcodeVersion >= 30);
BuildObjectListOrString fdirs(this, this->XcodeVersion >= 30);
+ BuildObjectListOrString sysdirs(this, this->XcodeVersion >= 30);
+ BuildObjectListOrString sysfdirs(this, this->XcodeVersion >= 30);
+ const bool emitSystemIncludes = this->XcodeVersion >= 83;
+
std::vector<std::string> includes;
this->CurrentLocalGenerator->GetIncludeDirectories(includes, gtgt, "C",
configName);
@@ -2027,11 +2026,22 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
frameworkDir += "/../";
frameworkDir = cmSystemTools::CollapseFullPath(frameworkDir);
if (emitted.insert(frameworkDir).second) {
- fdirs.Add(this->XCodeEscapePath(frameworkDir));
+ std::string incpath = this->XCodeEscapePath(frameworkDir);
+ if (emitSystemIncludes &&
+ gtgt->IsSystemIncludeDirectory(frameworkDir, configName)) {
+ sysfdirs.Add(incpath);
+ } else {
+ fdirs.Add(incpath);
+ }
}
} else {
std::string incpath = this->XCodeEscapePath(*i);
- dirs.Add(incpath);
+ if (emitSystemIncludes &&
+ gtgt->IsSystemIncludeDirectory(*i, configName)) {
+ sysdirs.Add(incpath);
+ } else {
+ dirs.Add(incpath);
+ }
}
}
// Add framework search paths needed for linking.
@@ -2040,7 +2050,13 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
for (std::vector<std::string>::const_iterator fdi = fwDirs.begin();
fdi != fwDirs.end(); ++fdi) {
if (emitted.insert(*fdi).second) {
- fdirs.Add(this->XCodeEscapePath(*fdi));
+ std::string incpath = this->XCodeEscapePath(*fdi);
+ if (emitSystemIncludes &&
+ gtgt->IsSystemIncludeDirectory(*fdi, configName)) {
+ sysfdirs.Add(incpath);
+ } else {
+ fdirs.Add(incpath);
+ }
}
}
}
@@ -2050,8 +2066,16 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
if (!dirs.IsEmpty()) {
buildSettings->AddAttribute("HEADER_SEARCH_PATHS", dirs.CreateList());
}
+ if (!sysfdirs.IsEmpty()) {
+ buildSettings->AddAttribute("SYSTEM_FRAMEWORK_SEARCH_PATHS",
+ sysfdirs.CreateList());
+ }
+ if (!sysdirs.IsEmpty()) {
+ buildSettings->AddAttribute("SYSTEM_HEADER_SEARCH_PATHS",
+ sysdirs.CreateList());
+ }
- if (this->XcodeVersion >= 60) {
+ if (this->XcodeVersion >= 60 && !emitSystemIncludes) {
// Add those per-language flags in addition to HEADER_SEARCH_PATHS to gain
// system include directory awareness. We need to also keep on setting
// HEADER_SEARCH_PATHS to work around a missing compile options flag for
@@ -2673,7 +2697,7 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
std::string linkObjs;
const char* sep = "";
std::vector<cmSourceFile const*> objs;
- gt->GetExternalObjects(objs, "");
+ gt->GetExternalObjects(objs, configName);
for (std::vector<cmSourceFile const*>::const_iterator oi = objs.begin();
oi != objs.end(); ++oi) {
if ((*oi)->GetObjectLibrary().empty()) {
@@ -2788,42 +2812,26 @@ bool cmGlobalXCodeGenerator::CreateGroups(
gtgt->AddSource(plist);
}
- std::vector<cmSourceFile*> classes;
- if (!gtgt->GetConfigCommonSourceFiles(classes)) {
- return false;
- }
+ std::vector<cmGeneratorTarget::AllConfigSource> const& sources =
+ gtgt->GetAllConfigSources();
+
// Put cmSourceFile instances in proper groups:
- for (std::vector<cmSourceFile*>::const_iterator s = classes.begin();
- s != classes.end(); s++) {
- cmSourceFile* sf = *s;
+ for (std::vector<cmGeneratorTarget::AllConfigSource>::const_iterator si =
+ sources.begin();
+ si != sources.end(); ++si) {
+ cmSourceFile const* sf = si->Source;
+ if (this->XcodeVersion >= 50 && !sf->GetObjectLibrary().empty()) {
+ // Object library files go on the link line instead.
+ continue;
+ }
// Add the file to the list of sources.
std::string const& source = sf->GetFullPath();
cmSourceGroup* sourceGroup =
mf->FindSourceGroup(source.c_str(), sourceGroups);
cmXCodeObject* pbxgroup = this->CreateOrGetPBXGroup(gtgt, sourceGroup);
- std::string key = GetGroupMapKey(gtgt, sf);
+ std::string key = GetGroupMapKeyFromPath(gtgt, source);
this->GroupMap[key] = pbxgroup;
}
-
- if (this->XcodeVersion < 50) {
- // Put OBJECT_LIBRARY objects in proper groups:
- std::vector<cmSourceFile const*> objs;
- gtgt->GetExternalObjects(objs, "");
- for (std::vector<cmSourceFile const*>::const_iterator oi =
- objs.begin();
- oi != objs.end(); ++oi) {
- if ((*oi)->GetObjectLibrary().empty()) {
- continue;
- }
- std::string const& source = (*oi)->GetFullPath();
- cmSourceGroup* sourceGroup =
- mf->FindSourceGroup(source.c_str(), sourceGroups);
- cmXCodeObject* pbxgroup =
- this->CreateOrGetPBXGroup(gtgt, sourceGroup);
- std::string key = GetGroupMapKeyFromPath(gtgt, source);
- this->GroupMap[key] = pbxgroup;
- }
- }
}
}
return true;
@@ -3741,6 +3749,18 @@ bool cmGlobalXCodeGenerator::IsMultiConfig() const
return true;
}
+bool cmGlobalXCodeGenerator::HasKnownObjectFileLocation(
+ std::string* reason) const
+{
+ if (this->ObjectDirArch.find('$') != std::string::npos) {
+ if (reason != CM_NULLPTR) {
+ *reason = " under Xcode with multiple architectures";
+ }
+ return false;
+ }
+ return true;
+}
+
bool cmGlobalXCodeGenerator::UseEffectivePlatformName(cmMakefile* mf) const
{
const char* epnValue =
diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h
index 982dabd..a733d5c 100644
--- a/Source/cmGlobalXCodeGenerator.h
+++ b/Source/cmGlobalXCodeGenerator.h
@@ -87,6 +87,8 @@ public:
i.e. "Can I build Debug and Release in the same tree?" */
bool IsMultiConfig() const CM_OVERRIDE;
+ bool HasKnownObjectFileLocation(std::string* reason) const CM_OVERRIDE;
+
bool UseEffectivePlatformName(cmMakefile* mf) const CM_OVERRIDE;
bool ShouldStripResourcePath(cmMakefile*) const CM_OVERRIDE;
diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx
index c8923b0..ba554aa 100644
--- a/Source/cmInstallCommand.cxx
+++ b/Source/cmInstallCommand.cxx
@@ -206,6 +206,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
cmCAStringVector archiveArgVector(&argHelper, "ARCHIVE", &group);
cmCAStringVector libraryArgVector(&argHelper, "LIBRARY", &group);
cmCAStringVector runtimeArgVector(&argHelper, "RUNTIME", &group);
+ cmCAStringVector objectArgVector(&argHelper, "OBJECTS", &group);
cmCAStringVector frameworkArgVector(&argHelper, "FRAMEWORK", &group);
cmCAStringVector bundleArgVector(&argHelper, "BUNDLE", &group);
cmCAStringVector includesArgVector(&argHelper, "INCLUDES", &group);
@@ -234,6 +235,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
cmInstallCommandArguments archiveArgs(this->DefaultComponentName);
cmInstallCommandArguments libraryArgs(this->DefaultComponentName);
cmInstallCommandArguments runtimeArgs(this->DefaultComponentName);
+ cmInstallCommandArguments objectArgs(this->DefaultComponentName);
cmInstallCommandArguments frameworkArgs(this->DefaultComponentName);
cmInstallCommandArguments bundleArgs(this->DefaultComponentName);
cmInstallCommandArguments privateHeaderArgs(this->DefaultComponentName);
@@ -246,6 +248,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
archiveArgs.Parse(&archiveArgVector.GetVector(), &unknownArgs);
libraryArgs.Parse(&libraryArgVector.GetVector(), &unknownArgs);
runtimeArgs.Parse(&runtimeArgVector.GetVector(), &unknownArgs);
+ objectArgs.Parse(&objectArgVector.GetVector(), &unknownArgs);
frameworkArgs.Parse(&frameworkArgVector.GetVector(), &unknownArgs);
bundleArgs.Parse(&bundleArgVector.GetVector(), &unknownArgs);
privateHeaderArgs.Parse(&privateHeaderArgVector.GetVector(), &unknownArgs);
@@ -265,6 +268,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
archiveArgs.SetGenericArguments(&genericArgs);
libraryArgs.SetGenericArguments(&genericArgs);
runtimeArgs.SetGenericArguments(&genericArgs);
+ objectArgs.SetGenericArguments(&genericArgs);
frameworkArgs.SetGenericArguments(&genericArgs);
bundleArgs.SetGenericArguments(&genericArgs);
privateHeaderArgs.SetGenericArguments(&genericArgs);
@@ -274,6 +278,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
success = success && archiveArgs.Finalize();
success = success && libraryArgs.Finalize();
success = success && runtimeArgs.Finalize();
+ success = success && objectArgs.Finalize();
success = success && frameworkArgs.Finalize();
success = success && bundleArgs.Finalize();
success = success && privateHeaderArgs.Finalize();
@@ -287,8 +292,8 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
// Enforce argument rules too complex to specify for the
// general-purpose parser.
if (archiveArgs.GetNamelinkOnly() || runtimeArgs.GetNamelinkOnly() ||
- frameworkArgs.GetNamelinkOnly() || bundleArgs.GetNamelinkOnly() ||
- privateHeaderArgs.GetNamelinkOnly() ||
+ objectArgs.GetNamelinkOnly() || frameworkArgs.GetNamelinkOnly() ||
+ bundleArgs.GetNamelinkOnly() || privateHeaderArgs.GetNamelinkOnly() ||
publicHeaderArgs.GetNamelinkOnly() || resourceArgs.GetNamelinkOnly()) {
this->SetError(
"TARGETS given NAMELINK_ONLY option not in LIBRARY group. "
@@ -296,8 +301,8 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
return false;
}
if (archiveArgs.GetNamelinkSkip() || runtimeArgs.GetNamelinkSkip() ||
- frameworkArgs.GetNamelinkSkip() || bundleArgs.GetNamelinkSkip() ||
- privateHeaderArgs.GetNamelinkSkip() ||
+ objectArgs.GetNamelinkSkip() || frameworkArgs.GetNamelinkSkip() ||
+ bundleArgs.GetNamelinkSkip() || privateHeaderArgs.GetNamelinkSkip() ||
publicHeaderArgs.GetNamelinkSkip() || resourceArgs.GetNamelinkSkip()) {
this->SetError(
"TARGETS given NAMELINK_SKIP option not in LIBRARY group. "
@@ -356,11 +361,15 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
return false;
}
if (target->GetType() == cmStateEnums::OBJECT_LIBRARY) {
- std::ostringstream e;
- e << "TARGETS given OBJECT library \"" << (*targetIt)
- << "\" which may not be installed.";
- this->SetError(e.str());
- return false;
+ std::string reason;
+ if (!this->Makefile->GetGlobalGenerator()->HasKnownObjectFileLocation(
+ &reason)) {
+ std::ostringstream e;
+ e << "TARGETS given OBJECT library \"" << (*targetIt)
+ << "\" which may not be installed" << reason << ".";
+ this->SetError(e.str());
+ return false;
+ }
}
// Store the target in the list to be installed.
targets.push_back(target);
@@ -379,6 +388,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
bool installsArchive = false;
bool installsLibrary = false;
bool installsRuntime = false;
+ bool installsObject = false;
bool installsFramework = false;
bool installsBundle = false;
bool installsPrivateHeader = false;
@@ -393,6 +403,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
cmInstallTargetGenerator* archiveGenerator = CM_NULLPTR;
cmInstallTargetGenerator* libraryGenerator = CM_NULLPTR;
cmInstallTargetGenerator* runtimeGenerator = CM_NULLPTR;
+ cmInstallTargetGenerator* objectGenerator = CM_NULLPTR;
cmInstallTargetGenerator* frameworkGenerator = CM_NULLPTR;
cmInstallTargetGenerator* bundleGenerator = CM_NULLPTR;
cmInstallFilesGenerator* privateHeaderGenerator = CM_NULLPTR;
@@ -522,6 +533,20 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
return false;
}
} break;
+ case cmStateEnums::OBJECT_LIBRARY: {
+ // Objects use OBJECT properties.
+ if (!objectArgs.GetDestination().empty()) {
+ objectGenerator =
+ CreateInstallTargetGenerator(target, objectArgs, false);
+ } else {
+ std::ostringstream e;
+ e << "TARGETS given no OBJECTS DESTINATION for object library "
+ "target \""
+ << target.GetName() << "\".";
+ this->SetError(e.str());
+ return false;
+ }
+ } break;
case cmStateEnums::EXECUTABLE: {
if (target.IsAppBundleOnApple()) {
// Application bundles use the BUNDLE properties.
@@ -664,6 +689,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
installsArchive = installsArchive || archiveGenerator != CM_NULLPTR;
installsLibrary = installsLibrary || libraryGenerator != CM_NULLPTR;
installsRuntime = installsRuntime || runtimeGenerator != CM_NULLPTR;
+ installsObject = installsObject || objectGenerator != CM_NULLPTR;
installsFramework = installsFramework || frameworkGenerator != CM_NULLPTR;
installsBundle = installsBundle || bundleGenerator != CM_NULLPTR;
installsPrivateHeader =
@@ -675,6 +701,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
this->Makefile->AddInstallGenerator(archiveGenerator);
this->Makefile->AddInstallGenerator(libraryGenerator);
this->Makefile->AddInstallGenerator(runtimeGenerator);
+ this->Makefile->AddInstallGenerator(objectGenerator);
this->Makefile->AddInstallGenerator(frameworkGenerator);
this->Makefile->AddInstallGenerator(bundleGenerator);
this->Makefile->AddInstallGenerator(privateHeaderGenerator);
@@ -692,6 +719,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
te->HeaderGenerator = publicHeaderGenerator;
te->LibraryGenerator = libraryGenerator;
te->RuntimeGenerator = runtimeGenerator;
+ te->ObjectsGenerator = objectGenerator;
this->Makefile->GetGlobalGenerator()
->GetExportSets()[exports.GetString()]
->AddTargetExport(te);
@@ -715,6 +743,10 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
this->Makefile->GetGlobalGenerator()->AddInstallComponent(
runtimeArgs.GetComponent().c_str());
}
+ if (installsObject) {
+ this->Makefile->GetGlobalGenerator()->AddInstallComponent(
+ objectArgs.GetComponent().c_str());
+ }
if (installsFramework) {
this->Makefile->GetGlobalGenerator()->AddInstallComponent(
frameworkArgs.GetComponent().c_str());
diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx
index 88fcc56..6ecf42d 100644
--- a/Source/cmInstallTargetGenerator.cxx
+++ b/Source/cmInstallTargetGenerator.cxx
@@ -60,25 +60,6 @@ void cmInstallTargetGenerator::GenerateScript(std::ostream& os)
void cmInstallTargetGenerator::GenerateScriptForConfig(
std::ostream& os, const std::string& config, Indent const& indent)
{
- // Compute the build tree directory from which to copy the target.
- std::string fromDirConfig;
- if (this->Target->NeedRelinkBeforeInstall(config)) {
- fromDirConfig =
- this->Target->GetLocalGenerator()->GetCurrentBinaryDirectory();
- fromDirConfig += cmake::GetCMakeFilesDirectory();
- fromDirConfig += "/CMakeRelink.dir/";
- } else {
- fromDirConfig = this->Target->GetDirectory(config, this->ImportLibrary);
- fromDirConfig += "/";
- }
- std::string toDir =
- this->ConvertToAbsoluteDestination(this->GetDestination(config));
- toDir += "/";
-
- // Compute the list of files to install for this target.
- std::vector<std::string> filesFrom;
- std::vector<std::string> filesTo;
- std::string literal_args;
cmStateEnums::TargetType targetType = this->Target->GetType();
cmInstallType type = cmInstallType();
switch (targetType) {
@@ -100,7 +81,11 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(
assert(false &&
"INTERFACE_LIBRARY targets have no installable outputs.");
break;
+
case cmStateEnums::OBJECT_LIBRARY:
+ this->GenerateScriptForConfigObjectLibrary(os, config, indent);
+ return;
+
case cmStateEnums::UTILITY:
case cmStateEnums::GLOBAL_TARGET:
case cmStateEnums::UNKNOWN_LIBRARY:
@@ -109,6 +94,28 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(
"cmInstallTargetGenerator created with non-installable target.");
return;
}
+
+ // Compute the build tree directory from which to copy the target.
+ std::string fromDirConfig;
+ if (this->Target->NeedRelinkBeforeInstall(config)) {
+ fromDirConfig =
+ this->Target->GetLocalGenerator()->GetCurrentBinaryDirectory();
+ fromDirConfig += cmake::GetCMakeFilesDirectory();
+ fromDirConfig += "/CMakeRelink.dir/";
+ } else {
+ fromDirConfig = this->Target->GetDirectory(config, this->ImportLibrary);
+ fromDirConfig += "/";
+ }
+
+ std::string toDir =
+ this->ConvertToAbsoluteDestination(this->GetDestination(config));
+ toDir += "/";
+
+ // Compute the list of files to install for this target.
+ std::vector<std::string> filesFrom;
+ std::vector<std::string> filesTo;
+ std::string literal_args;
+
if (targetType == cmStateEnums::EXECUTABLE) {
// There is a bug in cmInstallCommand if this fails.
assert(this->NamelinkMode == NamelinkModeNone);
@@ -315,6 +322,49 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(
&cmInstallTargetGenerator::PostReplacementTweaks);
}
+static std::string computeInstallObjectDir(cmGeneratorTarget* gt,
+ std::string const& config)
+{
+ std::string objectDir = "objects";
+ if (!config.empty()) {
+ objectDir += "-";
+ objectDir += config;
+ }
+ objectDir += "/";
+ objectDir += gt->GetName();
+ return objectDir;
+}
+
+void cmInstallTargetGenerator::GenerateScriptForConfigObjectLibrary(
+ std::ostream& os, const std::string& config, Indent const& indent)
+{
+ // Compute all the object files inside this target
+ std::vector<std::string> objects;
+ this->Target->GetTargetObjectNames(config, objects);
+
+ std::string const dest = this->GetDestination(config) + "/" +
+ computeInstallObjectDir(this->Target, config);
+
+ std::string const obj_dir = this->Target->GetObjectDirectory(config);
+ std::string const literal_args = " FILES_FROM_DIR \"" + obj_dir + "\"";
+
+ const char* no_dir_permissions = CM_NULLPTR;
+ const char* no_rename = CM_NULLPTR;
+ this->AddInstallRule(os, dest, cmInstallType_FILES, objects, this->Optional,
+ this->FilePermissions.c_str(), no_dir_permissions,
+ no_rename, literal_args.c_str(), indent);
+}
+
+void cmInstallTargetGenerator::GetInstallObjectNames(
+ std::string const& config, std::vector<std::string>& objects) const
+{
+ this->Target->GetTargetObjectNames(config, objects);
+ for (std::vector<std::string>::iterator i = objects.begin();
+ i != objects.end(); ++i) {
+ *i = computeInstallObjectDir(this->Target, config) + "/" + *i;
+ }
+}
+
std::string cmInstallTargetGenerator::GetDestination(
std::string const& config) const
{
diff --git a/Source/cmInstallTargetGenerator.h b/Source/cmInstallTargetGenerator.h
index e6b11b8..6aaa3ba 100644
--- a/Source/cmInstallTargetGenerator.h
+++ b/Source/cmInstallTargetGenerator.h
@@ -41,6 +41,9 @@ public:
std::string GetInstallFilename(const std::string& config) const;
+ void GetInstallObjectNames(std::string const& config,
+ std::vector<std::string>& objects) const;
+
enum NameType
{
NameNormal,
@@ -65,6 +68,9 @@ protected:
void GenerateScript(std::ostream& os) CM_OVERRIDE;
void GenerateScriptForConfig(std::ostream& os, const std::string& config,
Indent const& indent) CM_OVERRIDE;
+ void GenerateScriptForConfigObjectLibrary(std::ostream& os,
+ const std::string& config,
+ Indent const& indent);
typedef void (cmInstallTargetGenerator::*TweakMethod)(std::ostream&,
Indent const&,
const std::string&,
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index 56ce2bd..7535ef4 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -30,7 +30,7 @@ public:
typedef cmComputeLinkInformation::ItemVector ItemVector;
void OutputLibraries(std::ostream& fout, ItemVector const& libs);
void OutputObjects(std::ostream& fout, cmGeneratorTarget* t,
- const char* isep = 0);
+ std::string const& config, const char* isep = 0);
private:
cmLocalVisualStudio7Generator* LocalGenerator;
@@ -898,8 +898,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
// end of <Tool Name=VCMIDLTool
// Add manifest tool settings.
- if (targetBuilds &&
- this->GetVersion() >= cmGlobalVisualStudioGenerator::VS8) {
+ if (targetBuilds) {
const char* manifestTool = "VCManifestTool";
if (this->FortranProject) {
manifestTool = "VFManifestTool";
@@ -1040,10 +1039,9 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
fout << "\t\t\t<Tool\n"
<< "\t\t\t\tName=\"" << tool << "\"\n";
- if (this->GetVersion() < cmGlobalVisualStudioGenerator::VS8 ||
- this->FortranProject) {
+ if (this->FortranProject) {
std::ostringstream libdeps;
- this->Internal->OutputObjects(libdeps, target);
+ this->Internal->OutputObjects(libdeps, target, configName);
if (!libdeps.str().empty()) {
fout << "\t\t\t\tAdditionalDependencies=\"" << libdeps.str()
<< "\"\n";
@@ -1094,9 +1092,8 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
// libraries which may be set by the user to something bad.
fout << "\t\t\t\tAdditionalDependencies=\"$(NOINHERIT) "
<< this->Makefile->GetSafeDefinition(standardLibsVar.c_str());
- if (this->GetVersion() < cmGlobalVisualStudioGenerator::VS8 ||
- this->FortranProject) {
- this->Internal->OutputObjects(fout, target, " ");
+ if (this->FortranProject) {
+ this->Internal->OutputObjects(fout, target, configName, " ");
}
fout << " ";
this->Internal->OutputLibraries(fout, cli.GetItems());
@@ -1179,9 +1176,8 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
// libraries which may be set by the user to something bad.
fout << "\t\t\t\tAdditionalDependencies=\"$(NOINHERIT) "
<< this->Makefile->GetSafeDefinition(standardLibsVar.c_str());
- if (this->GetVersion() < cmGlobalVisualStudioGenerator::VS8 ||
- this->FortranProject) {
- this->Internal->OutputObjects(fout, target, " ");
+ if (this->FortranProject) {
+ this->Internal->OutputObjects(fout, target, configName, " ");
}
fout << " ";
this->Internal->OutputLibraries(fout, cli.GetItems());
@@ -1300,21 +1296,20 @@ void cmLocalVisualStudio7GeneratorInternals::OutputLibraries(
}
void cmLocalVisualStudio7GeneratorInternals::OutputObjects(
- std::ostream& fout, cmGeneratorTarget* gt, const char* isep)
+ std::ostream& fout, cmGeneratorTarget* gt, std::string const& configName,
+ const char* isep)
{
// VS < 8 does not support per-config source locations so we
// list object library content on the link line instead.
cmLocalVisualStudio7Generator* lg = this->LocalGenerator;
std::string currentBinDir = lg->GetCurrentBinaryDirectory();
- std::vector<cmSourceFile*> sources;
- if (!gt->GetConfigCommonSourceFiles(sources)) {
- return;
- }
+ std::vector<cmSourceFile const*> objs;
+ gt->GetExternalObjects(objs, configName);
const char* sep = isep ? isep : "";
- for (std::vector<cmSourceFile*>::const_iterator i = sources.begin();
- i != sources.end(); i++) {
+ for (std::vector<cmSourceFile const*>::const_iterator i = objs.begin();
+ i != objs.end(); ++i) {
if (!(*i)->GetObjectLibrary().empty()) {
std::string const& objFile = (*i)->GetFullPath();
std::string rel = lg->ConvertToRelativePath(currentBinDir, objFile);
@@ -1369,27 +1364,26 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
// We may be modifying the source groups temporarily, so make a copy.
std::vector<cmSourceGroup> sourceGroups = this->Makefile->GetSourceGroups();
- // get the classes from the source lists then add them to the groups
- std::vector<cmSourceFile*> classes;
- if (!target->GetConfigCommonSourceFiles(classes)) {
- return;
- }
- for (std::vector<cmSourceFile*>::const_iterator i = classes.begin();
- i != classes.end(); i++) {
- if (!(*i)->GetObjectLibrary().empty()) {
- if (this->GetVersion() < cmGlobalVisualStudioGenerator::VS8 ||
- this->FortranProject) {
- // VS < 8 does not support per-config source locations so we
- // list object library content on the link line instead.
+ std::vector<cmGeneratorTarget::AllConfigSource> const& sources =
+ target->GetAllConfigSources();
+ std::map<cmSourceFile const*, size_t> sourcesIndex;
+
+ for (size_t si = 0; si < sources.size(); ++si) {
+ cmSourceFile const* sf = sources[si].Source;
+ sourcesIndex[sf] = si;
+ if (!sf->GetObjectLibrary().empty()) {
+ if (this->FortranProject) {
+ // Intel Fortran does not support per-config source locations
+ // so we list object library content on the link line instead.
// See OutputObjects.
continue;
}
}
// Add the file to the list of sources.
- std::string source = (*i)->GetFullPath();
+ std::string const source = sf->GetFullPath();
cmSourceGroup* sourceGroup =
this->Makefile->FindSourceGroup(source.c_str(), sourceGroups);
- sourceGroup->AssignSource(*i);
+ sourceGroup->AssignSource(sf);
}
// open the project
@@ -1402,7 +1396,7 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
// Loop through every source group.
for (unsigned int i = 0; i < sourceGroups.size(); ++i) {
cmSourceGroup sg = sourceGroups[i];
- this->WriteGroup(&sg, target, fout, libName, configs);
+ this->WriteGroup(&sg, target, fout, libName, configs, sourcesIndex);
}
fout << "\t</Files>\n";
@@ -1424,25 +1418,28 @@ struct cmLVS7GFileConfig
class cmLocalVisualStudio7GeneratorFCInfo
{
public:
- cmLocalVisualStudio7GeneratorFCInfo(cmLocalVisualStudio7Generator* lg,
- cmGeneratorTarget* target,
- cmSourceFile const& sf,
- std::vector<std::string> const& configs);
+ cmLocalVisualStudio7GeneratorFCInfo(
+ cmLocalVisualStudio7Generator* lg, cmGeneratorTarget* target,
+ cmGeneratorTarget::AllConfigSource const& acs,
+ std::vector<std::string> const& configs);
std::map<std::string, cmLVS7GFileConfig> FileConfigMap;
};
cmLocalVisualStudio7GeneratorFCInfo::cmLocalVisualStudio7GeneratorFCInfo(
cmLocalVisualStudio7Generator* lg, cmGeneratorTarget* gt,
- cmSourceFile const& sf, std::vector<std::string> const& configs)
+ cmGeneratorTarget::AllConfigSource const& acs,
+ std::vector<std::string> const& configs)
{
+ cmSourceFile const& sf = *acs.Source;
std::string objectName;
if (gt->HasExplicitObjectName(&sf)) {
objectName = gt->GetObjectName(&sf);
}
// Compute per-source, per-config information.
+ size_t ci = 0;
for (std::vector<std::string>::const_iterator i = configs.begin();
- i != configs.end(); ++i) {
+ i != configs.end(); ++i, ++ci) {
std::string configUpper = cmSystemTools::UpperCase(*i);
cmLVS7GFileConfig fc;
bool needfc = false;
@@ -1508,7 +1505,9 @@ cmLocalVisualStudio7GeneratorFCInfo::cmLocalVisualStudio7GeneratorFCInfo(
}
// If HEADER_FILE_ONLY is set, we must suppress this generation in
// the project file
- fc.ExcludedFromBuild = (sf.GetPropertyAsBool("HEADER_FILE_ONLY"));
+ fc.ExcludedFromBuild = sf.GetPropertyAsBool("HEADER_FILE_ONLY") ||
+ std::find(acs.Configs.begin(), acs.Configs.end(), ci) ==
+ acs.Configs.end();
if (fc.ExcludedFromBuild) {
needfc = true;
}
@@ -1563,7 +1562,8 @@ std::string cmLocalVisualStudio7Generator::ComputeLongestObjectDirectory(
bool cmLocalVisualStudio7Generator::WriteGroup(
const cmSourceGroup* sg, cmGeneratorTarget* target, std::ostream& fout,
- const std::string& libName, std::vector<std::string> const& configs)
+ const std::string& libName, std::vector<std::string> const& configs,
+ std::map<cmSourceFile const*, size_t> const& sourcesIndex)
{
cmGlobalVisualStudio7Generator* gg =
static_cast<cmGlobalVisualStudio7Generator*>(this->GlobalGenerator);
@@ -1574,7 +1574,8 @@ bool cmLocalVisualStudio7Generator::WriteGroup(
bool hasChildrenWithSources = false;
std::ostringstream tmpOut;
for (unsigned int i = 0; i < children.size(); ++i) {
- if (this->WriteGroup(&children[i], target, tmpOut, libName, configs)) {
+ if (this->WriteGroup(&children[i], target, tmpOut, libName, configs,
+ sourcesIndex)) {
hasChildrenWithSources = true;
}
}
@@ -1590,15 +1591,26 @@ bool cmLocalVisualStudio7Generator::WriteGroup(
this->WriteVCProjBeginGroup(fout, name.c_str(), "");
}
+ std::vector<cmGeneratorTarget::AllConfigSource> const& sources =
+ target->GetAllConfigSources();
+
// Loop through each source in the source group.
for (std::vector<const cmSourceFile*>::const_iterator sf =
sourceFiles.begin();
sf != sourceFiles.end(); ++sf) {
std::string source = (*sf)->GetFullPath();
- FCInfo fcinfo(this, target, *(*sf), configs);
if (source != libName || target->GetType() == cmStateEnums::UTILITY ||
target->GetType() == cmStateEnums::GLOBAL_TARGET) {
+ // Look up the source kind and configs.
+ std::map<cmSourceFile const*, size_t>::const_iterator map_it =
+ sourcesIndex.find(*sf);
+ // The map entry must exist because we populated it earlier.
+ assert(map_it != sourcesIndex.end());
+ cmGeneratorTarget::AllConfigSource const& acs = sources[map_it->second];
+
+ FCInfo fcinfo(this, target, acs, configs);
+
fout << "\t\t\t<File\n";
std::string d = this->ConvertToXMLOutputPathSingle(source.c_str());
// Tell MS-Dev what the source is. If the compiler knows how to
@@ -1638,6 +1650,9 @@ bool cmLocalVisualStudio7Generator::WriteGroup(
lang == "ASM_MASM") {
aCompilerTool = "MASM";
}
+ if (acs.Kind == cmGeneratorTarget::SourceKindExternalObject) {
+ aCompilerTool = "VCCustomBuildTool";
+ }
for (std::map<std::string, cmLVS7GFileConfig>::const_iterator fci =
fcinfo.FileConfigMap.begin();
fci != fcinfo.FileConfigMap.end(); ++fci) {
@@ -1942,11 +1957,7 @@ void cmLocalVisualStudio7Generator::WriteProjectStart(
<< "<VisualStudioProject\n"
<< "\tProjectType=\"Visual C++\"\n";
/* clang-format on */
- if (gg->GetVersion() == cmGlobalVisualStudioGenerator::VS71) {
- fout << "\tVersion=\"7.10\"\n";
- } else {
- fout << "\tVersion=\"" << (gg->GetVersion() / 10) << ".00\"\n";
- }
+ fout << "\tVersion=\"" << (gg->GetVersion() / 10) << ".00\"\n";
const char* projLabel = target->GetProperty("PROJECT_LABEL");
if (!projLabel) {
projLabel = libName.c_str();
@@ -1956,9 +1967,7 @@ void cmLocalVisualStudio7Generator::WriteProjectStart(
keyword = "Win32Proj";
}
fout << "\tName=\"" << projLabel << "\"\n";
- if (gg->GetVersion() >= cmGlobalVisualStudioGenerator::VS8) {
- fout << "\tProjectGUID=\"{" << gg->GetGUID(libName.c_str()) << "}\"\n";
- }
+ fout << "\tProjectGUID=\"{" << gg->GetGUID(libName.c_str()) << "}\"\n";
this->WriteProjectSCC(fout, target);
if (const char* targetFrameworkVersion =
target->GetProperty("VS_DOTNET_TARGET_FRAMEWORK_VERSION")) {
diff --git a/Source/cmLocalVisualStudio7Generator.h b/Source/cmLocalVisualStudio7Generator.h
index 2bf38ea..89a3ee3 100644
--- a/Source/cmLocalVisualStudio7Generator.h
+++ b/Source/cmLocalVisualStudio7Generator.h
@@ -119,7 +119,8 @@ private:
bool WriteGroup(const cmSourceGroup* sg, cmGeneratorTarget* target,
std::ostream& fout, const std::string& libName,
- std::vector<std::string> const& configs);
+ std::vector<std::string> const& configs,
+ std::map<cmSourceFile const*, size_t> const& sourcesIndex);
friend class cmLocalVisualStudio7GeneratorFCInfo;
friend class cmLocalVisualStudio7GeneratorInternals;
diff --git a/Source/cmQtAutoGeneratorInitializer.cxx b/Source/cmQtAutoGeneratorInitializer.cxx
index e6d9a9f..239b18d 100644
--- a/Source/cmQtAutoGeneratorInitializer.cxx
+++ b/Source/cmQtAutoGeneratorInitializer.cxx
@@ -96,6 +96,41 @@ static std::string GetQtMajorVersion(cmGeneratorTarget const* target)
return qtMajorVersion;
}
+static std::string GetQtMinorVersion(cmGeneratorTarget const* target,
+ const std::string& qtMajorVersion)
+{
+ cmMakefile* makefile = target->Target->GetMakefile();
+ std::string qtMinorVersion;
+ if (qtMajorVersion == "5") {
+ qtMinorVersion = makefile->GetSafeDefinition("Qt5Core_VERSION_MINOR");
+ }
+ if (qtMinorVersion.empty()) {
+ qtMinorVersion = makefile->GetSafeDefinition("QT_VERSION_MINOR");
+ }
+
+ const char* targetQtVersion =
+ target->GetLinkInterfaceDependentStringProperty("QT_MINOR_VERSION", "");
+ if (targetQtVersion != CM_NULLPTR) {
+ qtMinorVersion = targetQtVersion;
+ }
+ return qtMinorVersion;
+}
+
+static bool QtVersionGreaterOrEqual(const std::string& major,
+ const std::string& minor,
+ unsigned long requestMajor,
+ unsigned long requestMinor)
+{
+ unsigned long majorUL(0);
+ unsigned long minorUL(0);
+ if (cmSystemTools::StringToULong(major.c_str(), &majorUL) &&
+ cmSystemTools::StringToULong(minor.c_str(), &minorUL)) {
+ return (majorUL > requestMajor) ||
+ (majorUL == requestMajor && minorUL >= requestMinor);
+ }
+ return false;
+}
+
static void GetCompileDefinitionsAndDirectories(
cmGeneratorTarget const* target, const std::string& config,
std::string& incs, std::string& defs)
@@ -258,6 +293,12 @@ static void MocSetupAutoTarget(
AddDefinitionEscaped(makefile, "_moc_depend_filters",
GetSafeProperty(target, "AUTOMOC_DEPEND_FILTERS"));
+ if (QtVersionGreaterOrEqual(
+ qtMajorVersion, GetQtMinorVersion(target, qtMajorVersion), 5, 8)) {
+ AddDefinitionEscaped(
+ makefile, "_moc_predefs_cmd",
+ makefile->GetSafeDefinition("CMAKE_CXX_COMPILER_PREDEFINES_COMMAND"));
+ }
// Moc includes and compile definitions
{
std::string _moc_incs;
@@ -681,11 +722,11 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget(
if (gg->GetName().find("Visual Studio") != std::string::npos) {
cmGlobalVisualStudioGenerator* vsgg =
static_cast<cmGlobalVisualStudioGenerator*>(gg);
- // Under VS >= 7 use a PRE_BUILD event instead of a separate target to
+ // Under VS use a PRE_BUILD event instead of a separate target to
// reduce the number of targets loaded into the IDE.
// This also works around a VS 11 bug that may skip updating the target:
// https://connect.microsoft.com/VisualStudio/feedback/details/769495
- usePRE_BUILD = vsgg->GetVersion() >= cmGlobalVisualStudioGenerator::VS7;
+ usePRE_BUILD = true;
}
#endif
diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx
index 88ec9e8..d142693 100644
--- a/Source/cmQtAutoGenerators.cxx
+++ b/Source/cmQtAutoGenerators.cxx
@@ -360,6 +360,8 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile(
InfoGet(makefile, "AM_QT_MOC_EXECUTABLE", this->MocExecutable);
InfoGet(makefile, "AM_QT_UIC_EXECUTABLE", this->UicExecutable);
InfoGet(makefile, "AM_QT_RCC_EXECUTABLE", this->RccExecutable);
+
+ InfoGet(makefile, "AM_MOC_PREDEFS_CMD", this->MocPredefsCmd);
// Check Qt version
if ((this->QtMajorVersion != "4") && (this->QtMajorVersion != "5")) {
this->LogError("AutoGen: Error: Unsupported Qt version: " +
@@ -579,6 +581,12 @@ void cmQtAutoGenerators::Init(cmMakefile* makefile)
this->MocCppFilenameAbs = this->CurrentBinaryDir + this->MocCppFilenameRel;
+ // Moc predefs file
+ if (!this->MocPredefsCmd.empty()) {
+ this->MocPredefsFileRel = this->AutogenBuildSubDir + "moc_predefs.h";
+ this->MocPredefsFileAbs = this->CurrentBinaryDir + this->MocPredefsFileRel;
+ }
+
// Init file path checksum generator
fpathCheckSum.setupParentDirs(this->CurrentSourceDir, this->CurrentBinaryDir,
this->ProjectSourceDir,
@@ -1142,6 +1150,50 @@ bool cmQtAutoGenerators::MocGenerateAll(
return true;
}
+ // Generate moc_predefs
+ if (!this->MocPredefsCmd.empty()) {
+ if (!this->MakeParentDirectory(this->MocPredefsFileAbs)) {
+ this->LogError("AutoMoc: Error creating directory for " +
+ this->MocPredefsFileRel);
+ return false;
+ }
+ this->LogBold("Generating MOC predefs " + this->MocPredefsFileRel);
+
+ std::vector<std::string> cmd = this->MocPredefsCmd;
+ cmd.insert(cmd.end(), this->MocIncludes.begin(), this->MocIncludes.end());
+ for (std::vector<std::string>::const_iterator it =
+ this->MocDefinitions.begin();
+ it != this->MocDefinitions.end(); ++it) {
+ cmd.push_back("-D" + (*it));
+ }
+ cmd.insert(cmd.end(), this->MocOptions.begin(), this->MocOptions.end());
+
+ std::string output;
+ bool moc_predefsGenerated = this->RunCommand(cmd, output, false);
+ if (!moc_predefsGenerated) {
+ return false;
+ }
+
+ // actually write the file
+ cmsys::ofstream outfile;
+ outfile.open(this->MocPredefsFileAbs.c_str(), std::ios::trunc);
+ if (!outfile) {
+ moc_predefsGenerated = false;
+ this->LogError("AutoMoc: Error opening " + this->MocPredefsFileRel);
+ } else {
+ outfile << output;
+ // Check for write errors
+ if (!outfile.good()) {
+ moc_predefsGenerated = false;
+ this->LogError("AutoMoc: Error writing " + this->MocPredefsFileRel);
+ }
+ }
+
+ if (!moc_predefsGenerated) {
+ return false;
+ }
+ }
+
bool mocCompFileGenerated = false;
bool mocCompChanged = false;
@@ -1305,6 +1357,10 @@ bool cmQtAutoGenerators::MocGenerateFile(
cmd.push_back("-D" + (*it));
}
cmd.insert(cmd.end(), this->MocOptions.begin(), this->MocOptions.end());
+ if (!this->MocPredefsFileAbs.empty()) {
+ cmd.push_back("--include");
+ cmd.push_back(this->MocPredefsFileAbs);
+ }
#ifdef _WIN32
cmd.push_back("-DWIN32");
#endif
@@ -1805,7 +1861,7 @@ bool cmQtAutoGenerators::MakeParentDirectory(const std::string& filename) const
* @return True on success
*/
bool cmQtAutoGenerators::RunCommand(const std::vector<std::string>& command,
- std::string& output) const
+ std::string& output, bool verbose) const
{
// Log command
if (this->Verbose) {
@@ -1813,8 +1869,9 @@ bool cmQtAutoGenerators::RunCommand(const std::vector<std::string>& command,
}
// Execute command
int retVal = 0;
- bool res =
- cmSystemTools::RunSingleCommand(command, &output, &output, &retVal);
+ bool res = cmSystemTools::RunSingleCommand(
+ command, &output, &output, &retVal, CM_NULLPTR,
+ verbose ? cmSystemTools::OUTPUT_MERGE : cmSystemTools::OUTPUT_NONE);
return (res && (retVal == 0));
}
diff --git a/Source/cmQtAutoGenerators.h b/Source/cmQtAutoGenerators.h
index d359059..24c0a33 100644
--- a/Source/cmQtAutoGenerators.h
+++ b/Source/cmQtAutoGenerators.h
@@ -143,8 +143,8 @@ private:
const char* basePrefix,
const char* baseSuffix) const;
bool MakeParentDirectory(const std::string& filename) const;
- bool RunCommand(const std::vector<std::string>& command,
- std::string& output) const;
+ bool RunCommand(const std::vector<std::string>& command, std::string& output,
+ bool verbose = true) const;
bool FindHeader(std::string& header, const std::string& testBasePath) const;
@@ -177,6 +177,8 @@ private:
// - Moc
std::string MocCppFilenameRel;
std::string MocCppFilenameAbs;
+ std::string MocPredefsFileRel;
+ std::string MocPredefsFileAbs;
std::vector<std::string> MocSkipList;
std::vector<std::string> MocIncludePaths;
std::vector<std::string> MocIncludes;
@@ -198,6 +200,8 @@ private:
MacroFilter MacroFilters[2];
cmsys::RegularExpression RegExpMocInclude;
cmsys::RegularExpression RegExpUicInclude;
+ // - moc_predefs
+ std::vector<std::string> MocPredefsCmd;
// - Flags
bool IncludeProjectDirsBefore;
bool Verbose;
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index f4de125..39625ae 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -657,8 +657,6 @@ bool cmSystemTools::RunSingleCommand(std::vector<std::string> const& command,
while ((pipe = cmsysProcess_WaitForData(cp, &data, &length, CM_NULLPTR)) >
0) {
// Translate NULL characters in the output into valid text.
- // Visual Studio 7 puts these characters in the output of its
- // build process.
for (int i = 0; i < length; ++i) {
if (data[i] == '\0') {
data[i] = ' ';
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index d29a8bd..0b1bb06 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -291,13 +291,10 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
if (this->GetType() != cmStateEnums::UTILITY) {
const char* configProps[] = {
/* clang-format needs this comment to break after the opening brace */
- "ARCHIVE_OUTPUT_DIRECTORY_",
- "LIBRARY_OUTPUT_DIRECTORY_",
- "RUNTIME_OUTPUT_DIRECTORY_",
- "PDB_OUTPUT_DIRECTORY_",
- "COMPILE_PDB_OUTPUT_DIRECTORY_",
- "MAP_IMPORTED_CONFIG_",
- CM_NULLPTR
+ "ARCHIVE_OUTPUT_DIRECTORY_", "LIBRARY_OUTPUT_DIRECTORY_",
+ "RUNTIME_OUTPUT_DIRECTORY_", "PDB_OUTPUT_DIRECTORY_",
+ "COMPILE_PDB_OUTPUT_DIRECTORY_", "MAP_IMPORTED_CONFIG_",
+ "INTERPROCEDURAL_OPTIMIZATION_", CM_NULLPTR
};
for (std::vector<std::string>::iterator ci = configNames.begin();
ci != configNames.end(); ++ci) {
@@ -1354,11 +1351,9 @@ std::string cmTarget::ImportedGetFullPath(const std::string& config,
// Lookup/compute/cache the import information for this
// configuration.
- std::string config_upper;
- if (!config.empty()) {
- config_upper = cmSystemTools::UpperCase(config);
- } else {
- config_upper = "NOCONFIG";
+ std::string desired_config = config;
+ if (config.empty()) {
+ desired_config = "NOCONFIG";
}
std::string result;
@@ -1368,7 +1363,7 @@ std::string cmTarget::ImportedGetFullPath(const std::string& config,
std::string suffix;
if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
- this->GetMappedConfig(config_upper, &loc, &imp, suffix)) {
+ this->GetMappedConfig(desired_config, &loc, &imp, suffix)) {
if (!pimplib) {
if (loc) {
result = loc;
@@ -1451,18 +1446,28 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config,
const char** loc, const char** imp,
std::string& suffix) const
{
- std::string const locPropBase =
- this->GetType() == cmStateEnums::INTERFACE_LIBRARY ? "IMPORTED_LIBNAME"
- : "IMPORTED_LOCATION";
+ std::string config_upper;
+ if (!desired_config.empty()) {
+ config_upper = cmSystemTools::UpperCase(desired_config);
+ }
+
+ std::string locPropBase;
+ if (this->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+ locPropBase = "IMPORTED_LIBNAME";
+ } else if (this->GetType() == cmStateEnums::OBJECT_LIBRARY) {
+ locPropBase = "IMPORTED_OBJECTS";
+ } else {
+ locPropBase = "IMPORTED_LOCATION";
+ }
// Track the configuration-specific property suffix.
suffix = "_";
- suffix += desired_config;
+ suffix += config_upper;
std::vector<std::string> mappedConfigs;
{
std::string mapProp = "MAP_IMPORTED_CONFIG_";
- mapProp += desired_config;
+ mapProp += config_upper;
if (const char* mapValue = this->GetProperty(mapProp)) {
cmSystemTools::ExpandListArgument(mapValue, mappedConfigs, true);
}
diff --git a/Source/cmTargetExport.h b/Source/cmTargetExport.h
index 7b5339f..9304eab 100644
--- a/Source/cmTargetExport.h
+++ b/Source/cmTargetExport.h
@@ -26,6 +26,7 @@ public:
cmInstallTargetGenerator* ArchiveGenerator;
cmInstallTargetGenerator* RuntimeGenerator;
cmInstallTargetGenerator* LibraryGenerator;
+ cmInstallTargetGenerator* ObjectsGenerator;
cmInstallTargetGenerator* FrameworkGenerator;
cmInstallTargetGenerator* BundleGenerator;
cmInstallFilesGenerator* HeaderGenerator;
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 8e6014a..f0f04a8 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -1241,16 +1241,15 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
// collect up group information
std::vector<cmSourceGroup> sourceGroups = this->Makefile->GetSourceGroups();
- std::vector<cmSourceFile*> classes;
- if (!this->GeneratorTarget->GetConfigCommonSourceFiles(classes)) {
- return;
- }
+
+ std::vector<cmGeneratorTarget::AllConfigSource> const& sources =
+ this->GeneratorTarget->GetAllConfigSources();
std::set<cmSourceGroup*> groupsUsed;
- for (std::vector<cmSourceFile*>::const_iterator s = classes.begin();
- s != classes.end(); s++) {
- cmSourceFile* sf = *s;
- std::string const& source = sf->GetFullPath();
+ for (std::vector<cmGeneratorTarget::AllConfigSource>::const_iterator si =
+ sources.begin();
+ si != sources.end(); ++si) {
+ std::string const& source = si->Source->GetFullPath();
cmSourceGroup* sourceGroup =
this->Makefile->FindSourceGroup(source.c_str(), sourceGroups);
groupsUsed.insert(sourceGroup);
@@ -1734,12 +1733,17 @@ void cmVisualStudio10TargetGenerator::WriteAllSources()
}
this->WriteString("<ItemGroup>\n", 1);
- cmGeneratorTarget::KindedSources const& sources =
- this->GeneratorTarget->GetKindedSources("");
+ std::vector<size_t> all_configs;
+ for (size_t ci = 0; ci < this->Configurations.size(); ++ci) {
+ all_configs.push_back(ci);
+ }
+
+ std::vector<cmGeneratorTarget::AllConfigSource> const& sources =
+ this->GeneratorTarget->GetAllConfigSources();
- for (std::vector<cmGeneratorTarget::SourceAndKind>::const_iterator si =
- sources.Sources.begin();
- si != sources.Sources.end(); ++si) {
+ for (std::vector<cmGeneratorTarget::AllConfigSource>::const_iterator si =
+ sources.begin();
+ si != sources.end(); ++si) {
std::string tool;
switch (si->Kind) {
case cmGeneratorTarget::SourceKindAppManifest:
@@ -1810,14 +1814,35 @@ void cmVisualStudio10TargetGenerator::WriteAllSources()
}
if (!tool.empty()) {
+ // Compute set of configurations to exclude, if any.
+ std::vector<size_t> const& include_configs = si->Configs;
+ std::vector<size_t> exclude_configs;
+ std::set_difference(all_configs.begin(), all_configs.end(),
+ include_configs.begin(), include_configs.end(),
+ std::back_inserter(exclude_configs));
+
if (si->Kind == cmGeneratorTarget::SourceKindObjectSource) {
+ // FIXME: refactor generation to avoid tracking XML syntax state.
this->WriteSource(tool, si->Source, " ");
- if (this->OutputSourceSpecificFlags(si->Source)) {
+ bool have_nested = this->OutputSourceSpecificFlags(si->Source);
+ if (!exclude_configs.empty()) {
+ if (!have_nested) {
+ (*this->BuildFileStream) << ">\n";
+ }
+ this->WriteExcludeFromBuild(exclude_configs);
+ have_nested = true;
+ }
+ if (have_nested) {
this->WriteString("</", 2);
(*this->BuildFileStream) << tool << ">\n";
} else {
(*this->BuildFileStream) << " />\n";
}
+ } else if (!exclude_configs.empty()) {
+ this->WriteSource(tool, si->Source, ">\n");
+ this->WriteExcludeFromBuild(exclude_configs);
+ this->WriteString("</", 2);
+ (*this->BuildFileStream) << tool << ">\n";
} else {
this->WriteSource(tool, si->Source);
}
@@ -1856,7 +1881,8 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
std::string lang =
this->GlobalGenerator->GetLanguageFromExtension(sf.GetExtension().c_str());
std::string sourceLang = this->LocalGenerator->GetSourceFileLanguage(sf);
- const std::string& linkLanguage = this->GeneratorTarget->GetLinkerLanguage();
+ const std::string& linkLanguage =
+ this->GeneratorTarget->GetLinkerLanguage("");
bool needForceLang = false;
// source file does not match its extension language
if (lang != sourceLang) {
@@ -2001,6 +2027,19 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
return hasFlags;
}
+void cmVisualStudio10TargetGenerator::WriteExcludeFromBuild(
+ std::vector<size_t> const& exclude_configs)
+{
+ for (std::vector<size_t>::const_iterator ci = exclude_configs.begin();
+ ci != exclude_configs.end(); ++ci) {
+ this->WriteString("", 3);
+ (*this->BuildFileStream)
+ << "<ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='"
+ << cmVS10EscapeXML(this->Configurations[*ci]) << "|"
+ << cmVS10EscapeXML(this->Platform) << "'\">true</ExcludedFromBuild>\n";
+ }
+}
+
void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions()
{
cmStateEnums::TargetType ttype = this->GeneratorTarget->GetType();
diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h
index 7432244..bd270bf 100644
--- a/Source/cmVisualStudio10TargetGenerator.h
+++ b/Source/cmVisualStudio10TargetGenerator.h
@@ -62,6 +62,7 @@ private:
void WriteNsightTegraConfigurationValues(std::string const& config);
void WriteSource(std::string const& tool, cmSourceFile const* sf,
const char* end = 0);
+ void WriteExcludeFromBuild(std::vector<size_t> const& exclude_configs);
void WriteAllSources();
void WriteDotNetReferences();
void WriteDotNetReference(std::string const& ref, std::string const& hint);
diff --git a/Source/cmVisualStudioGeneratorOptions.cxx b/Source/cmVisualStudioGeneratorOptions.cxx
index abc4924..1f808c8 100644
--- a/Source/cmVisualStudioGeneratorOptions.cxx
+++ b/Source/cmVisualStudioGeneratorOptions.cxx
@@ -101,10 +101,6 @@ void cmVisualStudioGeneratorOptions::FixExceptionHandlingDefault()
// the flag to disable exception handling. When the user does
// remove the flag we need to override the IDE default of on.
switch (this->Version) {
- case cmGlobalVisualStudioGenerator::VS7:
- case cmGlobalVisualStudioGenerator::VS71:
- this->FlagMap["ExceptionHandling"] = "FALSE";
- break;
case cmGlobalVisualStudioGenerator::VS10:
case cmGlobalVisualStudioGenerator::VS11:
case cmGlobalVisualStudioGenerator::VS12:
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index f0ae316..737587d 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -63,7 +63,6 @@
#include "cmGlobalVisualStudio12Generator.h"
#include "cmGlobalVisualStudio14Generator.h"
#include "cmGlobalVisualStudio15Generator.h"
-#include "cmGlobalVisualStudio71Generator.h"
#include "cmGlobalVisualStudio8Generator.h"
#include "cmGlobalVisualStudio9Generator.h"
#include "cmVSSetupHelper.h"
@@ -1461,8 +1460,7 @@ void cmake::CreateDefaultGlobalGenerator()
{ "11.0", "Visual Studio 11 2012" }, //
{ "10.0", "Visual Studio 10 2010" }, //
{ "9.0", "Visual Studio 9 2008" }, //
- { "8.0", "Visual Studio 8 2005" }, //
- { "7.1", "Visual Studio 7 .NET 2003" }
+ { "8.0", "Visual Studio 8 2005" }
};
static const char* const vsEntries[] = {
"\\Setup\\VC;ProductDir", //
@@ -1672,7 +1670,6 @@ void cmake::AddDefaultGenerators()
this->Generators.push_back(cmGlobalVisualStudio10Generator::NewFactory());
this->Generators.push_back(cmGlobalVisualStudio9Generator::NewFactory());
this->Generators.push_back(cmGlobalVisualStudio8Generator::NewFactory());
- this->Generators.push_back(cmGlobalVisualStudio71Generator::NewFactory());
this->Generators.push_back(cmGlobalBorlandMakefileGenerator::NewFactory());
this->Generators.push_back(cmGlobalNMakeMakefileGenerator::NewFactory());
this->Generators.push_back(cmGlobalJOMMakefileGenerator::NewFactory());
diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt
index 28fe9e7..e15b49e 100644
--- a/Source/kwsys/CMakeLists.txt
+++ b/Source/kwsys/CMakeLists.txt
@@ -69,6 +69,7 @@
CMAKE_MINIMUM_REQUIRED(VERSION 2.6.3 FATAL_ERROR)
FOREACH(p
CMP0025 # CMake 3.0, Compiler id for Apple Clang is now AppleClang.
+ CMP0048 # CMake 3.0, Let the project command manage version variables.
CMP0056 # CMake 3.2, Honor link flags in try_compile() source-file signature.
CMP0063 # CMake 3.3, Honor visibility properties for all target types.
)
diff --git a/Source/kwsys/Encoding.hxx.in b/Source/kwsys/Encoding.hxx.in
index bf93f50..09691fd 100644
--- a/Source/kwsys/Encoding.hxx.in
+++ b/Source/kwsys/Encoding.hxx.in
@@ -59,6 +59,17 @@ public:
static std::string ToNarrow(const std::wstring& str);
static std::string ToNarrow(const wchar_t* str);
+#if defined(_WIN32)
+ /**
+ * Convert the path to an extended length path to avoid MAX_PATH length
+ * limitations on Windows. If the input is a local path the result will be
+ * prefixed with \\?\; if the input is instead a network path, the result
+ * will be prefixed with \\?\UNC\. All output will also be converted to
+ * absolute paths with Windows-style backslashes.
+ **/
+ static std::wstring ToWindowsExtendedPath(std::string const&);
+#endif
+
#endif // @KWSYS_NAMESPACE@_STL_HAS_WSTRING
}; // class Encoding
diff --git a/Source/kwsys/EncodingCXX.cxx b/Source/kwsys/EncodingCXX.cxx
index e904c1a..641c0e6 100644
--- a/Source/kwsys/EncodingCXX.cxx
+++ b/Source/kwsys/EncodingCXX.cxx
@@ -29,6 +29,7 @@
#if defined(_WIN32)
#include <windows.h>
+#include <ctype.h>
#include <shellapi.h>
#endif
@@ -214,6 +215,63 @@ std::string Encoding::ToNarrow(const wchar_t* wcstr)
}
return str;
}
+
+#if defined(_WIN32)
+// Convert local paths to UNC style paths
+std::wstring Encoding::ToWindowsExtendedPath(std::string const& source)
+{
+ std::wstring wsource = Encoding::ToWide(source);
+
+ // Resolve any relative paths
+ DWORD wfull_len;
+
+ /* The +3 is a workaround for a bug in some versions of GetFullPathNameW that
+ * won't return a large enough buffer size if the input is too small */
+ wfull_len = GetFullPathNameW(wsource.c_str(), 0, NULL, NULL) + 3;
+ std::vector<wchar_t> wfull(wfull_len);
+ GetFullPathNameW(wsource.c_str(), wfull_len, &wfull[0], NULL);
+
+ /* This should get the correct size without any extra padding from the
+ * previous size workaround. */
+ wfull_len = static_cast<DWORD>(wcslen(&wfull[0]));
+
+ if (wfull_len >= 2 && isalpha(wfull[0]) &&
+ wfull[1] == L':') { /* C:\Foo\bar\FooBar.txt */
+ return L"\\\\?\\" + std::wstring(&wfull[0]);
+ } else if (wfull_len >= 2 && wfull[0] == L'\\' &&
+ wfull[1] == L'\\') { /* Starts with \\ */
+ if (wfull_len >= 4 && wfull[2] == L'?' &&
+ wfull[3] == L'\\') { /* Starts with \\?\ */
+ if (wfull_len >= 8 && wfull[4] == L'U' && wfull[5] == L'N' &&
+ wfull[6] == L'C' &&
+ wfull[7] == L'\\') { /* \\?\UNC\Foo\bar\FooBar.txt */
+ return std::wstring(&wfull[0]);
+ } else if (wfull_len >= 6 && isalpha(wfull[4]) &&
+ wfull[5] == L':') { /* \\?\C:\Foo\bar\FooBar.txt */
+ return std::wstring(&wfull[0]);
+ } else if (wfull_len >= 5) { /* \\?\Foo\bar\FooBar.txt */
+ return L"\\\\?\\UNC\\" + std::wstring(&wfull[4]);
+ }
+ } else if (wfull_len >= 4 && wfull[2] == L'.' &&
+ wfull[3] == L'\\') { /* Starts with \\.\ a device name */
+ if (wfull_len >= 6 && isalpha(wfull[4]) &&
+ wfull[5] == L':') { /* \\.\C:\Foo\bar\FooBar.txt */
+ return L"\\\\?\\" + std::wstring(&wfull[4]);
+ } else if (wfull_len >=
+ 5) { /* \\.\Foo\bar\ Device name is left unchanged */
+ return std::wstring(&wfull[0]);
+ }
+ } else if (wfull_len >= 3) { /* \\Foo\bar\FooBar.txt */
+ return L"\\\\?\\UNC\\" + std::wstring(&wfull[2]);
+ }
+ }
+
+ // If this case has been reached, then the path is invalid. Leave it
+ // unchanged
+ return Encoding::ToWide(source);
+}
+#endif
+
#endif // KWSYS_STL_HAS_WSTRING
} // namespace KWSYS_NAMESPACE
diff --git a/Source/kwsys/FStream.hxx.in b/Source/kwsys/FStream.hxx.in
index d4bc6c9..a4c65fe 100644
--- a/Source/kwsys/FStream.hxx.in
+++ b/Source/kwsys/FStream.hxx.in
@@ -33,7 +33,7 @@ public:
typedef std::basic_filebuf<CharType, Traits> my_base_type;
basic_filebuf* open(char const* s, std::ios_base::openmode mode)
{
- const std::wstring wstr = Encoding::ToWide(s);
+ const std::wstring wstr = Encoding::ToWindowsExtendedPath(s);
return static_cast<basic_filebuf*>(my_base_type::open(wstr.c_str(), mode));
}
#endif
@@ -93,7 +93,7 @@ public:
#if defined(_MSC_VER)
const bool success = buf_->open(file_name, mode) != 0;
#else
- const std::wstring wstr = Encoding::ToWide(file_name);
+ const std::wstring wstr = Encoding::ToWindowsExtendedPath(file_name);
bool success = false;
std::wstring cmode = getcmode(mode);
file_ = _wfopen(wstr.c_str(), cmode.c_str());
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx
index 100a49c..b6da368 100644
--- a/Source/kwsys/SystemTools.cxx
+++ b/Source/kwsys/SystemTools.cxx
@@ -216,12 +216,12 @@ static time_t windows_filetime_to_posix_time(const FILETIME& ft)
inline int Mkdir(const std::string& dir)
{
return _wmkdir(
- KWSYS_NAMESPACE::SystemTools::ConvertToWindowsExtendedPath(dir).c_str());
+ KWSYS_NAMESPACE::Encoding::ToWindowsExtendedPath(dir).c_str());
}
inline int Rmdir(const std::string& dir)
{
return _wrmdir(
- KWSYS_NAMESPACE::SystemTools::ConvertToWindowsExtendedPath(dir).c_str());
+ KWSYS_NAMESPACE::Encoding::ToWindowsExtendedPath(dir).c_str());
}
inline const char* Getcwd(char* buf, unsigned int len)
{
@@ -745,7 +745,7 @@ const char* SystemTools::GetExecutableExtension()
FILE* SystemTools::Fopen(const std::string& file, const char* mode)
{
#ifdef _WIN32
- return _wfopen(SystemTools::ConvertToWindowsExtendedPath(file).c_str(),
+ return _wfopen(Encoding::ToWindowsExtendedPath(file).c_str(),
Encoding::ToWide(mode).c_str());
#else
return fopen(file.c_str(), mode);
@@ -1159,8 +1159,7 @@ bool SystemTools::PathExists(const std::string& path)
struct stat st;
return lstat(path.c_str(), &st) == 0;
#elif defined(_WIN32)
- return (GetFileAttributesW(
- SystemTools::ConvertToWindowsExtendedPath(path).c_str()) !=
+ return (GetFileAttributesW(Encoding::ToWindowsExtendedPath(path).c_str()) !=
INVALID_FILE_ATTRIBUTES);
#else
struct stat st;
@@ -1191,9 +1190,9 @@ bool SystemTools::FileExists(const std::string& filename)
}
return access(filename.c_str(), R_OK) == 0;
#elif defined(_WIN32)
- return (GetFileAttributesW(
- SystemTools::ConvertToWindowsExtendedPath(filename).c_str()) !=
- INVALID_FILE_ATTRIBUTES);
+ return (
+ GetFileAttributesW(Encoding::ToWindowsExtendedPath(filename).c_str()) !=
+ INVALID_FILE_ATTRIBUTES);
#else
// SCO OpenServer 5.0.7/3.2's command has 711 permission.
#if defined(_SCO_DS)
@@ -1249,7 +1248,7 @@ bool SystemTools::TestFileAccess(const std::string& filename,
permissions &= ~TEST_FILE_EXECUTE;
permissions |= TEST_FILE_READ;
}
- return _waccess(SystemTools::ConvertToWindowsExtendedPath(filename).c_str(),
+ return _waccess(Encoding::ToWindowsExtendedPath(filename).c_str(),
permissions) == 0;
#else
return access(filename.c_str(), permissions) == 0;
@@ -1274,7 +1273,7 @@ int SystemTools::Stat(const std::string& path, SystemTools::Stat_t* buf)
return -1;
}
#if defined(_WIN32) && !defined(__CYGWIN__)
- // Ideally we should use ConvertToWindowsExtendedPath to support
+ // Ideally we should use Encoding::ToWindowsExtendedPath to support
// long paths, but _wstat64 rejects paths with '?' in them, thinking
// they are wildcards.
std::wstring const& wpath = Encoding::ToWide(path);
@@ -1324,10 +1323,9 @@ bool SystemTools::Touch(const std::string& filename, bool create)
}
}
#if defined(_WIN32) && !defined(__CYGWIN__)
- HANDLE h =
- CreateFileW(SystemTools::ConvertToWindowsExtendedPath(filename).c_str(),
- FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE, 0, OPEN_EXISTING,
- FILE_FLAG_BACKUP_SEMANTICS, 0);
+ HANDLE h = CreateFileW(Encoding::ToWindowsExtendedPath(filename).c_str(),
+ FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE, 0,
+ OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
if (!h) {
return false;
}
@@ -1425,14 +1423,12 @@ bool SystemTools::FileTimeCompare(const std::string& f1, const std::string& f2,
// Windows version. Get the modification time from extended file attributes.
WIN32_FILE_ATTRIBUTE_DATA f1d;
WIN32_FILE_ATTRIBUTE_DATA f2d;
- if (!GetFileAttributesExW(
- SystemTools::ConvertToWindowsExtendedPath(f1).c_str(),
- GetFileExInfoStandard, &f1d)) {
+ if (!GetFileAttributesExW(Encoding::ToWindowsExtendedPath(f1).c_str(),
+ GetFileExInfoStandard, &f1d)) {
return false;
}
- if (!GetFileAttributesExW(
- SystemTools::ConvertToWindowsExtendedPath(f2).c_str(),
- GetFileExInfoStandard, &f2d)) {
+ if (!GetFileAttributesExW(Encoding::ToWindowsExtendedPath(f2).c_str(),
+ GetFileExInfoStandard, &f2d)) {
return false;
}
@@ -1960,59 +1956,10 @@ void SystemTools::ConvertToUnixSlashes(std::string& path)
}
#ifdef _WIN32
-// Convert local paths to UNC style paths
std::wstring SystemTools::ConvertToWindowsExtendedPath(
const std::string& source)
{
- std::wstring wsource = Encoding::ToWide(source);
-
- // Resolve any relative paths
- DWORD wfull_len;
-
- /* The +3 is a workaround for a bug in some versions of GetFullPathNameW that
- * won't return a large enough buffer size if the input is too small */
- wfull_len = GetFullPathNameW(wsource.c_str(), 0, NULL, NULL) + 3;
- std::vector<wchar_t> wfull(wfull_len);
- GetFullPathNameW(wsource.c_str(), wfull_len, &wfull[0], NULL);
-
- /* This should get the correct size without any extra padding from the
- * previous size workaround. */
- wfull_len = static_cast<DWORD>(wcslen(&wfull[0]));
-
- if (wfull_len >= 2 && isalpha(wfull[0]) &&
- wfull[1] == L':') { /* C:\Foo\bar\FooBar.txt */
- return L"\\\\?\\" + std::wstring(&wfull[0]);
- } else if (wfull_len >= 2 && wfull[0] == L'\\' &&
- wfull[1] == L'\\') { /* Starts with \\ */
- if (wfull_len >= 4 && wfull[2] == L'?' &&
- wfull[3] == L'\\') { /* Starts with \\?\ */
- if (wfull_len >= 8 && wfull[4] == L'U' && wfull[5] == L'N' &&
- wfull[6] == L'C' &&
- wfull[7] == L'\\') { /* \\?\UNC\Foo\bar\FooBar.txt */
- return std::wstring(&wfull[0]);
- } else if (wfull_len >= 6 && isalpha(wfull[4]) &&
- wfull[5] == L':') { /* \\?\C:\Foo\bar\FooBar.txt */
- return std::wstring(&wfull[0]);
- } else if (wfull_len >= 5) { /* \\?\Foo\bar\FooBar.txt */
- return L"\\\\?\\UNC\\" + std::wstring(&wfull[4]);
- }
- } else if (wfull_len >= 4 && wfull[2] == L'.' &&
- wfull[3] == L'\\') { /* Starts with \\.\ a device name */
- if (wfull_len >= 6 && isalpha(wfull[4]) &&
- wfull[5] == L':') { /* \\.\C:\Foo\bar\FooBar.txt */
- return L"\\\\?\\" + std::wstring(&wfull[4]);
- } else if (wfull_len >=
- 5) { /* \\.\Foo\bar\ Device name is left unchanged */
- return std::wstring(&wfull[0]);
- }
- } else if (wfull_len >= 3) { /* \\Foo\bar\FooBar.txt */
- return L"\\\\?\\UNC\\" + std::wstring(&wfull[2]);
- }
- }
-
- // If this case has been reached, then the path is invalid. Leave it
- // unchanged
- return Encoding::ToWide(source);
+ return Encoding::ToWindowsExtendedPath(source);
}
#endif
@@ -2129,15 +2076,14 @@ bool SystemTools::FilesDiffer(const std::string& source,
#if defined(_WIN32)
WIN32_FILE_ATTRIBUTE_DATA statSource;
- if (GetFileAttributesExW(
- SystemTools::ConvertToWindowsExtendedPath(source).c_str(),
- GetFileExInfoStandard, &statSource) == 0) {
+ if (GetFileAttributesExW(Encoding::ToWindowsExtendedPath(source).c_str(),
+ GetFileExInfoStandard, &statSource) == 0) {
return true;
}
WIN32_FILE_ATTRIBUTE_DATA statDestination;
if (GetFileAttributesExW(
- SystemTools::ConvertToWindowsExtendedPath(destination).c_str(),
+ Encoding::ToWindowsExtendedPath(destination).c_str(),
GetFileExInfoStandard, &statDestination) == 0) {
return true;
}
@@ -2261,8 +2207,7 @@ bool SystemTools::CopyFileAlways(const std::string& source,
// Open files
#if defined(_WIN32)
kwsys::ifstream fin(
- Encoding::ToNarrow(SystemTools::ConvertToWindowsExtendedPath(source))
- .c_str(),
+ Encoding::ToNarrow(Encoding::ToWindowsExtendedPath(source)).c_str(),
std::ios::in | std::ios::binary);
#else
kwsys::ifstream fin(source.c_str(), std::ios::in | std::ios::binary);
@@ -2279,8 +2224,7 @@ bool SystemTools::CopyFileAlways(const std::string& source,
#if defined(_WIN32)
kwsys::ofstream fout(
- Encoding::ToNarrow(
- SystemTools::ConvertToWindowsExtendedPath(real_destination))
+ Encoding::ToNarrow(Encoding::ToWindowsExtendedPath(real_destination))
.c_str(),
std::ios::out | std::ios::trunc | std::ios::binary);
#else
@@ -2345,8 +2289,7 @@ bool SystemTools::CopyADirectory(const std::string& source,
{
Directory dir;
#ifdef _WIN32
- dir.Load(
- Encoding::ToNarrow(SystemTools::ConvertToWindowsExtendedPath(source)));
+ dir.Load(Encoding::ToNarrow(Encoding::ToWindowsExtendedPath(source)));
#else
dir.Load(source);
#endif
@@ -2384,9 +2327,8 @@ unsigned long SystemTools::FileLength(const std::string& filename)
unsigned long length = 0;
#ifdef _WIN32
WIN32_FILE_ATTRIBUTE_DATA fs;
- if (GetFileAttributesExW(
- SystemTools::ConvertToWindowsExtendedPath(filename).c_str(),
- GetFileExInfoStandard, &fs) != 0) {
+ if (GetFileAttributesExW(Encoding::ToWindowsExtendedPath(filename).c_str(),
+ GetFileExInfoStandard, &fs) != 0) {
/* To support the full 64-bit file size, use fs.nFileSizeHigh
* and fs.nFileSizeLow to construct the 64 bit size
@@ -2420,9 +2362,8 @@ long int SystemTools::ModifiedTime(const std::string& filename)
long int mt = 0;
#ifdef _WIN32
WIN32_FILE_ATTRIBUTE_DATA fs;
- if (GetFileAttributesExW(
- SystemTools::ConvertToWindowsExtendedPath(filename).c_str(),
- GetFileExInfoStandard, &fs) != 0) {
+ if (GetFileAttributesExW(Encoding::ToWindowsExtendedPath(filename).c_str(),
+ GetFileExInfoStandard, &fs) != 0) {
mt = windows_filetime_to_posix_time(fs.ftLastWriteTime);
}
#else
@@ -2440,9 +2381,8 @@ long int SystemTools::CreationTime(const std::string& filename)
long int ct = 0;
#ifdef _WIN32
WIN32_FILE_ATTRIBUTE_DATA fs;
- if (GetFileAttributesExW(
- SystemTools::ConvertToWindowsExtendedPath(filename).c_str(),
- GetFileExInfoStandard, &fs) != 0) {
+ if (GetFileAttributesExW(Encoding::ToWindowsExtendedPath(filename).c_str(),
+ GetFileExInfoStandard, &fs) != 0) {
ct = windows_filetime_to_posix_time(fs.ftCreationTime);
}
#else
@@ -2656,7 +2596,7 @@ static bool DeleteJunction(const std::wstring& source)
bool SystemTools::RemoveFile(const std::string& source)
{
#ifdef _WIN32
- std::wstring const& ws = SystemTools::ConvertToWindowsExtendedPath(source);
+ std::wstring const& ws = Encoding::ToWindowsExtendedPath(source);
if (DeleteFileW(ws.c_str())) {
return true;
}
@@ -2706,8 +2646,7 @@ bool SystemTools::RemoveADirectory(const std::string& source)
Directory dir;
#ifdef _WIN32
- dir.Load(
- Encoding::ToNarrow(SystemTools::ConvertToWindowsExtendedPath(source)));
+ dir.Load(Encoding::ToNarrow(Encoding::ToWindowsExtendedPath(source)));
#else
dir.Load(source);
#endif
@@ -3064,8 +3003,8 @@ bool SystemTools::FileIsDirectory(const std::string& inName)
// Now check the file node type.
#if defined(_WIN32)
- DWORD attr = GetFileAttributesW(
- SystemTools::ConvertToWindowsExtendedPath(name).c_str());
+ DWORD attr =
+ GetFileAttributesW(Encoding::ToWindowsExtendedPath(name).c_str());
if (attr != INVALID_FILE_ATTRIBUTES) {
return (attr & FILE_ATTRIBUTE_DIRECTORY) != 0;
#else
@@ -3081,8 +3020,8 @@ bool SystemTools::FileIsDirectory(const std::string& inName)
bool SystemTools::FileIsSymlink(const std::string& name)
{
#if defined(_WIN32)
- DWORD attr = GetFileAttributesW(
- SystemTools::ConvertToWindowsExtendedPath(name).c_str());
+ DWORD attr =
+ GetFileAttributesW(Encoding::ToWindowsExtendedPath(name).c_str());
if (attr != INVALID_FILE_ATTRIBUTES) {
return (attr & FILE_ATTRIBUTE_REPARSE_POINT) != 0;
} else {
@@ -4398,8 +4337,8 @@ bool SystemTools::GetPermissions(const char* file, mode_t& mode)
bool SystemTools::GetPermissions(const std::string& file, mode_t& mode)
{
#if defined(_WIN32)
- DWORD attr = GetFileAttributesW(
- SystemTools::ConvertToWindowsExtendedPath(file).c_str());
+ DWORD attr =
+ GetFileAttributesW(Encoding::ToWindowsExtendedPath(file).c_str());
if (attr == INVALID_FILE_ATTRIBUTES) {
return false;
}
@@ -4451,8 +4390,7 @@ bool SystemTools::SetPermissions(const std::string& file, mode_t mode,
mode &= ~currentMask;
}
#ifdef _WIN32
- if (_wchmod(SystemTools::ConvertToWindowsExtendedPath(file).c_str(), mode) <
- 0)
+ if (_wchmod(Encoding::ToWindowsExtendedPath(file).c_str(), mode) < 0)
#else
if (chmod(file.c_str(), mode) < 0)
#endif
diff --git a/Source/kwsys/SystemTools.hxx.in b/Source/kwsys/SystemTools.hxx.in
index 53abce7..0849e1d 100644
--- a/Source/kwsys/SystemTools.hxx.in
+++ b/Source/kwsys/SystemTools.hxx.in
@@ -265,13 +265,7 @@ public:
static void ConvertToUnixSlashes(std::string& path);
#ifdef _WIN32
- /**
- * Convert the path to an extended length path to avoid MAX_PATH length
- * limitations on Windows. If the input is a local path the result will be
- * prefixed with \\?\; if the input is instead a network path, the result
- * will be prefixed with \\?\UNC\. All output will also be converted to
- * absolute paths with Windows-style backslashes.
- **/
+ /** Calls Encoding::ToWindowsExtendedPath. */
static std::wstring ConvertToWindowsExtendedPath(const std::string&);
#endif
diff --git a/Source/kwsys/testEncoding.cxx b/Source/kwsys/testEncoding.cxx
index 03f2ec9..457e8a8 100644
--- a/Source/kwsys/testEncoding.cxx
+++ b/Source/kwsys/testEncoding.cxx
@@ -180,6 +180,88 @@ static int testCommandLineArguments()
return status;
}
+static int testToWindowsExtendedPath()
+{
+#ifdef _WIN32
+ int ret = 0;
+ if (kwsys::Encoding::ToWindowsExtendedPath(
+ "L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo") !=
+ L"\\\\?\\L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo") {
+ std::cout << "Problem with ToWindowsExtendedPath "
+ << "\"L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo\""
+ << std::endl;
+ ++ret;
+ }
+
+ if (kwsys::Encoding::ToWindowsExtendedPath(
+ "L:/Local Mojo/Hex Power Pack/Iffy Voodoo") !=
+ L"\\\\?\\L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo") {
+ std::cout << "Problem with ToWindowsExtendedPath "
+ << "\"L:/Local Mojo/Hex Power Pack/Iffy Voodoo\"" << std::endl;
+ ++ret;
+ }
+
+ if (kwsys::Encoding::ToWindowsExtendedPath(
+ "\\\\Foo\\Local Mojo\\Hex Power Pack\\Iffy Voodoo") !=
+ L"\\\\?\\UNC\\Foo\\Local Mojo\\Hex Power Pack\\Iffy Voodoo") {
+ std::cout << "Problem with ToWindowsExtendedPath "
+ << "\"\\\\Foo\\Local Mojo\\Hex Power Pack\\Iffy Voodoo\""
+ << std::endl;
+ ++ret;
+ }
+
+ if (kwsys::Encoding::ToWindowsExtendedPath(
+ "//Foo/Local Mojo/Hex Power Pack/Iffy Voodoo") !=
+ L"\\\\?\\UNC\\Foo\\Local Mojo\\Hex Power Pack\\Iffy Voodoo") {
+ std::cout << "Problem with ToWindowsExtendedPath "
+ << "\"//Foo/Local Mojo/Hex Power Pack/Iffy Voodoo\""
+ << std::endl;
+ ++ret;
+ }
+
+ if (kwsys::Encoding::ToWindowsExtendedPath("//") != L"//") {
+ std::cout << "Problem with ToWindowsExtendedPath "
+ << "\"//\"" << std::endl;
+ ++ret;
+ }
+
+ if (kwsys::Encoding::ToWindowsExtendedPath("\\\\.\\") != L"\\\\.\\") {
+ std::cout << "Problem with ToWindowsExtendedPath "
+ << "\"\\\\.\\\"" << std::endl;
+ ++ret;
+ }
+
+ if (kwsys::Encoding::ToWindowsExtendedPath("\\\\.\\X") != L"\\\\.\\X") {
+ std::cout << "Problem with ToWindowsExtendedPath "
+ << "\"\\\\.\\X\"" << std::endl;
+ ++ret;
+ }
+
+ if (kwsys::Encoding::ToWindowsExtendedPath("\\\\.\\X:") != L"\\\\?\\X:") {
+ std::cout << "Problem with ToWindowsExtendedPath "
+ << "\"\\\\.\\X:\"" << std::endl;
+ ++ret;
+ }
+
+ if (kwsys::Encoding::ToWindowsExtendedPath("\\\\.\\X:\\") !=
+ L"\\\\?\\X:\\") {
+ std::cout << "Problem with ToWindowsExtendedPath "
+ << "\"\\\\.\\X:\\\"" << std::endl;
+ ++ret;
+ }
+
+ if (kwsys::Encoding::ToWindowsExtendedPath("NUL") != L"\\\\.\\NUL") {
+ std::cout << "Problem with ToWindowsExtendedPath "
+ << "\"NUL\"" << std::endl;
+ ++ret;
+ }
+
+ return ret;
+#else
+ return 0;
+#endif
+}
+
//----------------------------------------------------------------------------
int testEncoding(int, char* [])
{
@@ -196,6 +278,7 @@ int testEncoding(int, char* [])
ret |= testRobustEncoding();
ret |= testCommandLineArguments();
ret |= testWithNulls();
+ ret |= testToWindowsExtendedPath();
return ret;
}
diff --git a/Source/kwsys/testSystemTools.cxx b/Source/kwsys/testSystemTools.cxx
index 9b08a04..d11bcae 100644
--- a/Source/kwsys/testSystemTools.cxx
+++ b/Source/kwsys/testSystemTools.cxx
@@ -585,85 +585,6 @@ static bool CheckStringOperations()
res = false;
}
-#ifdef _WIN32
- if (kwsys::SystemTools::ConvertToWindowsExtendedPath(
- "L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo") !=
- L"\\\\?\\L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo") {
- std::cerr << "Problem with ConvertToWindowsExtendedPath "
- << "\"L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo\""
- << std::endl;
- res = false;
- }
-
- if (kwsys::SystemTools::ConvertToWindowsExtendedPath(
- "L:/Local Mojo/Hex Power Pack/Iffy Voodoo") !=
- L"\\\\?\\L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo") {
- std::cerr << "Problem with ConvertToWindowsExtendedPath "
- << "\"L:/Local Mojo/Hex Power Pack/Iffy Voodoo\"" << std::endl;
- res = false;
- }
-
- if (kwsys::SystemTools::ConvertToWindowsExtendedPath(
- "\\\\Foo\\Local Mojo\\Hex Power Pack\\Iffy Voodoo") !=
- L"\\\\?\\UNC\\Foo\\Local Mojo\\Hex Power Pack\\Iffy Voodoo") {
- std::cerr << "Problem with ConvertToWindowsExtendedPath "
- << "\"\\\\Foo\\Local Mojo\\Hex Power Pack\\Iffy Voodoo\""
- << std::endl;
- res = false;
- }
-
- if (kwsys::SystemTools::ConvertToWindowsExtendedPath(
- "//Foo/Local Mojo/Hex Power Pack/Iffy Voodoo") !=
- L"\\\\?\\UNC\\Foo\\Local Mojo\\Hex Power Pack\\Iffy Voodoo") {
- std::cerr << "Problem with ConvertToWindowsExtendedPath "
- << "\"//Foo/Local Mojo/Hex Power Pack/Iffy Voodoo\""
- << std::endl;
- res = false;
- }
-
- if (kwsys::SystemTools::ConvertToWindowsExtendedPath("//") != L"//") {
- std::cerr << "Problem with ConvertToWindowsExtendedPath "
- << "\"//\"" << std::endl;
- res = false;
- }
-
- if (kwsys::SystemTools::ConvertToWindowsExtendedPath("\\\\.\\") !=
- L"\\\\.\\") {
- std::cerr << "Problem with ConvertToWindowsExtendedPath "
- << "\"\\\\.\\\"" << std::endl;
- res = false;
- }
-
- if (kwsys::SystemTools::ConvertToWindowsExtendedPath("\\\\.\\X") !=
- L"\\\\.\\X") {
- std::cerr << "Problem with ConvertToWindowsExtendedPath "
- << "\"\\\\.\\X\"" << std::endl;
- res = false;
- }
-
- if (kwsys::SystemTools::ConvertToWindowsExtendedPath("\\\\.\\X:") !=
- L"\\\\?\\X:") {
- std::cerr << "Problem with ConvertToWindowsExtendedPath "
- << "\"\\\\.\\X:\"" << std::endl;
- res = false;
- }
-
- if (kwsys::SystemTools::ConvertToWindowsExtendedPath("\\\\.\\X:\\") !=
- L"\\\\?\\X:\\") {
- std::cerr << "Problem with ConvertToWindowsExtendedPath "
- << "\"\\\\.\\X:\\\"" << std::endl;
- res = false;
- }
-
- if (kwsys::SystemTools::ConvertToWindowsExtendedPath("NUL") !=
- L"\\\\.\\NUL") {
- std::cerr << "Problem with ConvertToWindowsExtendedPath "
- << "\"NUL\"" << std::endl;
- res = false;
- }
-
-#endif
-
if (kwsys::SystemTools::ConvertToWindowsOutputPath(
"L://Local Mojo/Hex Power Pack/Iffy Voodoo") !=
"\"L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo\"") {
diff --git a/Tests/BuildDepends/CMakeLists.txt b/Tests/BuildDepends/CMakeLists.txt
index 9b48b14..11978db 100644
--- a/Tests/BuildDepends/CMakeLists.txt
+++ b/Tests/BuildDepends/CMakeLists.txt
@@ -42,7 +42,7 @@ list(APPEND _cmake_options "-DTEST_LINK_DEPENDS=${TEST_LINK_DEPENDS}")
list(APPEND _cmake_options "-DCMAKE_FORCE_DEPFILES=1")
-if(NOT CMAKE_GENERATOR MATCHES "Visual Studio ([^789]|[789][0-9])")
+if(NOT CMAKE_GENERATOR MATCHES "Visual Studio ([^89]|[89][0-9])")
set(TEST_MULTI3 1)
list(APPEND _cmake_options "-DTEST_MULTI3=1")
endif()
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 910ff39..60a2cbb 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -46,7 +46,7 @@ if(BUILD_TESTING)
set(CMake_TEST_DEVENV "")
if(CMAKE_VS_DEVENV_COMMAND)
set(CMake_TEST_DEVENV "${CMAKE_VS_DEVENV_COMMAND}")
- elseif(CMAKE_GENERATOR MATCHES "Visual Studio [7-9] " AND
+ elseif(CMAKE_GENERATOR MATCHES "Visual Studio [89] " AND
NOT CMAKE_MAKE_PROGRAM MATCHES "[mM][sS][bB][uU][iI][lL][dD]\\.[eE][xX][eE]")
set(CMake_TEST_DEVENV "${CMAKE_MAKE_PROGRAM}")
endif()
@@ -325,7 +325,7 @@ if(BUILD_TESTING)
endif()
endif()
- if(${CMAKE_GENERATOR} MATCHES "Visual Studio ([^789]|[789][0-9])")
+ if(${CMAKE_GENERATOR} MATCHES "Visual Studio ([^89]|[89][0-9])")
ADD_TEST_MACRO(CSharpOnly CSharpOnly)
endif()
@@ -477,6 +477,17 @@ if(BUILD_TESTING)
ADD_TEST_MACRO(Module.CheckTypeSize CheckTypeSize)
+ set(Module.CheckIPOSupported-C_BUILD_OPTIONS -DCMake_TEST_IPO_WORKS_C=${CMake_TEST_IPO_WORKS_C})
+ ADD_TEST_MACRO(Module.CheckIPOSupported-C CheckIPOSupported-C)
+
+ set(Module.CheckIPOSupported-CXX_BUILD_OPTIONS -DCMake_TEST_IPO_WORKS_CXX=${CMake_TEST_IPO_WORKS_CXX})
+ ADD_TEST_MACRO(Module.CheckIPOSupported-CXX CheckIPOSupported-CXX)
+
+ if(CMAKE_Fortran_COMPILER)
+ set(Module.CheckIPOSupported-Fortran_BUILD_OPTIONS -DCMake_TEST_IPO_WORKS_Fortran=${CMake_TEST_IPO_WORKS_Fortran})
+ ADD_TEST_MACRO(Module.CheckIPOSupported-Fortran CheckIPOSupported-Fortran)
+ endif()
+
add_test(Module.ExternalData ${CMAKE_CTEST_COMMAND}
--build-and-test
"${CMake_SOURCE_DIR}/Tests/Module/ExternalData"
@@ -615,8 +626,8 @@ if(BUILD_TESTING)
endif()
# test for correct sub-project generation
- # not implemented in VS 7.0, Xcode, or Ninja
- if(NOT CMAKE_GENERATOR MATCHES "Visual Studio 7$|Xcode|Ninja")
+ # not implemented in Xcode or Ninja
+ if(NOT CMAKE_GENERATOR MATCHES "Xcode|Ninja")
# run cmake and configure all of SubProject
# but only build the independent executable car
add_test(SubProject ${CMAKE_CTEST_COMMAND}
@@ -1158,6 +1169,9 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
)
list(APPEND TEST_BUILD_DIRS
"${CMake_BINARY_DIR}/Tests/CMakeTestAllGenerators")
+ # This test runs a lot of processes. Do not make them compete
+ # for resources with other tests.
+ set_property(TEST CMakeTestAllGenerators PROPERTY RUN_SERIAL 1)
endif()
if(NOT DEFINED CTEST_RUN_CMakeTestMultipleConfigures)
@@ -1411,6 +1425,10 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
add_subdirectory(FindOpenSSL)
endif()
+ if(CMake_TEST_FindMPI)
+ add_subdirectory(FindMPI)
+ endif()
+
if(CMake_TEST_FindPNG)
add_subdirectory(FindPNG)
endif()
@@ -1924,7 +1942,6 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
endif()
if(MSVC AND NOT MSVC_VERSION LESS 1310
- AND NOT CMAKE_GENERATOR MATCHES "Visual Studio 7( |$)"
AND (NOT CMAKE_GENERATOR MATCHES "Visual Studio [89]( |$)"
OR CMAKE_SIZEOF_VOID_P EQUAL 4)
)
@@ -1936,7 +1953,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
ADD_TEST_MACRO(SBCS SBCS)
endif()
- if(NOT "${CMAKE_GENERATOR}" MATCHES "Visual Studio [789]( |$)"
+ if(NOT "${CMAKE_GENERATOR}" MATCHES "Visual Studio [89]( |$)"
AND NOT CMAKE_GENERATOR_TOOLSET)
ADD_TEST_MACRO(VSWindowsFormsResx VSWindowsFormsResx)
endif()
@@ -2135,7 +2152,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
endif()
endif()
- if(CMAKE_GENERATOR MATCHES "Visual Studio ([^789]|[789][0-9])" AND nasm)
+ if(CMAKE_GENERATOR MATCHES "Visual Studio ([^89]|[89][0-9])" AND nasm)
ADD_TEST_MACRO(VSNASM VSNASM)
endif()
diff --git a/Tests/CMakeOnly/CMakeLists.txt b/Tests/CMakeOnly/CMakeLists.txt
index 2b25766..c84fa74 100644
--- a/Tests/CMakeOnly/CMakeLists.txt
+++ b/Tests/CMakeOnly/CMakeLists.txt
@@ -33,7 +33,7 @@ add_CMakeOnly_test(CompilerIdCXX)
if(CMAKE_Fortran_COMPILER)
add_CMakeOnly_test(CompilerIdFortran)
endif()
-if(CMAKE_GENERATOR MATCHES "Visual Studio ([^789]|[789][0-9])")
+if(CMAKE_GENERATOR MATCHES "Visual Studio ([^89]|[89][0-9])")
add_CMakeOnly_test(CompilerIdCSharp)
endif()
diff --git a/Tests/CMakeTestAllGenerators/RunCMake.cmake b/Tests/CMakeTestAllGenerators/RunCMake.cmake
index 6d27d3b..bfbb3a5 100644
--- a/Tests/CMakeTestAllGenerators/RunCMake.cmake
+++ b/Tests/CMakeTestAllGenerators/RunCMake.cmake
@@ -9,42 +9,23 @@ endif()
# Analyze 'cmake --help' output for list of available generators:
#
execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${dir})
-execute_process(COMMAND ${CMAKE_COMMAND} --help
+execute_process(COMMAND ${CMAKE_COMMAND} -E capabilities
RESULT_VARIABLE result
OUTPUT_VARIABLE stdout
ERROR_VARIABLE stderr
WORKING_DIRECTORY ${dir})
-string(REPLACE ";" "\\;" stdout "${stdout}")
-string(REPLACE "\n" "E;" stdout "${stdout}")
-
-set(collecting 0)
set(generators)
-foreach(eline ${stdout})
- string(REGEX REPLACE "^(.*)E$" "\\1" line "${eline}")
- if(collecting AND NOT line STREQUAL "")
- if(line MATCHES "=")
- string(REGEX REPLACE "^ (.+)= (.*)$" "\\1" gen "${line}")
- if(gen MATCHES "[A-Za-z]")
- string(REGEX REPLACE "^(.*[^ ]) +$" "\\1" gen "${gen}")
- if(gen)
- set(generators ${generators} ${gen})
- endif()
- endif()
- else()
- if(line MATCHES "^ [A-Za-z0-9]")
- string(REGEX REPLACE "^ (.+)$" "\\1" gen "${line}")
- string(REGEX REPLACE "^(.*[^ ]) +$" "\\1" gen "${gen}")
- if(gen)
- set(generators ${generators} ${gen})
- endif()
- endif()
+string(REGEX MATCHALL [["name":"[^"]+","platformSupport"]] generators_json "${stdout}")
+foreach(gen_json IN LISTS generators_json)
+ if("${gen_json}" MATCHES [["name":"([^"]+)"]])
+ set(gen "${CMAKE_MATCH_1}")
+ if(NOT gen MATCHES " (Win64|IA64|ARM)$")
+ list(APPEND generators "${gen}")
endif()
endif()
- if(line STREQUAL "The following generators are available on this platform:")
- set(collecting 1)
- endif()
endforeach()
+list(REMOVE_DUPLICATES generators)
# Also call with one non-existent generator:
#
@@ -60,28 +41,6 @@ message(STATUS "CTEST_FULL_OUTPUT (Avoid ctest truncation of output)")
message(STATUS "CMake generators='${generators}'")
-# If we'll be testing any of the MinGW Makefiles generators, adjust the
-# ENV{PATH} to make sure libgmp-10.dll can be loaded as needed. But only if
-# the testing machine has a default MinGW install... (If you have a
-# non-default install, append to the PATH before running the test...)
-#
-if(generators MATCHES "MinGW Makefiles")
- if(EXISTS "C:/MinGW/bin/libgmp-10.dll")
- string(TOLOWER "$ENV{PATH}" path)
- if(NOT path MATCHES "/mingw/bin")
- if(UNIX)
- set(sep ":")
- set(mingw_bin "/mingw/bin")
- else()
- set(sep ";")
- set(mingw_bin "C:/MinGW/bin")
- endif()
- set(ENV{PATH} "$ENV{PATH}${sep}${mingw_bin}")
- message(STATUS "info: appending '${sep}${mingw_bin}' to the PATH")
- endif()
- endif()
-endif()
-
# First setup a source tree to run CMake on.
#
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_directory
diff --git a/Tests/ExportImport/Export/CMakeLists.txt b/Tests/ExportImport/Export/CMakeLists.txt
index f504c7b..eeae3f0 100644
--- a/Tests/ExportImport/Export/CMakeLists.txt
+++ b/Tests/ExportImport/Export/CMakeLists.txt
@@ -79,6 +79,15 @@ set_property(TARGET testLib7 PROPERTY OUTPUT_NAME_DEBUG testLib7D-$<CONFIG>)
set_property(TARGET testLib7 PROPERTY OUTPUT_NAME_RELEASE testLib7R-$<CONFIG>)
set_property(TARGET testLib7 PROPERTY OUTPUT_NAME testLib7-$<CONFIG>)
+# Test exporting OBJECT targets
+add_library(testLib8 OBJECT testLib8A.c testLib8B.c sub/testLib8C.c)
+
+if(NOT CMAKE_GENERATOR STREQUAL "Xcode" OR NOT CMAKE_OSX_ARCHITECTURES MATCHES "[;$]")
+ set(maybe_testLib8 testLib8)
+else()
+ set(maybe_testLib8 "")
+endif()
+
# Test using the target_link_libraries command to set the
# LINK_INTERFACE_LIBRARIES* properties. We construct two libraries
# providing the same two symbols. In each library one of the symbols
@@ -474,7 +483,7 @@ install(
TARGETS
testExe1 testLib1 testLib2 testExe2 testLib3 testLib4 testExe3 testExe4
testExe2lib testLib4lib testLib4libdbg testLib4libopt
- testLib6 testLib7
+ testLib6 testLib7 ${maybe_testLib8}
testLibCycleA testLibCycleB
testLibNoSONAME
cmp0022NEW cmp0022OLD
@@ -483,6 +492,7 @@ install(
RUNTIME DESTINATION $<1:bin>
LIBRARY DESTINATION $<1:lib> NAMELINK_SKIP
ARCHIVE DESTINATION $<1:lib>
+ OBJECTS DESTINATION $<1:lib>
FRAMEWORK DESTINATION Frameworks
BUNDLE DESTINATION Applications
)
@@ -535,6 +545,7 @@ export(TARGETS testExe1 testLib1 testLib2 testLib3
FILE ExportBuildTree.cmake
)
export(TARGETS testExe2 testLib4 testLib5 testLib6 testLib7 testExe3 testExe4 testExe2lib
+ ${maybe_testLib8}
testLib4lib testLib4libdbg testLib4libopt
testLibCycleA testLibCycleB
testLibNoSONAME
diff --git a/Tests/ExportImport/Export/sub/testLib8C.c b/Tests/ExportImport/Export/sub/testLib8C.c
new file mode 100644
index 0000000..a5568c7
--- /dev/null
+++ b/Tests/ExportImport/Export/sub/testLib8C.c
@@ -0,0 +1,4 @@
+int testLib8C(void)
+{
+ return 0;
+}
diff --git a/Tests/ExportImport/Export/testLib8A.c b/Tests/ExportImport/Export/testLib8A.c
new file mode 100644
index 0000000..c64655a
--- /dev/null
+++ b/Tests/ExportImport/Export/testLib8A.c
@@ -0,0 +1,4 @@
+int testLib8A(void)
+{
+ return 0;
+}
diff --git a/Tests/ExportImport/Export/testLib8B.c b/Tests/ExportImport/Export/testLib8B.c
new file mode 100644
index 0000000..1be6c9c
--- /dev/null
+++ b/Tests/ExportImport/Export/testLib8B.c
@@ -0,0 +1,4 @@
+int testLib8B(void)
+{
+ return 0;
+}
diff --git a/Tests/ExportImport/Import/A/CMakeLists.txt b/Tests/ExportImport/Import/A/CMakeLists.txt
index 5ce9628..01960ea 100644
--- a/Tests/ExportImport/Import/A/CMakeLists.txt
+++ b/Tests/ExportImport/Import/A/CMakeLists.txt
@@ -228,6 +228,16 @@ target_link_libraries(imp_lib1 exp_testLib2)
add_library(imp_lib1b STATIC imp_lib1.c)
target_link_libraries(imp_lib1b bld_testLib2)
+if(NOT CMAKE_GENERATOR STREQUAL "Xcode" OR NOT CMAKE_OSX_ARCHITECTURES MATCHES "[;$]")
+ # Create a executable that is using objects imported from the install tree
+ add_executable(imp_testLib8 imp_testLib8.c $<TARGET_OBJECTS:exp_testLib8>)
+
+ if(NOT CMAKE_GENERATOR STREQUAL "Xcode" OR NOT XCODE_VERSION VERSION_LESS 5)
+ # Create a executable that is using objects imported from the build tree
+ add_executable(imp_testLib8b imp_testLib8.c $<TARGET_OBJECTS:bld_testLib8>)
+ endif()
+endif()
+
#-----------------------------------------------------------------------------
# Test that handling imported targets, including transitive dependencies,
# works in CheckFunctionExists (...and hopefully all other try_compile() checks
diff --git a/Tests/ExportImport/Import/A/imp_testExe1.c b/Tests/ExportImport/Import/A/imp_testExe1.c
index 83a9bb5..3488439 100644
--- a/Tests/ExportImport/Import/A/imp_testExe1.c
+++ b/Tests/ExportImport/Import/A/imp_testExe1.c
@@ -1,15 +1,15 @@
-extern int generated_by_testExe1();
-extern int generated_by_testExe3();
-extern int generated_by_testExe4();
-extern int testLib2();
-extern int testLib3();
-extern int testLib4();
-extern int testLib4lib();
-extern int testLib5();
-extern int testLib6();
-extern int testLib7();
-extern int testLibCycleA1();
-extern int testLibPerConfigDest();
+extern int generated_by_testExe1(void);
+extern int generated_by_testExe3(void);
+extern int generated_by_testExe4(void);
+extern int testLib2(void);
+extern int testLib3(void);
+extern int testLib4(void);
+extern int testLib4lib(void);
+extern int testLib5(void);
+extern int testLib6(void);
+extern int testLib7(void);
+extern int testLibCycleA1(void);
+extern int testLibPerConfigDest(void);
/* Switch a symbol between debug and optimized builds to make sure the
proper library is found from the testLib4 link interface. */
diff --git a/Tests/ExportImport/Import/A/imp_testLib8.c b/Tests/ExportImport/Import/A/imp_testLib8.c
new file mode 100644
index 0000000..2749b17
--- /dev/null
+++ b/Tests/ExportImport/Import/A/imp_testLib8.c
@@ -0,0 +1,8 @@
+
+int testLib8A(void);
+int testLib8B(void);
+
+int main()
+{
+ return (testLib8A() + testLib8B());
+}
diff --git a/Tests/FindMPI/CMakeLists.txt b/Tests/FindMPI/CMakeLists.txt
new file mode 100644
index 0000000..121d978
--- /dev/null
+++ b/Tests/FindMPI/CMakeLists.txt
@@ -0,0 +1,21 @@
+foreach(c C CXX Fortran)
+ if(CMake_TEST_FindMPI_${c})
+ set(CMake_TEST_FindMPI_FLAG_${c} 1)
+ else()
+ set(CMake_TEST_FindMPI_FLAG_${c} 0)
+ endif()
+endforeach()
+
+add_test(NAME FindMPI.Test COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindMPI/Test"
+ "${CMake_BINARY_DIR}/Tests/FindMPI/Test"
+ ${build_generator_args}
+ --build-project TestFindMPI
+ --build-options ${build_options}
+ -DMPI_TEST_C=${CMake_TEST_FindMPI_FLAG_C}
+ -DMPI_TEST_CXX=${CMake_TEST_FindMPI_FLAG_CXX}
+ -DMPI_TEST_Fortran=${CMake_TEST_FindMPI_FLAG_Fortran}
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
diff --git a/Tests/FindMPI/Test/CMakeLists.txt b/Tests/FindMPI/Test/CMakeLists.txt
new file mode 100644
index 0000000..6f177f9
--- /dev/null
+++ b/Tests/FindMPI/Test/CMakeLists.txt
@@ -0,0 +1,41 @@
+cmake_minimum_required(VERSION 3.8)
+project(TestFindMPI)
+include(CTest)
+
+macro(source_code_mapper_helper LANG_NAME)
+ if("${LANG_NAME}" STREQUAL "C")
+ set(MPITEST_SOURCE_FILE "main.c")
+ elseif("${LANG_NAME}" STREQUAL "CXX")
+ configure_file("main.c" "main.cxx" COPYONLY)
+ set(MPITEST_SOURCE_FILE "main.cxx")
+ elseif("${LANG_NAME}" STREQUAL "Fortran")
+ set(MPITEST_SOURCE_FILE "main.f90")
+ endif()
+endmacro()
+
+foreach(c C CXX Fortran)
+ if("${MPI_TEST_${c}}")
+ message("Testing ${c}")
+ enable_language(${c})
+ endif()
+endforeach()
+
+find_package(MPI REQUIRED)
+
+foreach(c C CXX Fortran)
+ if(NOT "${MPI_TEST_${c}}")
+ continue()
+ endif()
+ source_code_mapper_helper(${c})
+ add_executable(test_tgt_${c} ${MPITEST_SOURCE_FILE})
+ target_link_libraries(test_tgt_${c} MPI::MPI_${c})
+ add_test(NAME test_tgt_${c} COMMAND test_tgt_${c})
+
+ add_executable(test_var_${c} ${MPITEST_SOURCE_FILE})
+ target_include_directories(test_var_${c} PRIVATE "${MPI_${c}_INCLUDE_PATH}")
+ target_link_libraries(test_var_${c} PRIVATE "${MPI_${c}_LINK_FLAGS}" "${MPI_${c}_LIBRARIES}")
+ set(copied_MPI_${c}_OPTIONS "${MPI_${c}_COMPILE_FLAGS}")
+ separate_arguments(copied_MPI_${c}_OPTIONS)
+ target_compile_options(test_var_${c} PRIVATE "${copied_MPI_${c}_OPTIONS}")
+ add_test(NAME test_var_${c} COMMAND test_var_${c})
+endforeach()
diff --git a/Tests/FindMPI/Test/main.c b/Tests/FindMPI/Test/main.c
new file mode 100644
index 0000000..7b7f175
--- /dev/null
+++ b/Tests/FindMPI/Test/main.c
@@ -0,0 +1,7 @@
+#include <mpi.h>
+
+int main(int argc, char** argv)
+{
+ MPI_Init(&argc, &argv);
+ MPI_Finalize();
+}
diff --git a/Tests/FindMPI/Test/main.f90 b/Tests/FindMPI/Test/main.f90
new file mode 100644
index 0000000..6fb6fd3
--- /dev/null
+++ b/Tests/FindMPI/Test/main.f90
@@ -0,0 +1,7 @@
+program mpi_test
+ include 'mpif.h'
+ integer ierror
+
+ call MPI_INIT(ierror)
+ call MPI_FINALIZE(ierror)
+end program mpi_test
diff --git a/Tests/GeneratorExpression/CMakeLists.txt b/Tests/GeneratorExpression/CMakeLists.txt
index adc87cd..8ac3419 100644
--- a/Tests/GeneratorExpression/CMakeLists.txt
+++ b/Tests/GeneratorExpression/CMakeLists.txt
@@ -292,3 +292,19 @@ set(CMP0044_TYPE NEW)
add_subdirectory(CMP0044 ${CMAKE_BINARY_DIR}/CMP0044-NEW)
set(CMP0044_TYPE OLD)
add_subdirectory(CMP0044 ${CMAKE_BINARY_DIR}/CMP0044-OLD)
+
+if(NOT CMAKE_GENERATOR STREQUAL Xcode OR NOT CMAKE_OSX_ARCHITECTURES MATCHES "[;$]")
+ add_library(objlib OBJECT objlib1.c objlib2.c)
+ file(GENERATE
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/objlib_files_$<CONFIGURATION>"
+ CONTENT "$<JOIN:$<TARGET_OBJECTS:objlib>,\n>\n"
+ )
+
+ add_custom_target(check_object_files ALL
+ COMMAND ${CMAKE_COMMAND}
+ "-DOBJLIB_LISTFILE=${CMAKE_CURRENT_BINARY_DIR}/objlib_files_$<CONFIGURATION>"
+ -DEXPECTED_NUM_OBJECTFILES=2
+ -P "${CMAKE_CURRENT_SOURCE_DIR}/check_object_files.cmake"
+ DEPENDS objlib
+ )
+endif()
diff --git a/Tests/GeneratorExpression/check_object_files.cmake b/Tests/GeneratorExpression/check_object_files.cmake
new file mode 100644
index 0000000..cfccd29
--- /dev/null
+++ b/Tests/GeneratorExpression/check_object_files.cmake
@@ -0,0 +1,26 @@
+
+if (NOT EXISTS ${OBJLIB_LISTFILE})
+ message(SEND_ERROR "Object listing file \"${OBJLIB_LISTFILE}\" not found!")
+endif()
+
+file(STRINGS ${OBJLIB_LISTFILE} objlib_files ENCODING UTF-8)
+
+list(LENGTH objlib_files num_objectfiles)
+if (NOT EXPECTED_NUM_OBJECTFILES EQUAL num_objectfiles)
+ message(SEND_ERROR "Unexpected number of entries in object list file (${num_objectfiles} instead of ${EXPECTED_NUM_OBJECTFILES})")
+endif()
+
+foreach(objlib_file ${objlib_files})
+ set(file_exists False)
+ if (EXISTS ${objlib_file})
+ set(file_exists True)
+ endif()
+
+ if (NOT file_exists)
+ if(attempts)
+ list(REMOVE_DUPLICATES attempts)
+ set(tried " Tried ${attempts}")
+ endif()
+ message(SEND_ERROR "File \"${objlib_file}\" does not exist!${tried}")
+ endif()
+endforeach()
diff --git a/Tests/GeneratorExpression/objlib1.c b/Tests/GeneratorExpression/objlib1.c
new file mode 100644
index 0000000..98a95a4
--- /dev/null
+++ b/Tests/GeneratorExpression/objlib1.c
@@ -0,0 +1,4 @@
+
+void objlib1()
+{
+}
diff --git a/Tests/GeneratorExpression/objlib2.c b/Tests/GeneratorExpression/objlib2.c
new file mode 100644
index 0000000..b2c1050
--- /dev/null
+++ b/Tests/GeneratorExpression/objlib2.c
@@ -0,0 +1,4 @@
+
+void objlib2()
+{
+}
diff --git a/Tests/Module/CheckIPOSupported-C/CMakeLists.txt b/Tests/Module/CheckIPOSupported-C/CMakeLists.txt
new file mode 100644
index 0000000..607dcd3
--- /dev/null
+++ b/Tests/Module/CheckIPOSupported-C/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 3.8)
+project(CheckIPOSupported-C LANGUAGES C)
+
+cmake_policy(SET CMP0069 NEW)
+
+include(CheckIPOSupported)
+check_ipo_supported(RESULT ipo_supported)
+if(ipo_supported)
+ set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
+elseif(CMake_TEST_IPO_WORKS_C)
+ message(FATAL_ERROR "IPO expected to work")
+endif()
+
+add_library(foo foo.c)
+add_executable(CheckIPOSupported-C main.c)
+target_link_libraries(CheckIPOSupported-C PUBLIC foo)
+
+enable_testing()
+add_test(NAME CheckIPOSupported-C COMMAND CheckIPOSupported-C)
diff --git a/Tests/Module/CheckIPOSupported-C/foo.c b/Tests/Module/CheckIPOSupported-C/foo.c
new file mode 100644
index 0000000..1e56597
--- /dev/null
+++ b/Tests/Module/CheckIPOSupported-C/foo.c
@@ -0,0 +1,4 @@
+int foo()
+{
+ return 0x42;
+}
diff --git a/Tests/Module/CheckIPOSupported-C/main.c b/Tests/Module/CheckIPOSupported-C/main.c
new file mode 100644
index 0000000..99204ab
--- /dev/null
+++ b/Tests/Module/CheckIPOSupported-C/main.c
@@ -0,0 +1,9 @@
+int foo();
+
+int main()
+{
+ if (foo() == 0) {
+ return 1;
+ }
+ return 0;
+}
diff --git a/Tests/Module/CheckIPOSupported-CXX/CMakeLists.txt b/Tests/Module/CheckIPOSupported-CXX/CMakeLists.txt
new file mode 100644
index 0000000..2dede93
--- /dev/null
+++ b/Tests/Module/CheckIPOSupported-CXX/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 3.8)
+project(CheckIPOSupported-CXX LANGUAGES CXX)
+
+cmake_policy(SET CMP0069 NEW)
+
+include(CheckIPOSupported)
+check_ipo_supported(RESULT ipo_supported)
+if(ipo_supported)
+ set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
+elseif(CMake_TEST_IPO_WORKS_CXX)
+ message(FATAL_ERROR "IPO expected to work")
+endif()
+
+add_library(foo foo.cpp)
+add_executable(CheckIPOSupported-CXX main.cpp)
+target_link_libraries(CheckIPOSupported-CXX PUBLIC foo)
+
+enable_testing()
+add_test(NAME CheckIPOSupported-CXX COMMAND CheckIPOSupported-CXX)
diff --git a/Tests/Module/CheckIPOSupported-CXX/foo.cpp b/Tests/Module/CheckIPOSupported-CXX/foo.cpp
new file mode 100644
index 0000000..1e56597
--- /dev/null
+++ b/Tests/Module/CheckIPOSupported-CXX/foo.cpp
@@ -0,0 +1,4 @@
+int foo()
+{
+ return 0x42;
+}
diff --git a/Tests/Module/CheckIPOSupported-CXX/main.cpp b/Tests/Module/CheckIPOSupported-CXX/main.cpp
new file mode 100644
index 0000000..99204ab
--- /dev/null
+++ b/Tests/Module/CheckIPOSupported-CXX/main.cpp
@@ -0,0 +1,9 @@
+int foo();
+
+int main()
+{
+ if (foo() == 0) {
+ return 1;
+ }
+ return 0;
+}
diff --git a/Tests/Module/CheckIPOSupported-Fortran/CMakeLists.txt b/Tests/Module/CheckIPOSupported-Fortran/CMakeLists.txt
new file mode 100644
index 0000000..dee5c25
--- /dev/null
+++ b/Tests/Module/CheckIPOSupported-Fortran/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 3.8)
+project(CheckIPOSupported-Fortran LANGUAGES Fortran)
+
+cmake_policy(SET CMP0069 NEW)
+
+include(CheckIPOSupported)
+check_ipo_supported(RESULT ipo_supported)
+if(ipo_supported)
+ set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
+elseif(CMake_TEST_IPO_WORKS_Fortran)
+ message(FATAL_ERROR "IPO expected to work")
+endif()
+
+add_library(foo foo.f)
+add_executable(CheckIPOSupported-Fortran main.f)
+target_link_libraries(CheckIPOSupported-Fortran PUBLIC foo)
+
+enable_testing()
+add_test(NAME CheckIPOSupported-Fortran COMMAND CheckIPOSupported-Fortran)
diff --git a/Tests/Module/CheckIPOSupported-Fortran/foo.f b/Tests/Module/CheckIPOSupported-Fortran/foo.f
new file mode 100644
index 0000000..945d2d5
--- /dev/null
+++ b/Tests/Module/CheckIPOSupported-Fortran/foo.f
@@ -0,0 +1,2 @@
+ SUBROUTINE FOO
+ END
diff --git a/Tests/Module/CheckIPOSupported-Fortran/main.f b/Tests/Module/CheckIPOSupported-Fortran/main.f
new file mode 100644
index 0000000..9d1de9f
--- /dev/null
+++ b/Tests/Module/CheckIPOSupported-Fortran/main.f
@@ -0,0 +1,3 @@
+ PROGRAM BOO
+ CALL FOO()
+ END
diff --git a/Tests/ObjectLibrary/CMakeLists.txt b/Tests/ObjectLibrary/CMakeLists.txt
index e3476df..4bffd12 100644
--- a/Tests/ObjectLibrary/CMakeLists.txt
+++ b/Tests/ObjectLibrary/CMakeLists.txt
@@ -16,11 +16,7 @@ add_custom_command(TARGET UseCshared POST_BUILD COMMAND ${CMAKE_COMMAND} -P ${CM
add_executable(UseCinternal main.c c.c $<TARGET_OBJECTS:A> $<TARGET_OBJECTS:B>)
-if("${CMAKE_GENERATOR}" MATCHES "^Visual Studio (7|7 .NET 2003)$")
- # VS 7 generators do not add objects as sources so we need a
- # dummy object to convince the IDE to build the targets below.
- set(dummy dummy.obj) # In MinGW: gcc -c dummy.c -o dummy.obj
-elseif("${CMAKE_GENERATOR}" MATCHES "Xcode")
+if("${CMAKE_GENERATOR}" MATCHES "Xcode")
# Xcode does not seem to support targets without sources.
set(dummy dummy.c)
endif()
diff --git a/Tests/Preprocess/CMakeLists.txt b/Tests/Preprocess/CMakeLists.txt
index 807a427..8c2cdc9 100644
--- a/Tests/Preprocess/CMakeLists.txt
+++ b/Tests/Preprocess/CMakeLists.txt
@@ -25,9 +25,6 @@ endif()
if("${CMAKE_GENERATOR}" MATCHES "Watcom WMake")
set(PP_WATCOM 1)
endif()
-if("${CMAKE_GENERATOR}" MATCHES "Visual Studio 7$")
- set(PP_VS70 1)
-endif()
if("${CMAKE_GENERATOR}" MATCHES "Visual Studio")
set(PP_VS 1)
endif()
@@ -46,14 +43,11 @@ endif()
# must not have it escaped inside the configured header.
set(STRING_EXTRA "")
-if(NOT BORLAND AND NOT PP_VS70)
- # Borland, VS70 IDE: ;
+if(NOT BORLAND)
+ # Borland: ;
# The Borland compiler will simply not accept a non-escaped semicolon
# on the command line. If it is escaped \; then the escape character
# shows up in the preprocessing output too.
- #
- # The VS 7.0 IDE separates definitions on semicolons and commas with
- # no regard for quotes. Fortunately VS 7.1 and above are okay.
set(SEMICOLON "\;")
endif()
diff --git a/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake b/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake
index ffd3ae1..67a6101 100644
--- a/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake
+++ b/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake
@@ -31,7 +31,7 @@ function(run_BuildDepends CASE)
endfunction()
run_BuildDepends(C-Exe)
-if(NOT RunCMake_GENERATOR MATCHES "Visual Studio 7|Xcode")
+if(NOT RunCMake_GENERATOR STREQUAL "Xcode")
if(RunCMake_GENERATOR MATCHES "Visual Studio 10")
# VS 10 forgets to re-link when a manifest changes
set(run_BuildDepends_skip_step_2 1)
diff --git a/Tests/RunCMake/CMP0026/CMP0026-OLD.cmake b/Tests/RunCMake/CMP0026/CMP0026-OLD.cmake
new file mode 100644
index 0000000..80497a3
--- /dev/null
+++ b/Tests/RunCMake/CMP0026/CMP0026-OLD.cmake
@@ -0,0 +1,12 @@
+enable_language(CXX)
+
+cmake_policy(SET CMP0026 OLD)
+
+set(out ${CMAKE_CURRENT_BINARY_DIR}/out.txt)
+
+add_library(somelib empty.cpp ${out})
+get_target_property(_loc somelib LOCATION)
+
+file(WRITE "${out}"
+ "source file written by project code after getting target LOCATION\n"
+ )
diff --git a/Tests/RunCMake/CMP0026/RunCMakeTest.cmake b/Tests/RunCMake/CMP0026/RunCMakeTest.cmake
index 6331717..047da28 100644
--- a/Tests/RunCMake/CMP0026/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CMP0026/RunCMakeTest.cmake
@@ -1,6 +1,7 @@
include(RunCMake)
run_cmake(CMP0026-WARN)
+run_cmake(CMP0026-OLD)
run_cmake(CMP0026-NEW)
run_cmake(CMP0026-IMPORTED)
run_cmake(CMP0026-CONFIG-LOCATION-NEW)
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 73a4965..32c4be8 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -270,13 +270,13 @@ endif()
if("${CMAKE_GENERATOR}" MATCHES "Visual Studio")
add_RunCMake_test(include_external_msproject)
- if("${CMAKE_GENERATOR}" MATCHES "Visual Studio ([789]|10)" AND NOT CMAKE_VS_DEVENV_COMMAND)
+ if("${CMAKE_GENERATOR}" MATCHES "Visual Studio ([89]|10)" AND NOT CMAKE_VS_DEVENV_COMMAND)
set(NO_USE_FOLDERS 1)
endif()
add_RunCMake_test(VSSolution -DNO_USE_FOLDERS=${NO_USE_FOLDERS})
endif()
-if("${CMAKE_GENERATOR}" MATCHES "Visual Studio ([^789]|[789][0-9])")
+if("${CMAKE_GENERATOR}" MATCHES "Visual Studio ([^89]|[89][0-9])")
add_RunCMake_test(VS10Project)
endif()
diff --git a/Tests/RunCMake/CommandLine/DeprecateVS71-WARN-ON-stderr.txt b/Tests/RunCMake/CommandLine/DeprecateVS71-WARN-ON-stderr.txt
deleted file mode 100644
index 2cb01ff..0000000
--- a/Tests/RunCMake/CommandLine/DeprecateVS71-WARN-ON-stderr.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-^CMake Warning:
- The "Visual Studio 7 .NET 2003" generator is deprecated and will be removed
- in a future version of CMake.
-
- Add CMAKE_WARN_VS71=OFF to the cache to disable this warning.$
diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
index b213ee2..f327f78 100644
--- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
@@ -78,13 +78,6 @@ if(RunCMake_GENERATOR STREQUAL "Ninja")
unset(RunCMake_TEST_NO_CLEAN)
endif()
-if(RunCMake_GENERATOR STREQUAL "Visual Studio 7 .NET 2003")
- set(RunCMake_WARN_VS71 1)
- run_cmake(DeprecateVS71-WARN-ON)
- unset(RunCMake_WARN_VS71)
- run_cmake(DeprecateVS71-WARN-OFF)
-endif()
-
if(UNIX)
run_cmake_command(E_create_symlink-no-arg
${CMAKE_COMMAND} -E create_symlink
diff --git a/Tests/RunCMake/File_Generate/OutputConflict-stderr.txt b/Tests/RunCMake/File_Generate/OutputConflict-stderr.txt
index 0abb7df..a242180 100644
--- a/Tests/RunCMake/File_Generate/OutputConflict-stderr.txt
+++ b/Tests/RunCMake/File_Generate/OutputConflict-stderr.txt
@@ -1,5 +1,6 @@
CMake Error in CMakeLists.txt:
- Evaluation file to be written multiple times for different configurations
- or languages with different content:
+ Evaluation file to be written multiple times with different content. This
+ is generally caused by the content evaluating the configuration type,
+ language, or location of object files:
.*output.txt
diff --git a/Tests/RunCMake/File_Generate/OutputNameMatchesObjects-stderr.txt b/Tests/RunCMake/File_Generate/OutputNameMatchesObjects-stderr.txt
index d3aa973..b08ef5a 100644
--- a/Tests/RunCMake/File_Generate/OutputNameMatchesObjects-stderr.txt
+++ b/Tests/RunCMake/File_Generate/OutputNameMatchesObjects-stderr.txt
@@ -1,9 +1,8 @@
-CMake Error at OutputNameMatchesObjects.cmake:2 \(file\):
+CMake Error at OutputNameMatchesObjects.cmake:[0-9]+ \(file\):
Error evaluating generator expression:
\$<TARGET_OBJECTS:foo>
- The evaluation of the TARGET_OBJECTS generator expression is only suitable
- for consumption by CMake. It is not suitable for writing out elsewhere.
+ Objects of target "foo" referenced but is not an OBJECT library.
Call Stack \(most recent call first\):
- CMakeLists.txt:6 \(include\)
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/File_Generate/OutputNameMatchesObjects.cmake b/Tests/RunCMake/File_Generate/OutputNameMatchesObjects.cmake
index d807450..daa7c49 100644
--- a/Tests/RunCMake/File_Generate/OutputNameMatchesObjects.cmake
+++ b/Tests/RunCMake/File_Generate/OutputNameMatchesObjects.cmake
@@ -1,3 +1,4 @@
+enable_language(CXX)
file(GENERATE
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/$<BOOL:$<TARGET_OBJECTS:foo>>somefile.cpp"
diff --git a/Tests/RunCMake/ObjectLibrary/Export-stderr.txt b/Tests/RunCMake/ObjectLibrary/Export-stderr.txt
deleted file mode 100644
index bdadca4..0000000
--- a/Tests/RunCMake/ObjectLibrary/Export-stderr.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-CMake Error at Export.cmake:2 \(export\):
- export given OBJECT library "A" which may not be exported.
-Call Stack \(most recent call first\):
- CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/TargetObjects/BadContext-result.txt b/Tests/RunCMake/ObjectLibrary/ExportNotSupported-result.txt
index d00491f..d00491f 100644
--- a/Tests/RunCMake/TargetObjects/BadContext-result.txt
+++ b/Tests/RunCMake/ObjectLibrary/ExportNotSupported-result.txt
diff --git a/Tests/RunCMake/ObjectLibrary/ExportNotSupported-stderr.txt b/Tests/RunCMake/ObjectLibrary/ExportNotSupported-stderr.txt
new file mode 100644
index 0000000..5420159
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/ExportNotSupported-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at ExportNotSupported.cmake:[0-9]+ \(export\):
+ export given OBJECT library "A" which may not be exported under Xcode with
+ multiple architectures.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ObjectLibrary/ExportNotSupported.cmake b/Tests/RunCMake/ObjectLibrary/ExportNotSupported.cmake
new file mode 100644
index 0000000..a3f104e
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/ExportNotSupported.cmake
@@ -0,0 +1,2 @@
+add_library(A OBJECT a.c)
+export(TARGETS A FILE AExport.cmake)
diff --git a/Tests/RunCMake/ObjectLibrary/Import.cmake b/Tests/RunCMake/ObjectLibrary/Import.cmake
index 806b44a..42f4468 100644
--- a/Tests/RunCMake/ObjectLibrary/Import.cmake
+++ b/Tests/RunCMake/ObjectLibrary/Import.cmake
@@ -1 +1,12 @@
+
add_library(A OBJECT IMPORTED)
+
+# We don't actually build this example so just configure dummy
+# object files to test. They do not have to exist.
+set_property(TARGET A APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
+set_target_properties(A PROPERTIES
+ IMPORTED_OBJECTS_DEBUG "${CMAKE_CURRENT_BINARY_DIR}/does_not_exist.o"
+ IMPORTED_OBJECTS "${CMAKE_CURRENT_BINARY_DIR}/does_not_exist.o"
+ )
+
+add_library(B $<TARGET_OBJECTS:A> b.c)
diff --git a/Tests/RunCMake/ObjectLibrary/Install-result.txt b/Tests/RunCMake/ObjectLibrary/ImportNotSupported-result.txt
index d00491f..d00491f 100644
--- a/Tests/RunCMake/ObjectLibrary/Install-result.txt
+++ b/Tests/RunCMake/ObjectLibrary/ImportNotSupported-result.txt
diff --git a/Tests/RunCMake/ObjectLibrary/Import-stderr.txt b/Tests/RunCMake/ObjectLibrary/ImportNotSupported-stderr.txt
index 74b496a..0fadac2 100644
--- a/Tests/RunCMake/ObjectLibrary/Import-stderr.txt
+++ b/Tests/RunCMake/ObjectLibrary/ImportNotSupported-stderr.txt
@@ -1,4 +1,5 @@
-CMake Error at Import.cmake:1 \(add_library\):
- The OBJECT library type may not be used for IMPORTED libraries.
+CMake Error at ImportNotSupported.cmake:[0-9]+ \(add_library\):
+ The OBJECT library type may not be used for IMPORTED libraries under Xcode
+ with multiple architectures.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ObjectLibrary/ImportNotSupported.cmake b/Tests/RunCMake/ObjectLibrary/ImportNotSupported.cmake
new file mode 100644
index 0000000..806b44a
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/ImportNotSupported.cmake
@@ -0,0 +1 @@
+add_library(A OBJECT IMPORTED)
diff --git a/Tests/RunCMake/ObjectLibrary/Import-result.txt b/Tests/RunCMake/ObjectLibrary/InstallNotSupported-result.txt
index d00491f..d00491f 100644
--- a/Tests/RunCMake/ObjectLibrary/Import-result.txt
+++ b/Tests/RunCMake/ObjectLibrary/InstallNotSupported-result.txt
diff --git a/Tests/RunCMake/ObjectLibrary/Install-stderr.txt b/Tests/RunCMake/ObjectLibrary/InstallNotSupported-stderr.txt
index d2f9f4a..35a0e4f 100644
--- a/Tests/RunCMake/ObjectLibrary/Install-stderr.txt
+++ b/Tests/RunCMake/ObjectLibrary/InstallNotSupported-stderr.txt
@@ -1,4 +1,5 @@
-CMake Error at Install.cmake:2 \(install\):
- install TARGETS given OBJECT library "A" which may not be installed.
+CMake Error at InstallNotSupported.cmake:[0-9]+ \(install\):
+ install TARGETS given OBJECT library "A" which may not be installed under
+ Xcode with multiple architectures.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ObjectLibrary/InstallNotSupported.cmake b/Tests/RunCMake/ObjectLibrary/InstallNotSupported.cmake
new file mode 100644
index 0000000..c1d214b
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/InstallNotSupported.cmake
@@ -0,0 +1,2 @@
+add_library(A OBJECT a.c)
+install(TARGETS A DESTINATION lib)
diff --git a/Tests/RunCMake/ObjectLibrary/RunCMakeTest.cmake b/Tests/RunCMake/ObjectLibrary/RunCMakeTest.cmake
index e932693..fe708ce 100644
--- a/Tests/RunCMake/ObjectLibrary/RunCMakeTest.cmake
+++ b/Tests/RunCMake/ObjectLibrary/RunCMakeTest.cmake
@@ -5,9 +5,15 @@ run_cmake(BadSourceExpression2)
run_cmake(BadSourceExpression3)
run_cmake(BadObjSource1)
run_cmake(BadObjSource2)
-run_cmake(Export)
-run_cmake(Import)
-run_cmake(Install)
+if(RunCMake_GENERATOR STREQUAL "Xcode" AND "$ENV{CMAKE_OSX_ARCHITECTURES}" MATCHES "[;$]")
+ run_cmake(ExportNotSupported)
+ run_cmake(ImportNotSupported)
+ run_cmake(InstallNotSupported)
+else()
+ run_cmake(Export)
+ run_cmake(Import)
+ run_cmake(Install)
+endif()
run_cmake(LinkObjLHS)
run_cmake(LinkObjRHS1)
run_cmake(LinkObjRHS2)
diff --git a/Tests/RunCMake/ObjectLibrary/b.c b/Tests/RunCMake/ObjectLibrary/b.c
new file mode 100644
index 0000000..6751907
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/b.c
@@ -0,0 +1,4 @@
+int b(void)
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/RunCMake.cmake b/Tests/RunCMake/RunCMake.cmake
index 9e2fe7a..04eadd5 100644
--- a/Tests/RunCMake/RunCMake.cmake
+++ b/Tests/RunCMake/RunCMake.cmake
@@ -51,9 +51,6 @@ function(run_cmake test)
if(APPLE)
list(APPEND RunCMake_TEST_OPTIONS -DCMAKE_POLICY_DEFAULT_CMP0025=NEW)
endif()
- if(RunCMake_GENERATOR STREQUAL "Visual Studio 7 .NET 2003" AND NOT RunCMake_WARN_VS71)
- list(APPEND RunCMake_TEST_OPTIONS -DCMAKE_WARN_VS71=OFF)
- endif()
if(RunCMake_MAKE_PROGRAM)
list(APPEND RunCMake_TEST_OPTIONS "-DCMAKE_MAKE_PROGRAM=${RunCMake_MAKE_PROGRAM}")
endif()
diff --git a/Tests/RunCMake/TargetObjects/BadContext-stderr.txt b/Tests/RunCMake/TargetObjects/BadContext-stderr.txt
deleted file mode 100644
index b78189e..0000000
--- a/Tests/RunCMake/TargetObjects/BadContext-stderr.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-(CMake Error at BadContext.cmake:4 \(file\):
- Error evaluating generator expression:
-
- \$<TARGET_OBJECTS:NoTarget>
-
- The evaluation of the TARGET_OBJECTS generator expression is only suitable
- for consumption by CMake. It is not suitable for writing out elsewhere.
-Call Stack \(most recent call first\):
- CMakeLists.txt:3 \(include\)
-*)+
-(CMake Error at BadContext.cmake:5 \(file\):
- Error evaluating generator expression:
-
- \$<TARGET_OBJECTS:NoTarget>
-
- The evaluation of the TARGET_OBJECTS generator expression is only suitable
- for consumption by CMake. It is not suitable for writing out elsewhere.
-Call Stack \(most recent call first\):
- CMakeLists.txt:3 \(include\)
-*)+
-CMake Error:
- Error evaluating generator expression:
-
- \$<TARGET_OBJECTS:NoTarget>
-
- The evaluation of the TARGET_OBJECTS generator expression is only suitable
- for consumption by CMake. It is not suitable for writing out elsewhere.
diff --git a/Tests/RunCMake/ObjectLibrary/Export-result.txt b/Tests/RunCMake/TargetObjects/NoTarget-result.txt
index d00491f..d00491f 100644
--- a/Tests/RunCMake/ObjectLibrary/Export-result.txt
+++ b/Tests/RunCMake/TargetObjects/NoTarget-result.txt
diff --git a/Tests/RunCMake/TargetObjects/NoTarget-stderr.txt b/Tests/RunCMake/TargetObjects/NoTarget-stderr.txt
new file mode 100644
index 0000000..eadccaf
--- /dev/null
+++ b/Tests/RunCMake/TargetObjects/NoTarget-stderr.txt
@@ -0,0 +1,24 @@
+(CMake Error at NoTarget.cmake:4 \(file\):
+ Error evaluating generator expression:
+
+ \$<TARGET_OBJECTS:NoTarget>
+
+ Objects of target "NoTarget" referenced but no such target exists.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+*)+
+(CMake Error at NoTarget.cmake:5 \(file\):
+ Error evaluating generator expression:
+
+ \$<TARGET_OBJECTS:NoTarget>
+
+ Objects of target "NoTarget" referenced but no such target exists.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+*)+
+CMake Error:
+ Error evaluating generator expression:
+
+ \$<TARGET_OBJECTS:NoTarget>
+
+ Objects of target "NoTarget" referenced but no such target exists.
diff --git a/Tests/RunCMake/TargetObjects/BadContext.cmake b/Tests/RunCMake/TargetObjects/NoTarget.cmake
index 5d7e33e..5d7e33e 100644
--- a/Tests/RunCMake/TargetObjects/BadContext.cmake
+++ b/Tests/RunCMake/TargetObjects/NoTarget.cmake
diff --git a/Tests/RunCMake/TargetObjects/NotObjlibTarget-result.txt b/Tests/RunCMake/TargetObjects/NotObjlibTarget-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/TargetObjects/NotObjlibTarget-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/TargetObjects/NotObjlibTarget-stderr.txt b/Tests/RunCMake/TargetObjects/NotObjlibTarget-stderr.txt
new file mode 100644
index 0000000..a66794c
--- /dev/null
+++ b/Tests/RunCMake/TargetObjects/NotObjlibTarget-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at NotObjlibTarget.cmake:3 \(file\):
+ Error evaluating generator expression:
+
+ \$<TARGET_OBJECTS:StaticLib>
+
+ Objects of target "StaticLib" referenced but is not an OBJECT library.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/TargetObjects/NotObjlibTarget.cmake b/Tests/RunCMake/TargetObjects/NotObjlibTarget.cmake
new file mode 100644
index 0000000..8e5fdd0
--- /dev/null
+++ b/Tests/RunCMake/TargetObjects/NotObjlibTarget.cmake
@@ -0,0 +1,3 @@
+add_library(StaticLib empty.cpp)
+
+file(GENERATE OUTPUT test_output CONTENT $<TARGET_OBJECTS:StaticLib>)
diff --git a/Tests/RunCMake/TargetObjects/RunCMakeTest.cmake b/Tests/RunCMake/TargetObjects/RunCMakeTest.cmake
index 85c76e2..30b9fee 100644
--- a/Tests/RunCMake/TargetObjects/RunCMakeTest.cmake
+++ b/Tests/RunCMake/TargetObjects/RunCMakeTest.cmake
@@ -1,3 +1,4 @@
include(RunCMake)
-run_cmake(BadContext)
+run_cmake(NoTarget)
+run_cmake(NotObjlibTarget)
diff --git a/Tests/RunCMake/TargetObjects/empty.cpp b/Tests/RunCMake/TargetObjects/empty.cpp
new file mode 100644
index 0000000..4086dcc
--- /dev/null
+++ b/Tests/RunCMake/TargetObjects/empty.cpp
@@ -0,0 +1,4 @@
+int empty()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/VSSolution/RunCMakeTest.cmake b/Tests/RunCMake/VSSolution/RunCMakeTest.cmake
index 4ec3e3b..3a04db4 100644
--- a/Tests/RunCMake/VSSolution/RunCMakeTest.cmake
+++ b/Tests/RunCMake/VSSolution/RunCMakeTest.cmake
@@ -12,6 +12,6 @@ run_cmake(StartupProject)
run_cmake(StartupProjectMissing)
run_cmake(AddPackageToDefault)
-if(RunCMake_GENERATOR MATCHES "Visual Studio ([^7]|[7][0-9])" AND NOT NO_USE_FOLDERS)
+if(NOT NO_USE_FOLDERS)
run_cmake(StartupProjectUseFolders)
endif()
diff --git a/Tests/RunCMake/file/INSTALL-FILES_FROM_DIR-bad-result.txt b/Tests/RunCMake/file/INSTALL-FILES_FROM_DIR-bad-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/file/INSTALL-FILES_FROM_DIR-bad-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file/INSTALL-FILES_FROM_DIR-bad-stderr.txt b/Tests/RunCMake/file/INSTALL-FILES_FROM_DIR-bad-stderr.txt
new file mode 100644
index 0000000..9d5f876
--- /dev/null
+++ b/Tests/RunCMake/file/INSTALL-FILES_FROM_DIR-bad-stderr.txt
@@ -0,0 +1,15 @@
+^CMake Error at INSTALL-FILES_FROM_DIR-bad.cmake:[0-9]+ \(file\):
+ file option FILES_FROM_DIR requires all files to be specified as relative
+ paths\.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
++
+CMake Error at INSTALL-FILES_FROM_DIR-bad.cmake:[0-9]+ \(file\):
+ file INSTALL option RENAME may not be combined with FILES_FROM_DIR\.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
++
+CMake Error at INSTALL-FILES_FROM_DIR-bad.cmake:[0-9]+ \(file\):
+ file option FILES_FROM_DIR may not appear after PATTERN or REGEX\.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/file/INSTALL-FILES_FROM_DIR-bad.cmake b/Tests/RunCMake/file/INSTALL-FILES_FROM_DIR-bad.cmake
new file mode 100644
index 0000000..807b704
--- /dev/null
+++ b/Tests/RunCMake/file/INSTALL-FILES_FROM_DIR-bad.cmake
@@ -0,0 +1,5 @@
+set(src ${CMAKE_CURRENT_SOURCE_DIR}/from)
+set(dst ${CMAKE_CURRENT_BINARY_DIR}/from)
+file(INSTALL FILES ${src}/a.txt FILES_FROM_DIR ${src} DESTINATION ${dst})
+file(INSTALL FILES a.txt FILES_FROM_DIR ${src} DESTINATION ${dst} RENAME b.txt)
+file(INSTALL FILES a.txt DESTINATION ${dst} PATTERN *.txt FILES_FROM_DIR)
diff --git a/Tests/RunCMake/file/INSTALL-FILES_FROM_DIR-stdout.txt b/Tests/RunCMake/file/INSTALL-FILES_FROM_DIR-stdout.txt
new file mode 100644
index 0000000..1c3c693
--- /dev/null
+++ b/Tests/RunCMake/file/INSTALL-FILES_FROM_DIR-stdout.txt
@@ -0,0 +1,8 @@
+-- Before Installing
+-- Installing: .*/Tests/RunCMake/file/INSTALL-FILES_FROM_DIR-build/from/a.txt
+-- Installing: .*/Tests/RunCMake/file/INSTALL-FILES_FROM_DIR-build/from/a/b.txt
+-- Installing: .*/Tests/RunCMake/file/INSTALL-FILES_FROM_DIR-build/from/a/b/c.txt
+-- Up-to-date: .*/Tests/RunCMake/file/INSTALL-FILES_FROM_DIR-build/from/a.txt
+-- Up-to-date: .*/Tests/RunCMake/file/INSTALL-FILES_FROM_DIR-build/from/a/b.txt
+-- Up-to-date: .*/Tests/RunCMake/file/INSTALL-FILES_FROM_DIR-build/from/a/b/c.txt
+-- After Installing
diff --git a/Tests/RunCMake/file/INSTALL-FILES_FROM_DIR.cmake b/Tests/RunCMake/file/INSTALL-FILES_FROM_DIR.cmake
new file mode 100644
index 0000000..24e5282
--- /dev/null
+++ b/Tests/RunCMake/file/INSTALL-FILES_FROM_DIR.cmake
@@ -0,0 +1,7 @@
+set(src ${CMAKE_CURRENT_SOURCE_DIR}/from)
+set(dst ${CMAKE_CURRENT_BINARY_DIR}/from)
+file(REMOVE RECURSE ${dst})
+message(STATUS "Before Installing")
+file(INSTALL FILES a.txt a/b.txt a/b/c.txt FILES_FROM_DIR ${src} DESTINATION ${dst})
+file(INSTALL FILES a.txt a/b.txt a/b/c.txt FILES_FROM_DIR from DESTINATION ${dst})
+message(STATUS "After Installing")
diff --git a/Tests/RunCMake/file/RunCMakeTest.cmake b/Tests/RunCMake/file/RunCMakeTest.cmake
index 63cbdd9..26051b4 100644
--- a/Tests/RunCMake/file/RunCMakeTest.cmake
+++ b/Tests/RunCMake/file/RunCMakeTest.cmake
@@ -8,6 +8,8 @@ run_cmake(UPLOAD-unused-argument)
run_cmake(UPLOAD-httpheader-not-set)
run_cmake(UPLOAD-pass-not-set)
run_cmake(INSTALL-DIRECTORY)
+run_cmake(INSTALL-FILES_FROM_DIR)
+run_cmake(INSTALL-FILES_FROM_DIR-bad)
run_cmake(INSTALL-MESSAGE-bad)
run_cmake(FileOpenFailRead)
run_cmake(LOCK)
diff --git a/Tests/RunCMake/CommandLine/DeprecateVS71-WARN-ON.cmake b/Tests/RunCMake/file/from/a.txt
index e69de29..e69de29 100644
--- a/Tests/RunCMake/CommandLine/DeprecateVS71-WARN-ON.cmake
+++ b/Tests/RunCMake/file/from/a.txt
diff --git a/Tests/RunCMake/CommandLine/DeprecateVS71-WARN-OFF.cmake b/Tests/RunCMake/file/from/a/b.txt
index e69de29..e69de29 100644
--- a/Tests/RunCMake/CommandLine/DeprecateVS71-WARN-OFF.cmake
+++ b/Tests/RunCMake/file/from/a/b.txt
diff --git a/Tests/RunCMake/file/from/a/b/c.txt b/Tests/RunCMake/file/from/a/b/c.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/file/from/a/b/c.txt