summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt1
-rw-r--r--CONTRIBUTING.rst10
-rw-r--r--Help/dev/README.rst31
-rw-r--r--Help/dev/review.rst306
-rw-r--r--Help/dev/testing.rst42
-rw-r--r--Help/manual/cmake-properties.7.rst1
-rw-r--r--Help/manual/cmake-variables.7.rst57
-rw-r--r--Help/prop_tgt/INTERPROCEDURAL_OPTIMIZATION.rst4
-rw-r--r--Help/prop_tgt/MAP_IMPORTED_CONFIG_CONFIG.rst45
-rw-r--r--Help/release/dev/CMAKE_INTERPROCEDURAL_OPTIMIZATION.rst6
-rw-r--r--Help/release/dev/cmake-xcode-schemes.rst2
-rw-r--r--Help/release/dev/cpack-sign-uninstaller.rst5
-rw-r--r--Help/release/dev/gcc_archiving_tools.rst8
-rw-r--r--Help/variable/CMAKE_GCC_AR.rst7
-rw-r--r--Help/variable/CMAKE_GCC_RANLIB.rst7
-rw-r--r--Help/variable/CMAKE_INTERPROCEDURAL_OPTIMIZATION.rst8
-rw-r--r--Help/variable/CMAKE_VS_PLATFORM_TOOLSET_CUDA.rst12
-rw-r--r--Help/variable/CMAKE_XCODE_GENERATE_SCHEME.rst (renamed from Help/prop_gbl/XCODE_GENERATE_SCHEME.rst)4
-rw-r--r--Help/variable/MSVC_VERSION.rst3
-rw-r--r--Modules/BundleUtilities.cmake13
-rw-r--r--Modules/CMakeASMCompiler.cmake.in2
-rw-r--r--Modules/CMakeCCompiler.cmake.in2
-rw-r--r--Modules/CMakeCXXCompiler.cmake.in2
-rw-r--r--Modules/CMakeDetermineCCompiler.cmake4
-rw-r--r--Modules/CMakeDetermineCUDACompiler.cmake51
-rw-r--r--Modules/CMakeDetermineCXXCompiler.cmake4
-rw-r--r--Modules/CMakeDetermineCompilerId.cmake20
-rw-r--r--Modules/CMakeDetermineFortranCompiler.cmake3
-rw-r--r--Modules/CMakeFortranCompiler.cmake.in2
-rw-r--r--Modules/CPackNSIS.cmake4
-rw-r--r--Modules/CheckLanguage.cmake2
-rw-r--r--Modules/Compiler/GNU-FindBinUtils.cmake25
-rw-r--r--Modules/CompilerId/VS-10.vcxproj.in12
-rw-r--r--Modules/FindGit.cmake16
-rw-r--r--Modules/FindHDF5.cmake7
-rw-r--r--Modules/FindJNI.cmake5
-rw-r--r--Modules/FindVulkan.cmake9
-rw-r--r--Modules/NSIS.template.in45
-rw-r--r--Modules/WriteCompilerDetectionHeader.cmake17
-rw-r--r--Source/CMakeLists.txt4
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/CPack/OSXScriptLauncher.cxx1
-rw-r--r--Source/CPack/cmCPackArchiveGenerator.cxx10
-rw-r--r--Source/CPack/cmCPackGenerator.cxx4
-rw-r--r--Source/CTest/cmCTestBuildAndTestHandler.cxx14
-rw-r--r--Source/CTest/cmCTestBuildAndTestHandler.h2
-rw-r--r--Source/CTest/cmCTestCoverageHandler.cxx25
-rw-r--r--Source/CTest/cmCTestHandlerCommand.cxx5
-rw-r--r--Source/CTest/cmCTestMultiProcessHandler.cxx11
-rw-r--r--Source/CTest/cmCTestRunTest.cxx19
-rw-r--r--Source/CTest/cmCTestSubmitHandler.cxx13
-rw-r--r--Source/CTest/cmCTestTestHandler.cxx70
-rw-r--r--Source/cmCTest.cxx2
-rw-r--r--Source/cmCommonTargetGenerator.cxx15
-rw-r--r--Source/cmCommonTargetGenerator.h3
-rw-r--r--Source/cmDepends.cxx14
-rw-r--r--Source/cmFileCommand.cxx69
-rw-r--r--Source/cmFileCommand.h1
-rw-r--r--Source/cmFileMonitor.h2
-rw-r--r--Source/cmGeneratorTarget.cxx56
-rw-r--r--Source/cmGeneratorTarget.h16
-rw-r--r--Source/cmGlobalGenerator.cxx9
-rw-r--r--Source/cmGlobalVisualStudio10Generator.cxx281
-rw-r--r--Source/cmGlobalVisualStudio10Generator.h16
-rw-r--r--Source/cmGlobalVisualStudioGenerator.cxx16
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx3
-rw-r--r--Source/cmLocalGenerator.cxx11
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx39
-rw-r--r--Source/cmLocalVisualStudio7Generator.h1
-rw-r--r--Source/cmMakefile.cxx11
-rw-r--r--Source/cmMakefileExecutableTargetGenerator.cxx5
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.cxx5
-rw-r--r--Source/cmMakefileTargetGenerator.cxx78
-rw-r--r--Source/cmMakefileTargetGenerator.h3
-rw-r--r--Source/cmNinjaNormalTargetGenerator.cxx61
-rw-r--r--Source/cmNinjaTargetGenerator.cxx7
-rw-r--r--Source/cmOrderDirectories.cxx22
-rw-r--r--Source/cmOrderDirectories.h2
-rw-r--r--Source/cmQtAutoGeneratorCommon.cxx215
-rw-r--r--Source/cmQtAutoGeneratorCommon.h34
-rw-r--r--Source/cmQtAutoGeneratorInitializer.cxx486
-rw-r--r--Source/cmQtAutoGenerators.cxx342
-rw-r--r--Source/cmQtAutoGenerators.h4
-rw-r--r--Source/cmStateTypes.h3
-rw-r--r--Source/cmTarget.cxx1
-rw-r--r--Source/cmVS10CudaFlagTable.h51
-rw-r--r--Source/cmVS10CudaHostFlagTable.h35
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx195
-rw-r--r--Source/cmVisualStudio10TargetGenerator.h5
-rw-r--r--Source/cmVisualStudioGeneratorOptions.cxx127
-rw-r--r--Source/cmVisualStudioGeneratorOptions.h22
-rw-r--r--Source/cmWorkingDirectory.cxx24
-rw-r--r--Source/cmWorkingDirectory.h25
-rw-r--r--Source/cmake.cxx30
-rw-r--r--Source/kwsys/SystemInformation.cxx20
-rw-r--r--Source/kwsys/SystemInformation.hxx.in1
-rw-r--r--Source/kwsys/SystemTools.cxx2
-rw-r--r--Source/kwsys/testSystemInformation.cxx2
-rw-r--r--Tests/CPackComponents/CMakeLists.txt2
-rw-r--r--Tests/CheckFortran.cmake2
-rw-r--r--Tests/CudaOnly/SeparateCompilation/CMakeLists.txt16
-rw-r--r--Tests/CudaOnly/WithDefs/CMakeLists.txt11
-rw-r--r--Tests/CudaOnly/WithDefs/main_for_vs.cu1
-rw-r--r--Tests/Module/WriteCompilerDetectionHeader/main.cpp3
-rw-r--r--Tests/Module/WriteCompilerDetectionHeader/multi_files.cpp3
-rw-r--r--Tests/QtAutogen/CMakeLists.txt86
-rw-r--r--Tests/QtAutogen/automoc_rerun/CMakeLists.txt27
-rw-r--r--Tests/QtAutogen/automoc_rerun/test1.cpp5
-rw-r--r--Tests/QtAutogen/automoc_rerun/test1.h.in18
-rw-r--r--Tests/QtAutogen/automoc_rerun/test1.h.in27
-rw-r--r--Tests/QtAutogen/autorcc_depends/CMakeLists.txt27
-rw-r--r--Tests/QtAutogen/mocDepends/CMakeLists.txt45
-rw-r--r--Tests/QtAutogen/mocDepends/invalid.hpp.in1
-rw-r--r--Tests/QtAutogen/mocDepends/object.hpp.in14
-rw-r--r--Tests/QtAutogen/mocDepends/simpleLib.cpp.in9
-rw-r--r--Tests/QtAutogen/mocDepends/simpleLib.hpp.in11
-rw-r--r--Tests/QtAutogen/mocDepends/test1.cpp9
-rw-r--r--Tests/QtAutogen/mocDepends/test2.cpp10
-rw-r--r--Tests/QtAutogen/mocDepends/test2.hpp16
-rw-r--r--Tests/QtAutogen/mocRerun/CMakeLists.txt35
-rw-r--r--Tests/QtAutogen/mocRerun/input.txt (renamed from Tests/QtAutogen/automoc_rerun/input.txt)0
-rw-r--r--Tests/QtAutogen/mocRerun/main.cpp.in18
-rw-r--r--Tests/QtAutogen/mocRerun/res1.qrc (renamed from Tests/QtAutogen/automoc_rerun/res1.qrc)0
-rw-r--r--Tests/QtAutogen/mocRerun/test1a.h.in8
-rw-r--r--Tests/QtAutogen/mocRerun/test1b.h.in7
-rw-r--r--Tests/QtAutogen/rccDepends/CMakeLists.txt36
-rw-r--r--Tests/QtAutogen/rccDepends/main.cpp (renamed from Tests/QtAutogen/autorcc_depends/test_res1.cpp)0
-rw-r--r--Tests/QtAutogen/rccDepends/res/input1.txt.in (renamed from Tests/QtAutogen/autorcc_depends/res1/input.txt.in)0
-rw-r--r--Tests/QtAutogen/rccDepends/res/input2.txt.in1
-rw-r--r--Tests/QtAutogen/rccDepends/res1.qrc.in (renamed from Tests/QtAutogen/autorcc_depends/res1.qrc.in)0
-rw-r--r--Tests/QtAutogen/rccDepends/res2.qrc.in5
-rw-r--r--Tests/RunCMake/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake6
-rw-r--r--Tests/RunCMake/GeneratorToolset/TestToolsetCudaBoth-stdout.txt2
-rw-r--r--Tests/RunCMake/GeneratorToolset/TestToolsetCudaBoth.cmake2
-rw-r--r--Tests/RunCMake/GeneratorToolset/TestToolsetCudaOnly-stdout.txt2
-rw-r--r--Tests/RunCMake/GeneratorToolset/TestToolsetCudaOnly.cmake2
-rw-r--r--Tests/RunCMake/RuntimePath/A.c4
-rw-r--r--Tests/RunCMake/RuntimePath/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/RuntimePath/RunCMakeTest.cmake18
-rw-r--r--Tests/RunCMake/RuntimePath/SymlinkImplicit.cmake17
-rw-r--r--Tests/RunCMake/RuntimePath/SymlinkImplicitCheck-result.txt1
-rw-r--r--Tests/RunCMake/RuntimePath/SymlinkImplicitCheck-stderr.txt22
-rw-r--r--Tests/RunCMake/RuntimePath/SymlinkImplicitCheck.cmake2
-rw-r--r--Tests/RunCMake/RuntimePath/main.c4
-rw-r--r--Tests/RunCMake/XcodeProject/RunCMakeTest.cmake16
-rw-r--r--Tests/RunCMake/XcodeProject/XcodeSchemaGeneration.cmake5
-rw-r--r--Tests/RunCMake/file/READ_ELF-result.txt1
-rw-r--r--Tests/RunCMake/file/READ_ELF-stderr.txt2
-rw-r--r--Tests/RunCMake/file/READ_ELF.cmake2
-rw-r--r--Tests/RunCMake/file/RunCMakeTest.cmake1
-rw-r--r--Utilities/GitSetup/config9
-rw-r--r--Utilities/Release/release_cmake.cmake8
-rwxr-xr-xUtilities/Release/release_cmake.sh.in6
-rwxr-xr-xUtilities/SetupForDevelopment.sh5
-rw-r--r--Utilities/Sphinx/conf.py.in4
-rwxr-xr-xbootstrap1
157 files changed, 2924 insertions, 1003 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 472c6ab..ed5de10 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -806,6 +806,7 @@ if(NOT CMake_TEST_EXTERNAL_CMAKE)
PATTERN "*.sh*" PERMISSIONS OWNER_READ OWNER_EXECUTE OWNER_WRITE
GROUP_READ GROUP_EXECUTE
WORLD_READ WORLD_EXECUTE
+ REGEX "Help/dev($|/)" EXCLUDE
)
# Install auxiliary files integrating with other tools.
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
index 921ba7c..434f0f4 100644
--- a/CONTRIBUTING.rst
+++ b/CONTRIBUTING.rst
@@ -1,6 +1,11 @@
Contributing to CMake
*********************
+The following summarizes the process for contributing changes.
+See documentation on `CMake Development`_ for more information.
+
+.. _`CMake Development`: Help/dev/README.rst
+
Community
=========
@@ -19,13 +24,18 @@ CMake uses `Kitware's GitLab Instance`_ to manage development and code review.
To contribute patches:
#. Fork the upstream `CMake Repository`_ into a personal account.
+#. Run `Utilities/SetupForDevelopment.sh`_ for local configuration.
#. 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.
#. Create a GitLab Merge Request targeting the upstream ``master`` branch.
+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 Review Process`: Help/dev/review.rst
Code Style
==========
diff --git a/Help/dev/README.rst b/Help/dev/README.rst
new file mode 100644
index 0000000..0dc512a
--- /dev/null
+++ b/Help/dev/README.rst
@@ -0,0 +1,31 @@
+CMake Development
+*****************
+
+This directory contains documentation about development of CMake itself.
+It is not part of the user documentation distributed with CMake.
+
+Contributor Instructions
+========================
+
+See `CONTRIBUTING.rst`_ for instructions to contribute changes.
+
+The process for contributing changes is the same whether or not one
+has been invited to participate directly in upstream development.
+
+.. _`CONTRIBUTING.rst`: ../../CONTRIBUTING.rst
+
+Upstream Development
+====================
+
+CMake uses `Kitware's GitLab Instance`_ to manage development, review, and
+integration of changes. The `CMake Repository`_ holds the integration
+branches and tags. Upstream development processes are covered by the
+following documents:
+
+* The `CMake Review Process`_ manages integration of changes.
+* The `CMake Testing Process`_ drives integration testing.
+
+.. _`Kitware's GitLab Instance`: https://gitlab.kitware.com
+.. _`CMake Repository`: https://gitlab.kitware.com/cmake/cmake
+.. _`CMake Review Process`: review.rst
+.. _`CMake Testing Process`: testing.rst
diff --git a/Help/dev/review.rst b/Help/dev/review.rst
new file mode 100644
index 0000000..e23c0fb
--- /dev/null
+++ b/Help/dev/review.rst
@@ -0,0 +1,306 @@
+CMake Review Process
+********************
+
+The following documents the process for reviewing and integrating changes.
+See `CONTRIBUTING.rst`_ for instructions to contribute changes.
+See documentation on `CMake Development`_ for more information.
+
+.. _`CONTRIBUTING.rst`: ../../CONTRIBUTING.rst
+.. _`CMake Development`: README.rst
+
+.. contents:: The review process consists of the following steps:
+
+Merge Request
+=============
+
+A user initiates the review process for a change by pushing a *topic
+branch* to his or her own fork of the `CMake Repository`_ on GitLab and
+creating a *merge request* ("MR"). The new MR will appear on the
+`CMake Merge Requests Page`_. The rest of the review and integration
+process is managed by the merge request page for the change.
+
+During the review process, the MR submitter should address review comments
+or test failures by updating the MR with a (force-)push of the topic
+branch. The update initiates a new round of review.
+
+We recommend that users enable the "Remove source branch when merge
+request is accepted" option when creating the MR or by editing it.
+This will cause the MR topic branch to be automatically removed from
+the user's fork during the `Merge`_ step.
+
+.. _`CMake Merge Requests Page`: https://gitlab.kitware.com/cmake/cmake/merge_requests
+.. _`CMake Repository`: https://gitlab.kitware.com/cmake/cmake
+
+Workflow Status
+---------------
+
+`CMake GitLab Project Developers`_ may set one of the following labels
+in GitLab to track the state of a MR:
+
+* ``workflow:wip`` indicates that the MR needs additional updates from
+ the MR submitter before further review. Use this label after making
+ comments that require such updates.
+
+* ``workflow:in-review`` indicates that the MR awaits feedback from a
+ human reviewer or from `Topic Testing`_. Use this label after making
+ comments requesting such feedback.
+
+* ``workflow:nightly-testing`` indicates that the MR awaits results
+ of `Integration Testing`_. Use this label after making comments
+ requesting such staging.
+
+* ``workflow:expired`` indicates that the MR has been closed due
+ to a period of inactivity. See the `Expire`_ step. Use this label
+ after closing a MR for this reason.
+
+The workflow status labels are intended to be mutually exclusive,
+so please remove any existing workflow label when adding one.
+
+.. _`CMake GitLab Project Developers`: https://gitlab.kitware.com/cmake/cmake/settings/members
+
+Robot Review
+============
+
+The "Kitware Robot" (``@kwrobot``) automatically performs basic checks on
+the commits proposed in a MR. If all is well the robot silently reports
+a successful "build" status to GitLab. Otherwise the robot posts a comment
+with its diagnostics. **A topic may not be merged until the automatic
+review succeeds.** The MR submitter is expected to address the robot's
+comments by *rewriting* the commits named by the robot's diagnostics
+(e.g. via ``git rebase -i``).
+
+The automatic check is repeated whenever the topic branch is updated.
+One may explicitly request a re-check by adding a comment with the
+following command among the `comment trailing lines`_::
+
+ Do: check
+
+``@kwrobot`` will add an award emoji to the comment to indicate that it
+was processed and also run its checks again.
+
+Human Review
+============
+
+Anyone is welcome to review merge requests and make comments!
+
+Reviewers may add comments providing feedback or to acknowledge their
+approval. Lines of specific forms will be extracted during the `merge`_
+step and included as trailing lines of the generated merge commit message.
+Each review comment consists of up to two parts which must be specified
+in the following order: `comment body`_, then `comment trailing lines`_.
+Each part is optional, but they must be specified in this order.
+
+Comment Body
+------------
+
+The body of a comment may be free-form `GitLab Flavored Markdown`_.
+See GitLab documentation on `Special GitLab References`_ to add links to
+things like issues, commits, or other merge requests (even across projects).
+
+Additionally, a line in the comment body may start with one of the
+following votes:
+
+* ``-1`` or ``:-1:`` indicates "the change is not ready for integration".
+
+* ``+1`` or ``:+1:`` indicates "I like the change".
+ This adds an ``Acked-by:`` trailer to the `merge`_ commit message.
+
+* ``+2`` indicates "the change is ready for integration".
+ This adds a ``Reviewed-by:`` trailer to the `merge`_ commit message.
+
+* ``+3`` indicates "I have tested the change and verified it works".
+ This adds a ``Tested-by:`` trailer to the `merge`_ commit message.
+
+.. _`GitLab Flavored Markdown`: https://gitlab.kitware.com/help/user/markdown.md
+.. _`Special GitLab References`: https://gitlab.kitware.com/help/user/markdown.md#special-gitlab-references
+
+Comment Trailing Lines
+----------------------
+
+Zero or more *trailing* lines in the last section of a comment may appear
+with the form ``Key: Value``. The first such line should be separated
+from a preceding `comment body`_ by a blank line. Any key-value pair(s)
+may be specified for human reference. A few specific keys have meaning to
+``@kwrobot`` as follows.
+
+Comment Trailer Votes
+^^^^^^^^^^^^^^^^^^^^^
+
+Among the `comment trailing lines`_ one may cast a vote using one of the
+following pairs followed by nothing but whitespace before the end of the line:
+
+* ``Rejected-by: me`` indicates "the change is not ready for integration".
+* ``Acked-by: me`` indicates "I like the change".
+ This adds an ``Acked-by:`` trailer to the `merge`_ commit message.
+* ``Reviewed-by: me`` indicates "the change is ready for integration".
+ This adds a ``Reviewed-by:`` trailer to the `merge`_ commit message.
+* ``Tested-by: me`` indicates "I have tested the change and verified it works".
+ This adds a ``Tested-by:`` trailer to the `merge`_ commit message.
+
+Each ``me`` reference may instead be an ``@username`` reference or a full
+``Real Name <user@domain>`` reference to credit someone else for performing
+the review. References to ``me`` and ``@username`` will automatically be
+transformed into a real name and email address according to the user's
+GitLab account profile.
+
+Comment Trailer Commands
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+Among the `comment trailing lines`_ authorized users may issue special
+commands to ``@kwrobot`` using the form ``Do: ...``:
+
+* ``Do: check`` explicitly re-runs `Robot Review`_ checks.
+* ``Do: test`` submits the MR for `Topic Testing`_.
+* ``Do: stage`` submits the MR for `Integration Testing`_.
+* ``Do: merge`` submits the MR for `Merge`_.
+
+See the corresponding sections for details on permissions and options
+for each command.
+
+Topic Testing
+=============
+
+CMake has a `buildbot`_ instance watching for merge requests to test.
+`CMake GitLab Project Developers`_ may activate buildbot on a MR by
+adding a comment with a command among the `comment trailing lines`_::
+
+ Do: test
+
+``@kwrobot`` will add an award emoji to the comment to indicate that it
+was processed and also inform buildbot about the request. The buildbot
+user (``@buildbot``) will schedule builds and respond with a comment
+linking to the `CMake CDash Page`_ with a filter for results associated
+with the topic test request. If the MR topic branch is updated by a
+push a new ``Do: test`` command is needed to activate testing again.
+
+The ``Do: test`` command accepts the following arguments:
+
+* ``--stop``: clear the list of commands for the merge request
+* ``--clear``: clear previous commands before adding this command
+* ``--regex-include <arg>`` or ``-i <arg>``: only build on builders
+ matching ``<arg>`` (a Python regular expression)
+* ``--regex-exclude <arg>`` or ``-e <arg>``: exclude builds on builders
+ matching ``<arg>`` (a Python regular expression)
+
+Builder names follow the pattern ``project-host-os-buildtype-generator``:
+
+* ``project``: always ``cmake`` for CMake builds
+* ``host``: the buildbot host
+* ``os``: one of ``windows``, ``osx``, or ``linux``
+* ``buildtype``: ``release`` or ``debug``
+* ``generator``: ``ninja``, ``makefiles``, or ``vs<year>``
+
+.. _`buildbot`: http://buildbot.net
+.. _`CMake CDash Page`: https://open.cdash.org/index.php?project=CMake
+
+Integration Testing
+===================
+
+The above `topic testing`_ tests the MR topic independent of other
+merge requests and on only a few key platforms and configurations.
+The `CMake Testing Process`_ also has a large number of machines
+provided by Kitware and generous volunteers that cover nearly all
+supported platforms, generators, and configurations. In order to
+avoid overwhelming these resources, they do not test every MR
+individually. Instead, these machines follow an *integration branch*,
+run tests on a nightly basis (or continuously during the day), and
+post to the `CMake CDash Page`_. Some follow ``master``. Most follow
+a special integration branch, the *topic stage*.
+
+The topic stage is a special branch maintained by the "Kitware Robot"
+(``@kwrobot``). It consists of the head of the MR target integration
+branch (e.g. ``master``) branch followed by a sequence of merges each
+integrating changes from an open MR that has been staged for integration
+testing. Each time the target integration branch is updated the stage
+is rebuilt automatically by merging the staged MR topics again.
+
+`CMake GitLab Project Developers`_ may stage a MR for integration testing
+by adding a comment with a command among the `comment trailing lines`_::
+
+ Do: stage
+
+``@kwrobot`` will add an award emoji to the comment to indicate that it
+was processed and also attempt to add the MR topic branch to the topic
+stage. If the MR cannot be added (e.g. due to conflicts) the robot will
+post a comment explaining what went wrong.
+
+Once a MR has been added to the topic stage it will remain on the stage
+until one of the following occurs:
+
+* The MR topic branch is updated by a push.
+
+* The MR target integration branch (e.g. ``master``) branch is updated
+ and the MR cannot be merged into the topic stage again due to conflicts.
+
+* A developer or the submitter posts an explicit ``Do: unstage`` command.
+
+* The MR is closed.
+
+* The MR is merged.
+
+Once a MR has been removed from the topic stage a new ``Do: stage``
+command is needed to stage it again.
+
+.. _`CMake Testing Process`: testing.rst
+
+Resolve
+=======
+
+A MR may be resolved in one of the following ways.
+
+Merge
+-----
+
+Once review has concluded that the MR topic is ready for integration,
+`CMake GitLab Project Masters`_ may merge the topic by adding a comment
+with a command among the `comment trailing lines`_::
+
+ Do: merge
+
+``@kwrobot`` will add an award emoji to the comment to indicate that it
+was processed and also attempt to merge the MR topic branch to the MR
+target integration branch (e.g. ``master``). If the MR cannot be merged
+(e.g. due to conflicts) the robot will post a comment explaining what
+went wrong. If the MR is merged the robot will also remove the source
+branch from the user's fork if the corresponding MR option was checked.
+
+The robot automatically constructs a merge commit message of the following
+form::
+
+ Merge topic 'mr-topic-branch-name'
+
+ 00000000 commit message subject line (one line per commit)
+
+ Acked-by: Kitware Robot <kwrobot@kitware.com>
+ Merge-request: !0000
+
+Mention of the commit short sha1s and MR number helps GitLab link the
+commits back to the merge request and indicates when they were merged.
+The ``Acked-by:`` trailer shown indicates that `Robot Review`_ passed.
+Additional ``Acked-by:``, ``Reviewed-by:``, and similar trailers may be
+collected from `Human Review`_ comments that have been made since the
+last time the MR topic branch was updated with a push.
+
+The ``Do: merge`` command accepts the following arguments:
+
+* ``-t <topic>``: substitute ``<topic>`` for the name of the MR topic
+ branch in the constructed merge commit message.
+
+.. _`CMake GitLab Project Masters`: https://gitlab.kitware.com/cmake/cmake/settings/members
+
+Close
+-----
+
+If review has concluded that the MR should not be integrated then it
+may be closed through GitLab.
+
+Expire
+------
+
+If progress on a MR has stalled for a while, it may be closed with a
+``workflow:expired`` label and a comment indicating that the MR has
+been closed due to inactivity.
+
+Contributors are welcome to re-open an expired MR when they are ready
+to continue work. Please re-open *before* pushing an update to the
+MR topic branch to ensure GitLab will still act on the association.
diff --git a/Help/dev/testing.rst b/Help/dev/testing.rst
new file mode 100644
index 0000000..731930c
--- /dev/null
+++ b/Help/dev/testing.rst
@@ -0,0 +1,42 @@
+CMake Testing Process
+*********************
+
+The following documents the process for running integration testing builds.
+See documentation on `CMake Development`_ for more information.
+
+.. _`CMake Development`: README.rst
+
+CMake Dashboard Scripts
+=======================
+
+The *integration testing* step of the `CMake Review Process`_ uses a set of
+testing machines that follow an integration branch on their own schedule to
+drive testing and submit results to the `CMake CDash Page`_. Anyone is
+welcome to provide testing machines in order to help keep support for their
+platforms working.
+
+The `CMake Dashboard Scripts Repository`_ provides CTest scripts to drive
+nightly, continous, and experimental testing of CMake. Use the following
+commands to set up a new integration testing client:
+
+.. code-block:: console
+
+ $ mkdir -p ~/Dashboards
+ $ cd ~/Dashboards
+ $ git clone https://gitlab.kitware.com/cmake/dashboard-scripts.git CMakeScripts
+ $ cd CMakeScripts
+
+The ``cmake_common.cmake`` script contains comments at the top with
+instructions to set up a testing client. As it instructs, create a
+CTest script with local settings and include ``cmake_common.cmake``.
+
+.. _`CMake Review Process`: review.rst
+.. _`CMake CDash Page`: https://open.cdash.org/index.php?project=CMake
+.. _`CMake Dashboard Scripts Repository`: https://gitlab.kitware.com/cmake/dashboard-scripts
+
+Nightly Start Time
+------------------
+
+The ``cmake_common.cmake`` script expects its includer to be run from a
+nightly scheduled task (cron job). Schedule such tasks for sometime after
+``1:00am UTC``, the time at which our nightly testing branches fast-forward.
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index 2157ba5..e07150a 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -46,7 +46,6 @@ Properties of Global Scope
/prop_gbl/TARGET_SUPPORTS_SHARED_LIBS
/prop_gbl/USE_FOLDERS
/prop_gbl/XCODE_EMIT_EFFECTIVE_PLATFORM_NAME
- /prop_gbl/XCODE_GENERATE_SCHEME
.. _`Directory Properties`:
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index 79c7cd8..9d8d596 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -13,9 +13,9 @@ Variables that Provide Information
.. toctree::
:maxdepth: 1
+ /variable/CMAKE_AR
/variable/CMAKE_ARGC
/variable/CMAKE_ARGV0
- /variable/CMAKE_AR
/variable/CMAKE_BINARY_DIR
/variable/CMAKE_BUILD_TOOL
/variable/CMAKE_CACHEFILE_DIR
@@ -40,6 +40,8 @@ Variables that Provide Information
/variable/CMAKE_FIND_PACKAGE_NAME
/variable/CMAKE_FIND_PACKAGE_SORT_DIRECTION
/variable/CMAKE_FIND_PACKAGE_SORT_ORDER
+ /variable/CMAKE_GCC_AR
+ /variable/CMAKE_GCC_RANLIB
/variable/CMAKE_GENERATOR
/variable/CMAKE_GENERATOR_PLATFORM
/variable/CMAKE_GENERATOR_TOOLSET
@@ -82,18 +84,20 @@ Variables that Provide Information
/variable/CMAKE_VS_NsightTegra_VERSION
/variable/CMAKE_VS_PLATFORM_NAME
/variable/CMAKE_VS_PLATFORM_TOOLSET
+ /variable/CMAKE_VS_PLATFORM_TOOLSET_CUDA
/variable/CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE
/variable/CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION
+ /variable/CMAKE_XCODE_GENERATE_SCHEME
/variable/CMAKE_XCODE_PLATFORM_TOOLSET
- /variable/PROJECT_BINARY_DIR
/variable/PROJECT-NAME_BINARY_DIR
- /variable/PROJECT_NAME
/variable/PROJECT-NAME_SOURCE_DIR
/variable/PROJECT-NAME_VERSION
/variable/PROJECT-NAME_VERSION_MAJOR
/variable/PROJECT-NAME_VERSION_MINOR
/variable/PROJECT-NAME_VERSION_PATCH
/variable/PROJECT-NAME_VERSION_TWEAK
+ /variable/PROJECT_BINARY_DIR
+ /variable/PROJECT_NAME
/variable/PROJECT_SOURCE_DIR
/variable/PROJECT_VERSION
/variable/PROJECT_VERSION_MAJOR
@@ -127,7 +131,6 @@ Variables that Change Behavior
/variable/CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION
/variable/CMAKE_EXPORT_COMPILE_COMMANDS
/variable/CMAKE_EXPORT_NO_PACKAGE_REGISTRY
- /variable/CMAKE_SYSROOT
/variable/CMAKE_FIND_APPBUNDLE
/variable/CMAKE_FIND_FRAMEWORK
/variable/CMAKE_FIND_LIBRARY_CUSTOM_LIB_SUFFIX
@@ -144,9 +147,9 @@ Variables that Change Behavior
/variable/CMAKE_FIND_ROOT_PATH_MODE_PROGRAM
/variable/CMAKE_FRAMEWORK_PATH
/variable/CMAKE_IGNORE_PATH
- /variable/CMAKE_INCLUDE_PATH
/variable/CMAKE_INCLUDE_DIRECTORIES_BEFORE
/variable/CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE
+ /variable/CMAKE_INCLUDE_PATH
/variable/CMAKE_INSTALL_DEFAULT_COMPONENT_NAME
/variable/CMAKE_INSTALL_MESSAGE
/variable/CMAKE_INSTALL_PREFIX
@@ -164,6 +167,7 @@ Variables that Change Behavior
/variable/CMAKE_STAGING_PREFIX
/variable/CMAKE_SUBLIME_TEXT_2_ENV_SETTINGS
/variable/CMAKE_SUBLIME_TEXT_2_EXCLUDE_BUILD_TREE
+ /variable/CMAKE_SYSROOT
/variable/CMAKE_SYSTEM_APPBUNDLE_PATH
/variable/CMAKE_SYSTEM_FRAMEWORK_PATH
/variable/CMAKE_SYSTEM_IGNORE_PATH
@@ -188,23 +192,24 @@ Variables that Describe the System
/variable/CMAKE_COMPILER_2005
/variable/CMAKE_HOST_APPLE
/variable/CMAKE_HOST_SOLARIS
+ /variable/CMAKE_HOST_SYSTEM
/variable/CMAKE_HOST_SYSTEM_NAME
/variable/CMAKE_HOST_SYSTEM_PROCESSOR
- /variable/CMAKE_HOST_SYSTEM
/variable/CMAKE_HOST_SYSTEM_VERSION
/variable/CMAKE_HOST_UNIX
/variable/CMAKE_HOST_WIN32
- /variable/CMAKE_LIBRARY_ARCHITECTURE_REGEX
/variable/CMAKE_LIBRARY_ARCHITECTURE
+ /variable/CMAKE_LIBRARY_ARCHITECTURE_REGEX
/variable/CMAKE_OBJECT_PATH_MAX
+ /variable/CMAKE_SYSTEM
/variable/CMAKE_SYSTEM_NAME
/variable/CMAKE_SYSTEM_PROCESSOR
- /variable/CMAKE_SYSTEM
/variable/CMAKE_SYSTEM_VERSION
/variable/CYGWIN
/variable/ENV
/variable/GHS-MULTI
/variable/MINGW
+ /variable/MSVC
/variable/MSVC10
/variable/MSVC11
/variable/MSVC12
@@ -215,7 +220,6 @@ Variables that Describe the System
/variable/MSVC80
/variable/MSVC90
/variable/MSVC_IDE
- /variable/MSVC
/variable/MSVC_VERSION
/variable/UNIX
/variable/WIN32
@@ -257,9 +261,9 @@ Variables that Control the Build
/variable/CMAKE_ANDROID_STL_TYPE
/variable/CMAKE_ARCHIVE_OUTPUT_DIRECTORY
/variable/CMAKE_ARCHIVE_OUTPUT_DIRECTORY_CONFIG
+ /variable/CMAKE_AUTOMOC
/variable/CMAKE_AUTOMOC_DEPEND_FILTERS
/variable/CMAKE_AUTOMOC_MOC_OPTIONS
- /variable/CMAKE_AUTOMOC
/variable/CMAKE_AUTORCC
/variable/CMAKE_AUTORCC_OPTIONS
/variable/CMAKE_AUTOUIC
@@ -273,18 +277,19 @@ Variables that Control the Build
/variable/CMAKE_CONFIG_POSTFIX
/variable/CMAKE_DEBUG_POSTFIX
/variable/CMAKE_ENABLE_EXPORTS
+ /variable/CMAKE_EXE_LINKER_FLAGS
/variable/CMAKE_EXE_LINKER_FLAGS_CONFIG
/variable/CMAKE_EXE_LINKER_FLAGS_CONFIG_INIT
- /variable/CMAKE_EXE_LINKER_FLAGS
/variable/CMAKE_EXE_LINKER_FLAGS_INIT
/variable/CMAKE_Fortran_FORMAT
/variable/CMAKE_Fortran_MODULE_DIRECTORY
/variable/CMAKE_GNUtoMS
- /variable/CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE
/variable/CMAKE_INCLUDE_CURRENT_DIR
+ /variable/CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE
/variable/CMAKE_INSTALL_NAME_DIR
/variable/CMAKE_INSTALL_RPATH
/variable/CMAKE_INSTALL_RPATH_USE_LINK_PATH
+ /variable/CMAKE_INTERPROCEDURAL_OPTIMIZATION
/variable/CMAKE_IOS_INSTALL_COMBINED
/variable/CMAKE_LANG_CLANG_TIDY
/variable/CMAKE_LANG_COMPILER_LAUNCHER
@@ -303,9 +308,9 @@ Variables that Control the Build
/variable/CMAKE_MACOSX_BUNDLE
/variable/CMAKE_MACOSX_RPATH
/variable/CMAKE_MAP_IMPORTED_CONFIG_CONFIG
+ /variable/CMAKE_MODULE_LINKER_FLAGS
/variable/CMAKE_MODULE_LINKER_FLAGS_CONFIG
/variable/CMAKE_MODULE_LINKER_FLAGS_CONFIG_INIT
- /variable/CMAKE_MODULE_LINKER_FLAGS
/variable/CMAKE_MODULE_LINKER_FLAGS_INIT
/variable/CMAKE_NINJA_OUTPUT_PATH_PREFIX
/variable/CMAKE_NO_BUILTIN_CHRPATH
@@ -318,15 +323,15 @@ Variables that Control the Build
/variable/CMAKE_POSITION_INDEPENDENT_CODE
/variable/CMAKE_RUNTIME_OUTPUT_DIRECTORY
/variable/CMAKE_RUNTIME_OUTPUT_DIRECTORY_CONFIG
+ /variable/CMAKE_SHARED_LINKER_FLAGS
/variable/CMAKE_SHARED_LINKER_FLAGS_CONFIG
/variable/CMAKE_SHARED_LINKER_FLAGS_CONFIG_INIT
- /variable/CMAKE_SHARED_LINKER_FLAGS
/variable/CMAKE_SHARED_LINKER_FLAGS_INIT
/variable/CMAKE_SKIP_BUILD_RPATH
/variable/CMAKE_SKIP_INSTALL_RPATH
+ /variable/CMAKE_STATIC_LINKER_FLAGS
/variable/CMAKE_STATIC_LINKER_FLAGS_CONFIG
/variable/CMAKE_STATIC_LINKER_FLAGS_CONFIG_INIT
- /variable/CMAKE_STATIC_LINKER_FLAGS
/variable/CMAKE_STATIC_LINKER_FLAGS_INIT
/variable/CMAKE_TRY_COMPILE_CONFIGURATION
/variable/CMAKE_TRY_COMPILE_PLATFORM_VARIABLES
@@ -335,8 +340,8 @@ Variables that Control the Build
/variable/CMAKE_VISIBILITY_INLINES_HIDDEN
/variable/CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD
/variable/CMAKE_VS_INCLUDE_PACKAGE_TO_DEFAULT_BUILD
- /variable/CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS
/variable/CMAKE_WIN32_EXECUTABLE
+ /variable/CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS
/variable/CMAKE_XCODE_ATTRIBUTE_an-attribute
/variable/EXECUTABLE_OUTPUT_PATH
/variable/LIBRARY_OUTPUT_PATH
@@ -350,10 +355,6 @@ Variables for Languages
/variable/CMAKE_COMPILER_IS_GNUCC
/variable/CMAKE_COMPILER_IS_GNUCXX
/variable/CMAKE_COMPILER_IS_GNUG77
- /variable/CMAKE_C_COMPILE_FEATURES
- /variable/CMAKE_C_EXTENSIONS
- /variable/CMAKE_C_STANDARD
- /variable/CMAKE_C_STANDARD_REQUIRED
/variable/CMAKE_CUDA_EXTENSIONS
/variable/CMAKE_CUDA_STANDARD
/variable/CMAKE_CUDA_STANDARD_REQUIRED
@@ -362,6 +363,10 @@ Variables for Languages
/variable/CMAKE_CXX_EXTENSIONS
/variable/CMAKE_CXX_STANDARD
/variable/CMAKE_CXX_STANDARD_REQUIRED
+ /variable/CMAKE_C_COMPILE_FEATURES
+ /variable/CMAKE_C_EXTENSIONS
+ /variable/CMAKE_C_STANDARD
+ /variable/CMAKE_C_STANDARD_REQUIRED
/variable/CMAKE_Fortran_MODDIR_DEFAULT
/variable/CMAKE_Fortran_MODDIR_FLAG
/variable/CMAKE_Fortran_MODOUT_FLAG
@@ -372,27 +377,27 @@ Variables for Languages
/variable/CMAKE_LANG_ARCHIVE_APPEND
/variable/CMAKE_LANG_ARCHIVE_CREATE
/variable/CMAKE_LANG_ARCHIVE_FINISH
- /variable/CMAKE_LANG_COMPILE_OBJECT
+ /variable/CMAKE_LANG_COMPILER
/variable/CMAKE_LANG_COMPILER_ABI
+ /variable/CMAKE_LANG_COMPILER_EXTERNAL_TOOLCHAIN
/variable/CMAKE_LANG_COMPILER_ID
/variable/CMAKE_LANG_COMPILER_LOADED
- /variable/CMAKE_LANG_COMPILER
- /variable/CMAKE_LANG_COMPILER_EXTERNAL_TOOLCHAIN
/variable/CMAKE_LANG_COMPILER_TARGET
/variable/CMAKE_LANG_COMPILER_VERSION
+ /variable/CMAKE_LANG_COMPILE_OBJECT
/variable/CMAKE_LANG_CREATE_SHARED_LIBRARY
/variable/CMAKE_LANG_CREATE_SHARED_MODULE
/variable/CMAKE_LANG_CREATE_STATIC_LIBRARY
+ /variable/CMAKE_LANG_FLAGS
/variable/CMAKE_LANG_FLAGS_DEBUG
/variable/CMAKE_LANG_FLAGS_DEBUG_INIT
+ /variable/CMAKE_LANG_FLAGS_INIT
/variable/CMAKE_LANG_FLAGS_MINSIZEREL
/variable/CMAKE_LANG_FLAGS_MINSIZEREL_INIT
/variable/CMAKE_LANG_FLAGS_RELEASE
/variable/CMAKE_LANG_FLAGS_RELEASE_INIT
/variable/CMAKE_LANG_FLAGS_RELWITHDEBINFO
/variable/CMAKE_LANG_FLAGS_RELWITHDEBINFO_INIT
- /variable/CMAKE_LANG_FLAGS
- /variable/CMAKE_LANG_FLAGS_INIT
/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_DEBUG
/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_MINSIZEREL
/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_RELEASE
@@ -403,8 +408,8 @@ Variables for Languages
/variable/CMAKE_LANG_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES
/variable/CMAKE_LANG_IMPLICIT_LINK_LIBRARIES
/variable/CMAKE_LANG_LIBRARY_ARCHITECTURE
- /variable/CMAKE_LANG_LINKER_PREFERENCE_PROPAGATES
/variable/CMAKE_LANG_LINKER_PREFERENCE
+ /variable/CMAKE_LANG_LINKER_PREFERENCE_PROPAGATES
/variable/CMAKE_LANG_LINK_EXECUTABLE
/variable/CMAKE_LANG_OUTPUT_EXTENSION
/variable/CMAKE_LANG_PLATFORM_ID
diff --git a/Help/prop_tgt/INTERPROCEDURAL_OPTIMIZATION.rst b/Help/prop_tgt/INTERPROCEDURAL_OPTIMIZATION.rst
index effa3b0..3f68c31 100644
--- a/Help/prop_tgt/INTERPROCEDURAL_OPTIMIZATION.rst
+++ b/Help/prop_tgt/INTERPROCEDURAL_OPTIMIZATION.rst
@@ -5,3 +5,7 @@ Enable interprocedural optimization for a target.
If set to true, enables interprocedural optimizations if they are
known to be supported by the compiler.
+
+This property is initialized by the
+:variable:`CMAKE_INTERPROCEDURAL_OPTIMIZATION` variable if it is set when a
+target is created.
diff --git a/Help/prop_tgt/MAP_IMPORTED_CONFIG_CONFIG.rst b/Help/prop_tgt/MAP_IMPORTED_CONFIG_CONFIG.rst
index 4da855b..266ccf0 100644
--- a/Help/prop_tgt/MAP_IMPORTED_CONFIG_CONFIG.rst
+++ b/Help/prop_tgt/MAP_IMPORTED_CONFIG_CONFIG.rst
@@ -23,3 +23,48 @@ is ignored for non-imported targets.
This property is initialized by the value of the
:variable:`CMAKE_MAP_IMPORTED_CONFIG_<CONFIG>` variable if it is set when a
target is created.
+
+Example
+^^^^^^^
+
+For example creating imported C++ library ``foo``:
+
+.. code-block:: cmake
+
+ add_library(foo STATIC IMPORTED)
+
+Use ``foo_debug`` path for ``Debug`` build type:
+
+.. code-block:: cmake
+
+ set_property(
+ TARGET foo APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG
+ )
+
+ set_target_properties(foo PROPERTIES
+ IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "CXX"
+ IMPORTED_LOCATION_DEBUG "${foo_debug}"
+ )
+
+Use ``foo_release`` path for ``Release`` build type:
+
+.. code-block:: cmake
+
+ set_property(
+ TARGET foo APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE
+ )
+
+ set_target_properties(foo PROPERTIES
+ IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "CXX"
+ IMPORTED_LOCATION_RELEASE "${foo_release}"
+ )
+
+Use ``Release`` version of library for ``MinSizeRel`` and ``RelWithDebInfo``
+build types:
+
+.. code-block:: cmake
+
+ set_target_properties(foo PROPERTIES
+ MAP_IMPORTED_CONFIG_MINSIZEREL Release
+ MAP_IMPORTED_CONFIG_RELWITHDEBINFO Release
+ )
diff --git a/Help/release/dev/CMAKE_INTERPROCEDURAL_OPTIMIZATION.rst b/Help/release/dev/CMAKE_INTERPROCEDURAL_OPTIMIZATION.rst
new file mode 100644
index 0000000..fc4f733
--- /dev/null
+++ b/Help/release/dev/CMAKE_INTERPROCEDURAL_OPTIMIZATION.rst
@@ -0,0 +1,6 @@
+CMAKE_INTERPROCEDURAL_OPTIMIZATION
+----------------------------------
+
+* A :variable:`CMAKE_INTERPROCEDURAL_OPTIMIZATION` variable was added to
+ initialize the :prop_tgt:`INTERPROCEDURAL_OPTIMIZATION` property on all
+ targets.
diff --git a/Help/release/dev/cmake-xcode-schemes.rst b/Help/release/dev/cmake-xcode-schemes.rst
index 27c19d7..81068ae 100644
--- a/Help/release/dev/cmake-xcode-schemes.rst
+++ b/Help/release/dev/cmake-xcode-schemes.rst
@@ -3,4 +3,4 @@ cmake-xcode-schemes
* The :generator:`Xcode` generator got the ability to create schema files.
This is still an experimental feature and can be activated by setting the
- :prop_gbl:`XCODE_GENERATE_SCHEME` global property to a ``TRUE`` value.
+ :variable:`CMAKE_XCODE_GENERATE_SCHEME` variable to a ``TRUE`` value.
diff --git a/Help/release/dev/cpack-sign-uninstaller.rst b/Help/release/dev/cpack-sign-uninstaller.rst
new file mode 100644
index 0000000..ff2b402
--- /dev/null
+++ b/Help/release/dev/cpack-sign-uninstaller.rst
@@ -0,0 +1,5 @@
+cpack-sign_uninstaller
+----------------------
+
+* The :module:`CPackNSIS` module learned to sign the uninstaller
+ when using :variable:`CPACK_NSIS_SIGN_UNINSTALLER` variable.
diff --git a/Help/release/dev/gcc_archiving_tools.rst b/Help/release/dev/gcc_archiving_tools.rst
new file mode 100644
index 0000000..b3cc7d6
--- /dev/null
+++ b/Help/release/dev/gcc_archiving_tools.rst
@@ -0,0 +1,8 @@
+gcc_archiving_tools
+-------------------
+
+* The :variable:`CMAKE_GCC_AR` variable with the path to GCC wrapper of ``ar``
+ utility was added.
+
+* The :variable:`CMAKE_GCC_RANLIB` variable with the path to GCC wrapper of
+ ``ranlib`` utility was added.
diff --git a/Help/variable/CMAKE_GCC_AR.rst b/Help/variable/CMAKE_GCC_AR.rst
new file mode 100644
index 0000000..ac90b46
--- /dev/null
+++ b/Help/variable/CMAKE_GCC_AR.rst
@@ -0,0 +1,7 @@
+CMAKE_GCC_AR
+------------
+
+A wrapper around ``ar`` adding the appropriate ``--plugin`` option for the
+GCC compiler. For other compilers variable is not defined.
+
+See also :variable:`CMAKE_AR`.
diff --git a/Help/variable/CMAKE_GCC_RANLIB.rst b/Help/variable/CMAKE_GCC_RANLIB.rst
new file mode 100644
index 0000000..3d42aba
--- /dev/null
+++ b/Help/variable/CMAKE_GCC_RANLIB.rst
@@ -0,0 +1,7 @@
+CMAKE_GCC_RANLIB
+----------------
+
+A wrapper around ``ranlib`` adding the appropriate ``--plugin`` option for the
+GCC compiler. For other compilers variable is not defined.
+
+See also :variable:`CMAKE_RANLIB`.
diff --git a/Help/variable/CMAKE_INTERPROCEDURAL_OPTIMIZATION.rst b/Help/variable/CMAKE_INTERPROCEDURAL_OPTIMIZATION.rst
new file mode 100644
index 0000000..b0cbb62
--- /dev/null
+++ b/Help/variable/CMAKE_INTERPROCEDURAL_OPTIMIZATION.rst
@@ -0,0 +1,8 @@
+CMAKE_INTERPROCEDURAL_OPTIMIZATION
+----------------------------------
+
+Default value for :prop_tgt:`INTERPROCEDURAL_OPTIMIZATION` of targets.
+
+This variable is used to initialize the :prop_tgt:`INTERPROCEDURAL_OPTIMIZATION`
+property on all the targets. See that target property for additional
+information.
diff --git a/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_CUDA.rst b/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_CUDA.rst
new file mode 100644
index 0000000..1604a76
--- /dev/null
+++ b/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_CUDA.rst
@@ -0,0 +1,12 @@
+CMAKE_VS_PLATFORM_TOOLSET_CUDA
+------------------------------
+
+NVIDIA CUDA Toolkit version whose Visual Studio toolset to use.
+
+The :ref:`Visual Studio Generators` for VS 2010 and above support using
+a CUDA toolset provided by a CUDA Toolkit. The toolset version number
+may be specified by a field in :variable:`CMAKE_GENERATOR_TOOLSET` of
+the form ``cuda=8.0``. If none is specified CMake will choose a default
+version. CMake provides the selected CUDA toolset version in this variable.
+The value may be empty if no CUDA Toolkit with Visual Studio integration
+is installed.
diff --git a/Help/prop_gbl/XCODE_GENERATE_SCHEME.rst b/Help/variable/CMAKE_XCODE_GENERATE_SCHEME.rst
index be8b5b0..c9fcc92 100644
--- a/Help/prop_gbl/XCODE_GENERATE_SCHEME.rst
+++ b/Help/variable/CMAKE_XCODE_GENERATE_SCHEME.rst
@@ -1,5 +1,5 @@
-XCODE_GENERATE_SCHEME
----------------------
+CMAKE_XCODE_GENERATE_SCHEME
+---------------------------
If enabled, the Xcode generator will generate schema files. Those are
are useful to invoke analyze, archive, build-for-testing and test
diff --git a/Help/variable/MSVC_VERSION.rst b/Help/variable/MSVC_VERSION.rst
index e2aff3c9..8932147 100644
--- a/Help/variable/MSVC_VERSION.rst
+++ b/Help/variable/MSVC_VERSION.rst
@@ -13,4 +13,5 @@ Known version numbers are::
1600 = VS 10.0
1700 = VS 11.0
1800 = VS 12.0
- 1900 = VS 14.0, 15.0
+ 1900 = VS 14.0
+ 1910 = VS 15.0
diff --git a/Modules/BundleUtilities.cmake b/Modules/BundleUtilities.cmake
index 5d6f402..121a8f0 100644
--- a/Modules/BundleUtilities.cmake
+++ b/Modules/BundleUtilities.cmake
@@ -432,6 +432,16 @@ function(get_item_rpaths item rpaths_var)
endif()
endif()
+ if(UNIX AND NOT APPLE)
+ file(READ_ELF ${item} RPATH rpath_var RUNPATH runpath_var CAPTURE_ERROR error_var)
+ get_filename_component(item_dir ${item} DIRECTORY)
+ foreach(rpath ${rpath_var} ${runpath_var})
+ # Substitute $ORIGIN with the exepath and add to the found rpaths
+ string(REPLACE "$ORIGIN" "${item_dir}" rpath "${rpath}")
+ gp_append_unique(${rpaths_var} "${rpath}")
+ endforeach()
+ endif()
+
set(${rpaths_var} ${${rpaths_var}} PARENT_SCOPE)
endfunction()
@@ -998,7 +1008,8 @@ function(verify_bundle_prerequisites bundle result_var info_var)
endif()
if(NOT ignoreFile)
- get_prerequisites("${f}" prereqs 1 1 "${exepath}" "")
+ get_item_rpaths(${f} _main_exe_rpaths)
+ get_prerequisites("${f}" prereqs 1 1 "${exepath}" "${_main_exe_rpaths}")
# On the Mac,
# "embedded" and "system" prerequisites are fine... anything else means
diff --git a/Modules/CMakeASMCompiler.cmake.in b/Modules/CMakeASMCompiler.cmake.in
index 8e58307..ad65698 100644
--- a/Modules/CMakeASMCompiler.cmake.in
+++ b/Modules/CMakeASMCompiler.cmake.in
@@ -1,7 +1,9 @@
set(CMAKE_ASM@ASM_DIALECT@_COMPILER "@_CMAKE_ASM_COMPILER@")
set(CMAKE_ASM@ASM_DIALECT@_COMPILER_ARG1 "@_CMAKE_ASM_COMPILER_ARG1@")
set(CMAKE_AR "@CMAKE_AR@")
+set(CMAKE_GCC_AR "@CMAKE_GCC_AR@")
set(CMAKE_RANLIB "@CMAKE_RANLIB@")
+set(CMAKE_GCC_RANLIB "@CMAKE_GCC_RANLIB@")
set(CMAKE_LINKER "@CMAKE_LINKER@")
set(CMAKE_ASM@ASM_DIALECT@_COMPILER_LOADED 1)
set(CMAKE_ASM@ASM_DIALECT@_COMPILER_ID "@_CMAKE_ASM_COMPILER_ID@")
diff --git a/Modules/CMakeCCompiler.cmake.in b/Modules/CMakeCCompiler.cmake.in
index 50b12f2..ab068a2 100644
--- a/Modules/CMakeCCompiler.cmake.in
+++ b/Modules/CMakeCCompiler.cmake.in
@@ -14,7 +14,9 @@ set(CMAKE_C_SIMULATE_ID "@CMAKE_C_SIMULATE_ID@")
set(CMAKE_C_SIMULATE_VERSION "@CMAKE_C_SIMULATE_VERSION@")
@SET_MSVC_C_ARCHITECTURE_ID@
set(CMAKE_AR "@CMAKE_AR@")
+set(CMAKE_GCC_AR "@CMAKE_GCC_AR@")
set(CMAKE_RANLIB "@CMAKE_RANLIB@")
+set(CMAKE_GCC_RANLIB "@CMAKE_GCC_RANLIB@")
set(CMAKE_LINKER "@CMAKE_LINKER@")
set(CMAKE_COMPILER_IS_GNUCC @CMAKE_COMPILER_IS_GNUCC@)
set(CMAKE_C_COMPILER_LOADED 1)
diff --git a/Modules/CMakeCXXCompiler.cmake.in b/Modules/CMakeCXXCompiler.cmake.in
index 6d56488..27c8881 100644
--- a/Modules/CMakeCXXCompiler.cmake.in
+++ b/Modules/CMakeCXXCompiler.cmake.in
@@ -15,7 +15,9 @@ set(CMAKE_CXX_SIMULATE_ID "@CMAKE_CXX_SIMULATE_ID@")
set(CMAKE_CXX_SIMULATE_VERSION "@CMAKE_CXX_SIMULATE_VERSION@")
@SET_MSVC_CXX_ARCHITECTURE_ID@
set(CMAKE_AR "@CMAKE_AR@")
+set(CMAKE_GCC_AR "@CMAKE_GCC_AR@")
set(CMAKE_RANLIB "@CMAKE_RANLIB@")
+set(CMAKE_GCC_RANLIB "@CMAKE_GCC_RANLIB@")
set(CMAKE_LINKER "@CMAKE_LINKER@")
set(CMAKE_COMPILER_IS_GNUCXX @CMAKE_COMPILER_IS_GNUCXX@)
set(CMAKE_CXX_COMPILER_LOADED 1)
diff --git a/Modules/CMakeDetermineCCompiler.cmake b/Modules/CMakeDetermineCCompiler.cmake
index 4a315e0..5d9850d 100644
--- a/Modules/CMakeDetermineCCompiler.cmake
+++ b/Modules/CMakeDetermineCCompiler.cmake
@@ -166,6 +166,10 @@ if (CMAKE_CROSSCOMPILING AND NOT _CMAKE_TOOLCHAIN_PREFIX)
endif ()
include(CMakeFindBinUtils)
+set(_CMAKE_PROCESSING_LANGUAGE "C")
+include(Compiler/${CMAKE_C_COMPILER_ID}-FindBinUtils OPTIONAL)
+unset(_CMAKE_PROCESSING_LANGUAGE)
+
if(MSVC_C_ARCHITECTURE_ID)
set(SET_MSVC_C_ARCHITECTURE_ID
"set(MSVC_C_ARCHITECTURE_ID ${MSVC_C_ARCHITECTURE_ID})")
diff --git a/Modules/CMakeDetermineCUDACompiler.cmake b/Modules/CMakeDetermineCUDACompiler.cmake
index 375e230..55a6f0c 100644
--- a/Modules/CMakeDetermineCUDACompiler.cmake
+++ b/Modules/CMakeDetermineCUDACompiler.cmake
@@ -5,36 +5,40 @@ include(${CMAKE_ROOT}/Modules/CMakeDetermineCompiler.cmake)
include(${CMAKE_ROOT}/Modules//CMakeParseImplicitLinkInfo.cmake)
if( NOT ( ("${CMAKE_GENERATOR}" MATCHES "Make") OR
- ("${CMAKE_GENERATOR}" MATCHES "Ninja") ) )
+ ("${CMAKE_GENERATOR}" MATCHES "Ninja") OR
+ ("${CMAKE_GENERATOR}" MATCHES "Visual Studio (1|[7-9][0-9])") ) )
message(FATAL_ERROR "CUDA language not currently supported by \"${CMAKE_GENERATOR}\" generator")
endif()
-if(NOT CMAKE_CUDA_COMPILER)
- set(CMAKE_CUDA_COMPILER_INIT NOTFOUND)
-
- # prefer the environment variable CUDACXX
- if(NOT $ENV{CUDACXX} STREQUAL "")
- get_filename_component(CMAKE_CUDA_COMPILER_INIT $ENV{CUDACXX} PROGRAM PROGRAM_ARGS CMAKE_CUDA_FLAGS_ENV_INIT)
- if(CMAKE_CUDA_FLAGS_ENV_INIT)
- set(CMAKE_CUDA_COMPILER_ARG1 "${CMAKE_CUDA_FLAGS_ENV_INIT}" CACHE STRING "First argument to CXX compiler")
- endif()
- if(NOT EXISTS ${CMAKE_CUDA_COMPILER_INIT})
- message(FATAL_ERROR "Could not find compiler set in environment variable CUDACXX:\n$ENV{CUDACXX}.\n${CMAKE_CUDA_COMPILER_INIT}")
+if(${CMAKE_GENERATOR} MATCHES "Visual Studio")
+else()
+ if(NOT CMAKE_CUDA_COMPILER)
+ set(CMAKE_CUDA_COMPILER_INIT NOTFOUND)
+
+ # prefer the environment variable CUDACXX
+ if(NOT $ENV{CUDACXX} STREQUAL "")
+ get_filename_component(CMAKE_CUDA_COMPILER_INIT $ENV{CUDACXX} PROGRAM PROGRAM_ARGS CMAKE_CUDA_FLAGS_ENV_INIT)
+ if(CMAKE_CUDA_FLAGS_ENV_INIT)
+ set(CMAKE_CUDA_COMPILER_ARG1 "${CMAKE_CUDA_FLAGS_ENV_INIT}" CACHE STRING "First argument to CXX compiler")
+ endif()
+ if(NOT EXISTS ${CMAKE_CUDA_COMPILER_INIT})
+ message(FATAL_ERROR "Could not find compiler set in environment variable CUDACXX:\n$ENV{CUDACXX}.\n${CMAKE_CUDA_COMPILER_INIT}")
+ endif()
endif()
+
+ # finally list compilers to try
+ if(NOT CMAKE_CUDA_COMPILER_INIT)
+ set(CMAKE_CUDA_COMPILER_LIST nvcc)
endif()
- # finally list compilers to try
- if(NOT CMAKE_CUDA_COMPILER_INIT)
- set(CMAKE_CUDA_COMPILER_LIST nvcc)
+ _cmake_find_compiler(CUDA)
+ else()
+ _cmake_find_compiler_path(CUDA)
endif()
- _cmake_find_compiler(CUDA)
-else()
- _cmake_find_compiler_path(CUDA)
+ mark_as_advanced(CMAKE_CUDA_COMPILER)
endif()
-mark_as_advanced(CMAKE_CUDA_COMPILER)
-
#Allow the user to specify a host compiler
set(CMAKE_CUDA_HOST_COMPILER "" CACHE FILEPATH "Host compiler to be used by nvcc")
if(NOT $ENV{CUDAHOSTCXX} STREQUAL "")
@@ -75,7 +79,12 @@ if(MSVC_CUDA_ARCHITECTURE_ID)
"set(MSVC_CUDA_ARCHITECTURE_ID ${MSVC_CUDA_ARCHITECTURE_ID})")
endif()
-if(CMAKE_CUDA_COMPILER_ID STREQUAL NVIDIA)
+if(${CMAKE_GENERATOR} MATCHES "Visual Studio")
+ set(CMAKE_CUDA_HOST_LINK_LAUNCHER "${CMAKE_LINKER}")
+ set(CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES "")
+ set(CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES "")
+ set(CMAKE_CUDA_HOST_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "")
+elseif(CMAKE_CUDA_COMPILER_ID STREQUAL NVIDIA)
set(_nvcc_log "")
string(REPLACE "\r" "" _nvcc_output_orig "${CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT}")
if(_nvcc_output_orig MATCHES "#\\\$ +LIBRARIES= *([^\n]*)\n")
diff --git a/Modules/CMakeDetermineCXXCompiler.cmake b/Modules/CMakeDetermineCXXCompiler.cmake
index f2e0bb2..4d85150 100644
--- a/Modules/CMakeDetermineCXXCompiler.cmake
+++ b/Modules/CMakeDetermineCXXCompiler.cmake
@@ -161,6 +161,10 @@ if (CMAKE_CROSSCOMPILING AND NOT _CMAKE_TOOLCHAIN_PREFIX)
endif ()
include(CMakeFindBinUtils)
+set(_CMAKE_PROCESSING_LANGUAGE "CXX")
+include(Compiler/${CMAKE_CXX_COMPILER_ID}-FindBinUtils OPTIONAL)
+unset(_CMAKE_PROCESSING_LANGUAGE)
+
if(MSVC_CXX_ARCHITECTURE_ID)
set(SET_MSVC_CXX_ARCHITECTURE_ID
"set(MSVC_CXX_ARCHITECTURE_ID ${MSVC_CXX_ARCHITECTURE_ID})")
diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake
index ae485bf..6fce8e2 100644
--- a/Modules/CMakeDetermineCompilerId.cmake
+++ b/Modules/CMakeDetermineCompilerId.cmake
@@ -235,6 +235,26 @@ Id flags: ${testflags} ${CMAKE_${lang}_COMPILER_ID_FLAGS_ALWAYS}
endif()
set(id_dir ${CMAKE_${lang}_COMPILER_ID_DIR})
set(id_src "${src}")
+ set(id_compile "ClCompile")
+ set(id_PostBuildEvent_Command "for %%i in (${id_cl}) do %40echo CMAKE_${lang}_COMPILER=%%~$PATH:i")
+ set(id_Import_props "")
+ set(id_Import_targets "")
+ set(id_ItemDefinitionGroup_entry "")
+ set(id_Link_AdditionalDependencies "")
+ if(lang STREQUAL CUDA)
+ if(NOT CMAKE_VS_PLATFORM_TOOLSET_CUDA)
+ message(FATAL_ERROR "No CUDA toolset found.")
+ endif()
+ set(cuda_tools "CUDA ${CMAKE_VS_PLATFORM_TOOLSET_CUDA}")
+ set(id_compile "CudaCompile")
+ set(id_PostBuildEvent_Command [[echo CMAKE_CUDA_COMPILER=$(CudaToolkitBinDir)\nvcc.exe]])
+ string(CONCAT id_Import_props [[<Import Project="$(VCTargetsPath)\BuildCustomizations\]] "${cuda_tools}" [[.props" />]])
+ string(CONCAT id_Import_targets [[<Import Project="$(VCTargetsPath)\BuildCustomizations\]] "${cuda_tools}" [[.targets" />]])
+ if(CMAKE_VS_PLATFORM_NAME STREQUAL x64)
+ set(id_ItemDefinitionGroup_entry "<CudaCompile><TargetMachinePlatform>64</TargetMachinePlatform></CudaCompile>")
+ endif()
+ set(id_Link_AdditionalDependencies "<AdditionalDependencies>cudart.lib</AdditionalDependencies>")
+ endif()
configure_file(${CMAKE_ROOT}/Modules/CompilerId/VS-${v}.${ext}.in
${id_dir}/CompilerId${lang}.${ext} @ONLY)
if(CMAKE_VS_MSBUILD_COMMAND AND NOT lang STREQUAL "Fortran")
diff --git a/Modules/CMakeDetermineFortranCompiler.cmake b/Modules/CMakeDetermineFortranCompiler.cmake
index 484fa66..9e9770a 100644
--- a/Modules/CMakeDetermineFortranCompiler.cmake
+++ b/Modules/CMakeDetermineFortranCompiler.cmake
@@ -255,6 +255,9 @@ if (CMAKE_CROSSCOMPILING AND NOT _CMAKE_TOOLCHAIN_PREFIX)
endif ()
include(CMakeFindBinUtils)
+set(_CMAKE_PROCESSING_LANGUAGE "Fortran")
+include(Compiler/${CMAKE_Fortran_COMPILER_ID}-FindBinUtils OPTIONAL)
+unset(_CMAKE_PROCESSING_LANGUAGE)
if(MSVC_Fortran_ARCHITECTURE_ID)
set(SET_MSVC_Fortran_ARCHITECTURE_ID
diff --git a/Modules/CMakeFortranCompiler.cmake.in b/Modules/CMakeFortranCompiler.cmake.in
index 69800d7..c49621b 100644
--- a/Modules/CMakeFortranCompiler.cmake.in
+++ b/Modules/CMakeFortranCompiler.cmake.in
@@ -8,7 +8,9 @@ set(CMAKE_Fortran_SIMULATE_ID "@CMAKE_Fortran_SIMULATE_ID@")
set(CMAKE_Fortran_SIMULATE_VERSION "@CMAKE_Fortran_SIMULATE_VERSION@")
@SET_MSVC_Fortran_ARCHITECTURE_ID@
set(CMAKE_AR "@CMAKE_AR@")
+set(CMAKE_GCC_AR "@CMAKE_GCC_AR@")
set(CMAKE_RANLIB "@CMAKE_RANLIB@")
+set(CMAKE_GCC_RANLIB "@CMAKE_GCC_RANLIB@")
set(CMAKE_COMPILER_IS_GNUG77 @CMAKE_COMPILER_IS_GNUG77@)
set(CMAKE_Fortran_COMPILER_LOADED 1)
set(CMAKE_Fortran_COMPILER_WORKS @CMAKE_Fortran_COMPILER_WORKS@)
diff --git a/Modules/CPackNSIS.cmake b/Modules/CPackNSIS.cmake
index 18d1871..37fedf3 100644
--- a/Modules/CPackNSIS.cmake
+++ b/Modules/CPackNSIS.cmake
@@ -133,6 +133,10 @@
# "doc/cmake-@CMake_VERSION_MAJOR@.@CMake_VERSION_MINOR@/cmake.html"
# "CMake Help" "https://cmake.org" "CMake Web Site")
#
+# .. variable:: CPACK_NSIS_SIGN_UNINSTALLER
+#
+# Specify a command to use for signing the uninstaller. The command will
+# be invoked a path to the uninstaller as its only argument.
#FIXME we should put NSIS specific code here
#FIXME but I'm not doing it because I'm not able to test it...
diff --git a/Modules/CheckLanguage.cmake b/Modules/CheckLanguage.cmake
index 6b4a9e4..1ea91d2 100644
--- a/Modules/CheckLanguage.cmake
+++ b/Modules/CheckLanguage.cmake
@@ -46,6 +46,8 @@ file(WRITE \"\${CMAKE_CURRENT_BINARY_DIR}/result.cmake\"
execute_process(
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/Check${lang}
COMMAND ${CMAKE_COMMAND} . -G ${CMAKE_GENERATOR}
+ -A "${CMAKE_GENERATOR_PLATFORM}"
+ -T "${CMAKE_GENERATOR_TOOLSET}"
OUTPUT_VARIABLE output
ERROR_VARIABLE output
RESULT_VARIABLE result
diff --git a/Modules/Compiler/GNU-FindBinUtils.cmake b/Modules/Compiler/GNU-FindBinUtils.cmake
new file mode 100644
index 0000000..466d4cf
--- /dev/null
+++ b/Modules/Compiler/GNU-FindBinUtils.cmake
@@ -0,0 +1,25 @@
+if(NOT DEFINED _CMAKE_PROCESSING_LANGUAGE OR _CMAKE_PROCESSING_LANGUAGE STREQUAL "")
+ message(FATAL_ERROR "Internal error: _CMAKE_PROCESSING_LANGUAGE is not set")
+endif()
+
+string(REGEX MATCH "^([0-9]+\\.[0-9]+)" __version_x_y
+ "${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_VERSION}")
+
+# Try to find tools in the same directory as GCC itself
+get_filename_component(__gcc_hints "${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER}" DIRECTORY)
+
+# http://manpages.ubuntu.com/manpages/wily/en/man1/gcc-ar.1.html
+find_program(CMAKE_GCC_AR NAMES
+ "${_CMAKE_TOOLCHAIN_PREFIX}gcc-ar"
+ "${_CMAKE_TOOLCHAIN_PREFIX}gcc-ar-${__version_x_y}"
+ HINTS ${__gcc_hints}
+ DOC "A wrapper around 'ar' adding the appropriate '--plugin' option for the GCC compiler"
+)
+
+# http://manpages.ubuntu.com/manpages/wily/en/man1/gcc-ranlib.1.html
+find_program(CMAKE_GCC_RANLIB NAMES
+ "${_CMAKE_TOOLCHAIN_PREFIX}gcc-ranlib"
+ "${_CMAKE_TOOLCHAIN_PREFIX}gcc-ranlib-${__version_x_y}"
+ HINTS ${__gcc_hints}
+ DOC "A wrapper around 'ranlib' adding the appropriate '--plugin' option for the GCC compiler"
+)
diff --git a/Modules/CompilerId/VS-10.vcxproj.in b/Modules/CompilerId/VS-10.vcxproj.in
index 50be9cb..6b9b361 100644
--- a/Modules/CompilerId/VS-10.vcxproj.in
+++ b/Modules/CompilerId/VS-10.vcxproj.in
@@ -25,6 +25,9 @@
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ @id_Import_props@
+ </ImportGroup>
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|@id_platform@'">.\</OutDir>
@@ -44,16 +47,21 @@
<DebugInformationFormat>
</DebugInformationFormat>
</ClCompile>
+ @id_ItemDefinitionGroup_entry@
<Link>
<GenerateDebugInformation>false</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
+ @id_Link_AdditionalDependencies@
</Link>
<PostBuildEvent>
- <Command>for %%i in (@id_cl@) do %40echo CMAKE_@id_lang@_COMPILER=%%~$PATH:i</Command>
+ <Command>@id_PostBuildEvent_Command@</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
- <ClCompile Include="@id_src@" />
+ <@id_compile@ Include="@id_src@" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ @id_Import_targets@
+ </ImportGroup>
</Project>
diff --git a/Modules/FindGit.cmake b/Modules/FindGit.cmake
index b830c08..fae31eb 100644
--- a/Modules/FindGit.cmake
+++ b/Modules/FindGit.cmake
@@ -43,12 +43,26 @@ if(CMAKE_HOST_WIN32)
endif()
endif()
+# First search the PATH and specific locations.
find_program(GIT_EXECUTABLE
NAMES ${git_names}
PATHS ${github_path} ${_git_sourcetree_path}
- PATH_SUFFIXES Git/cmd Git/bin
DOC "Git command line client"
)
+
+if(CMAKE_HOST_WIN32)
+ # Now look for installations in Git/ directories under typical installation
+ # prefixes on Windows. Exclude PATH from this search because VS 2017's
+ # command prompt happens to have a PATH entry with a Git/ subdirectory
+ # containing a minimal git not meant for general use.
+ find_program(GIT_EXECUTABLE
+ NAMES ${git_names}
+ PATH_SUFFIXES Git/cmd Git/bin
+ NO_SYSTEM_ENVIRONMENT_PATH
+ DOC "Git command line client"
+ )
+endif()
+
mark_as_advanced(GIT_EXECUTABLE)
unset(git_names)
diff --git a/Modules/FindHDF5.cmake b/Modules/FindHDF5.cmake
index 927ec64..4884174 100644
--- a/Modules/FindHDF5.cmake
+++ b/Modules/FindHDF5.cmake
@@ -69,6 +69,9 @@
# HDF5_C_DEFINITIONS -- Required compiler definitions for HDF5 C bindings
# HDF5_CXX_DEFINITIONS -- Required compiler definitions for HDF5 C++ bindings
# HDF5_Fortran_DEFINITIONS -- Required compiler definitions for HDF5 Fortran bindings
+# HDF5_C_INCLUDE_DIRS -- Required include directories for HDF5 C bindings
+# HDF5_CXX_INCLUDE_DIRS -- Required include directories for HDF5 C++ bindings
+# HDF5_Fortran_INCLUDE_DIRS -- Required include directories for HDF5 Fortran bindings
# HDF5_C_LIBRARIES - Required libraries for the HDF5 C bindings
# HDF5_CXX_LIBRARIES - Required libraries for the HDF5 C++ bindings
# HDF5_Fortran_LIBRARIES - Required libraries for the HDF5 Fortran bindings
@@ -358,7 +361,7 @@ macro( _HDF5_parse_compile_line
list(APPEND ${include_paths} "${CMAKE_MATCH_1}")
elseif("${arg}" MATCHES "^-D(.*)$")
# compile definition
- list(APPEND ${definitions} "${CMAKE_MATCH_1}")
+ list(APPEND ${definitions} "-D${CMAKE_MATCH_1}")
elseif("${arg}" MATCHES "^-L(.*)$")
# library search path
list(APPEND ${library_paths} "${CMAKE_MATCH_1}")
@@ -696,6 +699,8 @@ if( NOT HDF5_FOUND )
${_HDF5_SEARCH_OPTS}
)
mark_as_advanced(HDF5_${__lang}_INCLUDE_DIR)
+ # set the _DIRS variable as this is what the user will normally use
+ set(HDF5_${__lang}_INCLUDE_DIRS ${HDF5_${__lang}_INCLUDE_DIR})
list(APPEND HDF5_INCLUDE_DIRS ${HDF5_${__lang}_INCLUDE_DIR})
# find the HDF5 libraries
diff --git a/Modules/FindJNI.cmake b/Modules/FindJNI.cmake
index 39e504f..cebba10 100644
--- a/Modules/FindJNI.cmake
+++ b/Modules/FindJNI.cmake
@@ -145,6 +145,9 @@ JAVA_APPEND_LIBRARY_DIRECTORIES(JAVA_AWT_LIBRARY_DIRECTORIES
/usr/lib/jvm/default-java/jre/lib/{libarch}
/usr/lib/jvm/default-java/jre/lib
/usr/lib/jvm/default-java/lib
+ # Arch Linux specific paths for default JVM
+ /usr/lib/jvm/default/jre/lib/{libarch}
+ /usr/lib/jvm/default/lib/{libarch}
# Ubuntu specific paths for default JVM
/usr/lib/jvm/java-8-openjdk-{libarch}/jre/lib/{libarch} # Ubuntu 15.10
/usr/lib/jvm/java-7-openjdk-{libarch}/jre/lib/{libarch} # Ubuntu 15.10
@@ -200,6 +203,8 @@ JAVA_APPEND_LIBRARY_DIRECTORIES(JAVA_AWT_INCLUDE_DIRECTORIES
/opt/sun-jdk-1.5.0.04/include
# Debian specific path for default JVM
/usr/lib/jvm/default-java/include
+ # Arch specific path for default JVM
+ /usr/lib/jvm/default/include
# OpenBSD specific path for default JVM
/usr/local/jdk-1.7.0/include
/usr/local/jdk-1.6.0/include
diff --git a/Modules/FindVulkan.cmake b/Modules/FindVulkan.cmake
index 820e0eb..1f4c8ad 100644
--- a/Modules/FindVulkan.cmake
+++ b/Modules/FindVulkan.cmake
@@ -39,12 +39,17 @@ if(WIN32)
find_library(Vulkan_LIBRARY
NAMES vulkan-1
PATHS
- "$ENV{VULKAN_SDK}/Bin")
+ "$ENV{VULKAN_SDK}/Lib"
+ "$ENV{VULKAN_SDK}/Bin"
+ )
elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)
find_library(Vulkan_LIBRARY
NAMES vulkan-1
PATHS
- "$ENV{VULKAN_SDK}/Bin32")
+ "$ENV{VULKAN_SDK}/Lib32"
+ "$ENV{VULKAN_SDK}/Bin32"
+ NO_SYSTEM_ENVIRONMENT_PATH
+ )
endif()
else()
find_path(Vulkan_INCLUDE_DIR
diff --git a/Modules/NSIS.template.in b/Modules/NSIS.template.in
index 9001888..ffa6277 100644
--- a/Modules/NSIS.template.in
+++ b/Modules/NSIS.template.in
@@ -29,6 +29,33 @@
;--------------------------------
;General
+!ifdef INNER
+ OutFile "$%TEMP%\tempinstaller.exe"
+ SetCompress off ; for speed
+!else
+ ; Call makensis again, defining INNER. This writes an installer for us which, when
+ ; it is invoked, will just write the uninstaller to some location, and then exit.
+ ; Be sure to substitute the name of this script here.
+
+ !system "$\"${NSISDIR}\makensis$\" /DINNER $\"@CPACK_TEMPORARY_DIRECTORY@/../project.nsi$\"" = 0
+
+ ; So now run that installer we just created as %TEMP%\tempinstaller.exe. Since it
+ ; calls quit the return value isn't zero.
+
+ !system "$%TEMP%\tempinstaller.exe" = 2
+
+ ; That will have written an uninstaller binary for us. Now we sign it with your
+ ; favourite code signing tool.
+
+ !tempfile INCEXIST
+ !system 'if exist "@CPACK_NSIS_SIGN_UNINSTALLER@" echo !define HAVE_SIGN_UNINST > "${INCEXIST}"'
+ !include "${INCEXIST}"
+ !delfile "${INCEXIST}"
+ !ifdef HAVE_SIGN_UNINST
+ !system '"@CPACK_NSIS_SIGN_UNINSTALLER@" "$%TEMP%\Uninstall.exe"' = 0
+ !endif
+
+ ; Good. Now we can carry on writing the real installer.
;Name and file
Name "@CPACK_NSIS_PACKAGE_NAME@"
@@ -36,6 +63,7 @@
;Set compression
SetCompressor @CPACK_NSIS_COMPRESSOR@
+!endif
;Require administrator access
RequestExecutionLevel admin
@@ -559,8 +587,10 @@ FunctionEnd
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
+!ifdef INNER
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES
+!endif
;--------------------------------
;Languages
@@ -642,7 +672,10 @@ Section "-Core installation"
WriteRegStr SHCTX "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "" $INSTDIR
;Create uninstaller
- WriteUninstaller "$INSTDIR\Uninstall.exe"
+!ifndef INNER
+ ; this packages the signed uninstaller
+ File "$%TEMP%\Uninstall.exe"
+!endif
Push "DisplayName"
Push "@CPACK_NSIS_DISPLAY_NAME@"
Call ConditionalAddToRegisty
@@ -801,6 +834,7 @@ FunctionEnd
;--------------------------------
;Uninstaller Section
+!ifdef INNER
Section "Uninstall"
ReadRegStr $START_MENU SHCTX \
"Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "StartMenu"
@@ -886,6 +920,7 @@ Section "Uninstall"
Call un.RemoveFromPath
doNotRemoveFromPath:
SectionEnd
+!endif
;--------------------------------
; determine admin versus local install
@@ -898,6 +933,14 @@ SectionEnd
; "Program Files" for AllUsers, "My Documents" for JustMe...
Function .onInit
+!ifdef INNER
+ ; If INNER is defined, then we aren't supposed to do anything except write out
+ ; the installer. This is better than processing a command line option as it means
+ ; this entire code path is not present in the final (real) installer.
+
+ WriteUninstaller "$%TEMP%\Uninstall.exe"
+ Quit ; just bail out quickly when running the "inner" installer
+!endif
StrCmp "@CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL@" "ON" 0 inst
ReadRegStr $0 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "UninstallString"
diff --git a/Modules/WriteCompilerDetectionHeader.cmake b/Modules/WriteCompilerDetectionHeader.cmake
index 0b16aa4..362099e 100644
--- a/Modules/WriteCompilerDetectionHeader.cmake
+++ b/Modules/WriteCompilerDetectionHeader.cmake
@@ -503,10 +503,19 @@ function(write_compiler_detection_header
if (feature STREQUAL cxx_static_assert)
set(def_value "${prefix_arg}_STATIC_ASSERT(X)")
set(def_value_msg "${prefix_arg}_STATIC_ASSERT_MSG(X, MSG)")
- set(static_assert_struct "template<bool> struct ${prefix_arg}StaticAssert;\ntemplate<> struct ${prefix_arg}StaticAssert<true>{};\n")
- set(def_standard "# define ${def_value} static_assert(X, #X)\n# define ${def_value_msg} static_assert(X, MSG)")
- set(def_alternative "${static_assert_struct}# define ${def_value} sizeof(${prefix_arg}StaticAssert<X>)\n# define ${def_value_msg} sizeof(${prefix_arg}StaticAssert<X>)")
- string(APPEND file_content "# if defined(${def_name}) && ${def_name}\n${def_standard}\n# else\n${def_alternative}\n# endif\n\n")
+ set(def_fallback "enum { ${prefix_arg}_STATIC_ASSERT_JOIN(${prefix_arg}StaticAssertEnum, __LINE__) = sizeof(${prefix_arg}StaticAssert<X>) }")
+ string(APPEND file_content "# if defined(${def_name}) && ${def_name}
+# define ${def_value} static_assert(X, #X)
+# define ${def_value_msg} static_assert(X, MSG)
+# else
+# define ${prefix_arg}_STATIC_ASSERT_JOIN(X, Y) ${prefix_arg}_STATIC_ASSERT_JOIN_IMPL(X, Y)
+# define ${prefix_arg}_STATIC_ASSERT_JOIN_IMPL(X, Y) X##Y
+template<bool> struct ${prefix_arg}StaticAssert;
+template<> struct ${prefix_arg}StaticAssert<true>{};
+# define ${def_value} ${def_fallback}
+# define ${def_value_msg} ${def_fallback}
+# endif
+\n")
endif()
if (feature STREQUAL cxx_alignas)
set(def_value "${prefix_arg}_ALIGNAS(X)")
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 76b98fc..59920f8 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -344,6 +344,8 @@ set(SRCS
cmPropertyDefinitionMap.h
cmPropertyMap.cxx
cmPropertyMap.h
+ cmQtAutoGeneratorCommon.cxx
+ cmQtAutoGeneratorCommon.h
cmQtAutoGeneratorInitializer.cxx
cmQtAutoGeneratorInitializer.h
cmQtAutoGenerators.cxx
@@ -381,6 +383,8 @@ set(SRCS
cmVariableWatch.h
cmVersion.cxx
cmVersion.h
+ cmWorkingDirectory.cxx
+ cmWorkingDirectory.h
cmXMLParser.cxx
cmXMLParser.h
cmXMLSafe.cxx
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 62324e8..ffc0041 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 20170302)
+set(CMake_VERSION_PATCH 20170313)
#set(CMake_VERSION_RC 1)
diff --git a/Source/CPack/OSXScriptLauncher.cxx b/Source/CPack/OSXScriptLauncher.cxx
index b159e64..aeabde9 100644
--- a/Source/CPack/OSXScriptLauncher.cxx
+++ b/Source/CPack/OSXScriptLauncher.cxx
@@ -20,7 +20,6 @@
int main(int argc, char* argv[])
{
// if ( cmsys::SystemTools::FileExists(
- std::string cwd = cmsys::SystemTools::GetCurrentWorkingDirectory();
cmsys::ofstream ofs("/tmp/output.txt");
CFStringRef fileName;
diff --git a/Source/CPack/cmCPackArchiveGenerator.cxx b/Source/CPack/cmCPackArchiveGenerator.cxx
index 9d9cd66..cc01b0c 100644
--- a/Source/CPack/cmCPackArchiveGenerator.cxx
+++ b/Source/CPack/cmCPackArchiveGenerator.cxx
@@ -7,6 +7,7 @@
#include "cmCPackLog.h"
#include "cmGeneratedFileStream.h"
#include "cmSystemTools.h"
+#include "cmWorkingDirectory.h"
#include <map>
#include <ostream>
@@ -37,9 +38,8 @@ int cmCPackArchiveGenerator::addOneComponentToArchive(
// Add the files of this component to the archive
std::string localToplevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY"));
localToplevel += "/" + component->Name;
- std::string dir = cmSystemTools::GetCurrentWorkingDirectory();
// Change to local toplevel
- cmSystemTools::ChangeDirectory(localToplevel);
+ cmWorkingDirectory workdir(localToplevel);
std::string filePrefix;
if (this->IsOn("CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY")) {
filePrefix = this->GetOption("CPACK_PACKAGE_FILE_NAME");
@@ -64,8 +64,6 @@ int cmCPackArchiveGenerator::addOneComponentToArchive(
return 0;
}
}
- // Go back to previous dir
- cmSystemTools::ChangeDirectory(dir);
return 1;
}
@@ -227,8 +225,7 @@ int cmCPackArchiveGenerator::PackageFiles()
// CASE 3 : NON COMPONENT package.
DECLARE_AND_OPEN_ARCHIVE(packageFileNames[0], archive);
std::vector<std::string>::const_iterator fileIt;
- std::string dir = cmSystemTools::GetCurrentWorkingDirectory();
- cmSystemTools::ChangeDirectory(toplevel);
+ cmWorkingDirectory workdir(toplevel);
for (fileIt = files.begin(); fileIt != files.end(); ++fileIt) {
// Get the relative path to the file
std::string rp =
@@ -241,7 +238,6 @@ int cmCPackArchiveGenerator::PackageFiles()
return 0;
}
}
- cmSystemTools::ChangeDirectory(dir);
// The destructor of cmArchiveWrite will close and finish the write
return 1;
}
diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx
index e1a4a2a..f6ea8cf 100644
--- a/Source/CPack/cmCPackGenerator.cxx
+++ b/Source/CPack/cmCPackGenerator.cxx
@@ -16,6 +16,7 @@
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmStateSnapshot.h"
+#include "cmWorkingDirectory.h"
#include "cmXMLSafe.h"
#include "cm_auto_ptr.hxx"
#include "cmake.h"
@@ -383,7 +384,7 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories(
goToDir += "/" + subdir;
cmCPackLogger(cmCPackLog::LOG_DEBUG, "Change dir to: " << goToDir
<< std::endl);
- cmSystemTools::ChangeDirectory(goToDir);
+ cmWorkingDirectory workdir(goToDir);
for (symlinkedIt = symlinkedFiles.begin();
symlinkedIt != symlinkedFiles.end(); ++symlinkedIt) {
cmCPackLogger(cmCPackLog::LOG_DEBUG, "Will create a symlink: "
@@ -408,7 +409,6 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories(
}
cmCPackLogger(cmCPackLog::LOG_DEBUG, "Going back to: " << curDir
<< std::endl);
- cmSystemTools::ChangeDirectory(curDir);
}
}
}
diff --git a/Source/CTest/cmCTestBuildAndTestHandler.cxx b/Source/CTest/cmCTestBuildAndTestHandler.cxx
index 6780a0e..6f81429 100644
--- a/Source/CTest/cmCTestBuildAndTestHandler.cxx
+++ b/Source/CTest/cmCTestBuildAndTestHandler.cxx
@@ -6,6 +6,7 @@
#include "cmCTestTestHandler.h"
#include "cmGlobalGenerator.h"
#include "cmSystemTools.h"
+#include "cmWorkingDirectory.h"
#include "cmake.h"
#include <cmsys/Process.h>
@@ -42,7 +43,7 @@ int cmCTestBuildAndTestHandler::ProcessHandler()
int cmCTestBuildAndTestHandler::RunCMake(std::string* outstring,
std::ostringstream& out,
std::string& cmakeOutString,
- std::string& cwd, cmake* cm)
+ cmake* cm)
{
unsigned int k;
std::vector<std::string> args;
@@ -85,8 +86,6 @@ int cmCTestBuildAndTestHandler::RunCMake(std::string* outstring,
if (cm->Run(args) != 0) {
out << "Error: cmake execution failed\n";
out << cmakeOutString << "\n";
- // return to the original directory
- cmSystemTools::ChangeDirectory(cwd);
if (outstring) {
*outstring = out.str();
} else {
@@ -99,8 +98,6 @@ int cmCTestBuildAndTestHandler::RunCMake(std::string* outstring,
if (cm->Run(args) != 0) {
out << "Error: cmake execution failed\n";
out << cmakeOutString << "\n";
- // return to the original directory
- cmSystemTools::ChangeDirectory(cwd);
if (outstring) {
*outstring = out.str();
} else {
@@ -199,13 +196,12 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring)
double clock_start = cmSystemTools::GetTime();
// make sure the binary dir is there
- std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
out << "Internal cmake changing into directory: " << this->BinaryDir
<< std::endl;
if (!cmSystemTools::FileIsDirectory(this->BinaryDir)) {
cmSystemTools::MakeDirectory(this->BinaryDir.c_str());
}
- cmSystemTools::ChangeDirectory(this->BinaryDir);
+ cmWorkingDirectory workdir(this->BinaryDir);
if (this->BuildNoCMake) {
// Make the generator available for the Build call below.
@@ -217,7 +213,7 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring)
cm.LoadCache(this->BinaryDir);
} else {
// do the cmake step, no timeout here since it is not a sub process
- if (this->RunCMake(outstring, out, cmakeOutString, cwd, &cm)) {
+ if (this->RunCMake(outstring, out, cmakeOutString, &cm)) {
return 1;
}
}
@@ -304,8 +300,6 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring)
} else {
cmCTestLog(this->CTest, ERROR_MESSAGE, out.str());
}
- // return to the original directory
- cmSystemTools::ChangeDirectory(cwd);
return 1;
}
diff --git a/Source/CTest/cmCTestBuildAndTestHandler.h b/Source/CTest/cmCTestBuildAndTestHandler.h
index 5885738..af082a3 100644
--- a/Source/CTest/cmCTestBuildAndTestHandler.h
+++ b/Source/CTest/cmCTestBuildAndTestHandler.h
@@ -46,7 +46,7 @@ protected:
///! Run CMake and build a test and then run it as a single test.
int RunCMakeAndTest(std::string* output);
int RunCMake(std::string* outstring, std::ostringstream& out,
- std::string& cmakeOutString, std::string& cwd, cmake* cm);
+ std::string& cmakeOutString, cmake* cm);
std::string Output;
diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx
index 989c096..120c5d9 100644
--- a/Source/CTest/cmCTestCoverageHandler.cxx
+++ b/Source/CTest/cmCTestCoverageHandler.cxx
@@ -12,6 +12,7 @@
#include "cmParseJacocoCoverage.h"
#include "cmParsePHPCoverage.h"
#include "cmSystemTools.h"
+#include "cmWorkingDirectory.h"
#include "cmXMLWriter.h"
#include "cmake.h"
@@ -969,9 +970,8 @@ int cmCTestCoverageHandler::HandleGCovCoverage(
std::string testingDir = this->CTest->GetBinaryDir() + "/Testing";
std::string tempDir = testingDir + "/CoverageInfo";
- std::string currentDirectory = cmSystemTools::GetCurrentWorkingDirectory();
cmSystemTools::MakeDirectory(tempDir.c_str());
- cmSystemTools::ChangeDirectory(tempDir);
+ cmWorkingDirectory workdir(tempDir);
int gcovStyle = 0;
@@ -1294,7 +1294,6 @@ int cmCTestCoverageHandler::HandleGCovCoverage(
}
}
- cmSystemTools::ChangeDirectory(currentDirectory);
return file_count;
}
@@ -1340,7 +1339,6 @@ int cmCTestCoverageHandler::HandleLCovCoverage(
return 0;
}
std::string testingDir = this->CTest->GetBinaryDir();
- std::string currentDirectory = cmSystemTools::GetCurrentWorkingDirectory();
std::set<std::string> missingFiles;
@@ -1362,7 +1360,7 @@ int cmCTestCoverageHandler::HandleLCovCoverage(
cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "." << std::flush,
this->Quiet);
std::string fileDir = cmSystemTools::GetFilenamePath(*it);
- cmSystemTools::ChangeDirectory(fileDir);
+ cmWorkingDirectory workdir(fileDir);
std::string command = "\"" + lcovCommand + "\" " + lcovExtraFlags + " ";
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
@@ -1552,7 +1550,6 @@ int cmCTestCoverageHandler::HandleLCovCoverage(
}
}
- cmSystemTools::ChangeDirectory(currentDirectory);
return file_count;
}
@@ -1591,13 +1588,8 @@ bool cmCTestCoverageHandler::FindLCovFiles(std::vector<std::string>& files)
gl.RecurseOff(); // No need of recurse if -prof_dir${BUILD_DIR} flag is
// used while compiling.
gl.RecurseThroughSymlinksOff();
- std::string prevBinaryDir;
std::string buildDir = this->CTest->GetCTestConfiguration("BuildDirectory");
- if (cmSystemTools::ChangeDirectory(buildDir)) {
- cmCTestLog(this->CTest, ERROR_MESSAGE, "Error changing directory to "
- << buildDir << std::endl);
- return false;
- }
+ cmWorkingDirectory workdir(buildDir);
// Run profmerge to merge all *.dyn files into dpi files
if (!cmSystemTools::RunSingleCommand("profmerge")) {
@@ -1605,11 +1597,9 @@ bool cmCTestCoverageHandler::FindLCovFiles(std::vector<std::string>& files)
return false;
}
- prevBinaryDir = cmSystemTools::GetCurrentWorkingDirectory();
-
// DPI file should appear in build directory
std::string daGlob;
- daGlob = prevBinaryDir;
+ daGlob = buildDir;
daGlob += "/*.dpi";
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
" looking for dpi files in: " << daGlob << std::endl,
@@ -1646,11 +1636,7 @@ int cmCTestCoverageHandler::HandleTracePyCoverage(
std::string testingDir = this->CTest->GetBinaryDir() + "/Testing";
std::string tempDir = testingDir + "/CoverageInfo";
- std::string currentDirectory = cmSystemTools::GetCurrentWorkingDirectory();
cmSystemTools::MakeDirectory(tempDir.c_str());
- cmSystemTools::ChangeDirectory(tempDir);
-
- cmSystemTools::ChangeDirectory(currentDirectory);
std::vector<std::string>::iterator fileIt;
int file_count = 0;
@@ -1737,7 +1723,6 @@ int cmCTestCoverageHandler::HandleTracePyCoverage(
}
++file_count;
}
- cmSystemTools::ChangeDirectory(currentDirectory);
return file_count;
}
diff --git a/Source/CTest/cmCTestHandlerCommand.cxx b/Source/CTest/cmCTestHandlerCommand.cxx
index 2a67d47..c99e450 100644
--- a/Source/CTest/cmCTestHandlerCommand.cxx
+++ b/Source/CTest/cmCTestHandlerCommand.cxx
@@ -6,6 +6,7 @@
#include "cmCTestGenericHandler.h"
#include "cmMakefile.h"
#include "cmSystemTools.h"
+#include "cmWorkingDirectory.h"
#include "cmake.h"
#include <sstream>
@@ -216,8 +217,7 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args,
handler->SetSubmitIndex(atoi(this->Values[ct_SUBMIT_INDEX]));
}
}
- std::string current_dir = cmSystemTools::GetCurrentWorkingDirectory();
- cmSystemTools::ChangeDirectory(
+ cmWorkingDirectory workdir(
this->CTest->GetCTestConfiguration("BuildDirectory"));
int res = handler->ProcessHandler();
if (this->Values[ct_RETURN_VALUE] && *this->Values[ct_RETURN_VALUE]) {
@@ -243,7 +243,6 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args,
this->Makefile->AddDefinition(this->Values[ct_CAPTURE_CMAKE_ERROR],
returnString);
}
- cmSystemTools::ChangeDirectory(current_dir);
return true;
}
diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx
index c1724ab..ff465ab 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.cxx
+++ b/Source/CTest/cmCTestMultiProcessHandler.cxx
@@ -7,6 +7,7 @@
#include "cmCTestScriptHandler.h"
#include "cmCTestTestHandler.h"
#include "cmSystemTools.h"
+#include "cmWorkingDirectory.h"
#include <algorithm>
#include <cmsys/FStream.hxx>
@@ -138,8 +139,7 @@ void cmCTestMultiProcessHandler::StartTestProcess(int test)
}
}
- std::string current_dir = cmSystemTools::GetCurrentWorkingDirectory();
- cmSystemTools::ChangeDirectory(this->Properties[test]->Directory);
+ cmWorkingDirectory workdir(this->Properties[test]->Directory);
// Lock the resources we'll be using
this->LockResources(test);
@@ -166,7 +166,6 @@ void cmCTestMultiProcessHandler::StartTestProcess(int test)
this->Failed->push_back(this->Properties[test]->Name);
delete testRun;
}
- cmSystemTools::ChangeDirectory(current_dir);
}
void cmCTestMultiProcessHandler::LockResources(int index)
@@ -683,9 +682,7 @@ void cmCTestMultiProcessHandler::PrintTestList()
count++;
cmCTestTestHandler::cmCTestTestProperties& p = *it->second;
- // push working dir
- std::string current_dir = cmSystemTools::GetCurrentWorkingDirectory();
- cmSystemTools::ChangeDirectory(p.Directory);
+ cmWorkingDirectory workdir(p.Directory);
cmCTestRunTest testRun(this->TestHandler);
testRun.SetIndex(p.Index);
@@ -724,8 +721,6 @@ void cmCTestMultiProcessHandler::PrintTestList()
cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " ", this->Quiet);
cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, p.Name << std::endl,
this->Quiet);
- // pop working dir
- cmSystemTools::ChangeDirectory(current_dir);
}
cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, std::endl
diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx
index ac1644f..f148f30 100644
--- a/Source/CTest/cmCTestRunTest.cxx
+++ b/Source/CTest/cmCTestRunTest.cxx
@@ -7,6 +7,7 @@
#include "cmCTestTestHandler.h"
#include "cmProcess.h"
#include "cmSystemTools.h"
+#include "cmWorkingDirectory.h"
#include <cmConfigure.h>
#include <cm_curl.h>
@@ -270,14 +271,11 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started)
*this->TestHandler->LogFile << "Test time = " << buf << std::endl;
}
- // Set the working directory to the tests directory
- std::string oldpath = cmSystemTools::GetCurrentWorkingDirectory();
- cmSystemTools::ChangeDirectory(this->TestProperties->Directory);
-
- this->DartProcessing();
-
- // restore working directory
- cmSystemTools::ChangeDirectory(oldpath);
+ // Set the working directory to the tests directory to process Dart files.
+ {
+ cmWorkingDirectory workdir(this->TestProperties->Directory);
+ this->DartProcessing();
+ }
// if this is doing MemCheck then all the output needs to be put into
// Output since that is what is parsed by cmCTestMemCheckHandler
@@ -356,11 +354,8 @@ bool cmCTestRunTest::StartAgain()
}
this->RunAgain = false; // reset
// change to tests directory
- std::string current_dir = cmSystemTools::GetCurrentWorkingDirectory();
- cmSystemTools::ChangeDirectory(this->TestProperties->Directory);
+ cmWorkingDirectory workdir(this->TestProperties->Directory);
this->StartTest(this->TotalNumberOfTests);
- // change back
- cmSystemTools::ChangeDirectory(current_dir);
return true;
}
diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx
index 5e5119d..cc399b0 100644
--- a/Source/CTest/cmCTestSubmitHandler.cxx
+++ b/Source/CTest/cmCTestSubmitHandler.cxx
@@ -19,6 +19,7 @@
#include "cmState.h"
#include "cmSystemTools.h"
#include "cmThirdParty.h"
+#include "cmWorkingDirectory.h"
#include "cmXMLParser.h"
#include "cmake.h"
@@ -1519,7 +1520,6 @@ int cmCTestSubmitHandler::ProcessHandler()
#endif
} else if (dropMethod == "scp") {
std::string url;
- std::string oldWorkingDirectory;
if (!this->CTest->GetCTestConfiguration("DropSiteUser").empty()) {
url += this->CTest->GetCTestConfiguration("DropSiteUser") + "@";
}
@@ -1528,19 +1528,16 @@ int cmCTestSubmitHandler::ProcessHandler()
// change to the build directory so that we can uses a relative path
// on windows since scp dosn't support "c:" a drive in the path
- oldWorkingDirectory = cmSystemTools::GetCurrentWorkingDirectory();
- cmSystemTools::ChangeDirectory(buildDirectory);
+ cmWorkingDirectory workdir(buildDirectory);
if (!this->SubmitUsingSCP(this->CTest->GetCTestConfiguration("ScpCommand"),
"Testing/" + this->CTest->GetCurrentTag(), files,
prefix, url)) {
- cmSystemTools::ChangeDirectory(oldWorkingDirectory);
cmCTestLog(this->CTest, ERROR_MESSAGE,
" Problems when submitting via SCP" << std::endl);
ofs << " Problems when submitting via SCP" << std::endl;
return -1;
}
- cmSystemTools::ChangeDirectory(oldWorkingDirectory);
cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
" Submission successful" << std::endl, this->Quiet);
ofs << " Submission successful" << std::endl;
@@ -1550,22 +1547,18 @@ int cmCTestSubmitHandler::ProcessHandler()
// change to the build directory so that we can uses a relative path
// on windows since scp dosn't support "c:" a drive in the path
- std::string oldWorkingDirectory =
- cmSystemTools::GetCurrentWorkingDirectory();
- cmSystemTools::ChangeDirectory(buildDirectory);
+ cmWorkingDirectory workdir(buildDirectory);
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
" Change directory: " << buildDirectory << std::endl,
this->Quiet);
if (!this->SubmitUsingCP("Testing/" + this->CTest->GetCurrentTag(), files,
prefix, location)) {
- cmSystemTools::ChangeDirectory(oldWorkingDirectory);
cmCTestLog(this->CTest, ERROR_MESSAGE,
" Problems when submitting via CP" << std::endl);
ofs << " Problems when submitting via cp" << std::endl;
return -1;
}
- cmSystemTools::ChangeDirectory(oldWorkingDirectory);
cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
" Submission successful" << std::endl, this->Quiet);
ofs << " Submission successful" << std::endl;
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx
index 6175e50..9d22065 100644
--- a/Source/CTest/cmCTestTestHandler.cxx
+++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -27,6 +27,7 @@
#include "cmState.h"
#include "cmStateSnapshot.h"
#include "cmSystemTools.h"
+#include "cmWorkingDirectory.h"
#include "cmXMLWriter.h"
#include "cm_auto_ptr.hxx"
#include "cm_utf8.h"
@@ -86,22 +87,24 @@ bool cmCTestSubdirCommand::InitialPass(std::vector<std::string> const& args,
// No subdirectory? So what...
continue;
}
- cmSystemTools::ChangeDirectory(fname);
- const char* testFilename;
- if (cmSystemTools::FileExists("CTestTestfile.cmake")) {
- // does the CTestTestfile.cmake exist ?
- testFilename = "CTestTestfile.cmake";
- } else if (cmSystemTools::FileExists("DartTestfile.txt")) {
- // does the DartTestfile.txt exist ?
- testFilename = "DartTestfile.txt";
- } else {
- // No CTestTestfile? Who cares...
- continue;
+ bool readit = false;
+ {
+ cmWorkingDirectory workdir(fname);
+ const char* testFilename;
+ if (cmSystemTools::FileExists("CTestTestfile.cmake")) {
+ // does the CTestTestfile.cmake exist ?
+ testFilename = "CTestTestfile.cmake";
+ } else if (cmSystemTools::FileExists("DartTestfile.txt")) {
+ // does the DartTestfile.txt exist ?
+ testFilename = "DartTestfile.txt";
+ } else {
+ // No CTestTestfile? Who cares...
+ continue;
+ }
+ fname += "/";
+ fname += testFilename;
+ readit = this->Makefile->ReadDependentFile(fname.c_str());
}
- fname += "/";
- fname += testFilename;
- bool readit = this->Makefile->ReadDependentFile(fname.c_str());
- cmSystemTools::ChangeDirectory(cwd);
if (!readit) {
std::string m = "Could not find include file: ";
m += fname;
@@ -109,7 +112,6 @@ bool cmCTestSubdirCommand::InitialPass(std::vector<std::string> const& args,
return false;
}
}
- cmSystemTools::ChangeDirectory(cwd);
return true;
}
@@ -149,9 +151,7 @@ bool cmCTestAddSubdirectoryCommand::InitialPass(
return false;
}
- std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
- cmSystemTools::ChangeDirectory(cwd);
- std::string fname = cwd;
+ std::string fname = cmSystemTools::GetCurrentWorkingDirectory();
fname += "/";
fname += args[0];
@@ -159,23 +159,23 @@ bool cmCTestAddSubdirectoryCommand::InitialPass(
// No subdirectory? So what...
return true;
}
- cmSystemTools::ChangeDirectory(fname);
- const char* testFilename;
- if (cmSystemTools::FileExists("CTestTestfile.cmake")) {
- // does the CTestTestfile.cmake exist ?
- testFilename = "CTestTestfile.cmake";
- } else if (cmSystemTools::FileExists("DartTestfile.txt")) {
- // does the DartTestfile.txt exist ?
- testFilename = "DartTestfile.txt";
- } else {
- // No CTestTestfile? Who cares...
- cmSystemTools::ChangeDirectory(cwd);
- return true;
+ bool readit = false;
+ {
+ const char* testFilename;
+ if (cmSystemTools::FileExists("CTestTestfile.cmake")) {
+ // does the CTestTestfile.cmake exist ?
+ testFilename = "CTestTestfile.cmake";
+ } else if (cmSystemTools::FileExists("DartTestfile.txt")) {
+ // does the DartTestfile.txt exist ?
+ testFilename = "DartTestfile.txt";
+ } else {
+ // No CTestTestfile? Who cares...
+ return true;
+ }
+ fname += "/";
+ fname += testFilename;
+ readit = this->Makefile->ReadDependentFile(fname.c_str());
}
- fname += "/";
- fname += testFilename;
- bool readit = this->Makefile->ReadDependentFile(fname.c_str());
- cmSystemTools::ChangeDirectory(cwd);
if (!readit) {
std::string m = "Could not find include file: ";
m += fname;
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index 559275e..e6e50e9 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -1122,7 +1122,6 @@ int cmCTest::RunTest(std::vector<const char*> argv, std::string* output,
if (log) {
*log << "* Run internal CTest" << std::endl;
}
- std::string oldpath = cmSystemTools::GetCurrentWorkingDirectory();
CM_AUTO_PTR<cmSystemTools::SaveRestoreEnvironment> saveEnv;
if (modifyEnv) {
@@ -1137,7 +1136,6 @@ int cmCTest::RunTest(std::vector<const char*> argv, std::string* output,
if (log && output) {
*log << *output;
}
- cmSystemTools::ChangeDirectory(oldpath);
if (output) {
cmCTestLog(this, HANDLER_VERBOSE_OUTPUT,
"Internal cmCTest object used to run test." << std::endl
diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx
index 239582f..fd1ad36 100644
--- a/Source/cmCommonTargetGenerator.cxx
+++ b/Source/cmCommonTargetGenerator.cxx
@@ -26,7 +26,6 @@ cmCommonTargetGenerator::cmCommonTargetGenerator(cmGeneratorTarget* gt)
, GlobalGenerator(static_cast<cmGlobalCommonGenerator*>(
gt->LocalGenerator->GetGlobalGenerator()))
, ConfigName(LocalGenerator->GetConfigName())
- , ModuleDefinitionFile(GeneratorTarget->GetModuleDefinitionFile(ConfigName))
{
}
@@ -63,14 +62,9 @@ void cmCommonTargetGenerator::AddFeatureFlags(std::string& flags,
void cmCommonTargetGenerator::AddModuleDefinitionFlag(
cmLinkLineComputer* linkLineComputer, std::string& flags)
{
- // A module definition file only makes sense on certain target types.
- if (this->GeneratorTarget->GetType() != cmStateEnums::SHARED_LIBRARY &&
- this->GeneratorTarget->GetType() != cmStateEnums::MODULE_LIBRARY &&
- this->GeneratorTarget->GetType() != cmStateEnums::EXECUTABLE) {
- return;
- }
-
- if (!this->ModuleDefinitionFile) {
+ cmGeneratorTarget::ModuleDefinitionInfo const* mdi =
+ this->GeneratorTarget->GetModuleDefinitionInfo(this->GetConfigName());
+ if (!mdi || mdi->DefFile.empty()) {
return;
}
@@ -85,8 +79,7 @@ void cmCommonTargetGenerator::AddModuleDefinitionFlag(
// vs6's "cl -link" pass it to the linker.
std::string flag = defFileFlag;
flag += this->LocalGenerator->ConvertToOutputFormat(
- linkLineComputer->ConvertToLinkReference(
- this->ModuleDefinitionFile->GetFullPath()),
+ linkLineComputer->ConvertToLinkReference(mdi->DefFile),
cmOutputConverter::SHELL);
this->LocalGenerator->AppendFlags(flags, flag);
}
diff --git a/Source/cmCommonTargetGenerator.h b/Source/cmCommonTargetGenerator.h
index d67fefb..8d68123 100644
--- a/Source/cmCommonTargetGenerator.h
+++ b/Source/cmCommonTargetGenerator.h
@@ -44,9 +44,6 @@ protected:
cmGlobalCommonGenerator* GlobalGenerator;
std::string ConfigName;
- // The windows module definition source file (.def), if any.
- cmSourceFile const* ModuleDefinitionFile;
-
void AppendFortranFormatFlags(std::string& flags,
cmSourceFile const& source);
diff --git a/Source/cmDepends.cxx b/Source/cmDepends.cxx
index c189419..b8c76b9 100644
--- a/Source/cmDepends.cxx
+++ b/Source/cmDepends.cxx
@@ -7,6 +7,7 @@
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmSystemTools.h"
+#include "cmWorkingDirectory.h"
#include <cmsys/FStream.hxx>
#include <sstream>
@@ -75,13 +76,7 @@ bool cmDepends::Check(const char* makeFile, const char* internalFile,
std::map<std::string, DependencyVector>& validDeps)
{
// Dependency checks must be done in proper working directory.
- std::string oldcwd = ".";
- if (this->CompileDirectory != ".") {
- // Get the CWD but do not call CollapseFullPath because
- // we only need it to cd back, and the form does not matter
- oldcwd = cmSystemTools::GetCurrentWorkingDirectory(false);
- cmSystemTools::ChangeDirectory(this->CompileDirectory);
- }
+ cmWorkingDirectory workdir(this->CompileDirectory);
// Check whether dependencies must be regenerated.
bool okay = true;
@@ -93,11 +88,6 @@ bool cmDepends::Check(const char* makeFile, const char* internalFile,
okay = false;
}
- // Restore working directory.
- if (oldcwd != ".") {
- cmSystemTools::ChangeDirectory(oldcwd);
- }
-
return okay;
}
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index 91cecb3..957b4cb 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -42,6 +42,10 @@
#include "cmFileLockResult.h"
#endif
+#if defined(CMAKE_USE_ELF_PARSER)
+#include "cmELF.h"
+#endif
+
class cmSystemToolsFileTime;
// Table of permissions flags.
@@ -166,6 +170,9 @@ bool cmFileCommand::InitialPass(std::vector<std::string> const& args,
if (subCommand == "RPATH_REMOVE") {
return this->HandleRPathRemoveCommand(args);
}
+ if (subCommand == "READ_ELF") {
+ return this->HandleReadElfCommand(args);
+ }
if (subCommand == "RELATIVE_PATH") {
return this->HandleRelativePathCommand(args);
}
@@ -2177,6 +2184,68 @@ bool cmFileCommand::HandleRPathCheckCommand(
return true;
}
+bool cmFileCommand::HandleReadElfCommand(std::vector<std::string> const& args)
+{
+ if (args.size() < 4) {
+ this->SetError("READ_ELF must be called with at least three additional "
+ "arguments.");
+ return false;
+ }
+
+ cmCommandArgumentsHelper argHelper;
+ cmCommandArgumentGroup group;
+
+ cmCAString readArg(&argHelper, "READ_ELF");
+ cmCAString fileNameArg(&argHelper, CM_NULLPTR);
+
+ cmCAString rpathArg(&argHelper, "RPATH", &group);
+ cmCAString runpathArg(&argHelper, "RUNPATH", &group);
+ cmCAString errorArg(&argHelper, "CAPTURE_ERROR", &group);
+
+ readArg.Follows(CM_NULLPTR);
+ fileNameArg.Follows(&readArg);
+ group.Follows(&fileNameArg);
+ argHelper.Parse(&args, CM_NULLPTR);
+
+ if (!cmSystemTools::FileExists(fileNameArg.GetString(), true)) {
+ std::ostringstream e;
+ e << "READ_ELF given FILE \"" << fileNameArg.GetString()
+ << "\" that does not exist.";
+ this->SetError(e.str());
+ return false;
+ }
+
+#if defined(CMAKE_USE_ELF_PARSER)
+ cmELF elf(fileNameArg.GetCString());
+
+ if (!rpathArg.GetString().empty()) {
+ if (cmELF::StringEntry const* se_rpath = elf.GetRPath()) {
+ std::string rpath(se_rpath->Value);
+ std::replace(rpath.begin(), rpath.end(), ':', ';');
+ this->Makefile->AddDefinition(rpathArg.GetString(), rpath.c_str());
+ }
+ }
+ if (!runpathArg.GetString().empty()) {
+ if (cmELF::StringEntry const* se_runpath = elf.GetRunPath()) {
+ std::string runpath(se_runpath->Value);
+ std::replace(runpath.begin(), runpath.end(), ':', ';');
+ this->Makefile->AddDefinition(runpathArg.GetString(), runpath.c_str());
+ }
+ }
+
+ return true;
+#else
+ std::string error = "ELF parser not available on this platform.";
+ if (errorArg.GetString().empty()) {
+ this->SetError(error);
+ return false;
+ } else {
+ this->Makefile->AddDefinition(errorArg.GetString(), error.c_str());
+ return true;
+ }
+#endif
+}
+
bool cmFileCommand::HandleInstallCommand(std::vector<std::string> const& args)
{
cmFileInstaller installer(this);
diff --git a/Source/cmFileCommand.h b/Source/cmFileCommand.h
index 319864c..2d82a23 100644
--- a/Source/cmFileCommand.h
+++ b/Source/cmFileCommand.h
@@ -53,6 +53,7 @@ protected:
bool HandleRelativePathCommand(std::vector<std::string> const& args);
bool HandleCMakePathCommand(std::vector<std::string> const& args,
bool nativePath);
+ bool HandleReadElfCommand(std::vector<std::string> const& args);
bool HandleRPathChangeCommand(std::vector<std::string> const& args);
bool HandleRPathCheckCommand(std::vector<std::string> const& args);
bool HandleRPathRemoveCommand(std::vector<std::string> const& args);
diff --git a/Source/cmFileMonitor.h b/Source/cmFileMonitor.h
index 48169b8..2957328 100644
--- a/Source/cmFileMonitor.h
+++ b/Source/cmFileMonitor.h
@@ -2,6 +2,8 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#pragma once
+#include <cmConfigure.h> // IWYU pragma: keep
+
#include <functional>
#include <string>
#include <vector>
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 47d685d..29698cf 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -112,7 +112,7 @@ struct IDLSourcesTag
struct ResxTag
{
};
-struct ModuleDefinitionFileTag
+struct ModuleDefinitionSourcesTag
{
};
struct AppManifestTag
@@ -236,8 +236,8 @@ struct TagVisitor
} else if (!sf->GetLanguage().empty()) {
DoAccept<IsSameTag<Tag, ObjectSourcesTag>::Result>::Do(this->Data, sf);
} else if (ext == "def") {
- DoAccept<IsSameTag<Tag, ModuleDefinitionFileTag>::Result>::Do(this->Data,
- sf);
+ DoAccept<IsSameTag<Tag, ModuleDefinitionSourcesTag>::Result>::Do(
+ this->Data, sf);
if (this->IsObjLib) {
this->BadObjLibFiles.push_back(sf);
}
@@ -681,6 +681,12 @@ bool cmGeneratorTarget::HasExplicitObjectName(cmSourceFile const* file) const
return it != this->ExplicitObjectName.end();
}
+void cmGeneratorTarget::GetModuleDefinitionSources(
+ std::vector<cmSourceFile const*>& data, const std::string& config) const
+{
+ IMPLEMENT_VISIT(ModuleDefinitionSources);
+}
+
void cmGeneratorTarget::GetIDLSources(std::vector<cmSourceFile const*>& data,
const std::string& config) const
{
@@ -1938,17 +1944,45 @@ cmGeneratorTarget::CompileInfo const* cmGeneratorTarget::GetCompileInfo(
return &i->second;
}
-cmSourceFile const* cmGeneratorTarget::GetModuleDefinitionFile(
- const std::string& config) const
+cmGeneratorTarget::ModuleDefinitionInfo const*
+cmGeneratorTarget::GetModuleDefinitionInfo(std::string const& config) const
{
- std::vector<cmSourceFile const*> data;
- IMPLEMENT_VISIT_IMPL(ModuleDefinitionFile,
- COMMA std::vector<cmSourceFile const*>)
- if (!data.empty()) {
- return data.front();
+ // A module definition file only makes sense on certain target types.
+ if (this->GetType() != cmStateEnums::SHARED_LIBRARY &&
+ this->GetType() != cmStateEnums::MODULE_LIBRARY &&
+ !this->IsExecutableWithExports()) {
+ return CM_NULLPTR;
}
- return CM_NULLPTR;
+ // Lookup/compute/cache the compile information for this configuration.
+ std::string config_upper;
+ if (!config.empty()) {
+ config_upper = cmSystemTools::UpperCase(config);
+ }
+ ModuleDefinitionInfoMapType::const_iterator i =
+ this->ModuleDefinitionInfoMap.find(config_upper);
+ if (i == this->ModuleDefinitionInfoMap.end()) {
+ ModuleDefinitionInfo info;
+ this->ComputeModuleDefinitionInfo(config, info);
+ ModuleDefinitionInfoMapType::value_type entry(config_upper, info);
+ i = this->ModuleDefinitionInfoMap.insert(entry).first;
+ }
+ return &i->second;
+}
+
+void cmGeneratorTarget::ComputeModuleDefinitionInfo(
+ std::string const& config, ModuleDefinitionInfo& info) const
+{
+ std::vector<cmSourceFile const*> sources;
+ this->GetModuleDefinitionSources(sources, config);
+ info.WindowsExportAllSymbols =
+ this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS") &&
+ this->GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS");
+ if (info.WindowsExportAllSymbols) {
+ info.DefFile = this->ObjectDirectory /* has slash */ + "exports.def";
+ } else if (!sources.empty()) {
+ info.DefFile = sources.front()->GetFullPath();
+ }
}
bool cmGeneratorTarget::IsDLLPlatform() const
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index e72e0a6..92285f3 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -77,6 +77,8 @@ public:
bool HasExplicitObjectName(cmSourceFile const* file) const;
void AddExplicitObjectName(cmSourceFile const* sf);
+ void GetModuleDefinitionSources(std::vector<cmSourceFile const*>&,
+ const std::string& config) const;
void GetResxSources(std::vector<cmSourceFile const*>&,
const std::string& config) const;
void GetIDLSources(std::vector<cmSourceFile const*>&,
@@ -233,7 +235,13 @@ public:
cmLocalGenerator* LocalGenerator;
cmGlobalGenerator const* GlobalGenerator;
- cmSourceFile const* GetModuleDefinitionFile(const std::string& config) const;
+ struct ModuleDefinitionInfo
+ {
+ std::string DefFile;
+ bool WindowsExportAllSymbols;
+ };
+ ModuleDefinitionInfo const* GetModuleDefinitionInfo(
+ std::string const& config) const;
/** Return whether or not the target is for a DLL platform. */
bool IsDLLPlatform() const;
@@ -721,6 +729,12 @@ private:
typedef std::map<std::string, OutputInfo> OutputInfoMapType;
mutable OutputInfoMapType OutputInfoMap;
+ typedef std::map<std::string, ModuleDefinitionInfo>
+ ModuleDefinitionInfoMapType;
+ mutable ModuleDefinitionInfoMapType ModuleDefinitionInfoMap;
+ void ComputeModuleDefinitionInfo(std::string const& config,
+ ModuleDefinitionInfo& info) const;
+
typedef std::pair<std::string, bool> OutputNameKey;
typedef std::map<OutputNameKey, std::string> OutputNameMapType;
mutable OutputNameMapType OutputNameMap;
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index b6b7d9e..1f5e624 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -42,6 +42,7 @@
#include "cmStateDirectory.h"
#include "cmStateTypes.h"
#include "cmVersion.h"
+#include "cmWorkingDirectory.h"
#include "cmake.h"
#if defined(CMAKE_BUILD_WITH_CMAKE)
@@ -1763,8 +1764,7 @@ int cmGlobalGenerator::Build(const std::string& /*unused*/,
/**
* Run an executable command and put the stdout in output.
*/
- std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
- cmSystemTools::ChangeDirectory(bindir);
+ cmWorkingDirectory workdir(bindir);
output += "Change Dir: ";
output += bindir;
output += "\n";
@@ -1804,8 +1804,6 @@ int cmGlobalGenerator::Build(const std::string& /*unused*/,
output += *outputPtr;
output += "\nGenerator: execution of make clean failed.\n";
- // return to the original directory
- cmSystemTools::ChangeDirectory(cwd);
return 1;
}
output += *outputPtr;
@@ -1828,8 +1826,6 @@ int cmGlobalGenerator::Build(const std::string& /*unused*/,
output += "\nGenerator: execution of make failed. Make command was: " +
makeCommandStr + "\n";
- // return to the original directory
- cmSystemTools::ChangeDirectory(cwd);
return 1;
}
output += *outputPtr;
@@ -1842,7 +1838,6 @@ int cmGlobalGenerator::Build(const std::string& /*unused*/,
retVal = 1;
}
- cmSystemTools::ChangeDirectory(cwd);
return retVal;
}
diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx
index b1285ac..ca98e6c 100644
--- a/Source/cmGlobalVisualStudio10Generator.cxx
+++ b/Source/cmGlobalVisualStudio10Generator.cxx
@@ -10,15 +10,25 @@
#include "cmSourceFile.h"
#include "cmVS10CLFlagTable.h"
#include "cmVS10CSharpFlagTable.h"
+#include "cmVS10CudaFlagTable.h"
+#include "cmVS10CudaHostFlagTable.h"
#include "cmVS10LibFlagTable.h"
#include "cmVS10LinkFlagTable.h"
#include "cmVS10MASMFlagTable.h"
#include "cmVS10NASMFlagTable.h"
#include "cmVS10RCFlagTable.h"
+#include "cmVersion.h"
#include "cmVisualStudioSlnData.h"
#include "cmVisualStudioSlnParser.h"
+#include "cmXMLWriter.h"
#include "cmake.h"
+#include <cmsys/FStream.hxx>
+#include <cmsys/Glob.hxx>
+#include <cmsys/RegularExpression.hxx>
+
+#include <algorithm>
+
static const char vs10generatorName[] = "Visual Studio 10 2010";
// Map generator name without year to name with year.
@@ -95,6 +105,7 @@ cmGlobalVisualStudio10Generator::cmGlobalVisualStudio10Generator(
"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\10.0\\Setup\\VC;"
"ProductDir",
vc10Express, cmSystemTools::KeyWOW64_32);
+ this->CudaEnabled = false;
this->SystemIsWindowsCE = false;
this->SystemIsWindowsPhone = false;
this->SystemIsWindowsStore = false;
@@ -113,6 +124,8 @@ cmGlobalVisualStudio10Generator::cmGlobalVisualStudio10Generator(
this->DefaultCSharpFlagTable = cmVS10CSharpFlagTable;
this->DefaultLibFlagTable = cmVS10LibFlagTable;
this->DefaultLinkFlagTable = cmVS10LinkFlagTable;
+ this->DefaultCudaFlagTable = cmVS10CudaFlagTable;
+ this->DefaultCudaHostFlagTable = cmVS10CudaHostFlagTable;
this->DefaultMasmFlagTable = cmVS10MASMFlagTable;
this->DefaultNasmFlagTable = cmVS10NASMFlagTable;
this->DefaultRcFlagTable = cmVS10RCFlagTable;
@@ -155,6 +168,13 @@ bool cmGlobalVisualStudio10Generator::SetGeneratorPlatform(
return true;
}
+static void cmCudaToolVersion(std::string& s)
+{
+ // "CUDA x.y.props" => "x.y"
+ s = s.substr(5);
+ s = s.substr(0, s.size() - 6);
+}
+
bool cmGlobalVisualStudio10Generator::SetGeneratorToolset(
std::string const& ts, cmMakefile* mf)
{
@@ -170,12 +190,37 @@ bool cmGlobalVisualStudio10Generator::SetGeneratorToolset(
if (!this->ParseGeneratorToolset(ts, mf)) {
return false;
}
+
+ if (!this->FindVCTargetsPath(mf)) {
+ return false;
+ }
+
+ if (this->GeneratorToolsetCuda.empty()) {
+ // Find the highest available version of the CUDA tools.
+ std::vector<std::string> cudaTools;
+ std::string const bcDir = this->VCTargetsPath + "/BuildCustomizations";
+ cmsys::Glob gl;
+ gl.SetRelative(bcDir.c_str());
+ if (gl.FindFiles(bcDir + "/CUDA *.props")) {
+ cudaTools = gl.GetFiles();
+ }
+ if (!cudaTools.empty()) {
+ std::for_each(cudaTools.begin(), cudaTools.end(), cmCudaToolVersion);
+ std::sort(cudaTools.begin(), cudaTools.end(),
+ cmSystemTools::VersionCompareGreater);
+ this->GeneratorToolsetCuda = cudaTools.at(0);
+ }
+ }
+
if (const char* toolset = this->GetPlatformToolset()) {
mf->AddDefinition("CMAKE_VS_PLATFORM_TOOLSET", toolset);
}
if (const char* hostArch = this->GetPlatformToolsetHostArchitecture()) {
mf->AddDefinition("CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE", hostArch);
}
+ if (const char* cuda = this->GetPlatformToolsetCuda()) {
+ mf->AddDefinition("CMAKE_VS_PLATFORM_TOOLSET_CUDA", cuda);
+ }
return true;
}
@@ -251,8 +296,10 @@ bool cmGlobalVisualStudio10Generator::ParseGeneratorToolset(
bool cmGlobalVisualStudio10Generator::ProcessGeneratorToolsetField(
std::string const& key, std::string const& value)
{
- static_cast<void>(key);
- static_cast<void>(value);
+ if (key == "cuda") {
+ this->GeneratorToolsetCuda = value;
+ return true;
+ }
return false;
}
@@ -417,6 +464,9 @@ void cmGlobalVisualStudio10Generator::EnableLanguage(
if (*it == "ASM_NASM") {
this->NasmEnabled = true;
}
+ if (*it == "CUDA") {
+ this->CudaEnabled = true;
+ }
}
this->AddPlatformDefinitions(mf);
cmGlobalVisualStudio8Generator::EnableLanguage(lang, mf, optional);
@@ -453,6 +503,20 @@ cmGlobalVisualStudio10Generator::GetPlatformToolsetHostArchitecture() const
return CM_NULLPTR;
}
+const char* cmGlobalVisualStudio10Generator::GetPlatformToolsetCuda() const
+{
+ if (!this->GeneratorToolsetCuda.empty()) {
+ return this->GeneratorToolsetCuda.c_str();
+ }
+ return CM_NULLPTR;
+}
+
+std::string const&
+cmGlobalVisualStudio10Generator::GetPlatformToolsetCudaString() const
+{
+ return this->GeneratorToolsetCuda;
+}
+
bool cmGlobalVisualStudio10Generator::FindMakeProgram(cmMakefile* mf)
{
if (!this->cmGlobalVisualStudio8Generator::FindMakeProgram(mf)) {
@@ -507,6 +571,208 @@ std::string cmGlobalVisualStudio10Generator::FindDevEnvCommand()
return this->cmGlobalVisualStudio71Generator::FindDevEnvCommand();
}
+bool cmGlobalVisualStudio10Generator::FindVCTargetsPath(cmMakefile* mf)
+{
+ // Skip this in special cases within our own test suite.
+ if (this->GetPlatformName() == "Test Platform" ||
+ this->GetPlatformToolsetString() == "Test Toolset") {
+ return true;
+ }
+
+ std::string wd;
+ if (!this->ConfiguredFilesPath.empty()) {
+ // In a try-compile we are given the outer CMakeFiles directory.
+ wd = this->ConfiguredFilesPath;
+ } else {
+ wd = this->GetCMakeInstance()->GetHomeOutputDirectory();
+ wd += cmake::GetCMakeFilesDirectory();
+ }
+ wd += "/";
+ wd += cmVersion::GetCMakeVersion();
+
+ // We record the result persistently in a file.
+ std::string const txt = wd + "/VCTargetsPath.txt";
+
+ // If we have a recorded result, use it.
+ {
+ cmsys::ifstream fin(txt.c_str());
+ if (fin && cmSystemTools::GetLineFromStream(fin, this->VCTargetsPath) &&
+ cmSystemTools::FileIsDirectory(this->VCTargetsPath)) {
+ cmSystemTools::ConvertToUnixSlashes(this->VCTargetsPath);
+ return true;
+ }
+ }
+
+ // Prepare the work directory.
+ if (!cmSystemTools::MakeDirectory(wd)) {
+ std::string e = "Failed to make directory:\n " + wd;
+ mf->IssueMessage(cmake::FATAL_ERROR, e.c_str());
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+
+ // Generate a project file for MSBuild to tell us the VCTargetsPath value.
+ std::string const vcxproj = "VCTargetsPath.vcxproj";
+ {
+ std::string const vcxprojAbs = wd + "/" + vcxproj;
+ cmsys::ofstream fout(vcxprojAbs.c_str());
+ cmXMLWriter xw(fout);
+
+ /* clang-format off */
+ xw.StartDocument();
+ xw.StartElement("Project");
+ xw.Attribute("DefaultTargets", "Build");
+ xw.Attribute("ToolsVersion", "4.0");
+ xw.Attribute("xmlns",
+ "http://schemas.microsoft.com/developer/msbuild/2003");
+ if (this->IsNsightTegra()) {
+ xw.StartElement("PropertyGroup");
+ xw.Attribute("Label", "NsightTegraProject");
+ xw.StartElement("NsightTegraProjectRevisionNumber");
+ xw.Content("6");
+ xw.EndElement(); // NsightTegraProjectRevisionNumber
+ xw.EndElement(); // PropertyGroup
+ }
+ xw.StartElement("ItemGroup");
+ xw.Attribute("Label", "ProjectConfigurations");
+ xw.StartElement("ProjectConfiguration");
+ xw.Attribute("Include", "Debug|" + this->GetPlatformName());
+ xw.StartElement("Configuration");
+ xw.Content("Debug");
+ xw.EndElement(); // Configuration
+ xw.StartElement("Platform");
+ xw.Content(this->GetPlatformName());
+ xw.EndElement(); // Platform
+ xw.EndElement(); // ProjectConfiguration
+ xw.EndElement(); // ItemGroup
+ xw.StartElement("PropertyGroup");
+ xw.Attribute("Label", "Globals");
+ xw.StartElement("ProjectGUID");
+ xw.Content("{F3FC6D86-508D-3FB1-96D2-995F08B142EC}");
+ xw.EndElement(); // ProjectGUID
+ xw.StartElement("Keyword");
+ xw.Content("Win32Proj");
+ xw.EndElement(); // Keyword
+ xw.StartElement("Platform");
+ xw.Content(this->GetPlatformName());
+ xw.EndElement(); // Platform
+ if (this->GetSystemName() == "WindowsPhone") {
+ xw.StartElement("ApplicationType");
+ xw.Content("Windows Phone");
+ xw.EndElement(); // ApplicationType
+ xw.StartElement("ApplicationTypeRevision");
+ xw.Content(this->GetSystemVersion());
+ xw.EndElement(); // ApplicationTypeRevision
+ } else if (this->GetSystemName() == "WindowsStore") {
+ xw.StartElement("ApplicationType");
+ xw.Content("Windows Store");
+ xw.EndElement(); // ApplicationType
+ xw.StartElement("ApplicationTypeRevision");
+ xw.Content(this->GetSystemVersion());
+ xw.EndElement(); // ApplicationTypeRevision
+ }
+ if (!this->WindowsTargetPlatformVersion.empty()) {
+ xw.StartElement("WindowsTargetPlatformVersion");
+ xw.Content(this->WindowsTargetPlatformVersion);
+ xw.EndElement(); // WindowsTargetPlatformVersion
+ }
+ if (this->GetPlatformName() == "ARM") {
+ xw.StartElement("WindowsSDKDesktopARMSupport");
+ xw.Content("true");
+ xw.EndElement(); // WindowsSDKDesktopARMSupport
+ }
+ xw.EndElement(); // PropertyGroup
+ xw.StartElement("Import");
+ xw.Attribute("Project",
+ "$(VCTargetsPath)\\Microsoft.Cpp.Default.props");
+ xw.EndElement(); // Import
+ if (!this->GeneratorToolsetHostArchitecture.empty()) {
+ xw.StartElement("PropertyGroup");
+ xw.StartElement("PreferredToolArchitecture");
+ xw.Content(this->GeneratorToolsetHostArchitecture);
+ xw.EndElement(); // PreferredToolArchitecture
+ xw.EndElement(); // PropertyGroup
+ }
+ xw.StartElement("PropertyGroup");
+ xw.Attribute("Label", "Configuration");
+ xw.StartElement("ConfigurationType");
+ if (this->IsNsightTegra()) {
+ // Tegra-Android platform does not understand "Utility".
+ xw.Content("StaticLibrary");
+ } else {
+ xw.Content("Utility");
+ }
+ xw.EndElement(); // ConfigurationType
+ xw.StartElement("CharacterSet");
+ xw.Content("MultiByte");
+ xw.EndElement(); // CharacterSet
+ if (this->IsNsightTegra()) {
+ xw.StartElement("NdkToolchainVersion");
+ xw.Content(this->GetPlatformToolsetString());
+ xw.EndElement(); // NdkToolchainVersion
+ } else {
+ xw.StartElement("PlatformToolset");
+ xw.Content(this->GetPlatformToolsetString());
+ xw.EndElement(); // PlatformToolset
+ }
+ xw.EndElement(); // PropertyGroup
+ xw.StartElement("Import");
+ xw.Attribute("Project", "$(VCTargetsPath)\\Microsoft.Cpp.props");
+ xw.EndElement(); // Import
+ xw.StartElement("ItemDefinitionGroup");
+ xw.StartElement("PostBuildEvent");
+ xw.StartElement("Command");
+ xw.Content("echo VCTargetsPath=$(VCTargetsPath)");
+ xw.EndElement(); // Command
+ xw.EndElement(); // PostBuildEvent
+ xw.EndElement(); // ItemDefinitionGroup
+ xw.StartElement("Import");
+ xw.Attribute("Project",
+ "$(VCTargetsPath)\\Microsoft.Cpp.targets");
+ xw.EndElement(); // Import
+ xw.EndElement(); // Project
+ xw.EndDocument();
+ /* clang-format on */
+ }
+
+ std::vector<std::string> cmd;
+ cmd.push_back(this->GetMSBuildCommand());
+ cmd.push_back(vcxproj);
+ cmd.push_back(std::string("/p:VisualStudioVersion=") +
+ this->GetIDEVersion());
+ std::string out;
+ int ret = 0;
+ cmsys::RegularExpression regex("\n *VCTargetsPath=([^%\r\n]+)[\r\n]");
+ if (!cmSystemTools::RunSingleCommand(cmd, &out, &out, &ret, wd.c_str(),
+ cmSystemTools::OUTPUT_NONE) ||
+ ret != 0 || !regex.find(out)) {
+ cmSystemTools::ReplaceString(out, "\n", "\n ");
+ std::ostringstream e;
+ /* clang-format off */
+ e <<
+ "Failed to run MSBuild command:\n"
+ " " << cmd[0] << "\n"
+ "to get the value of VCTargetsPath:\n"
+ " " << out << "\n"
+ ;
+ /* clang-format on */
+ if (ret != 0) {
+ e << "Exit code: " << ret << "\n";
+ }
+ mf->IssueMessage(cmake::FATAL_ERROR, e.str().c_str());
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+ this->VCTargetsPath = regex.match(1);
+ cmSystemTools::ConvertToUnixSlashes(this->VCTargetsPath);
+
+ {
+ cmsys::ofstream fout(txt.c_str());
+ fout << this->VCTargetsPath << "\n";
+ }
+ return true;
+}
+
void cmGlobalVisualStudio10Generator::GenerateBuildCommand(
std::vector<std::string>& makeCommand, const std::string& makeProgram,
const std::string& projectName, const std::string& projectDir,
@@ -721,6 +987,17 @@ cmIDEFlagTable const* cmGlobalVisualStudio10Generator::GetLinkFlagTable() const
return (table != CM_NULLPTR) ? table : this->DefaultLinkFlagTable;
}
+cmIDEFlagTable const* cmGlobalVisualStudio10Generator::GetCudaFlagTable() const
+{
+ return this->DefaultCudaFlagTable;
+}
+
+cmIDEFlagTable const* cmGlobalVisualStudio10Generator::GetCudaHostFlagTable()
+ const
+{
+ return this->DefaultCudaHostFlagTable;
+}
+
cmIDEFlagTable const* cmGlobalVisualStudio10Generator::GetMasmFlagTable() const
{
cmIDEFlagTable const* table = this->ToolsetOptions.GetMasmFlagTable(
diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h
index c5e4bcd..20f992a 100644
--- a/Source/cmGlobalVisualStudio10Generator.h
+++ b/Source/cmGlobalVisualStudio10Generator.h
@@ -42,6 +42,8 @@ public:
cmMakefile*, bool optional);
virtual void WriteSLNHeader(std::ostream& fout);
+ bool IsCudaEnabled() const { return this->CudaEnabled; }
+
/** Generating for Nsight Tegra VS plugin? */
bool IsNsightTegra() const;
std::string GetNsightTegraVersion() const;
@@ -53,6 +55,10 @@ public:
/** The toolset host architecture name (e.g. x64 for 64-bit host tools). */
const char* GetPlatformToolsetHostArchitecture() const;
+ /** The cuda toolset version. */
+ const char* GetPlatformToolsetCuda() const;
+ std::string const& GetPlatformToolsetCudaString() const;
+
/** Return the CMAKE_SYSTEM_NAME. */
std::string const& GetSystemName() const { return this->SystemName; }
@@ -94,6 +100,8 @@ public:
cmIDEFlagTable const* GetRcFlagTable() const;
cmIDEFlagTable const* GetLibFlagTable() const;
cmIDEFlagTable const* GetLinkFlagTable() const;
+ cmIDEFlagTable const* GetCudaFlagTable() const;
+ cmIDEFlagTable const* GetCudaHostFlagTable() const;
cmIDEFlagTable const* GetMasmFlagTable() const;
cmIDEFlagTable const* GetNasmFlagTable() const;
@@ -118,6 +126,7 @@ protected:
std::string GeneratorToolset;
std::string GeneratorToolsetHostArchitecture;
+ std::string GeneratorToolsetCuda;
std::string DefaultPlatformToolset;
std::string WindowsTargetPlatformVersion;
std::string SystemName;
@@ -127,6 +136,8 @@ protected:
cmIDEFlagTable const* DefaultCSharpFlagTable;
cmIDEFlagTable const* DefaultLibFlagTable;
cmIDEFlagTable const* DefaultLinkFlagTable;
+ cmIDEFlagTable const* DefaultCudaFlagTable;
+ cmIDEFlagTable const* DefaultCudaHostFlagTable;
cmIDEFlagTable const* DefaultMasmFlagTable;
cmIDEFlagTable const* DefaultNasmFlagTable;
cmIDEFlagTable const* DefaultRcFlagTable;
@@ -160,6 +171,11 @@ private:
bool ParseGeneratorToolset(std::string const& ts, cmMakefile* mf);
+ std::string VCTargetsPath;
+ bool FindVCTargetsPath(cmMakefile* mf);
+
+ bool CudaEnabled;
+
// We do not use the reload macros for VS >= 10.
virtual std::string GetUserMacrosDirectory() { return ""; }
};
diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx
index cc2536c..a073426 100644
--- a/Source/cmGlobalVisualStudioGenerator.cxx
+++ b/Source/cmGlobalVisualStudioGenerator.cxx
@@ -750,6 +750,10 @@ bool cmGlobalVisualStudioGenerator::TargetIsCSharpOnly(
if (!gt->GetConfigCommonSourceFiles(sources)) {
return false;
}
+ // Only "real" targets are allowed to be C# targets.
+ if (gt->Target->GetType() > cmStateEnums::OBJECT_LIBRARY) {
+ return false;
+ }
}
gt->GetLanguages(languages, "");
if (languages.size() == 1) {
@@ -810,10 +814,14 @@ void cmGlobalVisualStudioGenerator::AddSymbolExportCommand(
cmGeneratorTarget* gt, std::vector<cmCustomCommand>& commands,
std::string const& configName)
{
+ cmGeneratorTarget::ModuleDefinitionInfo const* mdi =
+ gt->GetModuleDefinitionInfo(configName);
+ if (!mdi || !mdi->WindowsExportAllSymbols) {
+ return;
+ }
+
std::vector<std::string> outputs;
- std::string deffile = gt->ObjectDirectory;
- deffile += "/exportall.def";
- outputs.push_back(deffile);
+ outputs.push_back(mdi->DefFile);
std::vector<std::string> empty;
std::vector<cmSourceFile const*> objectSources;
gt->GetObjectSources(objectSources, configName);
@@ -831,7 +839,7 @@ void cmGlobalVisualStudioGenerator::AddSymbolExportCommand(
cmdl.push_back(cmakeCommand);
cmdl.push_back("-E");
cmdl.push_back("__create_def");
- cmdl.push_back(deffile);
+ cmdl.push_back(mdi->DefFile);
std::string obj_dir_expanded = obj_dir;
cmSystemTools::ReplaceString(obj_dir_expanded, this->GetCMakeCFGIntDir(),
configName.c_str());
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index b023d5c..77f3408 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -3341,8 +3341,7 @@ void cmGlobalXCodeGenerator::OutputXCodeProject(
// Since the lowest available Xcode version for testing was 7.0,
// I'm setting this as a limit then
- if (this->GetCMakeInstance()->GetState()->GetGlobalPropertyAsBool(
- "XCODE_GENERATE_SCHEME") &&
+ if (root->GetMakefile()->IsOn("CMAKE_XCODE_GENERATE_SCHEME") &&
this->XcodeVersion >= 70) {
this->OutputXCodeSharedSchemes(xcodeDir);
this->OutputXCodeWorkspaceSettings(xcodeDir);
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 07d712c..82bf0b9 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -213,14 +213,7 @@ void cmLocalGenerator::TraceDependencies()
void cmLocalGenerator::GenerateTestFiles()
{
- std::string file = this->StateSnapshot.GetDirectory().GetCurrentBinary();
- file += "/";
- file += "CTestTestfile.cmake";
-
if (!this->Makefile->IsOn("CMAKE_TESTING_ENABLED")) {
- if (cmSystemTools::FileExists(file)) {
- cmSystemTools::RemoveFile(file);
- }
return;
}
@@ -229,6 +222,10 @@ void cmLocalGenerator::GenerateTestFiles()
const std::string& config =
this->Makefile->GetConfigurations(configurationTypes, false);
+ std::string file = this->StateSnapshot.GetDirectory().GetCurrentBinary();
+ file += "/";
+ file += "CTestTestfile.cmake";
+
cmGeneratedFileStream fout(file.c_str());
fout.SetCopyIfDifferent(true);
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index 6e976e1..8026de9 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -996,19 +996,14 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
linkOptions.AddTable(cmLocalVisualStudio7GeneratorLinkFlagTable);
linkOptions.Parse(extraLinkOptions.c_str());
- if (!this->ModuleDefinitionFile.empty()) {
- std::string defFile = this->ConvertToOutputFormat(
- this->ModuleDefinitionFile, cmOutputConverter::SHELL);
+ cmGeneratorTarget::ModuleDefinitionInfo const* mdi =
+ target->GetModuleDefinitionInfo(configName);
+ if (mdi && !mdi->DefFile.empty()) {
+ std::string defFile =
+ this->ConvertToOutputFormat(mdi->DefFile, cmOutputConverter::SHELL);
linkOptions.AddFlag("ModuleDefinitionFile", defFile.c_str());
}
- if ((target->GetType() == cmStateEnums::SHARED_LIBRARY ||
- target->IsExecutableWithExports()) &&
- this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS")) {
- if (target->GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS")) {
- linkOptions.AddFlag("ModuleDefinitionFile", "$(IntDir)/exportall.def");
- }
- }
switch (target->GetType()) {
case cmStateEnums::UNKNOWN_LIBRARY:
break;
@@ -1362,7 +1357,6 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
std::vector<cmSourceGroup> sourceGroups = this->Makefile->GetSourceGroups();
// get the classes from the source lists then add them to the groups
- this->ModuleDefinitionFile = "";
std::vector<cmSourceFile*> classes;
if (!target->GetConfigCommonSourceFiles(classes)) {
return;
@@ -1374,9 +1368,6 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
}
// Add the file to the list of sources.
std::string source = (*i)->GetFullPath();
- if (cmSystemTools::UpperCase((*i)->GetExtension()) == "DEF") {
- this->ModuleDefinitionFile = (*i)->GetFullPath();
- }
cmSourceGroup* sourceGroup =
this->Makefile->FindSourceGroup(source.c_str(), sourceGroups);
sourceGroup->AssignSource(*i);
@@ -1825,17 +1816,15 @@ void cmLocalVisualStudio7Generator::OutputTargetRules(
tool = this->FortranProject ? "VFPreLinkEventTool" : "VCPreLinkEventTool";
event.Start(tool);
bool addedPrelink = false;
- if ((target->GetType() == cmStateEnums::SHARED_LIBRARY ||
- target->IsExecutableWithExports()) &&
- this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS")) {
- if (target->GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS")) {
- addedPrelink = true;
- std::vector<cmCustomCommand> commands = target->GetPreLinkCommands();
- cmGlobalVisualStudioGenerator* gg =
- static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator);
- gg->AddSymbolExportCommand(target, commands, configName);
- event.Write(commands);
- }
+ cmGeneratorTarget::ModuleDefinitionInfo const* mdi =
+ target->GetModuleDefinitionInfo(configName);
+ if (mdi && mdi->WindowsExportAllSymbols) {
+ addedPrelink = true;
+ std::vector<cmCustomCommand> commands = target->GetPreLinkCommands();
+ cmGlobalVisualStudioGenerator* gg =
+ static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator);
+ gg->AddSymbolExportCommand(target, commands, configName);
+ event.Write(commands);
}
if (!addedPrelink) {
event.Write(target->GetPreLinkCommands());
diff --git a/Source/cmLocalVisualStudio7Generator.h b/Source/cmLocalVisualStudio7Generator.h
index d69cce1..ae6e2ed 100644
--- a/Source/cmLocalVisualStudio7Generator.h
+++ b/Source/cmLocalVisualStudio7Generator.h
@@ -128,7 +128,6 @@ private:
friend class EventWriter;
- std::string ModuleDefinitionFile;
bool FortranProject;
bool WindowsCEProject;
cmLocalVisualStudio7GeneratorInternals* Internal;
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index da32dd7..c4a488f 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -36,6 +36,7 @@
#include "cmTest.h"
#include "cmTestGenerator.h" // IWYU pragma: keep
#include "cmVersion.h"
+#include "cmWorkingDirectory.h"
#include "cm_auto_ptr.hxx"
#include "cmake.h"
@@ -3164,8 +3165,7 @@ int cmMakefile::TryCompile(const std::string& srcdir,
// change to the tests directory and run cmake
// use the cmake object instead of calling cmake
- std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
- cmSystemTools::ChangeDirectory(bindir);
+ cmWorkingDirectory workdir(bindir);
// make sure the same generator is used
// use this program as the cmake to be run, it should not
@@ -3179,8 +3179,6 @@ int cmMakefile::TryCompile(const std::string& srcdir,
this->GetGlobalGenerator()->GetName() +
"' could not be created.");
cmSystemTools::SetFatalErrorOccured();
- // return to the original directory
- cmSystemTools::ChangeDirectory(cwd);
this->IsSourceFileTryCompile = false;
return 1;
}
@@ -3244,8 +3242,6 @@ int cmMakefile::TryCompile(const std::string& srcdir,
this->IssueMessage(cmake::FATAL_ERROR,
"Failed to configure test project build system.");
cmSystemTools::SetFatalErrorOccured();
- // return to the original directory
- cmSystemTools::ChangeDirectory(cwd);
this->IsSourceFileTryCompile = false;
return 1;
}
@@ -3254,8 +3250,6 @@ int cmMakefile::TryCompile(const std::string& srcdir,
this->IssueMessage(cmake::FATAL_ERROR,
"Failed to generate test project build system.");
cmSystemTools::SetFatalErrorOccured();
- // return to the original directory
- cmSystemTools::ChangeDirectory(cwd);
this->IsSourceFileTryCompile = false;
return 1;
}
@@ -3264,7 +3258,6 @@ int cmMakefile::TryCompile(const std::string& srcdir,
int ret = this->GetGlobalGenerator()->TryCompile(
srcdir, bindir, projectName, targetName, fast, output, this);
- cmSystemTools::ChangeDirectory(cwd);
this->IsSourceFileTryCompile = false;
return ret;
}
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index 8ed5051..493f474 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -556,10 +556,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
}
// maybe create .def file from list of objects
- if (this->GeneratorTarget->IsExecutableWithExports() &&
- this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS")) {
- this->GenDefFile(real_link_commands, linkFlags);
- }
+ this->GenDefFile(real_link_commands);
std::string manifests = this->GetManifests();
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index bc456cf..e5fae13 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -750,10 +750,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
}
// maybe create .def file from list of objects
- if (this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY &&
- this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS")) {
- this->GenDefFile(real_link_commands, linkFlags);
- }
+ this->GenDefFile(real_link_commands);
std::string manifests = this->GetManifests();
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 54b3f36..1fa8702 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -1414,8 +1414,10 @@ void cmMakefileTargetGenerator::AppendLinkDepends(
this->AppendTargetDepends(depends);
// Add a dependency on the link definitions file, if any.
- if (this->ModuleDefinitionFile) {
- depends.push_back(this->ModuleDefinitionFile->GetFullPath());
+ cmGeneratorTarget::ModuleDefinitionInfo const* mdi =
+ this->GeneratorTarget->GetModuleDefinitionInfo(this->GetConfigName());
+ if (mdi && !mdi->WindowsExportAllSymbols && !mdi->DefFile.empty()) {
+ depends.push_back(mdi->DefFile);
}
// Add a dependency on user-specified manifest files, if any.
@@ -1718,49 +1720,39 @@ void cmMakefileTargetGenerator::AddIncludeFlags(std::string& flags,
}
void cmMakefileTargetGenerator::GenDefFile(
- std::vector<std::string>& real_link_commands, std::string& linkFlags)
+ std::vector<std::string>& real_link_commands)
{
- if (this->GeneratorTarget->GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS")) {
- std::string name_of_def_file =
- this->GeneratorTarget->GetSupportDirectory();
- name_of_def_file += std::string("/") + this->GeneratorTarget->GetName();
- name_of_def_file += ".def";
- std::string cmd = cmSystemTools::GetCMakeCommand();
- cmd = this->LocalGenerator->ConvertToOutputFormat(
- cmd, cmOutputConverter::SHELL);
- cmd += " -E __create_def ";
- cmd += this->LocalGenerator->ConvertToOutputFormat(
- this->LocalGenerator->MaybeConvertToRelativePath(
- this->LocalGenerator->GetCurrentBinaryDirectory(), name_of_def_file),
- cmOutputConverter::SHELL);
- cmd += " ";
- std::string objlist_file = name_of_def_file;
- objlist_file += ".objs";
- cmd += this->LocalGenerator->ConvertToOutputFormat(
- this->LocalGenerator->MaybeConvertToRelativePath(
- this->LocalGenerator->GetCurrentBinaryDirectory(), objlist_file),
- cmOutputConverter::SHELL);
- real_link_commands.insert(real_link_commands.begin(), cmd);
- // create a list of obj files for the -E __create_def to read
- cmGeneratedFileStream fout(objlist_file.c_str());
- for (std::vector<std::string>::const_iterator i = this->Objects.begin();
- i != this->Objects.end(); ++i) {
- if (cmHasLiteralSuffix(*i, ".obj")) {
- fout << *i << "\n";
- }
- }
- for (std::vector<std::string>::const_iterator i =
- this->ExternalObjects.begin();
- i != this->ExternalObjects.end(); ++i) {
+ cmGeneratorTarget::ModuleDefinitionInfo const* mdi =
+ this->GeneratorTarget->GetModuleDefinitionInfo(this->GetConfigName());
+ if (!mdi || !mdi->WindowsExportAllSymbols) {
+ return;
+ }
+ std::string cmd = cmSystemTools::GetCMakeCommand();
+ cmd =
+ this->LocalGenerator->ConvertToOutputFormat(cmd, cmOutputConverter::SHELL);
+ cmd += " -E __create_def ";
+ cmd += this->LocalGenerator->ConvertToOutputFormat(
+ this->LocalGenerator->MaybeConvertToRelativePath(
+ this->LocalGenerator->GetCurrentBinaryDirectory(), mdi->DefFile),
+ cmOutputConverter::SHELL);
+ cmd += " ";
+ std::string objlist_file = mdi->DefFile + ".objs";
+ cmd += this->LocalGenerator->ConvertToOutputFormat(
+ this->LocalGenerator->MaybeConvertToRelativePath(
+ this->LocalGenerator->GetCurrentBinaryDirectory(), objlist_file),
+ cmOutputConverter::SHELL);
+ real_link_commands.insert(real_link_commands.begin(), cmd);
+ // create a list of obj files for the -E __create_def to read
+ cmGeneratedFileStream fout(objlist_file.c_str());
+ for (std::vector<std::string>::const_iterator i = this->Objects.begin();
+ i != this->Objects.end(); ++i) {
+ if (cmHasLiteralSuffix(*i, ".obj")) {
fout << *i << "\n";
}
- // now add the def file link flag
- linkFlags += " ";
- linkFlags += this->Makefile->GetSafeDefinition("CMAKE_LINK_DEF_FILE_FLAG");
- linkFlags += this->LocalGenerator->ConvertToOutputFormat(
- this->LocalGenerator->MaybeConvertToRelativePath(
- this->LocalGenerator->GetCurrentBinaryDirectory(), name_of_def_file),
- cmOutputConverter::SHELL);
- linkFlags += " ";
+ }
+ for (std::vector<std::string>::const_iterator i =
+ this->ExternalObjects.begin();
+ i != this->ExternalObjects.end(); ++i) {
+ fout << *i << "\n";
}
}
diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h
index 347f9f2..07b8005 100644
--- a/Source/cmMakefileTargetGenerator.h
+++ b/Source/cmMakefileTargetGenerator.h
@@ -166,8 +166,7 @@ protected:
bool useWatcomQuote);
/** Add commands for generate def files */
- void GenDefFile(std::vector<std::string>& real_link_commands,
- std::string& linkFlags);
+ void GenDefFile(std::vector<std::string>& real_link_commands);
void AddIncludeFlags(std::string& flags,
const std::string& lang) CM_OVERRIDE;
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index 9bf0ccd..300618f 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -860,19 +860,6 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
linkLineComputer.get(), this->GetConfigName(), vars["LINK_LIBRARIES"],
vars["FLAGS"], vars["LINK_FLAGS"], frameworkPath, linkPath, &genTarget);
- if (this->GetMakefile()->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS") &&
- (gt.GetType() == cmStateEnums::SHARED_LIBRARY ||
- gt.IsExecutableWithExports())) {
- if (gt.GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS")) {
- std::string name_of_def_file = gt.GetSupportDirectory();
- name_of_def_file += "/" + gt.GetName();
- name_of_def_file += ".def ";
- vars["LINK_FLAGS"] += " /DEF:";
- vars["LINK_FLAGS"] += this->GetLocalGenerator()->ConvertToOutputFormat(
- name_of_def_file, cmOutputConverter::SHELL);
- }
- }
-
// Add OS X version flags, if any.
if (this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY ||
this->GeneratorTarget->GetType() == cmStateEnums::MODULE_LIBRARY) {
@@ -989,33 +976,27 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
}
// maybe create .def file from list of objects
- if ((gt.GetType() == cmStateEnums::SHARED_LIBRARY ||
- gt.IsExecutableWithExports()) &&
- this->GetMakefile()->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS")) {
- if (gt.GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS")) {
- std::string cmakeCommand =
- this->GetLocalGenerator()->ConvertToOutputFormat(
- cmSystemTools::GetCMakeCommand(), cmOutputConverter::SHELL);
- std::string name_of_def_file = gt.GetSupportDirectory();
- name_of_def_file += "/" + gt.GetName();
- name_of_def_file += ".def";
- std::string cmd = cmakeCommand;
- cmd += " -E __create_def ";
- cmd += this->GetLocalGenerator()->ConvertToOutputFormat(
- name_of_def_file, cmOutputConverter::SHELL);
- cmd += " ";
- cmNinjaDeps objs = this->GetObjects();
- std::string obj_list_file = name_of_def_file;
- obj_list_file += ".objs";
- cmd += this->GetLocalGenerator()->ConvertToOutputFormat(
- obj_list_file, cmOutputConverter::SHELL);
- preLinkCmdLines.push_back(cmd);
- // create a list of obj files for the -E __create_def to read
- cmGeneratedFileStream fout(obj_list_file.c_str());
- for (cmNinjaDeps::iterator i = objs.begin(); i != objs.end(); ++i) {
- if (cmHasLiteralSuffix(*i, ".obj")) {
- fout << *i << "\n";
- }
+ cmGeneratorTarget::ModuleDefinitionInfo const* mdi =
+ gt.GetModuleDefinitionInfo(this->GetConfigName());
+ if (mdi && mdi->WindowsExportAllSymbols) {
+ std::string cmakeCommand =
+ this->GetLocalGenerator()->ConvertToOutputFormat(
+ cmSystemTools::GetCMakeCommand(), cmOutputConverter::SHELL);
+ std::string cmd = cmakeCommand;
+ cmd += " -E __create_def ";
+ cmd += this->GetLocalGenerator()->ConvertToOutputFormat(
+ mdi->DefFile, cmOutputConverter::SHELL);
+ cmd += " ";
+ cmNinjaDeps objs = this->GetObjects();
+ std::string obj_list_file = mdi->DefFile + ".objs";
+ cmd += this->GetLocalGenerator()->ConvertToOutputFormat(
+ obj_list_file, cmOutputConverter::SHELL);
+ preLinkCmdLines.push_back(cmd);
+ // create a list of obj files for the -E __create_def to read
+ cmGeneratedFileStream fout(obj_list_file.c_str());
+ for (cmNinjaDeps::iterator i = objs.begin(); i != objs.end(); ++i) {
+ if (cmHasLiteralSuffix(*i, ".obj")) {
+ fout << *i << "\n";
}
}
}
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index b1f26e4..917383d 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -212,9 +212,10 @@ cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps() const
std::transform(deps.begin(), deps.end(), result.begin(), MapToNinjaPath());
// Add a dependency on the link definitions file, if any.
- if (this->ModuleDefinitionFile) {
- result.push_back(
- this->ConvertToNinjaPath(this->ModuleDefinitionFile->GetFullPath()));
+ cmGeneratorTarget::ModuleDefinitionInfo const* mdi =
+ this->GeneratorTarget->GetModuleDefinitionInfo(this->GetConfigName());
+ if (mdi && !mdi->WindowsExportAllSymbols && !mdi->DefFile.empty()) {
+ result.push_back(this->ConvertToNinjaPath(mdi->DefFile));
}
// Add a dependency on user-specified manifest files, if any.
diff --git a/Source/cmOrderDirectories.cxx b/Source/cmOrderDirectories.cxx
index 7744a5a..d48eb53 100644
--- a/Source/cmOrderDirectories.cxx
+++ b/Source/cmOrderDirectories.cxx
@@ -287,8 +287,7 @@ void cmOrderDirectories::AddRuntimeLibrary(std::string const& fullPath,
}
}
- if (this->ImplicitDirectories.find(dir) !=
- this->ImplicitDirectories.end()) {
+ if (this->IsImplicitDirectory(dir)) {
this->ImplicitDirEntries.push_back(
new cmOrderDirectoriesConstraintSOName(this, fullPath, soname));
return;
@@ -316,8 +315,7 @@ void cmOrderDirectories::AddLinkLibrary(std::string const& fullPath)
// Implicit link directories need special handling.
if (!this->ImplicitDirectories.empty()) {
std::string dir = cmSystemTools::GetFilenamePath(fullPath);
- if (this->ImplicitDirectories.find(dir) !=
- this->ImplicitDirectories.end()) {
+ if (this->IsImplicitDirectory(dir)) {
this->ImplicitDirEntries.push_back(
new cmOrderDirectoriesConstraintLibrary(this, fullPath));
return;
@@ -347,7 +345,18 @@ void cmOrderDirectories::AddLanguageDirectories(
void cmOrderDirectories::SetImplicitDirectories(
std::set<std::string> const& implicitDirs)
{
- this->ImplicitDirectories = implicitDirs;
+ this->ImplicitDirectories.clear();
+ for (std::set<std::string>::const_iterator i = implicitDirs.begin();
+ i != implicitDirs.end(); ++i) {
+ this->ImplicitDirectories.insert(this->GetRealPath(*i));
+ }
+}
+
+bool cmOrderDirectories::IsImplicitDirectory(std::string const& dir)
+{
+ std::string const& real = this->GetRealPath(dir);
+ return this->ImplicitDirectories.find(real) !=
+ this->ImplicitDirectories.end();
}
void cmOrderDirectories::SetLinkExtensionInfo(
@@ -394,8 +403,7 @@ void cmOrderDirectories::AddOriginalDirectories(
for (std::vector<std::string>::const_iterator di = dirs.begin();
di != dirs.end(); ++di) {
// We never explicitly specify implicit link directories.
- if (this->ImplicitDirectories.find(*di) !=
- this->ImplicitDirectories.end()) {
+ if (this->IsImplicitDirectory(*di)) {
continue;
}
diff --git a/Source/cmOrderDirectories.h b/Source/cmOrderDirectories.h
index 90a67e7..d9e0126 100644
--- a/Source/cmOrderDirectories.h
+++ b/Source/cmOrderDirectories.h
@@ -82,6 +82,8 @@ private:
// Compare directories after resolving symlinks.
bool IsSameDirectory(std::string const& l, std::string const& r);
+ bool IsImplicitDirectory(std::string const& dir);
+
std::string const& GetRealPath(std::string const& dir);
std::map<std::string, std::string> RealPaths;
diff --git a/Source/cmQtAutoGeneratorCommon.cxx b/Source/cmQtAutoGeneratorCommon.cxx
new file mode 100644
index 0000000..dcd61a3
--- /dev/null
+++ b/Source/cmQtAutoGeneratorCommon.cxx
@@ -0,0 +1,215 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmQtAutoGeneratorCommon.h"
+#include "cmAlgorithms.h"
+#include "cmSystemTools.h"
+
+#include <cmsys/FStream.hxx>
+#include <cmsys/RegularExpression.hxx>
+
+#include <sstream>
+
+// - Static functions
+
+static std::string utilStripCR(std::string const& line)
+{
+ // Strip CR characters rcc may have printed (possibly more than one!).
+ std::string::size_type cr = line.find('\r');
+ if (cr != line.npos) {
+ return line.substr(0, cr);
+ }
+ return line;
+}
+
+/// @brief Reads the resource files list from from a .qrc file - Qt4 version
+/// @return True if the .qrc file was successfully parsed
+static bool RccListInputsQt4(const std::string& fileName,
+ std::vector<std::string>& files,
+ std::string* errorMessage)
+{
+ bool allGood = true;
+ // Read qrc file content into string
+ std::string qrcContents;
+ {
+ cmsys::ifstream ifs(fileName.c_str());
+ if (ifs) {
+ std::ostringstream osst;
+ osst << ifs.rdbuf();
+ qrcContents = osst.str();
+ } else {
+ if (errorMessage != CM_NULLPTR) {
+ std::ostringstream ost;
+ ost << "AutoRcc: Error: Rcc file not readable:\n"
+ << cmQtAutoGeneratorCommon::Quoted(fileName) << "\n";
+ *errorMessage = ost.str();
+ }
+ allGood = false;
+ }
+ }
+ if (allGood) {
+ // qrc file directory
+ std::string qrcDir(cmsys::SystemTools::GetFilenamePath(fileName));
+ if (!qrcDir.empty()) {
+ qrcDir += '/';
+ }
+
+ cmsys::RegularExpression fileMatchRegex("(<file[^<]+)");
+ cmsys::RegularExpression fileReplaceRegex("(^<file[^>]*>)");
+
+ size_t offset = 0;
+ while (fileMatchRegex.find(qrcContents.c_str() + offset)) {
+ std::string qrcEntry = fileMatchRegex.match(1);
+ offset += qrcEntry.size();
+ {
+ fileReplaceRegex.find(qrcEntry);
+ std::string tag = fileReplaceRegex.match(1);
+ qrcEntry = qrcEntry.substr(tag.size());
+ }
+ if (!cmSystemTools::FileIsFullPath(qrcEntry.c_str())) {
+ qrcEntry = qrcDir + qrcEntry;
+ }
+ files.push_back(qrcEntry);
+ }
+ }
+ return allGood;
+}
+
+/// @brief Reads the resource files list from from a .qrc file - Qt5 version
+/// @return True if the .qrc file was successfully parsed
+static bool RccListInputsQt5(const std::string& rccCommand,
+ const std::string& fileName,
+ std::vector<std::string>& files,
+ std::string* errorMessage)
+{
+ if (rccCommand.empty()) {
+ cmSystemTools::Error("AutoRcc: Error: rcc executable not available\n");
+ return false;
+ }
+
+ // Read rcc features
+ bool hasDashDashList = false;
+ {
+ std::vector<std::string> command;
+ command.push_back(rccCommand);
+ command.push_back("--help");
+ std::string rccStdOut;
+ std::string rccStdErr;
+ int retVal = 0;
+ bool result =
+ cmSystemTools::RunSingleCommand(command, &rccStdOut, &rccStdErr, &retVal,
+ CM_NULLPTR, cmSystemTools::OUTPUT_NONE);
+ if (result && retVal == 0 &&
+ rccStdOut.find("--list") != std::string::npos) {
+ hasDashDashList = true;
+ }
+ }
+
+ // Run rcc list command
+ bool result = false;
+ int retVal = 0;
+ std::string rccStdOut;
+ std::string rccStdErr;
+ {
+ std::vector<std::string> command;
+ command.push_back(rccCommand);
+ command.push_back(hasDashDashList ? "--list" : "-list");
+ command.push_back(fileName);
+ result =
+ cmSystemTools::RunSingleCommand(command, &rccStdOut, &rccStdErr, &retVal,
+ CM_NULLPTR, cmSystemTools::OUTPUT_NONE);
+ }
+ if (!result || retVal) {
+ if (errorMessage != CM_NULLPTR) {
+ std::ostringstream ost;
+ ost << "AutoRcc: Error: Rcc list process for " << fileName
+ << " failed:\n"
+ << rccStdOut << "\n"
+ << rccStdErr << "\n";
+ *errorMessage = ost.str();
+ }
+ return false;
+ }
+
+ // Parse rcc std output
+ {
+ std::istringstream ostr(rccStdOut);
+ std::string oline;
+ while (std::getline(ostr, oline)) {
+ oline = utilStripCR(oline);
+ if (!oline.empty()) {
+ files.push_back(oline);
+ }
+ }
+ }
+ // Parse rcc error output
+ {
+ std::istringstream estr(rccStdErr);
+ std::string eline;
+ while (std::getline(estr, eline)) {
+ eline = utilStripCR(eline);
+ if (cmHasLiteralPrefix(eline, "RCC: Error in")) {
+ static std::string searchString = "Cannot find file '";
+
+ std::string::size_type pos = eline.find(searchString);
+ if (pos == std::string::npos) {
+ if (errorMessage != CM_NULLPTR) {
+ std::ostringstream ost;
+ ost << "AutoRcc: Error: Rcc lists unparsable output:\n"
+ << cmQtAutoGeneratorCommon::Quoted(eline) << "\n";
+ *errorMessage = ost.str();
+ }
+ return false;
+ }
+ pos += searchString.length();
+ std::string::size_type sz = eline.size() - pos - 1;
+ files.push_back(eline.substr(pos, sz));
+ }
+ }
+ }
+
+ return true;
+}
+
+// - Class definitions
+
+const char* cmQtAutoGeneratorCommon::listSep = "@LSEP@";
+
+std::string cmQtAutoGeneratorCommon::Quoted(const std::string& text)
+{
+ static const char* rep[18] = { "\\", "\\\\", "\"", "\\\"", "\a", "\\a",
+ "\b", "\\b", "\f", "\\f", "\n", "\\n",
+ "\r", "\\r", "\t", "\\t", "\v", "\\v" };
+
+ std::string res = text;
+ for (const char* const* it = cmArrayBegin(rep); it != cmArrayEnd(rep);
+ it += 2) {
+ cmSystemTools::ReplaceString(res, *it, *(it + 1));
+ }
+ res = '"' + res;
+ res += '"';
+ return res;
+}
+
+bool cmQtAutoGeneratorCommon::RccListInputs(const std::string& qtMajorVersion,
+ const std::string& rccCommand,
+ const std::string& fileName,
+ std::vector<std::string>& files,
+ std::string* errorMessage)
+{
+ bool allGood = false;
+ if (cmsys::SystemTools::FileExists(fileName.c_str())) {
+ if (qtMajorVersion == "4") {
+ allGood = RccListInputsQt4(fileName, files, errorMessage);
+ } else {
+ allGood = RccListInputsQt5(rccCommand, fileName, files, errorMessage);
+ }
+ } else {
+ if (errorMessage != CM_NULLPTR) {
+ std::ostringstream ost;
+ ost << "AutoRcc: Error: Rcc file does not exist:\n"
+ << cmQtAutoGeneratorCommon::Quoted(fileName) << "\n";
+ *errorMessage = ost.str();
+ }
+ }
+ return allGood;
+}
diff --git a/Source/cmQtAutoGeneratorCommon.h b/Source/cmQtAutoGeneratorCommon.h
new file mode 100644
index 0000000..ee97b71
--- /dev/null
+++ b/Source/cmQtAutoGeneratorCommon.h
@@ -0,0 +1,34 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cmQtAutoGeneratorCommon_h
+#define cmQtAutoGeneratorCommon_h
+
+#include <cmConfigure.h> // IWYU pragma: keep
+#include <string>
+#include <vector>
+
+class cmGeneratorTarget;
+class cmLocalGenerator;
+
+class cmQtAutoGeneratorCommon
+{
+ // - Types and statics
+public:
+ static const char* listSep;
+
+public:
+ /// @brief Returns a the string escaped and enclosed in quotes
+ ///
+ static std::string Quoted(const std::string& text);
+
+ /// @brief Reads the resource files list from from a .qrc file
+ /// @arg fileName Must be the absolute path of the .qrc file
+ /// @return True if the rcc file was successfully parsed
+ static bool RccListInputs(const std::string& qtMajorVersion,
+ const std::string& rccCommand,
+ const std::string& fileName,
+ std::vector<std::string>& files,
+ std::string* errorMessage = CM_NULLPTR);
+};
+
+#endif
diff --git a/Source/cmQtAutoGeneratorInitializer.cxx b/Source/cmQtAutoGeneratorInitializer.cxx
index a45b3d5..94cc981 100644
--- a/Source/cmQtAutoGeneratorInitializer.cxx
+++ b/Source/cmQtAutoGeneratorInitializer.cxx
@@ -1,6 +1,7 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmQtAutoGeneratorInitializer.h"
+#include "cmQtAutoGeneratorCommon.h"
#include "cmAlgorithms.h"
#include "cmCustomCommandLines.h"
@@ -44,14 +45,9 @@ static void utilCopyTargetProperty(cmTarget* destinationTarget,
}
}
-static std::string utilStripCR(std::string const& line)
+inline static bool PropertyEnabled(cmSourceFile* sourceFile, const char* key)
{
- // Strip CR characters rcc may have printed (possibly more than one!).
- std::string::size_type cr = line.find('\r');
- if (cr != line.npos) {
- return line.substr(0, cr);
- }
- return line;
+ return cmSystemTools::IsOn(sourceFile->GetPropertyForUser(key));
}
static std::string GetSafeProperty(cmGeneratorTarget const* target,
@@ -138,21 +134,17 @@ static void AddDefinitionEscaped(cmMakefile* makefile, const char* key,
key, cmOutputConverter::EscapeForCMake(cmJoin(values, ";")).c_str());
}
-static void SetupSourceFiles(cmGeneratorTarget const* target,
+static void AcquireScanFiles(cmGeneratorTarget const* target,
std::vector<std::string>& mocUicSources,
std::vector<std::string>& mocUicHeaders,
std::vector<std::string>& mocSkipList,
std::vector<std::string>& uicSkipList)
{
- cmMakefile* makefile = target->Target->GetMakefile();
-
- std::vector<cmSourceFile*> srcFiles;
- target->GetConfigCommonSourceFiles(srcFiles);
-
const bool mocTarget = target->GetPropertyAsBool("AUTOMOC");
const bool uicTarget = target->GetPropertyAsBool("AUTOUIC");
- cmFilePathChecksum fpathCheckSum(makefile);
+ std::vector<cmSourceFile*> srcFiles;
+ target->GetConfigCommonSourceFiles(srcFiles);
for (std::vector<cmSourceFile*>::const_iterator fileIt = srcFiles.begin();
fileIt != srcFiles.end(); ++fileIt) {
cmSourceFile* sf = *fileIt;
@@ -163,18 +155,12 @@ static void SetupSourceFiles(cmGeneratorTarget const* target,
!(fileType == cmSystemTools::HEADER_FILE_FORMAT)) {
continue;
}
- if (cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED"))) {
- continue;
- }
const std::string absFile =
cmsys::SystemTools::GetRealPath(sf->GetFullPath());
// Skip flags
- const bool skipAll =
- cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTOGEN"));
- const bool mocSkip =
- skipAll || cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTOMOC"));
- const bool uicSkip =
- skipAll || cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTOUIC"));
+ const bool skipAll = PropertyEnabled(sf, "SKIP_AUTOGEN");
+ const bool mocSkip = skipAll || PropertyEnabled(sf, "SKIP_AUTOMOC");
+ const bool uicSkip = skipAll || PropertyEnabled(sf, "SKIP_AUTOUIC");
// Add file name to skip lists.
// Do this even when the file is not added to the sources/headers lists
// because the file name may be extracted from an other file when
@@ -361,7 +347,8 @@ static void UicSetupAutoTarget(
uiFileFiles.push_back(absFile);
{
std::string opts = sf->GetProperty("AUTOUIC_OPTIONS");
- cmSystemTools::ReplaceString(opts, ";", "@list_sep@");
+ cmSystemTools::ReplaceString(opts, ";",
+ cmQtAutoGeneratorCommon::listSep);
uiFileOptions.push_back(opts);
}
}
@@ -469,146 +456,12 @@ static void RccMergeOptions(std::vector<std::string>& opts,
opts.insert(opts.end(), extraOpts.begin(), extraOpts.end());
}
-/// @brief Reads the resource files list from from a .qrc file - Qt5 version
-/// @return True if the .qrc file was successfully parsed
-static bool RccListInputsQt5(cmSourceFile* sf, cmGeneratorTarget const* target,
- std::vector<std::string>& depends)
-{
- const std::string rccCommand = RccGetExecutable(target, "5");
- if (rccCommand.empty()) {
- cmSystemTools::Error("AUTOGEN: error: rcc executable not available\n");
- return false;
- }
-
- bool hasDashDashList = false;
- // Read rcc features
- {
- std::vector<std::string> command;
- command.push_back(rccCommand);
- command.push_back("--help");
- std::string rccStdOut;
- std::string rccStdErr;
- int retVal = 0;
- bool result =
- cmSystemTools::RunSingleCommand(command, &rccStdOut, &rccStdErr, &retVal,
- CM_NULLPTR, cmSystemTools::OUTPUT_NONE);
- if (result && retVal == 0 &&
- rccStdOut.find("--list") != std::string::npos) {
- hasDashDashList = true;
- }
- }
- // Run rcc list command
- std::vector<std::string> command;
- command.push_back(rccCommand);
- command.push_back(hasDashDashList ? "--list" : "-list");
-
- std::string absFile = cmsys::SystemTools::GetRealPath(sf->GetFullPath());
- command.push_back(absFile);
-
- std::string rccStdOut;
- std::string rccStdErr;
- int retVal = 0;
- bool result =
- cmSystemTools::RunSingleCommand(command, &rccStdOut, &rccStdErr, &retVal,
- CM_NULLPTR, cmSystemTools::OUTPUT_NONE);
- if (!result || retVal) {
- std::ostringstream err;
- err << "AUTOGEN: error: Rcc list process for " << sf->GetFullPath()
- << " failed:\n"
- << rccStdOut << "\n"
- << rccStdErr << std::endl;
- cmSystemTools::Error(err.str().c_str());
- return false;
- }
-
- // Parse rcc list output
- {
- std::istringstream ostr(rccStdOut);
- std::string oline;
- while (std::getline(ostr, oline)) {
- oline = utilStripCR(oline);
- if (!oline.empty()) {
- depends.push_back(oline);
- }
- }
- }
-
- {
- std::istringstream estr(rccStdErr);
- std::string eline;
- while (std::getline(estr, eline)) {
- eline = utilStripCR(eline);
- if (cmHasLiteralPrefix(eline, "RCC: Error in")) {
- static std::string searchString = "Cannot find file '";
-
- std::string::size_type pos = eline.find(searchString);
- if (pos == std::string::npos) {
- std::ostringstream err;
- err << "AUTOGEN: error: Rcc lists unparsable output " << eline
- << std::endl;
- cmSystemTools::Error(err.str().c_str());
- return false;
- }
- pos += searchString.length();
- std::string::size_type sz = eline.size() - pos - 1;
- depends.push_back(eline.substr(pos, sz));
- }
- }
- }
-
- return true;
-}
-
-/// @brief Reads the resource files list from from a .qrc file - Qt4 version
-/// @return True if the .qrc file was successfully parsed
-static bool RccListInputsQt4(cmSourceFile* sf,
- std::vector<std::string>& depends)
-{
- // Read file into string
- std::string qrcContents;
- {
- std::ostringstream stream;
- stream << cmsys::ifstream(sf->GetFullPath().c_str()).rdbuf();
- qrcContents = stream.str();
- }
-
- cmsys::RegularExpression fileMatchRegex("(<file[^<]+)");
- cmsys::RegularExpression fileReplaceRegex("(^<file[^>]*>)");
-
- size_t offset = 0;
- while (fileMatchRegex.find(qrcContents.c_str() + offset)) {
- std::string qrcEntry = fileMatchRegex.match(1);
- offset += qrcEntry.size();
- {
- fileReplaceRegex.find(qrcEntry);
- std::string tag = fileReplaceRegex.match(1);
- qrcEntry = qrcEntry.substr(tag.size());
- }
- if (!cmSystemTools::FileIsFullPath(qrcEntry.c_str())) {
- qrcEntry = sf->GetLocation().GetDirectory() + "/" + qrcEntry;
- }
- depends.push_back(qrcEntry);
- }
- return true;
-}
-
-/// @brief Reads the resource files list from from a .qrc file
-/// @return True if the rcc file was successfully parsed
-static bool RccListInputs(const std::string& qtMajorVersion, cmSourceFile* sf,
- cmGeneratorTarget const* target,
- std::vector<std::string>& depends)
-{
- if (qtMajorVersion == "5") {
- return RccListInputsQt5(sf, target, depends);
- }
- return RccListInputsQt4(sf, depends);
-}
-
static void RccSetupAutoTarget(cmGeneratorTarget const* target,
const std::string& qtMajorVersion)
{
cmMakefile* makefile = target->Target->GetMakefile();
const bool qtMajorVersion5 = (qtMajorVersion == "5");
+ const std::string rccCommand = RccGetExecutable(target, qtMajorVersion);
std::vector<std::string> _rcc_files;
std::vector<std::string> _rcc_inputs;
std::vector<std::string> rccFileFiles;
@@ -623,53 +476,54 @@ static void RccSetupAutoTarget(cmGeneratorTarget const* target,
for (std::vector<cmSourceFile*>::const_iterator fileIt = srcFiles.begin();
fileIt != srcFiles.end(); ++fileIt) {
cmSourceFile* sf = *fileIt;
- if (sf->GetExtension() == "qrc") {
- const bool skip =
- cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTOGEN")) ||
- cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTORCC"));
- if (!skip) {
- const std::string absFile =
- cmsys::SystemTools::GetRealPath(sf->GetFullPath());
- // qrc file
- _rcc_files.push_back(absFile);
- // qrc file entries
- {
- std::string entriesList;
- if (!cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED"))) {
- std::vector<std::string> depends;
- if (RccListInputs(qtMajorVersion, sf, target, depends)) {
- entriesList = cmJoin(depends, "@list_sep@");
- } else {
- return;
- }
+ if ((sf->GetExtension() == "qrc") &&
+ !PropertyEnabled(sf, "SKIP_AUTOGEN") &&
+ !PropertyEnabled(sf, "SKIP_AUTORCC")) {
+ const std::string absFile =
+ cmsys::SystemTools::GetRealPath(sf->GetFullPath());
+ // qrc file
+ _rcc_files.push_back(absFile);
+ // qrc file entries
+ {
+ std::string entriesList = "{";
+ // Read input file list only for non generated .qrc files.
+ if (!PropertyEnabled(sf, "GENERATED")) {
+ std::string error;
+ std::vector<std::string> files;
+ if (cmQtAutoGeneratorCommon::RccListInputs(
+ qtMajorVersion, rccCommand, absFile, files, &error)) {
+ entriesList += cmJoin(files, cmQtAutoGeneratorCommon::listSep);
+ } else {
+ cmSystemTools::Error(error.c_str());
}
- _rcc_inputs.push_back(entriesList);
}
- // rcc options for this qrc file
- {
- // Merged target and file options
- std::vector<std::string> rccOptions(rccOptionsTarget);
- if (const char* prop = sf->GetProperty("AUTORCC_OPTIONS")) {
- std::vector<std::string> optsVec;
- cmSystemTools::ExpandListArgument(prop, optsVec);
- RccMergeOptions(rccOptions, optsVec, qtMajorVersion5);
- }
- // Only store non empty options lists
- if (!rccOptions.empty()) {
- rccFileFiles.push_back(absFile);
- rccFileOptions.push_back(cmJoin(rccOptions, "@list_sep@"));
- }
+ entriesList += "}";
+ _rcc_inputs.push_back(entriesList);
+ }
+ // rcc options for this qrc file
+ {
+ // Merged target and file options
+ std::vector<std::string> rccOptions(rccOptionsTarget);
+ if (const char* prop = sf->GetProperty("AUTORCC_OPTIONS")) {
+ std::vector<std::string> optsVec;
+ cmSystemTools::ExpandListArgument(prop, optsVec);
+ RccMergeOptions(rccOptions, optsVec, qtMajorVersion5);
+ }
+ // Only store non empty options lists
+ if (!rccOptions.empty()) {
+ rccFileFiles.push_back(absFile);
+ rccFileOptions.push_back(
+ cmJoin(rccOptions, cmQtAutoGeneratorCommon::listSep));
}
}
}
}
+ AddDefinitionEscaped(makefile, "_qt_rcc_executable", rccCommand);
AddDefinitionEscaped(makefile, "_rcc_files", _rcc_files);
AddDefinitionEscaped(makefile, "_rcc_inputs", _rcc_inputs);
AddDefinitionEscaped(makefile, "_rcc_options_files", rccFileFiles);
AddDefinitionEscaped(makefile, "_rcc_options_options", rccFileOptions);
- AddDefinitionEscaped(makefile, "_qt_rcc_executable",
- RccGetExecutable(target, qtMajorVersion));
}
void cmQtAutoGeneratorInitializer::InitializeAutogenSources(
@@ -691,12 +545,17 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget(
cmMakefile* makefile = target->Target->GetMakefile();
// Create a custom target for running generators at buildtime
+ const bool mocEnabled = target->GetPropertyAsBool("AUTOMOC");
+ const bool uicEnabled = target->GetPropertyAsBool("AUTOUIC");
+ const bool rccEnabled = target->GetPropertyAsBool("AUTORCC");
const std::string autogenTargetName = GetAutogenTargetName(target);
const std::string autogenBuildDir = GetAutogenTargetBuildDir(target);
const std::string workingDirectory =
cmSystemTools::CollapseFullPath("", makefile->GetCurrentBinaryDirectory());
const std::string qtMajorVersion = GetQtMajorVersion(target);
- std::vector<std::string> autogenOutputFiles;
+ const std::string rccCommand = RccGetExecutable(target, qtMajorVersion);
+ std::vector<std::string> autogenDepends;
+ std::vector<std::string> autogenProvides;
// Remove old settings on cleanup
{
@@ -706,32 +565,6 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget(
false);
}
- // Create autogen target build directory and add it to the clean files
- cmSystemTools::MakeDirectory(autogenBuildDir);
- makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES",
- autogenBuildDir.c_str(), false);
-
- if (target->GetPropertyAsBool("AUTOMOC") ||
- target->GetPropertyAsBool("AUTOUIC")) {
- // Create autogen target includes directory and
- // add it to the origin target INCLUDE_DIRECTORIES
- const std::string incsDir = autogenBuildDir + "include";
- cmSystemTools::MakeDirectory(incsDir);
- target->AddIncludeDirectory(incsDir, true);
- }
-
- if (target->GetPropertyAsBool("AUTOMOC")) {
- // Register moc compilation file as generated
- autogenOutputFiles.push_back(autogenBuildDir + "moc_compilation.cpp");
- }
-
- // Initialize autogen target dependencies
- std::vector<std::string> depends;
- if (const char* autogenDepends =
- target->GetProperty("AUTOGEN_TARGET_DEPENDS")) {
- cmSystemTools::ExpandListArgument(autogenDepends, depends);
- }
-
// Compose command lines
cmCustomCommandLines commandLines;
{
@@ -748,13 +581,13 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget(
std::string autogenComment;
{
std::vector<std::string> toolNames;
- if (target->GetPropertyAsBool("AUTOMOC")) {
+ if (mocEnabled) {
toolNames.push_back("MOC");
}
- if (target->GetPropertyAsBool("AUTOUIC")) {
+ if (uicEnabled) {
toolNames.push_back("UIC");
}
- if (target->GetPropertyAsBool("AUTORCC")) {
+ if (rccEnabled) {
toolNames.push_back("RCC");
}
@@ -770,6 +603,24 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget(
autogenComment = "Automatic " + tools + " for target " + target->GetName();
}
+ // Create autogen target build directory and add it to the clean files
+ cmSystemTools::MakeDirectory(autogenBuildDir);
+ makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES",
+ autogenBuildDir.c_str(), false);
+
+ // Create autogen target includes directory and
+ // add it to the origin target INCLUDE_DIRECTORIES
+ if (mocEnabled || uicEnabled) {
+ const std::string incsDir = autogenBuildDir + "include";
+ cmSystemTools::MakeDirectory(incsDir);
+ target->AddIncludeDirectory(incsDir, true);
+ }
+
+ // Register moc compilation file as generated
+ if (mocEnabled) {
+ autogenProvides.push_back(autogenBuildDir + "moc_compilation.cpp");
+ }
+
#if defined(_WIN32) && !defined(__CYGWIN__)
bool usePRE_BUILD = false;
cmGlobalGenerator* gg = lg->GetGlobalGenerator();
@@ -781,65 +632,100 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget(
// 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;
- if (usePRE_BUILD) {
- // If the autogen target depends on an other target
- // don't use PRE_BUILD
- for (std::vector<std::string>::iterator it = depends.begin();
- it != depends.end(); ++it) {
- if (!makefile->FindTargetToUse(it->c_str())) {
- usePRE_BUILD = false;
- break;
- }
- }
- }
}
#endif
- if (target->GetPropertyAsBool("AUTORCC")) {
+ // Initialize autogen target dependencies
+ if (const char* deps = target->GetProperty("AUTOGEN_TARGET_DEPENDS")) {
+ cmSystemTools::ExpandListArgument(deps, autogenDepends);
+ }
+ // Add link library targets to the autogen dependencies
+ {
+ const cmTarget::LinkLibraryVectorType& libVec =
+ target->Target->GetOriginalLinkLibraries();
+ for (cmTarget::LinkLibraryVectorType::const_iterator it = libVec.begin();
+ it != libVec.end(); ++it) {
+ const std::string& libName = it->first;
+ if (makefile->FindTargetToUse(libName) != CM_NULLPTR) {
+ autogenDepends.push_back(libName);
+ }
+ }
+ }
+ {
cmFilePathChecksum fpathCheckSum(makefile);
+ // Iterate over all source files
std::vector<cmSourceFile*> srcFiles;
target->GetConfigCommonSourceFiles(srcFiles);
for (std::vector<cmSourceFile*>::const_iterator fileIt = srcFiles.begin();
fileIt != srcFiles.end(); ++fileIt) {
cmSourceFile* sf = *fileIt;
- if (sf->GetExtension() == "qrc" &&
- !cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTOGEN")) &&
- !cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTORCC"))) {
- {
+ if (!PropertyEnabled(sf, "SKIP_AUTOGEN")) {
+ const std::string ext = sf->GetExtension();
+ // Add generated file that will be scanned by moc or uic to
+ // the dependencies
+ if (mocEnabled || uicEnabled) {
+ const cmSystemTools::FileFormat fileType =
+ cmSystemTools::GetFileFormat(ext.c_str());
+ if ((fileType == cmSystemTools::CXX_FILE_FORMAT) ||
+ (fileType == cmSystemTools::HEADER_FILE_FORMAT)) {
+ if (PropertyEnabled(sf, "GENERATED")) {
+ if ((mocEnabled && !PropertyEnabled(sf, "SKIP_AUTOMOC")) ||
+ (uicEnabled && !PropertyEnabled(sf, "SKIP_AUTOUIC"))) {
+ autogenDepends.push_back(
+ cmsys::SystemTools::GetRealPath(sf->GetFullPath()));
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ // Cannot use PRE_BUILD with generated files
+ usePRE_BUILD = false;
+#endif
+ }
+ }
+ }
+ }
+ // Process rcc enabled files
+ if (rccEnabled && (ext == "qrc") &&
+ !PropertyEnabled(sf, "SKIP_AUTORCC")) {
const std::string absFile =
cmsys::SystemTools::GetRealPath(sf->GetFullPath());
- // Run cmake again when .qrc file changes
- makefile->AddCMakeDependFile(absFile);
-
- std::string rccOutputFile = autogenBuildDir;
- rccOutputFile += fpathCheckSum.getPart(absFile);
- rccOutputFile += "/qrc_";
- rccOutputFile +=
- cmsys::SystemTools::GetFilenameWithoutLastExtension(absFile);
- rccOutputFile += ".cpp";
-
- // Add rcc output file to origin target sources
- cmSourceFile* gf = makefile->GetOrCreateSource(rccOutputFile, true);
- gf->SetProperty("SKIP_AUTOGEN", "On");
- target->AddSource(rccOutputFile);
- // Register rcc output file as generated
- autogenOutputFiles.push_back(rccOutputFile);
- }
- if (lg->GetGlobalGenerator()->GetName() == "Ninja"
-#if defined(_WIN32) && !defined(__CYGWIN__)
- || usePRE_BUILD
-#endif
- ) {
- if (!cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED"))) {
- RccListInputs(qtMajorVersion, sf, target, depends);
+ // Compose rcc output file name
+ {
+ std::string rccOut = autogenBuildDir;
+ rccOut += fpathCheckSum.getPart(absFile);
+ rccOut += "/qrc_";
+ rccOut +=
+ cmsys::SystemTools::GetFilenameWithoutLastExtension(absFile);
+ rccOut += ".cpp";
+
+ // Register rcc output file as generated
+ autogenProvides.push_back(rccOut);
+
+ // Add rcc output file to origin target sources
+ cmSourceFile* gf = makefile->GetOrCreateSource(rccOut, true);
+ gf->SetProperty("SKIP_AUTOGEN", "On");
+ target->AddSource(rccOut);
+ }
+
+ if (PropertyEnabled(sf, "GENERATED")) {
+ // Add generated qrc file to the dependencies
+ autogenDepends.push_back(absFile);
+ } else {
+ // Run cmake again when .qrc file changes
+ makefile->AddCMakeDependFile(absFile);
+
+ // Add the qrc input files to the dependencies
+ std::string error;
+ if (!cmQtAutoGeneratorCommon::RccListInputs(
+ qtMajorVersion, rccCommand, absFile, autogenDepends,
+ &error)) {
+ cmSystemTools::Error(error.c_str());
+ }
+ }
#if defined(_WIN32) && !defined(__CYGWIN__)
- // Cannot use PRE_BUILD because the resource files themselves
- // may not be sources within the target so VS may not know the
- // target needs to re-build at all.
- usePRE_BUILD = false;
+ // Cannot use PRE_BUILD because the resource files themselves
+ // may not be sources within the target so VS may not know the
+ // target needs to re-build at all.
+ usePRE_BUILD = false;
#endif
- }
}
}
}
@@ -847,12 +733,21 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget(
#if defined(_WIN32) && !defined(__CYGWIN__)
if (usePRE_BUILD) {
+ // If the autogen target depends on an other target don't use PRE_BUILD
+ for (std::vector<std::string>::iterator it = autogenDepends.begin();
+ it != autogenDepends.end(); ++it) {
+ if (makefile->FindTargetToUse(*it) != CM_NULLPTR) {
+ usePRE_BUILD = false;
+ break;
+ }
+ }
+ }
+ if (usePRE_BUILD) {
// Add the pre-build command directly to bypass the OBJECT_LIBRARY
// rejection in cmMakefile::AddCustomCommandToTarget because we know
// PRE_BUILD will work for an OBJECT_LIBRARY in this specific case.
std::vector<std::string> no_output;
- std::vector<std::string> no_byproducts;
- cmCustomCommand cc(makefile, no_output, no_byproducts, depends,
+ cmCustomCommand cc(makefile, no_output, autogenProvides, autogenDepends,
commandLines, autogenComment.c_str(),
workingDirectory.c_str());
cc.SetEscapeOldStyle(false);
@@ -863,7 +758,7 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget(
{
cmTarget* autogenTarget = makefile->AddUtilityCommand(
autogenTargetName, true, workingDirectory.c_str(),
- /*byproducts=*/autogenOutputFiles, depends, commandLines, false,
+ /*byproducts=*/autogenProvides, autogenDepends, commandLines, false,
autogenComment.c_str());
cmGeneratorTarget* gt = new cmGeneratorTarget(autogenTarget, lg);
@@ -900,38 +795,37 @@ void cmQtAutoGeneratorInitializer::SetupAutoGenerateTarget(
std::map<std::string, std::string> configMocDefines;
std::map<std::string, std::string> configUicOptions;
{
- // create a custom target for running generators at buildtime:
+ const bool mocEnabled = target->GetPropertyAsBool("AUTOMOC");
+ const bool uicEnabled = target->GetPropertyAsBool("AUTOUIC");
+ const bool rccEnabled = target->GetPropertyAsBool("AUTORCC");
const std::string autogenTargetName = GetAutogenTargetName(target);
const std::string qtMajorVersion = GetQtMajorVersion(target);
- AddDefinitionEscaped(makefile, "_autogen_target_name", autogenTargetName);
- AddDefinitionEscaped(makefile, "_origin_target_name", target->GetName());
- AddDefinitionEscaped(makefile, "_qt_version_major", qtMajorVersion);
-
std::vector<std::string> _sources;
std::vector<std::string> _headers;
- std::vector<std::string> mocSkipList;
- std::vector<std::string> uicSkipList;
- if (target->GetPropertyAsBool("AUTOMOC") ||
- target->GetPropertyAsBool("AUTOUIC") ||
- target->GetPropertyAsBool("AUTORCC")) {
- SetupSourceFiles(target, _sources, _headers, mocSkipList, uicSkipList);
+ if (mocEnabled || uicEnabled || rccEnabled) {
+ std::vector<std::string> mocSkipList;
+ std::vector<std::string> uicSkipList;
+ AcquireScanFiles(target, _sources, _headers, mocSkipList, uicSkipList);
+ if (mocEnabled) {
+ MocSetupAutoTarget(target, autogenTargetName, qtMajorVersion,
+ mocSkipList, configMocIncludes, configMocDefines);
+ }
+ if (uicEnabled) {
+ UicSetupAutoTarget(target, qtMajorVersion, uicSkipList,
+ configUicOptions);
+ }
+ if (rccEnabled) {
+ RccSetupAutoTarget(target, qtMajorVersion);
+ }
}
+
+ AddDefinitionEscaped(makefile, "_autogen_target_name", autogenTargetName);
+ AddDefinitionEscaped(makefile, "_origin_target_name", target->GetName());
+ AddDefinitionEscaped(makefile, "_qt_version_major", qtMajorVersion);
AddDefinitionEscaped(makefile, "_sources", _sources);
AddDefinitionEscaped(makefile, "_headers", _headers);
-
- if (target->GetPropertyAsBool("AUTOMOC")) {
- MocSetupAutoTarget(target, autogenTargetName, qtMajorVersion,
- mocSkipList, configMocIncludes, configMocDefines);
- }
- if (target->GetPropertyAsBool("AUTOUIC")) {
- UicSetupAutoTarget(target, qtMajorVersion, uicSkipList,
- configUicOptions);
- }
- if (target->GetPropertyAsBool("AUTORCC")) {
- RccSetupAutoTarget(target, qtMajorVersion);
- }
}
// Generate config file
diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx
index c83f9a9..246dd8d 100644
--- a/Source/cmQtAutoGenerators.cxx
+++ b/Source/cmQtAutoGenerators.cxx
@@ -1,6 +1,7 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmQtAutoGenerators.h"
+#include "cmQtAutoGeneratorCommon.h"
#include <algorithm>
#include <assert.h>
@@ -36,23 +37,9 @@ static const char* SettingsKeyRcc = "AM_RCC_OLD_SETTINGS";
// -- Static functions
-/**
- * @brief Returns a the string escaped and enclosed in quotes
- */
-static std::string Quoted(const std::string& text)
+inline static std::string Quoted(const std::string& text)
{
- static const char* rep[18] = { "\\", "\\\\", "\"", "\\\"", "\a", "\\a",
- "\b", "\\b", "\f", "\\f", "\n", "\\n",
- "\r", "\\r", "\t", "\\t", "\v", "\\v" };
-
- std::string res = text;
- for (const char* const* it = cmArrayBegin(rep); it != cmArrayEnd(rep);
- it += 2) {
- cmSystemTools::ReplaceString(res, *it, *(it + 1));
- }
- res = '"' + res;
- res += '"';
- return res;
+ return cmQtAutoGeneratorCommon::Quoted(text);
}
static void InfoGet(cmMakefile* makefile, const char* key, std::string& value)
@@ -138,13 +125,19 @@ static bool FileNameIsUnique(const std::string& filePath,
return true;
}
-static std::string ReadAll(const std::string& filename)
+static bool ReadAll(std::string& content, const std::string& filename)
{
- cmsys::ifstream file(filename.c_str());
- std::ostringstream stream;
- stream << file.rdbuf();
- file.close();
- return stream.str();
+ bool success = false;
+ {
+ cmsys::ifstream ifs(filename.c_str());
+ if (ifs) {
+ std::ostringstream osst;
+ osst << ifs.rdbuf();
+ content = osst.str();
+ success = true;
+ }
+ }
+ return success;
}
/**
@@ -178,7 +171,7 @@ static std::string JoinOptionsMap(
for (std::map<std::string, std::string>::const_iterator it = opts.begin();
it != opts.end(); ++it) {
if (it != opts.begin()) {
- result += "@list_sep@";
+ result += cmQtAutoGeneratorCommon::listSep;
}
result += it->first;
result += "===";
@@ -402,7 +395,8 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile(
} else {
this->LogError(
"AutoMoc: Error: AUTOMOC_DEPEND_FILTERS list size is not "
- "a multiple of 2");
+ "a multiple of 2 in:\n" +
+ Quoted(filename));
return false;
}
}
@@ -424,13 +418,14 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile(
fileIt = uicFilesVec.begin(),
optionIt = uicOptionsVec.begin();
fileIt != uicFilesVec.end(); ++fileIt, ++optionIt) {
- cmSystemTools::ReplaceString(*optionIt, "@list_sep@", ";");
+ cmSystemTools::ReplaceString(*optionIt,
+ cmQtAutoGeneratorCommon::listSep, ";");
this->UicOptions[*fileIt] = *optionIt;
}
} else {
this->LogError(
- "AutoGen: Error: Uic files/options lists size missmatch in: " +
- filename);
+ "AutoGen: Error: Uic files/options lists size missmatch in:\n" +
+ Quoted(filename));
return false;
}
}
@@ -439,47 +434,53 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile(
// - Rcc
if (this->RccEnabled()) {
InfoGet(makefile, "AM_RCC_SOURCES", this->RccSources);
+ // File options
{
std::vector<std::string> rccFilesVec;
std::vector<std::string> rccOptionsVec;
InfoGet(makefile, "AM_RCC_OPTIONS_FILES", rccFilesVec);
InfoGet(makefile, "AM_RCC_OPTIONS_OPTIONS", rccOptionsVec);
- if (rccFilesVec.size() != rccOptionsVec.size()) {
+ if (rccFilesVec.size() == rccOptionsVec.size()) {
+ for (std::vector<std::string>::iterator
+ fileIt = rccFilesVec.begin(),
+ optionIt = rccOptionsVec.begin();
+ fileIt != rccFilesVec.end(); ++fileIt, ++optionIt) {
+ // Replace item separator
+ cmSystemTools::ReplaceString(*optionIt,
+ cmQtAutoGeneratorCommon::listSep, ";");
+ this->RccOptions[*fileIt] = *optionIt;
+ }
+ } else {
this->LogError(
- "AutoGen: Error: RCC files/options lists size missmatch in: " +
- filename);
+ "AutoGen: Error: RCC files/options lists size missmatch in:\n" +
+ Quoted(filename));
return false;
}
- for (std::vector<std::string>::iterator fileIt = rccFilesVec.begin(),
- optionIt = rccOptionsVec.begin();
- fileIt != rccFilesVec.end(); ++fileIt, ++optionIt) {
- cmSystemTools::ReplaceString(*optionIt, "@list_sep@", ";");
- this->RccOptions[*fileIt] = *optionIt;
- }
}
+ // File lists
{
std::vector<std::string> rccInputLists;
InfoGet(makefile, "AM_RCC_INPUTS", rccInputLists);
-
- // qrc files in the end of the list may have been empty
- if (rccInputLists.size() < this->RccSources.size()) {
- rccInputLists.resize(this->RccSources.size());
- }
- if (this->RccSources.size() != rccInputLists.size()) {
+ if (this->RccSources.size() == rccInputLists.size()) {
+ for (std::vector<std::string>::iterator
+ fileIt = this->RccSources.begin(),
+ inputIt = rccInputLists.begin();
+ fileIt != this->RccSources.end(); ++fileIt, ++inputIt) {
+ // Remove braces
+ *inputIt = inputIt->substr(1, inputIt->size() - 2);
+ // Replace item separator
+ cmSystemTools::ReplaceString(*inputIt,
+ cmQtAutoGeneratorCommon::listSep, ";");
+ std::vector<std::string> rccInputFiles;
+ cmSystemTools::ExpandListArgument(*inputIt, rccInputFiles);
+ this->RccInputs[*fileIt] = rccInputFiles;
+ }
+ } else {
this->LogError(
- "AutoGen: Error: RCC sources/inputs lists size missmatch in: " +
- filename);
+ "AutoGen: Error: RCC sources/inputs lists size missmatch in:\n" +
+ Quoted(filename));
return false;
}
- for (std::vector<std::string>::iterator
- fileIt = this->RccSources.begin(),
- inputIt = rccInputLists.begin();
- fileIt != this->RccSources.end(); ++fileIt, ++inputIt) {
- cmSystemTools::ReplaceString(*inputIt, "@list_sep@", ";");
- std::vector<std::string> rccInputFiles;
- cmSystemTools::ExpandListArgument(*inputIt, rccInputFiles);
- this->RccInputs[*fileIt] = rccInputFiles;
- }
}
}
@@ -687,8 +688,10 @@ bool cmQtAutoGenerators::RunAutogen()
uicHeaderFiles.insert(headerName);
}
}
- this->ParseHeaders(mocHeaderFiles, uicHeaderFiles, mocsIncluded,
- mocsNotIncluded, mocDepends, uisIncluded);
+ if (!this->ParseHeaders(mocHeaderFiles, uicHeaderFiles, mocsIncluded,
+ mocsNotIncluded, mocDepends, uisIncluded)) {
+ return false;
+ };
// Generate files
if (!this->MocGenerateAll(mocsIncluded, mocsNotIncluded, mocDepends)) {
@@ -804,23 +807,29 @@ bool cmQtAutoGenerators::ParseSourceFile(
std::map<std::string, std::set<std::string> >& mocDepends,
std::map<std::string, std::vector<std::string> >& uisIncluded, bool relaxed)
{
- bool success = true;
- const std::string contentText = ReadAll(absFilename);
- if (contentText.empty()) {
- std::ostringstream ost;
- ost << "AutoGen: Warning: " << absFilename << "\n"
- << "The file is empty\n";
- this->LogWarning(ost.str());
- } else {
- // Parse source contents for MOC
- if (success && !this->MocSkip(absFilename)) {
- success = this->MocParseSourceContent(absFilename, contentText,
- mocsIncluded, mocDepends, relaxed);
- }
- // Parse source contents for UIC
- if (success && !this->UicSkip(absFilename)) {
- this->UicParseContent(absFilename, contentText, uisIncluded);
+ std::string contentText;
+ bool success = ReadAll(contentText, absFilename);
+ if (success) {
+ if (!contentText.empty()) {
+ // Parse source contents for MOC
+ if (success && !this->MocSkip(absFilename)) {
+ success = this->MocParseSourceContent(
+ absFilename, contentText, mocsIncluded, mocDepends, relaxed);
+ }
+ // Parse source contents for UIC
+ if (success && !this->UicSkip(absFilename)) {
+ this->UicParseContent(absFilename, contentText, uisIncluded);
+ }
+ } else {
+ std::ostringstream ost;
+ ost << "AutoGen: Warning: The file is empty:\n"
+ << Quoted(absFilename) << "\n";
+ this->LogWarning(ost.str());
}
+ } else {
+ std::ostringstream ost;
+ ost << "AutoGen: Error: Could not read file:\n" << Quoted(absFilename);
+ this->LogError(ost.str());
}
return success;
}
@@ -1083,7 +1092,7 @@ void cmQtAutoGenerators::SearchHeadersForSourceFile(
}
}
-void cmQtAutoGenerators::ParseHeaders(
+bool cmQtAutoGenerators::ParseHeaders(
const std::set<std::string>& mocHeaderFiles,
const std::set<std::string>& uicHeaderFiles,
const std::map<std::string, std::string>& mocsIncluded,
@@ -1091,6 +1100,7 @@ void cmQtAutoGenerators::ParseHeaders(
std::map<std::string, std::set<std::string> >& mocDepends,
std::map<std::string, std::vector<std::string> >& uisIncluded)
{
+ bool success = true;
// Merged header files list to read files only once
std::set<std::string> headerFiles;
headerFiles.insert(mocHeaderFiles.begin(), mocHeaderFiles.end());
@@ -1099,20 +1109,28 @@ void cmQtAutoGenerators::ParseHeaders(
for (std::set<std::string>::const_iterator hIt = headerFiles.begin();
hIt != headerFiles.end(); ++hIt) {
const std::string& headerName = *hIt;
- const std::string contentText = ReadAll(headerName);
-
- // Parse header content for MOC
- if ((mocHeaderFiles.find(headerName) != mocHeaderFiles.end()) &&
- (mocsIncluded.find(headerName) == mocsIncluded.end())) {
- this->MocParseHeaderContent(headerName, contentText, mocsNotIncluded,
- mocDepends);
- }
-
- // Parse header content for UIC
- if (uicHeaderFiles.find(headerName) != uicHeaderFiles.end()) {
- this->UicParseContent(headerName, contentText, uisIncluded);
+ std::string contentText;
+ if (ReadAll(contentText, headerName)) {
+ // Parse header content for MOC
+ if ((mocHeaderFiles.find(headerName) != mocHeaderFiles.end()) &&
+ (mocsIncluded.find(headerName) == mocsIncluded.end())) {
+ this->MocParseHeaderContent(headerName, contentText, mocsNotIncluded,
+ mocDepends);
+ }
+ // Parse header content for UIC
+ if (uicHeaderFiles.find(headerName) != uicHeaderFiles.end()) {
+ this->UicParseContent(headerName, contentText, uisIncluded);
+ }
+ } else {
+ std::ostringstream ost;
+ ost << "AutoGen: Error: Could not read header file:\n"
+ << Quoted(headerName);
+ this->LogError(ost.str());
+ success = false;
+ break;
}
}
+ return success;
}
bool cmQtAutoGenerators::MocGenerateAll(
@@ -1195,8 +1213,12 @@ bool cmQtAutoGenerators::MocGenerateAll(
// Check if the content of moc_compilation.cpp changed
{
- const std::string oldContents = ReadAll(this->MocCppFilenameAbs);
- mocCompChanged = (oldContents != automocSource);
+ std::string oldContents;
+ if (ReadAll(oldContents, this->MocCppFilenameAbs)) {
+ mocCompChanged = (oldContents != automocSource);
+ } else {
+ mocCompChanged = true;
+ }
}
bool success = true;
@@ -1290,18 +1312,12 @@ bool cmQtAutoGenerators::MocGenerateFile(
cmd.push_back(mocFileAbs);
cmd.push_back(sourceFile);
- // Log moc command
- if (this->Verbose) {
- this->LogCommand(cmd);
- }
-
// Execute moc command
- bool res = false;
- int retVal = 0;
std::string output;
- res = cmSystemTools::RunSingleCommand(cmd, &output, &output, &retVal);
-
- if (!res || (retVal != 0)) {
+ if (this->RunCommand(cmd, output)) {
+ // Success
+ mocGenerated = true;
+ } else {
// Command failed
{
std::ostringstream ost;
@@ -1313,9 +1329,6 @@ bool cmQtAutoGenerators::MocGenerateFile(
}
cmSystemTools::RemoveFile(mocFileAbs);
this->RunMocFailed = true;
- } else {
- // Success
- mocGenerated = true;
}
} else {
// Parent directory creation failed
@@ -1470,18 +1483,11 @@ bool cmQtAutoGenerators::UicGenerateFile(const std::string& realName,
cmd.push_back(uicFileAbs);
cmd.push_back(uiInputFile);
- // Log command
- if (this->Verbose) {
- this->LogCommand(cmd);
- }
-
- // Execute command
- bool res = false;
- int retVal = 0;
std::string output;
- res = cmSystemTools::RunSingleCommand(cmd, &output, &output, &retVal);
-
- if (!res || (retVal != 0)) {
+ if (this->RunCommand(cmd, output)) {
+ // Success
+ uicGenerated = true;
+ } else {
// Command failed
{
std::ostringstream ost;
@@ -1494,9 +1500,6 @@ bool cmQtAutoGenerators::UicGenerateFile(const std::string& realName,
}
cmSystemTools::RemoveFile(uicFileAbs);
this->RunUicFailed = true;
- } else {
- // Success
- uicGenerated = true;
}
} else {
// Parent directory creation failed
@@ -1566,13 +1569,30 @@ bool cmQtAutoGenerators::RccGenerateFile(const std::string& rccInputFile,
// Test if the resources list file is newer than build file
generateRcc = FileAbsentOrOlder(rccBuildFile, rccInputFile);
if (!generateRcc) {
- // Test if any resource file is newer than the build file
- const std::vector<std::string>& files = this->RccInputs[rccInputFile];
- for (std::vector<std::string>::const_iterator it = files.begin();
- it != files.end(); ++it) {
- if (FileAbsentOrOlder(rccBuildFile, *it)) {
- generateRcc = true;
- break;
+ // Acquire input file list
+ std::vector<std::string> readFiles;
+ const std::vector<std::string>* files = &this->RccInputs[rccInputFile];
+ if (files->empty()) {
+ // Read input file list from qrc file
+ std::string error;
+ if (cmQtAutoGeneratorCommon::RccListInputs(
+ this->QtMajorVersion, this->RccExecutable, rccInputFile,
+ readFiles, &error)) {
+ files = &readFiles;
+ } else {
+ files = CM_NULLPTR;
+ this->LogError(error);
+ this->RunRccFailed = true;
+ }
+ }
+ // Test if any input file is newer than the build file
+ if (files != CM_NULLPTR) {
+ for (std::vector<std::string>::const_iterator it = files->begin();
+ it != files->end(); ++it) {
+ if (FileAbsentOrOlder(rccBuildFile, *it)) {
+ generateRcc = true;
+ break;
+ }
}
}
}
@@ -1610,17 +1630,11 @@ bool cmQtAutoGenerators::RccGenerateFile(const std::string& rccInputFile,
cmd.push_back(rccBuildFile);
cmd.push_back(rccInputFile);
- // Log command
- if (this->Verbose) {
- this->LogCommand(cmd);
- }
-
- // Execute command
- bool res = false;
- int retVal = 0;
std::string output;
- res = cmSystemTools::RunSingleCommand(cmd, &output, &output, &retVal);
- if (!res || (retVal != 0)) {
+ if (this->RunCommand(cmd, output)) {
+ // Success
+ rccGenerated = true;
+ } else {
// Command failed
{
std::ostringstream ost;
@@ -1632,9 +1646,6 @@ bool cmQtAutoGenerators::RccGenerateFile(const std::string& rccInputFile,
}
cmSystemTools::RemoveFile(rccBuildFile);
this->RunRccFailed = true;
- } else {
- // Success
- rccGenerated = true;
}
} else {
// Parent directory creation failed
@@ -1712,7 +1723,18 @@ void cmQtAutoGenerators::LogError(const std::string& message) const
void cmQtAutoGenerators::LogCommand(
const std::vector<std::string>& command) const
{
- this->LogInfo(cmJoin(command, " "));
+ std::vector<std::string> cmdEscaped;
+ typedef std::vector<std::string>::const_iterator Iter;
+ for (Iter cit = command.begin(); cit != command.end(); ++cit) {
+ const std::string cesc = Quoted(*cit);
+ if ((cesc.size() > (cit->size() + 2)) ||
+ (cesc.find(' ') != std::string::npos)) {
+ cmdEscaped.push_back(cesc);
+ } else {
+ cmdEscaped.push_back(*cit);
+ }
+ }
+ this->LogInfo(cmJoin(cmdEscaped, " "));
}
/**
@@ -1762,6 +1784,41 @@ std::string cmQtAutoGenerators::ChecksumedPath(const std::string& sourceFile,
}
/**
+ * @brief Generates the parent directory of the given file on demand
+ * @return True on success
+ */
+bool cmQtAutoGenerators::MakeParentDirectory(const std::string& filename) const
+{
+ bool success = true;
+ const std::string dirName = cmSystemTools::GetFilenamePath(filename);
+ if (!dirName.empty()) {
+ success = cmsys::SystemTools::MakeDirectory(dirName);
+ if (!success) {
+ this->LogError("AutoGen: Error: Directory creation failed: " + dirName);
+ }
+ }
+ return success;
+}
+
+/**
+ * @brief Runs a command and returns true on success
+ * @return True on success
+ */
+bool cmQtAutoGenerators::RunCommand(const std::vector<std::string>& command,
+ std::string& output) const
+{
+ // Log command
+ if (this->Verbose) {
+ this->LogCommand(command);
+ }
+ // Execute command
+ int retVal = 0;
+ bool res =
+ cmSystemTools::RunSingleCommand(command, &output, &output, &retVal);
+ return (res && (retVal == 0));
+}
+
+/**
* @brief Tries to find the header file to the given file base path by
* appending different header extensions
* @return True on success
@@ -1835,20 +1892,3 @@ bool cmQtAutoGenerators::MocFindIncludedFile(
}
return success;
}
-
-/**
- * @brief Generates the parent directory of the given file on demand
- * @return True on success
- */
-bool cmQtAutoGenerators::MakeParentDirectory(const std::string& filename) const
-{
- bool success = true;
- const std::string dirName = cmSystemTools::GetFilenamePath(filename);
- if (!dirName.empty()) {
- success = cmsys::SystemTools::MakeDirectory(dirName);
- if (!success) {
- this->LogError("AutoGen: Error: Directory creation failed: " + dirName);
- }
- }
- return success;
-}
diff --git a/Source/cmQtAutoGenerators.h b/Source/cmQtAutoGenerators.h
index 3bff2b2..ee046de 100644
--- a/Source/cmQtAutoGenerators.h
+++ b/Source/cmQtAutoGenerators.h
@@ -78,7 +78,7 @@ private:
std::set<std::string>& mocHeaderFiles,
std::set<std::string>& uicHeaderFiles) const;
- void ParseHeaders(
+ bool ParseHeaders(
const std::set<std::string>& mocHeaderFiles,
const std::set<std::string>& uicHeaderFiles,
const std::map<std::string, std::string>& mocsIncluded,
@@ -142,6 +142,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 FindHeader(std::string& header, const std::string& testBasePath) const;
diff --git a/Source/cmStateTypes.h b/Source/cmStateTypes.h
index 2c974c1..da14cdb 100644
--- a/Source/cmStateTypes.h
+++ b/Source/cmStateTypes.h
@@ -27,6 +27,9 @@ enum SnapshotType
VariableScopeType
};
+// There are multiple overlapping ranges represented here. Be aware that adding
+// a value to this enumeration may cause failures in numerous places which
+// assume details about the ordering.
enum TargetType
{
EXECUTABLE,
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index c360c19..e3c7b63 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -230,6 +230,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
this->SetPropertyDefault("INSTALL_NAME_DIR", CM_NULLPTR);
this->SetPropertyDefault("INSTALL_RPATH", "");
this->SetPropertyDefault("INSTALL_RPATH_USE_LINK_PATH", "OFF");
+ this->SetPropertyDefault("INTERPROCEDURAL_OPTIMIZATION", CM_NULLPTR);
this->SetPropertyDefault("SKIP_BUILD_RPATH", "OFF");
this->SetPropertyDefault("BUILD_WITH_INSTALL_RPATH", "OFF");
this->SetPropertyDefault("ARCHIVE_OUTPUT_DIRECTORY", CM_NULLPTR);
diff --git a/Source/cmVS10CudaFlagTable.h b/Source/cmVS10CudaFlagTable.h
new file mode 100644
index 0000000..da19d64
--- /dev/null
+++ b/Source/cmVS10CudaFlagTable.h
@@ -0,0 +1,51 @@
+static cmVS7FlagTable cmVS10CudaFlagTable[] = {
+ // Collect options meant for the host compiler.
+ { "AdditionalCompilerOptions", "Xcompiler=", "Host compiler options", "",
+ cmVS7FlagTable::UserValue | cmVS7FlagTable::SpaceAppendable },
+ { "AdditionalCompilerOptions", "Xcompiler", "Host compiler options", "",
+ cmVS7FlagTable::UserFollowing | cmVS7FlagTable::SpaceAppendable },
+
+ // Select the CUDA runtime library.
+ { "CudaRuntime", "cudart=none", "No CUDA runtime library", "None", 0 },
+ { "CudaRuntime", "cudart=shared", "Shared/dynamic CUDA runtime library",
+ "Shared", 0 },
+ { "CudaRuntime", "cudart=static", "Static CUDA runtime library", "Static",
+ 0 },
+ { "CudaRuntime", "cudart", "CUDA runtime library", "",
+ cmVS7FlagTable::UserFollowing },
+
+ // Capture arch/code arguments into temporaries for post-processing.
+ { "cmake-temp-gencode", "gencode=", "", "",
+ cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable },
+ { "cmake-temp-gencode", "gencode", "", "",
+ cmVS7FlagTable::UserFollowing | cmVS7FlagTable::SemicolonAppendable },
+ { "cmake-temp-gencode", "-generate-code=", "", "",
+ cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable },
+ { "cmake-temp-gencode", "-generate-code", "", "",
+ cmVS7FlagTable::UserFollowing | cmVS7FlagTable::SemicolonAppendable },
+
+ { "cmake-temp-code", "code=", "", "", cmVS7FlagTable::UserValue },
+ { "cmake-temp-code", "code", "", "", cmVS7FlagTable::UserFollowing },
+ { "cmake-temp-code", "-gpu-code=", "", "", cmVS7FlagTable::UserValue },
+ { "cmake-temp-code", "-gpu-code", "", "", cmVS7FlagTable::UserFollowing },
+
+ { "cmake-temp-arch", "arch=", "", "", cmVS7FlagTable::UserValue },
+ { "cmake-temp-arch", "arch", "", "", cmVS7FlagTable::UserFollowing },
+ { "cmake-temp-arch", "-gpu-architecture=", "", "",
+ cmVS7FlagTable::UserValue },
+ { "cmake-temp-arch", "-gpu-architecture", "", "",
+ cmVS7FlagTable::UserFollowing },
+
+ // Other flags.
+
+ { "FastMath", "use_fast_math", "", "true", 0 },
+ { "FastMath", "-use_fast_math", "", "true", 0 },
+
+ { "GPUDebugInfo", "G", "", "true", 0 },
+ { "GPUDebugInfo", "-device-debug", "", "true", 0 },
+
+ { "HostDebugInfo", "g", "", "true", 0 },
+ { "HostDebugInfo", "-debug", "", "true", 0 },
+
+ { 0, 0, 0, 0, 0 }
+};
diff --git a/Source/cmVS10CudaHostFlagTable.h b/Source/cmVS10CudaHostFlagTable.h
new file mode 100644
index 0000000..5b61066
--- /dev/null
+++ b/Source/cmVS10CudaHostFlagTable.h
@@ -0,0 +1,35 @@
+static cmVS7FlagTable cmVS10CudaHostFlagTable[] = {
+ //{"Optimization", "", "<inherit from host>", "InheritFromHost", 0},
+ { "Optimization", "Od", "Disabled", "Od", 0 },
+ { "Optimization", "O1", "Minimize Size", "O1", 0 },
+ { "Optimization", "O2", "Maximize Speed", "O2", 0 },
+ { "Optimization", "Ox", "Full Optimization", "O3", 0 },
+
+ //{"Runtime", "", "<inherit from host>", "InheritFromHost", 0},
+ { "Runtime", "MT", "Multi-Threaded", "MT", 0 },
+ { "Runtime", "MTd", "Multi-Threaded Debug", "MTd", 0 },
+ { "Runtime", "MD", "Multi-Threaded DLL", "MD", 0 },
+ { "Runtime", "MDd", "Multi-threaded Debug DLL", "MDd", 0 },
+ { "Runtime", "ML", "Single-Threaded", "ML", 0 },
+ { "Runtime", "MLd", "Single-Threaded Debug", "MLd", 0 },
+
+ //{"RuntimeChecks", "", "<inherit from host>", "InheritFromHost", 0},
+ //{"RuntimeChecks", "", "Default", "Default", 0},
+ { "RuntimeChecks", "RTCs", "Stack Frames", "RTCs", 0 },
+ { "RuntimeChecks", "RTCu", "Uninitialized Variables", "RTCu", 0 },
+ { "RuntimeChecks", "RTC1", "Both", "RTC1", 0 },
+
+ //{"TypeInfo", "", "<inherit from host>", "InheritFromHost", 0},
+ { "TypeInfo", "GR", "Yes", "true", 0 },
+ { "TypeInfo", "GR-", "No", "false", 0 },
+
+ //{"Warning", "", "<inherit from host>", "InheritFromHost", 0},
+ { "Warning", "W0", "Off: Turn Off All Warnings", "W0", 0 },
+ { "Warning", "W1", "Level 1", "W1", 0 },
+ { "Warning", "W2", "Level 2", "W2", 0 },
+ { "Warning", "W3", "Level 3", "W3", 0 },
+ { "Warning", "W4", "Level 4", "W4", 0 },
+ { "Warning", "Wall", "Enable All Warnings", "Wall", 0 },
+
+ { 0, 0, 0, 0, 0 }
+};
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index fbf7447..052cc7f 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -112,6 +112,10 @@ cmVisualStudio10TargetGenerator::~cmVisualStudio10TargetGenerator()
i != this->LinkOptions.end(); ++i) {
delete i->second;
}
+ for (OptionsMap::iterator i = this->CudaOptions.begin();
+ i != this->CudaOptions.end(); ++i) {
+ delete i->second;
+ }
if (!this->BuildFileStream) {
return;
}
@@ -206,6 +210,9 @@ void cmVisualStudio10TargetGenerator::Generate()
if (!this->ComputeRcOptions()) {
return;
}
+ if (!this->ComputeCudaOptions()) {
+ return;
+ }
if (!this->ComputeMasmOptions()) {
return;
}
@@ -454,6 +461,14 @@ void cmVisualStudio10TargetGenerator::Generate()
this->WriteString("<Import Project=\"" VS10_CXX_PROPS "\" />\n", 1);
}
this->WriteString("<ImportGroup Label=\"ExtensionSettings\">\n", 1);
+ if (this->GlobalGenerator->IsCudaEnabled()) {
+ this->WriteString("<Import Project=\"$(VCTargetsPath)\\"
+ "BuildCustomizations\\CUDA ",
+ 2);
+ (*this->BuildFileStream)
+ << cmVS10EscapeXML(this->GlobalGenerator->GetPlatformToolsetCudaString())
+ << ".props\" />\n";
+ }
if (this->GlobalGenerator->IsMasmEnabled()) {
this->WriteString("<Import Project=\"$(VCTargetsPath)\\"
"BuildCustomizations\\masm.props\" />\n",
@@ -524,6 +539,14 @@ void cmVisualStudio10TargetGenerator::Generate()
this->WriteTargetSpecificReferences();
this->WriteString("<ImportGroup Label=\"ExtensionTargets\">\n", 1);
this->WriteTargetsFileReferences();
+ if (this->GlobalGenerator->IsCudaEnabled()) {
+ this->WriteString("<Import Project=\"$(VCTargetsPath)\\"
+ "BuildCustomizations\\CUDA ",
+ 2);
+ (*this->BuildFileStream)
+ << cmVS10EscapeXML(this->GlobalGenerator->GetPlatformToolsetCudaString())
+ << ".targets\" />\n";
+ }
if (this->GlobalGenerator->IsMasmEnabled()) {
this->WriteString("<Import Project=\"$(VCTargetsPath)\\"
"BuildCustomizations\\masm.targets\" />\n",
@@ -1694,8 +1717,10 @@ void cmVisualStudio10TargetGenerator::WriteSource(std::string const& tool,
//
// and fail if this exceeds the maximum allowed path length. Our path
// conversion uses full paths when possible to allow deeper trees.
- bool forceRelative = false;
- std::string sourceFile = this->ConvertPath(sf->GetFullPath(), false);
+ // However, CUDA 8.0 msbuild rules fail on absolute paths so for CUDA
+ // we must use relative paths.
+ bool forceRelative = sf->GetLanguage() == "CUDA";
+ std::string sourceFile = this->ConvertPath(sf->GetFullPath(), forceRelative);
if (this->LocalGenerator->GetVersion() ==
cmGlobalVisualStudioGenerator::VS10 &&
cmSystemTools::FileIsFullPath(sourceFile.c_str())) {
@@ -1772,6 +1797,8 @@ void cmVisualStudio10TargetGenerator::WriteAllSources()
tool = "ResourceCompile";
} else if (lang == "CSharp") {
tool = "Compile";
+ } else if (lang == "CUDA" && this->GlobalGenerator->IsCudaEnabled()) {
+ tool = "CudaCompile";
}
if (!tool.empty()) {
@@ -1841,10 +1868,9 @@ void cmVisualStudio10TargetGenerator::WriteAllSources()
(*this->BuildFileStream) << cmVS10EscapeXML(obj) << "\" />\n";
}
- if (cmSourceFile const* defsrc =
- this->GeneratorTarget->GetModuleDefinitionFile("")) {
- this->WriteSource("None", defsrc);
- }
+ std::vector<cmSourceFile const*> defSources;
+ this->GeneratorTarget->GetModuleDefinitionSources(defSources, "");
+ this->WriteSources("None", defSources);
if (this->IsMissingFiles) {
this->WriteMissingFiles();
@@ -2208,8 +2234,10 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
if (linkLanguage == "CXX") {
clOptions.AddFlag("CompileAs", "CompileAsCpp");
}
- this->LocalGenerator->AddCompileOptions(flags, this->GeneratorTarget,
- linkLanguage, configName.c_str());
+ if (linkLanguage != "CUDA") {
+ this->LocalGenerator->AddCompileOptions(flags, this->GeneratorTarget,
+ linkLanguage, configName.c_str());
+ }
// Get preprocessor definitions for this directory.
std::string defineFlags =
@@ -2401,6 +2429,99 @@ void cmVisualStudio10TargetGenerator::WriteRCOptions(
this->WriteString("</ResourceCompile>\n", 2);
}
+bool cmVisualStudio10TargetGenerator::ComputeCudaOptions()
+{
+ if (!this->GlobalGenerator->IsCudaEnabled()) {
+ return true;
+ }
+ for (std::vector<std::string>::const_iterator i =
+ this->Configurations.begin();
+ i != this->Configurations.end(); ++i) {
+ if (!this->ComputeCudaOptions(*i)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool cmVisualStudio10TargetGenerator::ComputeCudaOptions(
+ std::string const& configName)
+{
+ cmGlobalVisualStudio10Generator* gg =
+ static_cast<cmGlobalVisualStudio10Generator*>(this->GlobalGenerator);
+ CM_AUTO_PTR<Options> pOptions(new Options(
+ this->LocalGenerator, Options::CudaCompiler, gg->GetCudaFlagTable()));
+ Options& cudaOptions = *pOptions;
+
+ // Get compile flags for CUDA in this directory.
+ std::string CONFIG = cmSystemTools::UpperCase(configName);
+ std::string configFlagsVar = std::string("CMAKE_CUDA_FLAGS_") + CONFIG;
+ std::string flags =
+ std::string(this->Makefile->GetSafeDefinition("CMAKE_CUDA_FLAGS")) +
+ std::string(" ") +
+ std::string(this->Makefile->GetSafeDefinition(configFlagsVar));
+
+ // Get preprocessor definitions for this directory.
+ std::string defineFlags =
+ this->GeneratorTarget->Target->GetMakefile()->GetDefineFlags();
+
+ cudaOptions.Parse(flags.c_str());
+ cudaOptions.Parse(defineFlags.c_str());
+ cudaOptions.ParseFinish();
+
+ if (this->GeneratorTarget->GetPropertyAsBool("CUDA_SEPARABLE_COMPILATION")) {
+ cudaOptions.AddFlag("GenerateRelocatableDeviceCode", "true");
+ }
+
+ // Convert the host compiler options to the toolset's abstractions
+ // using a secondary flag table.
+ cudaOptions.ClearTables();
+ cudaOptions.AddTable(gg->GetCudaHostFlagTable());
+ cudaOptions.Reparse("AdditionalCompilerOptions");
+
+ // `CUDA 8.0.targets` places these before nvcc! Just drop whatever
+ // did not parse and hope it works.
+ cudaOptions.RemoveFlag("AdditionalCompilerOptions");
+
+ cudaOptions.FixCudaCodeGeneration();
+
+ std::vector<std::string> targetDefines;
+ this->GeneratorTarget->GetCompileDefinitions(targetDefines,
+ configName.c_str(), "CUDA");
+ cudaOptions.AddDefines(targetDefines);
+
+ // Add a definition for the configuration name.
+ std::string configDefine = "CMAKE_INTDIR=\"";
+ configDefine += configName;
+ configDefine += "\"";
+ cudaOptions.AddDefine(configDefine);
+ if (const char* exportMacro = this->GeneratorTarget->GetExportMacro()) {
+ cudaOptions.AddDefine(exportMacro);
+ }
+
+ this->CudaOptions[configName] = pOptions.release();
+ return true;
+}
+
+void cmVisualStudio10TargetGenerator::WriteCudaOptions(
+ std::string const& configName, std::vector<std::string> const& includes)
+{
+ if (!this->MSTools || !this->GlobalGenerator->IsCudaEnabled()) {
+ return;
+ }
+ this->WriteString("<CudaCompile>\n", 2);
+
+ Options& cudaOptions = *(this->CudaOptions[configName]);
+ cudaOptions.AppendFlag("Include", includes);
+ cudaOptions.AppendFlag("Include", "%(Include)");
+ cudaOptions.OutputPreprocessorDefinitions(*this->BuildFileStream, " ",
+ "\n", "CUDA");
+ cudaOptions.PrependInheritedString("AdditionalOptions");
+ cudaOptions.OutputFlagMap(*this->BuildFileStream, " ");
+
+ this->WriteString("</CudaCompile>\n", 2);
+}
+
bool cmVisualStudio10TargetGenerator::ComputeMasmOptions()
{
if (!this->GlobalGenerator->IsMasmEnabled()) {
@@ -2739,8 +2860,10 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions(
this->LocalGenerator, Options::Linker, gg->GetLinkFlagTable(), 0, this));
Options& linkOptions = *pOptions;
- const std::string& linkLanguage =
- this->GeneratorTarget->GetLinkerLanguage(config.c_str());
+ cmGeneratorTarget::LinkClosure const* linkClosure =
+ this->GeneratorTarget->GetLinkClosure(config);
+
+ const std::string& linkLanguage = linkClosure->LinkerLanguage;
if (linkLanguage.empty()) {
cmSystemTools::Error(
"CMake can not determine linker language for target: ",
@@ -2795,6 +2918,19 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions(
std::vector<std::string> libVec;
std::vector<std::string> vsTargetVec;
this->AddLibraries(cli, libVec, vsTargetVec);
+ if (std::find(linkClosure->Languages.begin(), linkClosure->Languages.end(),
+ "CUDA") != linkClosure->Languages.end()) {
+ switch (this->CudaOptions[config]->GetCudaRuntime()) {
+ case cmVisualStudioGeneratorOptions::CudaRuntimeStatic:
+ libVec.push_back("cudart_static.lib");
+ break;
+ case cmVisualStudioGeneratorOptions::CudaRuntimeShared:
+ libVec.push_back("cudart.lib");
+ break;
+ case cmVisualStudioGeneratorOptions::CudaRuntimeNone:
+ break;
+ }
+ }
std::string standardLibsVar = "CMAKE_";
standardLibsVar += linkLanguage;
standardLibsVar += "_STANDARD_LIBRARIES";
@@ -2915,24 +3051,15 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions(
linkOptions.Parse(flags.c_str());
if (this->MSTools) {
- if (cmSourceFile const* defsrc =
- this->GeneratorTarget->GetModuleDefinitionFile("")) {
- linkOptions.AddFlag("ModuleDefinitionFile",
- defsrc->GetFullPath().c_str());
+ cmGeneratorTarget::ModuleDefinitionInfo const* mdi =
+ this->GeneratorTarget->GetModuleDefinitionInfo(config);
+ if (mdi && !mdi->DefFile.empty()) {
+ linkOptions.AddFlag("ModuleDefinitionFile", mdi->DefFile.c_str());
}
linkOptions.AppendFlag("IgnoreSpecificDefaultLibraries",
"%(IgnoreSpecificDefaultLibraries)");
}
- if ((this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY ||
- this->GeneratorTarget->IsExecutableWithExports()) &&
- this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS")) {
- if (this->GeneratorTarget->GetPropertyAsBool(
- "WINDOWS_EXPORT_ALL_SYMBOLS")) {
- linkOptions.AddFlag("ModuleDefinitionFile", "$(IntDir)exportall.def");
- }
- }
-
// Hack to fix flag version selection in a common use case.
// FIXME: Select flag table based on toolset instead of VS version.
if (this->LocalGenerator->GetVersion() >=
@@ -3142,6 +3269,7 @@ void cmVisualStudio10TargetGenerator::WriteItemDefinitionGroups()
this->WriteClOptions(*i, includes);
// output rc compile flags <ResourceCompile></ResourceCompile>
this->WriteRCOptions(*i, includes);
+ this->WriteCudaOptions(*i, includes);
this->WriteMasmOptions(*i, includes);
this->WriteNasmOptions(*i, includes);
}
@@ -3170,18 +3298,15 @@ void cmVisualStudio10TargetGenerator::WriteEvents(
std::string const& configName)
{
bool addedPrelink = false;
- if ((this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY ||
- this->GeneratorTarget->IsExecutableWithExports()) &&
- this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS")) {
- if (this->GeneratorTarget->GetPropertyAsBool(
- "WINDOWS_EXPORT_ALL_SYMBOLS")) {
- addedPrelink = true;
- std::vector<cmCustomCommand> commands =
- this->GeneratorTarget->GetPreLinkCommands();
- this->GlobalGenerator->AddSymbolExportCommand(this->GeneratorTarget,
- commands, configName);
- this->WriteEvent("PreLinkEvent", commands, configName);
- }
+ cmGeneratorTarget::ModuleDefinitionInfo const* mdi =
+ this->GeneratorTarget->GetModuleDefinitionInfo(configName);
+ if (mdi && mdi->WindowsExportAllSymbols) {
+ addedPrelink = true;
+ std::vector<cmCustomCommand> commands =
+ this->GeneratorTarget->GetPreLinkCommands();
+ this->GlobalGenerator->AddSymbolExportCommand(this->GeneratorTarget,
+ commands, configName);
+ this->WriteEvent("PreLinkEvent", commands, configName);
}
if (!addedPrelink) {
this->WriteEvent("PreLinkEvent",
diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h
index 0ebb4e4..52d5550 100644
--- a/Source/cmVisualStudio10TargetGenerator.h
+++ b/Source/cmVisualStudio10TargetGenerator.h
@@ -98,6 +98,10 @@ private:
bool ComputeRcOptions(std::string const& config);
void WriteRCOptions(std::string const& config,
std::vector<std::string> const& includes);
+ bool ComputeCudaOptions();
+ bool ComputeCudaOptions(std::string const& config);
+ void WriteCudaOptions(std::string const& config,
+ std::vector<std::string> const& includes);
bool ComputeMasmOptions();
bool ComputeMasmOptions(std::string const& config);
void WriteMasmOptions(std::string const& config,
@@ -150,6 +154,7 @@ private:
typedef std::map<std::string, Options*> OptionsMap;
OptionsMap ClOptions;
OptionsMap RcOptions;
+ OptionsMap CudaOptions;
OptionsMap MasmOptions;
OptionsMap NasmOptions;
OptionsMap LinkOptions;
diff --git a/Source/cmVisualStudioGeneratorOptions.cxx b/Source/cmVisualStudioGeneratorOptions.cxx
index dfe5ce6..1ca6b9c 100644
--- a/Source/cmVisualStudioGeneratorOptions.cxx
+++ b/Source/cmVisualStudioGeneratorOptions.cxx
@@ -43,6 +43,8 @@ cmVisualStudioGeneratorOptions::cmVisualStudioGeneratorOptions(
this->FortranRuntimeDebug = false;
this->FortranRuntimeDLL = false;
this->FortranRuntimeMT = false;
+
+ this->UnknownFlagField = "AdditionalOptions";
}
cmVisualStudioGeneratorOptions::cmVisualStudioGeneratorOptions(
@@ -67,6 +69,8 @@ cmVisualStudioGeneratorOptions::cmVisualStudioGeneratorOptions(
this->FortranRuntimeDebug = false;
this->FortranRuntimeDLL = false;
this->FortranRuntimeMT = false;
+
+ this->UnknownFlagField = "AdditionalOptions";
}
void cmVisualStudioGeneratorOptions::AddTable(cmVS7FlagTable const* table)
@@ -81,6 +85,13 @@ void cmVisualStudioGeneratorOptions::AddTable(cmVS7FlagTable const* table)
}
}
+void cmVisualStudioGeneratorOptions::ClearTables()
+{
+ for (int i = 0; i < FlagTableCount; ++i) {
+ this->FlagTable[i] = CM_NULLPTR;
+ }
+}
+
void cmVisualStudioGeneratorOptions::FixExceptionHandlingDefault()
{
// Exception handling is on by default because the platform file has
@@ -176,6 +187,78 @@ bool cmVisualStudioGeneratorOptions::UsingSBCS() const
return false;
}
+cmVisualStudioGeneratorOptions::CudaRuntime
+cmVisualStudioGeneratorOptions::GetCudaRuntime() const
+{
+ std::map<std::string, FlagValue>::const_iterator i =
+ this->FlagMap.find("CudaRuntime");
+ if (i != this->FlagMap.end() && i->second.size() == 1) {
+ std::string const& cudaRuntime = i->second[0];
+ if (cudaRuntime == "Static") {
+ return CudaRuntimeStatic;
+ }
+ if (cudaRuntime == "Shared") {
+ return CudaRuntimeShared;
+ }
+ if (cudaRuntime == "None") {
+ return CudaRuntimeNone;
+ }
+ }
+ // nvcc default is static
+ return CudaRuntimeStatic;
+}
+
+void cmVisualStudioGeneratorOptions::FixCudaCodeGeneration()
+{
+ // Extract temporary values stored by our flag table.
+ FlagValue arch = this->TakeFlag("cmake-temp-arch");
+ FlagValue code = this->TakeFlag("cmake-temp-code");
+ FlagValue gencode = this->TakeFlag("cmake-temp-gencode");
+
+ // No -code allowed without -arch.
+ if (arch.empty()) {
+ code.clear();
+ }
+
+ if (arch.empty() && gencode.empty()) {
+ return;
+ }
+
+ // Create a CodeGeneration field with [arch],[code] syntax in each entry.
+ // CUDA will convert it to `-gencode=arch=[arch],code="[code],[arch]"`.
+ FlagValue& result = this->FlagMap["CodeGeneration"];
+
+ // First entries for the -arch=<arch> [-code=<code>,...] pair.
+ if (!arch.empty()) {
+ std::string arch_name = arch[0];
+ std::vector<std::string> codes;
+ if (!code.empty()) {
+ codes = cmSystemTools::tokenize(code[0], ",");
+ }
+ if (codes.empty()) {
+ codes.push_back(arch_name);
+ // nvcc -arch=<arch> has a special case that allows a real
+ // architecture to be specified instead of a virtual arch.
+ // It translates to -arch=<virtual> -code=<real>.
+ cmSystemTools::ReplaceString(arch_name, "sm_", "compute_");
+ }
+ for (std::vector<std::string>::iterator ci = codes.begin();
+ ci != codes.end(); ++ci) {
+ std::string entry = arch_name + "," + *ci;
+ result.push_back(entry);
+ }
+ }
+
+ // Now add entries for the -gencode=<arch>,<code> pairs.
+ for (std::vector<std::string>::iterator ei = gencode.begin();
+ ei != gencode.end(); ++ei) {
+ std::string entry = *ei;
+ cmSystemTools::ReplaceString(entry, "arch=", "");
+ cmSystemTools::ReplaceString(entry, "code=", "");
+ result.push_back(entry);
+ }
+}
+
void cmVisualStudioGeneratorOptions::Parse(const char* flags)
{
// Parse the input string as a windows command line since the string
@@ -209,6 +292,21 @@ void cmVisualStudioGeneratorOptions::ParseFinish()
rl += this->FortranRuntimeDLL ? "DLL" : "";
this->FlagMap["RuntimeLibrary"] = rl;
}
+
+ if (this->CurrentTool == CudaCompiler) {
+ std::map<std::string, FlagValue>::iterator i =
+ this->FlagMap.find("CudaRuntime");
+ if (i != this->FlagMap.end() && i->second.size() == 1) {
+ std::string& cudaRuntime = i->second[0];
+ if (cudaRuntime == "static") {
+ cudaRuntime = "Static";
+ } else if (cudaRuntime == "shared") {
+ cudaRuntime = "Shared";
+ } else if (cudaRuntime == "none") {
+ cudaRuntime = "None";
+ }
+ }
+ }
}
void cmVisualStudioGeneratorOptions::PrependInheritedString(
@@ -222,6 +320,18 @@ void cmVisualStudioGeneratorOptions::PrependInheritedString(
value = "%(" + key + ") " + value;
}
+void cmVisualStudioGeneratorOptions::Reparse(std::string const& key)
+{
+ std::map<std::string, FlagValue>::iterator i = this->FlagMap.find(key);
+ if (i == this->FlagMap.end() || i->second.size() != 1) {
+ return;
+ }
+ std::string const original = i->second[0];
+ i->second[0] = "";
+ this->UnknownFlagField = key;
+ this->Parse(original.c_str());
+}
+
void cmVisualStudioGeneratorOptions::StoreUnknownFlag(const char* flag)
{
// Look for Intel Fortran flags that do not map well in the flag table.
@@ -248,7 +358,19 @@ void cmVisualStudioGeneratorOptions::StoreUnknownFlag(const char* flag)
std::string const opts = cmOutputConverter::EscapeWindowsShellArgument(
flag, cmOutputConverter::Shell_Flag_AllowMakeVariables |
cmOutputConverter::Shell_Flag_VSIDE);
- this->AppendFlagString("AdditionalOptions", opts);
+ this->AppendFlagString(this->UnknownFlagField, opts);
+}
+
+cmIDEOptions::FlagValue cmVisualStudioGeneratorOptions::TakeFlag(
+ std::string const& key)
+{
+ FlagValue value;
+ std::map<std::string, FlagValue>::iterator i = this->FlagMap.find(key);
+ if (i != this->FlagMap.end()) {
+ value = i->second;
+ this->FlagMap.erase(i);
+ }
+ return value;
}
void cmVisualStudioGeneratorOptions::SetConfiguration(const char* config)
@@ -264,6 +386,9 @@ void cmVisualStudioGeneratorOptions::OutputPreprocessorDefinitions(
return;
}
const char* tag = "PreprocessorDefinitions";
+ if (lang == "CUDA") {
+ tag = "Defines";
+ }
if (this->Version >= cmGlobalVisualStudioGenerator::VS10) {
// if there are configuration specific flags, then
// use the configuration specific tag for PreprocessorDefinitions
diff --git a/Source/cmVisualStudioGeneratorOptions.h b/Source/cmVisualStudioGeneratorOptions.h
index 8c49470..52689e0 100644
--- a/Source/cmVisualStudioGeneratorOptions.h
+++ b/Source/cmVisualStudioGeneratorOptions.h
@@ -26,6 +26,7 @@ public:
{
Compiler,
ResourceCompiler,
+ CudaCompiler,
MasmCompiler,
NasmCompiler,
Linker,
@@ -43,12 +44,19 @@ public:
// Add a table of flags.
void AddTable(cmVS7FlagTable const* table);
+ // Clear the flag tables.
+ void ClearTables();
+
// Store options from command line flags.
void Parse(const char* flags);
void ParseFinish();
void PrependInheritedString(std::string const& key);
+ // Parse the content of the given flag table entry again to extract
+ // known flags and leave the rest in the original entry.
+ void Reparse(std::string const& key);
+
// Fix the ExceptionHandling option to default to off.
void FixExceptionHandlingDefault();
@@ -59,6 +67,16 @@ public:
bool UsingUnicode() const;
bool UsingSBCS() const;
+ enum CudaRuntime
+ {
+ CudaRuntimeStatic,
+ CudaRuntimeShared,
+ CudaRuntimeNone
+ };
+ CudaRuntime GetCudaRuntime() const;
+
+ void FixCudaCodeGeneration();
+
bool IsDebug() const;
bool IsWinRt() const;
bool IsManaged() const;
@@ -81,7 +99,11 @@ private:
bool FortranRuntimeDLL;
bool FortranRuntimeMT;
+ std::string UnknownFlagField;
+
virtual void StoreUnknownFlag(const char* flag);
+
+ FlagValue TakeFlag(std::string const& key);
};
#endif
diff --git a/Source/cmWorkingDirectory.cxx b/Source/cmWorkingDirectory.cxx
new file mode 100644
index 0000000..99c9ba8
--- /dev/null
+++ b/Source/cmWorkingDirectory.cxx
@@ -0,0 +1,24 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmWorkingDirectory.h"
+
+#include "cmSystemTools.h"
+
+cmWorkingDirectory::cmWorkingDirectory(std::string const& newdir)
+{
+ this->OldDir = cmSystemTools::GetCurrentWorkingDirectory();
+ cmSystemTools::ChangeDirectory(newdir);
+}
+
+cmWorkingDirectory::~cmWorkingDirectory()
+{
+ this->Pop();
+}
+
+void cmWorkingDirectory::Pop()
+{
+ if (!this->OldDir.empty()) {
+ cmSystemTools::ChangeDirectory(this->OldDir);
+ this->OldDir.clear();
+ }
+}
diff --git a/Source/cmWorkingDirectory.h b/Source/cmWorkingDirectory.h
new file mode 100644
index 0000000..af0fd44
--- /dev/null
+++ b/Source/cmWorkingDirectory.h
@@ -0,0 +1,25 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cmWorkingDirectory_h
+#define cmWorkingDirectory_h
+
+#include <cmConfigure.h> // IWYU pragma: keep
+
+#include <string>
+
+/** \class cmWorkingDirectory
+ * \brief An RAII class to manipulate the working directory.
+ */
+class cmWorkingDirectory
+{
+public:
+ cmWorkingDirectory(std::string const& newdir);
+ ~cmWorkingDirectory();
+
+ void Pop();
+
+private:
+ std::string OldDir;
+};
+
+#endif
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index b2384cd..3af3be6 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -23,6 +23,7 @@
#include "cmTargetLinkLibraryType.h"
#include "cmUtils.hxx"
#include "cmVersionConfig.h"
+#include "cmWorkingDirectory.h"
#include "cm_auto_ptr.hxx"
#if defined(CMAKE_BUILD_WITH_CMAKE)
@@ -2199,24 +2200,23 @@ int cmake::GetSystemInformation(std::vector<std::string>& args)
resultFile += "/__cmake_systeminformation/results.txt";
}
- // now run cmake on the CMakeLists file
- cmSystemTools::ChangeDirectory(destPath);
- std::vector<std::string> args2;
- args2.push_back(args[0]);
- args2.push_back(destPath);
- std::string resultArg = "-DRESULT_FILE=";
- resultArg += resultFile;
- args2.push_back(resultArg);
- int res = this->Run(args2, false);
+ {
+ // now run cmake on the CMakeLists file
+ cmWorkingDirectory workdir(destPath);
+ std::vector<std::string> args2;
+ args2.push_back(args[0]);
+ args2.push_back(destPath);
+ std::string resultArg = "-DRESULT_FILE=";
+ resultArg += resultFile;
+ args2.push_back(resultArg);
+ int res = this->Run(args2, false);
- if (res != 0) {
- std::cerr << "Error: --system-information failed on internal CMake!\n";
- return res;
+ if (res != 0) {
+ std::cerr << "Error: --system-information failed on internal CMake!\n";
+ return res;
+ }
}
- // change back to the original directory
- cmSystemTools::ChangeDirectory(cwd);
-
// echo results to stdout if needed
if (writeToStdout) {
FILE* fin = cmsys::SystemTools::Fopen(resultFile, "r");
diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx
index 86f7552..93312e9 100644
--- a/Source/kwsys/SystemInformation.cxx
+++ b/Source/kwsys/SystemInformation.cxx
@@ -539,6 +539,7 @@ protected:
std::string OSRelease;
std::string OSVersion;
std::string OSPlatform;
+ bool OSIs64Bit;
};
SystemInformation::SystemInformation()
@@ -1499,6 +1500,7 @@ SystemInformationImplementation::SystemInformationImplementation()
this->OSRelease = "";
this->OSVersion = "";
this->OSPlatform = "";
+ this->OSIs64Bit = (sizeof(void*) == 8);
}
SystemInformationImplementation::~SystemInformationImplementation()
@@ -5320,10 +5322,20 @@ bool SystemInformationImplementation::QueryOSInformation()
this->Hostname = name;
const char* arch = getenv("PROCESSOR_ARCHITECTURE");
+ const char* wow64 = getenv("PROCESSOR_ARCHITEW6432");
if (arch) {
this->OSPlatform = arch;
}
+ if (wow64) {
+ // the PROCESSOR_ARCHITEW6432 is only defined when running 32bit programs
+ // on 64bit OS
+ this->OSIs64Bit = true;
+ } else if (arch) {
+ // all values other than x86 map to 64bit architectures
+ this->OSIs64Bit = (strncmp(arch, "x86", 3) != 0);
+ }
+
#else
struct utsname unameInfo;
@@ -5334,6 +5346,12 @@ bool SystemInformationImplementation::QueryOSInformation()
this->OSRelease = unameInfo.release;
this->OSVersion = unameInfo.version;
this->OSPlatform = unameInfo.machine;
+
+ // This is still insufficient to capture 64bit architecture such
+ // powerpc and possible mips and sparc
+ if (this->OSPlatform.find_first_of("64") != std::string::npos) {
+ this->OSIs64Bit = true;
+ }
}
#ifdef __APPLE__
@@ -5387,6 +5405,6 @@ void SystemInformationImplementation::TrimNewline(std::string& output)
/** Return true if the machine is 64 bits */
bool SystemInformationImplementation::Is64Bits()
{
- return (sizeof(void*) == 8);
+ return this->OSIs64Bit;
}
}
diff --git a/Source/kwsys/SystemInformation.hxx.in b/Source/kwsys/SystemInformation.hxx.in
index cc09393..54e7fc1 100644
--- a/Source/kwsys/SystemInformation.hxx.in
+++ b/Source/kwsys/SystemInformation.hxx.in
@@ -65,6 +65,7 @@ public:
// on this system.
std::string GetOSDescription();
+ // returns if the operating system is 64bit or not.
bool Is64Bits();
unsigned int GetNumberOfLogicalCPU();
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx
index 8c82ec1..65b7b26 100644
--- a/Source/kwsys/SystemTools.cxx
+++ b/Source/kwsys/SystemTools.cxx
@@ -3331,7 +3331,7 @@ std::string SystemTools::CollapseFullPath(const std::string& in_path,
SystemTools::SplitPath(in_path, path_components);
// If the input path is relative, start with a base path.
- if (path_components[0].length() == 0) {
+ if (path_components[0].empty()) {
std::vector<std::string> base_components;
if (in_base) {
// Use the given base path.
diff --git a/Source/kwsys/testSystemInformation.cxx b/Source/kwsys/testSystemInformation.cxx
index 86a1e1e..3a9217f 100644
--- a/Source/kwsys/testSystemInformation.cxx
+++ b/Source/kwsys/testSystemInformation.cxx
@@ -52,6 +52,7 @@ int testSystemInformation(int, char* [])
printMethod(info, GetOSRelease);
printMethod(info, GetOSVersion);
printMethod(info, GetOSPlatform);
+ printMethod(info, Is64Bits);
printMethod(info, GetVendorString);
printMethod(info, GetVendorID);
printMethod(info, GetTypeID);
@@ -63,7 +64,6 @@ int testSystemInformation(int, char* [])
printMethod2(info, GetProcessorCacheSize, "KB");
printMethod(info, GetLogicalProcessorsPerPhysical);
printMethod2(info, GetProcessorClockFrequency, "MHz");
- printMethod(info, Is64Bits);
printMethod(info, GetNumberOfLogicalCPU);
printMethod(info, GetNumberOfPhysicalCPU);
printMethod(info, DoesCPUSupportCPUID);
diff --git a/Tests/CPackComponents/CMakeLists.txt b/Tests/CPackComponents/CMakeLists.txt
index 3c8ae35..5b03c9e 100644
--- a/Tests/CPackComponents/CMakeLists.txt
+++ b/Tests/CPackComponents/CMakeLists.txt
@@ -79,7 +79,7 @@ set(CPACK_NSIS_MENU_LINKS
)
# Suggested default root for end users of the installer:
-set(CPACK_NSIS_INSTALL_ROOT "C:\\Program Files\\CMake Tests Install Root")
+set(CPACK_NSIS_INSTALL_ROOT "C:/Program Files/CMake Tests Install Root")
# Include CPack to introduce the appropriate targets
include(CPack)
diff --git a/Tests/CheckFortran.cmake b/Tests/CheckFortran.cmake
index 93990ad..b1652ba 100644
--- a/Tests/CheckFortran.cmake
+++ b/Tests/CheckFortran.cmake
@@ -18,6 +18,8 @@ file(WRITE \"\${CMAKE_CURRENT_BINARY_DIR}/result.cmake\"
execute_process(
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CheckFortran
COMMAND ${CMAKE_COMMAND} . -G ${CMAKE_GENERATOR}
+ -A "${CMAKE_GENERATOR_PLATFORM}"
+ -T "${CMAKE_GENERATOR_TOOLSET}"
OUTPUT_VARIABLE output
ERROR_VARIABLE output
RESULT_VARIABLE result
diff --git a/Tests/CudaOnly/SeparateCompilation/CMakeLists.txt b/Tests/CudaOnly/SeparateCompilation/CMakeLists.txt
index d134b96..420d7a9 100644
--- a/Tests/CudaOnly/SeparateCompilation/CMakeLists.txt
+++ b/Tests/CudaOnly/SeparateCompilation/CMakeLists.txt
@@ -12,22 +12,22 @@ project (CudaOnlySeparateCompilation CUDA)
string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=compute_30")
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CUDA_STANDARD 11)
-add_library(CUDASerarateLibA STATIC file1.cu file2.cu file3.cu)
+add_library(CUDASeparateLibA STATIC file1.cu file2.cu file3.cu)
#Having file4/file5 in a shared library causes serious problems
#with the nvcc linker and it will generate bad entries that will
#cause a segv when trying to run the executable
#
-add_library(CUDASerarateLibB STATIC file4.cu file5.cu)
-target_link_libraries(CUDASerarateLibB PRIVATE CUDASerarateLibA)
+add_library(CUDASeparateLibB STATIC file4.cu file5.cu)
+target_link_libraries(CUDASeparateLibB PRIVATE CUDASeparateLibA)
add_executable(CudaOnlySeparateCompilation main.cu)
-target_link_libraries(CudaOnlySeparateCompilation PRIVATE CUDASerarateLibB)
+target_link_libraries(CudaOnlySeparateCompilation PRIVATE CUDASeparateLibB)
-set_target_properties( CUDASerarateLibA
- CUDASerarateLibB
+set_target_properties( CUDASeparateLibA
+ CUDASeparateLibB
PROPERTIES CUDA_SEPARABLE_COMPILATION ON)
-set_target_properties( CUDASerarateLibA
- CUDASerarateLibB
+set_target_properties( CUDASeparateLibA
+ CUDASeparateLibB
PROPERTIES POSITION_INDEPENDENT_CODE ON)
diff --git a/Tests/CudaOnly/WithDefs/CMakeLists.txt b/Tests/CudaOnly/WithDefs/CMakeLists.txt
index 2646d29..38f2a44 100644
--- a/Tests/CudaOnly/WithDefs/CMakeLists.txt
+++ b/Tests/CudaOnly/WithDefs/CMakeLists.txt
@@ -16,8 +16,15 @@ set(release_compile_defs DEFREL)
#build a executable that needs to be passed a complex define through add_defintions
#this verifies we can pass things such as '_','(' to nvcc
add_definitions("-DPACKED_DEFINE=__attribute__((packed))")
-set_source_files_properties(main.notcu PROPERTIES LANGUAGE CUDA)
-add_executable(CudaOnlyWithDefs main.notcu)
+
+if(CMAKE_GENERATOR MATCHES "Visual Studio")
+ # CUDA MSBuild rules do not pass '-x cu' to nvcc
+ set(main main_for_vs.cu)
+else()
+ set(main main.notcu)
+ set_source_files_properties(main.notcu PROPERTIES LANGUAGE CUDA)
+endif()
+add_executable(CudaOnlyWithDefs ${main})
target_compile_options(CudaOnlyWithDefs
PRIVATE
diff --git a/Tests/CudaOnly/WithDefs/main_for_vs.cu b/Tests/CudaOnly/WithDefs/main_for_vs.cu
new file mode 100644
index 0000000..56078e7
--- /dev/null
+++ b/Tests/CudaOnly/WithDefs/main_for_vs.cu
@@ -0,0 +1 @@
+#include "main.notcu"
diff --git a/Tests/Module/WriteCompilerDetectionHeader/main.cpp b/Tests/Module/WriteCompilerDetectionHeader/main.cpp
index 192094c..9979cba 100644
--- a/Tests/Module/WriteCompilerDetectionHeader/main.cpp
+++ b/Tests/Module/WriteCompilerDetectionHeader/main.cpp
@@ -8,6 +8,9 @@
#error Expect no C features defined
#endif
+TEST_STATIC_ASSERT(true);
+TEST_STATIC_ASSERT_MSG(true, "msg");
+
int main()
{
return 0;
diff --git a/Tests/Module/WriteCompilerDetectionHeader/multi_files.cpp b/Tests/Module/WriteCompilerDetectionHeader/multi_files.cpp
index 1635091..d1f178f 100644
--- a/Tests/Module/WriteCompilerDetectionHeader/multi_files.cpp
+++ b/Tests/Module/WriteCompilerDetectionHeader/multi_files.cpp
@@ -8,6 +8,9 @@
#error Expect no C features defined
#endif
+MULTI_STATIC_ASSERT(true);
+MULTI_STATIC_ASSERT_MSG(true, "msg");
+
int main()
{
return 0;
diff --git a/Tests/QtAutogen/CMakeLists.txt b/Tests/QtAutogen/CMakeLists.txt
index 4960472..86af746 100644
--- a/Tests/QtAutogen/CMakeLists.txt
+++ b/Tests/QtAutogen/CMakeLists.txt
@@ -83,62 +83,92 @@ target_compile_features(empty PRIVATE ${QT_COMPILE_FEATURES})
# -- Test
# When a file listed in a .qrc file changes the target must be rebuilt
try_compile(RCC_DEPENDS
- "${CMAKE_CURRENT_BINARY_DIR}/autorcc_depends"
- "${CMAKE_CURRENT_SOURCE_DIR}/autorcc_depends"
- autorcc_depends
+ "${CMAKE_CURRENT_BINARY_DIR}/rccDepends"
+ "${CMAKE_CURRENT_SOURCE_DIR}/rccDepends"
+ rccDepends
CMAKE_FLAGS "-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}"
"-DQT_TEST_VERSION=${QT_TEST_VERSION}"
"-DCMAKE_PREFIX_PATH=${Qt_PREFIX_DIR}"
OUTPUT_VARIABLE output
)
if (NOT RCC_DEPENDS)
- message(SEND_ERROR "Initial build of autorcc_depends failed. Output: ${output}")
+ message(SEND_ERROR "Initial build of rccDepends failed. Output: ${output}")
endif()
-file(STRINGS "${CMAKE_CURRENT_BINARY_DIR}/autorcc_depends/info_file.txt" qrc_files)
-
-list(GET qrc_files 0 qrc_file1)
-
+# Get name and timestamp of the output binary
+file(STRINGS "${CMAKE_CURRENT_BINARY_DIR}/rccDepends/target1.txt" target1List)
+list(GET target1List 0 binFile)
set(timeformat "%Y%j%H%M%S")
+file(TIMESTAMP "${binFile}" timeBegin "${timeformat}")
-file(TIMESTAMP "${qrc_file1}" file1_before "${timeformat}")
-
+# Touch first qrc input file and rebuild
execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1) # Ensure that the timestamp will change.
-execute_process(COMMAND "${CMAKE_COMMAND}" -E touch "${CMAKE_CURRENT_BINARY_DIR}/autorcc_depends/res1/input.txt")
-
+execute_process(COMMAND "${CMAKE_COMMAND}" -E touch "${CMAKE_CURRENT_BINARY_DIR}/rccDepends/res1/input.txt")
execute_process(COMMAND "${CMAKE_COMMAND}" --build .
- WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/autorcc_depends"
+ WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/rccDepends"
+ RESULT_VARIABLE rccDepends_result
)
+if (rccDepends_result)
+ message(SEND_ERROR "Second build of rccDepends failed.")
+endif()
+# Compare timestamps
+file(TIMESTAMP "${binFile}" timeStep1 "${timeformat}")
+if (NOT timeStep1 GREATER timeBegin)
+ message(SEND_ERROR "File (${binFile}) should have changed in the first step!")
+endif()
-file(TIMESTAMP "${qrc_file1}" file1_step1 "${timeformat}")
-
-if (NOT file1_step1 GREATER file1_before)
- message(SEND_ERROR "file1 (${qrc_file1}) should have changed in the first step!")
+# Touch second qrc input file and rebuild
+execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1) # Ensure that the timestamp will change.
+execute_process(COMMAND "${CMAKE_COMMAND}" -E touch "${CMAKE_CURRENT_BINARY_DIR}/rccDepends/res2/input.txt")
+execute_process(COMMAND "${CMAKE_COMMAND}" --build .
+ WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/rccDepends"
+ RESULT_VARIABLE rccDepends_result
+)
+if (rccDepends_result)
+ message(SEND_ERROR "Third build of rccDepends failed.")
+endif()
+# Compare timestamps
+file(TIMESTAMP "${binFile}" timeStep2 "${timeformat}")
+if (NOT timeStep2 GREATER timeStep1)
+ message(SEND_ERROR "File (${binFile}) should have changed in the second step!")
endif()
# -- Test
# Ensure a repeated build succeeds when a header containing a QObject changes
try_compile(MOC_RERUN
- "${CMAKE_CURRENT_BINARY_DIR}/automoc_rerun"
- "${CMAKE_CURRENT_SOURCE_DIR}/automoc_rerun"
- automoc_rerun
+ "${CMAKE_CURRENT_BINARY_DIR}/mocRerun"
+ "${CMAKE_CURRENT_SOURCE_DIR}/mocRerun"
+ mocRerun
CMAKE_FLAGS "-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}"
"-DQT_TEST_VERSION=${QT_TEST_VERSION}"
"-DCMAKE_PREFIX_PATH=${Qt_PREFIX_DIR}"
OUTPUT_VARIABLE output
)
if (NOT MOC_RERUN)
- message(SEND_ERROR "Initial build of automoc_rerun failed. Output: ${output}")
+ message(SEND_ERROR "Initial build of mocRerun failed. Output: ${output}")
endif()
-configure_file(automoc_rerun/test1.h.in2 automoc_rerun/test1.h COPYONLY)
+# Get name and timestamp of the output binary
+file(STRINGS "${CMAKE_CURRENT_BINARY_DIR}/mocRerun/target1.txt" target1List)
+list(GET target1List 0 binFile)
+set(timeformat "%Y%j%H%M%S")
+file(TIMESTAMP "${binFile}" timeBegin "${timeformat}")
+# Change file content and rebuild
+execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1)
+configure_file(mocRerun/test1b.h.in mocRerun/test1.h COPYONLY)
execute_process(COMMAND "${CMAKE_COMMAND}" --build .
- WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/automoc_rerun"
- RESULT_VARIABLE automoc_rerun_result
+ WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/mocRerun"
+ RESULT_VARIABLE mocRerun_result
)
-if (automoc_rerun_result)
- message(SEND_ERROR "Second build of automoc_rerun failed.")
+if (mocRerun_result)
+ message(SEND_ERROR "Second build of mocRerun failed.")
+endif()
+
+# Compare timestamps
+file(TIMESTAMP "${binFile}" timeStep1 "${timeformat}")
+if (NOT timeStep1 GREATER timeBegin)
+ message(SEND_ERROR "File (${binFile}) should have changed in the first step!")
endif()
# -- Test
@@ -209,6 +239,10 @@ target_link_libraries(skipRccB ${QT_LIBRARIES})
add_subdirectory(sameName)
# -- Test
+# Tests AUTOMOC with generated sources
+add_subdirectory(mocDepends)
+
+# -- Test
# Tests various include moc patterns
add_subdirectory(mocIncludeStrict)
diff --git a/Tests/QtAutogen/automoc_rerun/CMakeLists.txt b/Tests/QtAutogen/automoc_rerun/CMakeLists.txt
deleted file mode 100644
index 92a682b..0000000
--- a/Tests/QtAutogen/automoc_rerun/CMakeLists.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-cmake_minimum_required(VERSION 3.7)
-project(automoc_rerun CXX)
-
-if (QT_TEST_VERSION STREQUAL 4)
- find_package(Qt4 REQUIRED)
- set(QT_CORE_TARGET Qt4::QtCore)
-else()
- if (NOT QT_TEST_VERSION STREQUAL 5)
- message(SEND_ERROR "Invalid Qt version specified.")
- endif()
-
- find_package(Qt5Core REQUIRED)
- set(QT_CORE_TARGET Qt5::Core)
-endif()
-
-set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTORCC ON)
-
-configure_file(test1.h.in1 test1.h COPYONLY)
-
-add_executable(test1
- ${CMAKE_CURRENT_BINARY_DIR}/test1.h
- test1.cpp
- res1.qrc
- )
-target_include_directories(test1 PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
-target_link_libraries(test1 ${QT_CORE_TARGET})
diff --git a/Tests/QtAutogen/automoc_rerun/test1.cpp b/Tests/QtAutogen/automoc_rerun/test1.cpp
deleted file mode 100644
index 4316a91..0000000
--- a/Tests/QtAutogen/automoc_rerun/test1.cpp
+++ /dev/null
@@ -1,5 +0,0 @@
-#include "test1.h"
-int main()
-{
- return 0;
-}
diff --git a/Tests/QtAutogen/automoc_rerun/test1.h.in1 b/Tests/QtAutogen/automoc_rerun/test1.h.in1
deleted file mode 100644
index fee2c09..0000000
--- a/Tests/QtAutogen/automoc_rerun/test1.h.in1
+++ /dev/null
@@ -1,8 +0,0 @@
-#include <QObject>
-class test1 : public QObject
-{
- Q_OBJECT
- public slots:
- void onTst1() {}
- void onTst2() {}
-};
diff --git a/Tests/QtAutogen/automoc_rerun/test1.h.in2 b/Tests/QtAutogen/automoc_rerun/test1.h.in2
deleted file mode 100644
index 6531d10..0000000
--- a/Tests/QtAutogen/automoc_rerun/test1.h.in2
+++ /dev/null
@@ -1,7 +0,0 @@
-#include <QObject>
-class test1 : public QObject
-{
- Q_OBJECT
- public slots:
- void onTst1() {}
-};
diff --git a/Tests/QtAutogen/autorcc_depends/CMakeLists.txt b/Tests/QtAutogen/autorcc_depends/CMakeLists.txt
deleted file mode 100644
index 7b51e11..0000000
--- a/Tests/QtAutogen/autorcc_depends/CMakeLists.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-cmake_minimum_required(VERSION 3.7)
-project(autorcc_depends)
-
-set(CMAKE_AUTORCC ON)
-
-if (QT_TEST_VERSION STREQUAL 4)
- find_package(Qt4 REQUIRED)
- set(QT_CORE_TARGET Qt4::QtCore)
-else()
- if (NOT QT_TEST_VERSION STREQUAL 5)
- message(SEND_ERROR "Invalid Qt version specified.")
- endif()
-
- find_package(Qt5Core REQUIRED)
- set(QT_CORE_TARGET Qt5::Core)
-endif()
-
-configure_file(res1.qrc.in res1.qrc @ONLY)
-configure_file(res1/input.txt.in res1/input.txt @ONLY)
-
-add_executable(test_res1
- test_res1.cpp
- ${CMAKE_CURRENT_BINARY_DIR}/res1.qrc
-)
-target_link_libraries(test_res1 ${QT_CORE_TARGET})
-add_custom_command(TARGET test_res1 POST_BUILD COMMAND
- ${CMAKE_COMMAND} -E echo "$<TARGET_FILE:test_res1>" > info_file.txt)
diff --git a/Tests/QtAutogen/mocDepends/CMakeLists.txt b/Tests/QtAutogen/mocDepends/CMakeLists.txt
new file mode 100644
index 0000000..8bd72eb
--- /dev/null
+++ b/Tests/QtAutogen/mocDepends/CMakeLists.txt
@@ -0,0 +1,45 @@
+cmake_minimum_required(VERSION 3.7)
+project(mocDepends)
+
+if (QT_TEST_VERSION STREQUAL 4)
+ find_package(Qt4 REQUIRED)
+ set(QT_CORE_TARGET Qt4::QtCore)
+else()
+ if (NOT QT_TEST_VERSION STREQUAL 5)
+ message(SEND_ERROR "Invalid Qt version specified.")
+ endif()
+
+ find_package(Qt5Core REQUIRED)
+ set(QT_CORE_TARGET Qt5::Core)
+endif()
+
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+# -- Test 1 using generated header
+# This tests the dependency of AUTOMOC of mocDepends1 to the generated object.hpp
+add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/object.hpp
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/invalid.hpp.in ${CMAKE_CURRENT_BINARY_DIR}/object.hpp
+ COMMAND ${CMAKE_COMMAND} -E sleep 3
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/object.hpp.in ${CMAKE_CURRENT_BINARY_DIR}/object.hpp
+ )
+
+add_executable(mocDepends1 test1.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/object.hpp
+)
+target_link_libraries(mocDepends1 ${QT_CORE_TARGET})
+set_target_properties(mocDepends1 PROPERTIES AUTOMOC TRUE)
+
+# -- Test 2 using generated library
+# This tests the dependency of AUTOMOC of mocDepends2 to the
+# generated simpleLib.hpp which belongs to a linked library of mocDepends2
+add_custom_command(OUTPUT simpleLib.hpp simpleLib.cpp
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/invalid.hpp.in ${CMAKE_CURRENT_BINARY_DIR}/simpleLib.hpp
+ COMMAND ${CMAKE_COMMAND} -E sleep 3
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/simpleLib.hpp.in ${CMAKE_CURRENT_BINARY_DIR}/simpleLib.hpp
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/simpleLib.cpp.in ${CMAKE_CURRENT_BINARY_DIR}/simpleLib.cpp
+ )
+add_library(SimpleLib STATIC simpleLib.hpp simpleLib.cpp)
+
+add_executable(mocDepends2 test2.cpp )
+target_link_libraries(mocDepends2 SimpleLib ${QT_CORE_TARGET})
+set_target_properties(mocDepends2 PROPERTIES AUTOMOC TRUE)
diff --git a/Tests/QtAutogen/mocDepends/invalid.hpp.in b/Tests/QtAutogen/mocDepends/invalid.hpp.in
new file mode 100644
index 0000000..854d9a1
--- /dev/null
+++ b/Tests/QtAutogen/mocDepends/invalid.hpp.in
@@ -0,0 +1 @@
+#ifndef
diff --git a/Tests/QtAutogen/mocDepends/object.hpp.in b/Tests/QtAutogen/mocDepends/object.hpp.in
new file mode 100644
index 0000000..f364f7c
--- /dev/null
+++ b/Tests/QtAutogen/mocDepends/object.hpp.in
@@ -0,0 +1,14 @@
+#ifndef OBJECT_HPP
+#define OBJECT_HPP
+
+#include <QObject>
+
+class Object : public QObject
+{
+ Q_OBJECT
+public:
+ Q_SLOT
+ void aSlot(){};
+};
+
+#endif
diff --git a/Tests/QtAutogen/mocDepends/simpleLib.cpp.in b/Tests/QtAutogen/mocDepends/simpleLib.cpp.in
new file mode 100644
index 0000000..fa33bd3
--- /dev/null
+++ b/Tests/QtAutogen/mocDepends/simpleLib.cpp.in
@@ -0,0 +1,9 @@
+#include "simpleLib.hpp"
+
+SimpleLib::SimpleLib()
+{
+}
+
+SimpleLib::~SimpleLib()
+{
+}
diff --git a/Tests/QtAutogen/mocDepends/simpleLib.hpp.in b/Tests/QtAutogen/mocDepends/simpleLib.hpp.in
new file mode 100644
index 0000000..758f1f6
--- /dev/null
+++ b/Tests/QtAutogen/mocDepends/simpleLib.hpp.in
@@ -0,0 +1,11 @@
+#ifndef SIMPLE_LIB_H
+#define SIMPLE_LIB_H
+
+class SimpleLib
+{
+public:
+ SimpleLib();
+ ~SimpleLib();
+};
+
+#endif
diff --git a/Tests/QtAutogen/mocDepends/test1.cpp b/Tests/QtAutogen/mocDepends/test1.cpp
new file mode 100644
index 0000000..92c259c
--- /dev/null
+++ b/Tests/QtAutogen/mocDepends/test1.cpp
@@ -0,0 +1,9 @@
+
+#include "object.hpp"
+
+int main()
+{
+ Object obj;
+
+ return 0;
+}
diff --git a/Tests/QtAutogen/mocDepends/test2.cpp b/Tests/QtAutogen/mocDepends/test2.cpp
new file mode 100644
index 0000000..155b19b
--- /dev/null
+++ b/Tests/QtAutogen/mocDepends/test2.cpp
@@ -0,0 +1,10 @@
+
+#include "test2.hpp"
+
+int main()
+{
+ SimpleLib obj;
+ LObject lobject;
+
+ return 0;
+}
diff --git a/Tests/QtAutogen/mocDepends/test2.hpp b/Tests/QtAutogen/mocDepends/test2.hpp
new file mode 100644
index 0000000..0125f07
--- /dev/null
+++ b/Tests/QtAutogen/mocDepends/test2.hpp
@@ -0,0 +1,16 @@
+#ifndef TEST2_HPP
+#define TEST2_HPP
+
+#include "simpleLib.hpp"
+#include <QObject>
+
+// This object triggers the AUTOMOC on this file
+class LObject : public QObject
+{
+ Q_OBJECT
+public:
+ Q_SLOT
+ void aSlot(){};
+};
+
+#endif
diff --git a/Tests/QtAutogen/mocRerun/CMakeLists.txt b/Tests/QtAutogen/mocRerun/CMakeLists.txt
new file mode 100644
index 0000000..6689f50
--- /dev/null
+++ b/Tests/QtAutogen/mocRerun/CMakeLists.txt
@@ -0,0 +1,35 @@
+cmake_minimum_required(VERSION 3.7)
+project(mocRerun CXX)
+
+if (QT_TEST_VERSION STREQUAL 4)
+ find_package(Qt4 REQUIRED)
+ set(QT_CORE_TARGET Qt4::QtCore)
+else()
+ if (NOT QT_TEST_VERSION STREQUAL 5)
+ message(SEND_ERROR "Invalid Qt version specified.")
+ endif()
+
+ find_package(Qt5Core REQUIRED)
+ set(QT_CORE_TARGET Qt5::Core)
+endif()
+
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_AUTORCC ON)
+
+configure_file(test1a.h.in test1.h COPYONLY)
+# Generated source file
+add_custom_command(OUTPUT main.cpp
+ COMMAND ${CMAKE_COMMAND} -E sleep 3
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp.in ${CMAKE_CURRENT_BINARY_DIR}/main.cpp
+ )
+
+add_executable(mocRerun
+ ${CMAKE_CURRENT_BINARY_DIR}/test1.h
+ ${CMAKE_CURRENT_BINARY_DIR}/main.cpp
+ res1.qrc
+ )
+target_include_directories(mocRerun PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
+target_link_libraries(mocRerun ${QT_CORE_TARGET})
+# Write target name to text file
+add_custom_command(TARGET mocRerun POST_BUILD COMMAND
+ ${CMAKE_COMMAND} -E echo "$<TARGET_FILE:mocRerun>" > target1.txt)
diff --git a/Tests/QtAutogen/automoc_rerun/input.txt b/Tests/QtAutogen/mocRerun/input.txt
index da62762..da62762 100644
--- a/Tests/QtAutogen/automoc_rerun/input.txt
+++ b/Tests/QtAutogen/mocRerun/input.txt
diff --git a/Tests/QtAutogen/mocRerun/main.cpp.in b/Tests/QtAutogen/mocRerun/main.cpp.in
new file mode 100644
index 0000000..b37ff61
--- /dev/null
+++ b/Tests/QtAutogen/mocRerun/main.cpp.in
@@ -0,0 +1,18 @@
+#include "test1.h"
+
+class Test2 : public QObject
+{
+ Q_OBJECT
+public slots:
+ void onTst1() {}
+};
+
+int main()
+{
+ Test1 test1;
+ Test2 test2;
+
+ return 0;
+}
+
+#include "main.moc"
diff --git a/Tests/QtAutogen/automoc_rerun/res1.qrc b/Tests/QtAutogen/mocRerun/res1.qrc
index fb804b5..fb804b5 100644
--- a/Tests/QtAutogen/automoc_rerun/res1.qrc
+++ b/Tests/QtAutogen/mocRerun/res1.qrc
diff --git a/Tests/QtAutogen/mocRerun/test1a.h.in b/Tests/QtAutogen/mocRerun/test1a.h.in
new file mode 100644
index 0000000..a335046
--- /dev/null
+++ b/Tests/QtAutogen/mocRerun/test1a.h.in
@@ -0,0 +1,8 @@
+#include <QObject>
+class Test1 : public QObject
+{
+ Q_OBJECT
+public slots:
+ void onTst1() {}
+ void onTst2() {}
+};
diff --git a/Tests/QtAutogen/mocRerun/test1b.h.in b/Tests/QtAutogen/mocRerun/test1b.h.in
new file mode 100644
index 0000000..6128eeb
--- /dev/null
+++ b/Tests/QtAutogen/mocRerun/test1b.h.in
@@ -0,0 +1,7 @@
+#include <QObject>
+class Test1 : public QObject
+{
+ Q_OBJECT
+public slots:
+ void onTst1() {}
+};
diff --git a/Tests/QtAutogen/rccDepends/CMakeLists.txt b/Tests/QtAutogen/rccDepends/CMakeLists.txt
new file mode 100644
index 0000000..de98573
--- /dev/null
+++ b/Tests/QtAutogen/rccDepends/CMakeLists.txt
@@ -0,0 +1,36 @@
+cmake_minimum_required(VERSION 3.7)
+project(rccDepends)
+
+set(CMAKE_AUTORCC ON)
+
+if (QT_TEST_VERSION STREQUAL 4)
+ find_package(Qt4 REQUIRED)
+ set(QT_CORE_TARGET Qt4::QtCore)
+else()
+ if (NOT QT_TEST_VERSION STREQUAL 5)
+ message(SEND_ERROR "Invalid Qt version specified.")
+ endif()
+
+ find_package(Qt5Core REQUIRED)
+ set(QT_CORE_TARGET Qt5::Core)
+endif()
+
+configure_file(res/input1.txt.in res1/input.txt @ONLY)
+configure_file(res/input2.txt.in res2/input.txt @ONLY)
+# Configure time generated qrc file
+configure_file(res1.qrc.in res1.qrc @ONLY)
+# Dependency generated qrc file
+add_custom_command(OUTPUT res2.qrc
+ COMMAND ${CMAKE_COMMAND} -E sleep 3
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/res2.qrc.in ${CMAKE_CURRENT_BINARY_DIR}/res2.qrc
+ )
+
+
+add_executable(rccDepends
+ main.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/res1.qrc
+ ${CMAKE_CURRENT_BINARY_DIR}/res2.qrc
+)
+target_link_libraries(rccDepends ${QT_CORE_TARGET})
+add_custom_command(TARGET rccDepends POST_BUILD COMMAND
+ ${CMAKE_COMMAND} -E echo "$<TARGET_FILE:rccDepends>" > target1.txt)
diff --git a/Tests/QtAutogen/autorcc_depends/test_res1.cpp b/Tests/QtAutogen/rccDepends/main.cpp
index 766b775..766b775 100644
--- a/Tests/QtAutogen/autorcc_depends/test_res1.cpp
+++ b/Tests/QtAutogen/rccDepends/main.cpp
diff --git a/Tests/QtAutogen/autorcc_depends/res1/input.txt.in b/Tests/QtAutogen/rccDepends/res/input1.txt.in
index da62762..da62762 100644
--- a/Tests/QtAutogen/autorcc_depends/res1/input.txt.in
+++ b/Tests/QtAutogen/rccDepends/res/input1.txt.in
diff --git a/Tests/QtAutogen/rccDepends/res/input2.txt.in b/Tests/QtAutogen/rccDepends/res/input2.txt.in
new file mode 100644
index 0000000..08e14b7
--- /dev/null
+++ b/Tests/QtAutogen/rccDepends/res/input2.txt.in
@@ -0,0 +1 @@
+Res2 input.
diff --git a/Tests/QtAutogen/autorcc_depends/res1.qrc.in b/Tests/QtAutogen/rccDepends/res1.qrc.in
index 2a5417b..2a5417b 100644
--- a/Tests/QtAutogen/autorcc_depends/res1.qrc.in
+++ b/Tests/QtAutogen/rccDepends/res1.qrc.in
diff --git a/Tests/QtAutogen/rccDepends/res2.qrc.in b/Tests/QtAutogen/rccDepends/res2.qrc.in
new file mode 100644
index 0000000..18b916a
--- /dev/null
+++ b/Tests/QtAutogen/rccDepends/res2.qrc.in
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/">
+ <file>res2/input.txt</file>
+ </qresource>
+</RCC>
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 6423bfd..5157b9f 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -156,6 +156,9 @@ add_RunCMake_test(TargetPropertyGeneratorExpressions)
add_RunCMake_test(Languages)
add_RunCMake_test(LinkStatic)
add_RunCMake_test(ObjectLibrary)
+if(UNIX AND CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG AND CMAKE_EXECUTABLE_FORMAT STREQUAL "ELF")
+ add_RunCMake_test(RuntimePath)
+endif()
add_RunCMake_test(Swift)
add_RunCMake_test(TargetObjects)
add_RunCMake_test(TargetSources)
diff --git a/Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake b/Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake
index 44c67a2..f6449f2 100644
--- a/Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake
@@ -6,6 +6,12 @@ run_cmake(NoToolset)
if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[01245]")
set(RunCMake_GENERATOR_TOOLSET "Test Toolset")
run_cmake(TestToolset)
+ set(RunCMake_GENERATOR_TOOLSET "Test Toolset,cuda=Test Cuda")
+ run_cmake(TestToolsetCudaBoth)
+ set(RunCMake_GENERATOR_TOOLSET ",cuda=Test Cuda")
+ run_cmake(TestToolsetCudaOnly)
+ set(RunCMake_GENERATOR_TOOLSET "cuda=Test Cuda")
+ run_cmake(TestToolsetCudaOnly)
if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[245]")
set(RunCMake_GENERATOR_TOOLSET "Test Toolset,host=x64")
run_cmake(TestToolsetHostArchBoth)
diff --git a/Tests/RunCMake/GeneratorToolset/TestToolsetCudaBoth-stdout.txt b/Tests/RunCMake/GeneratorToolset/TestToolsetCudaBoth-stdout.txt
new file mode 100644
index 0000000..90503e2
--- /dev/null
+++ b/Tests/RunCMake/GeneratorToolset/TestToolsetCudaBoth-stdout.txt
@@ -0,0 +1,2 @@
+-- CMAKE_VS_PLATFORM_TOOLSET='Test Toolset'
+-- CMAKE_VS_PLATFORM_TOOLSET_CUDA='Test Cuda'
diff --git a/Tests/RunCMake/GeneratorToolset/TestToolsetCudaBoth.cmake b/Tests/RunCMake/GeneratorToolset/TestToolsetCudaBoth.cmake
new file mode 100644
index 0000000..befa0af
--- /dev/null
+++ b/Tests/RunCMake/GeneratorToolset/TestToolsetCudaBoth.cmake
@@ -0,0 +1,2 @@
+message(STATUS "CMAKE_VS_PLATFORM_TOOLSET='${CMAKE_VS_PLATFORM_TOOLSET}'")
+message(STATUS "CMAKE_VS_PLATFORM_TOOLSET_CUDA='${CMAKE_VS_PLATFORM_TOOLSET_CUDA}'")
diff --git a/Tests/RunCMake/GeneratorToolset/TestToolsetCudaOnly-stdout.txt b/Tests/RunCMake/GeneratorToolset/TestToolsetCudaOnly-stdout.txt
new file mode 100644
index 0000000..94e1e43
--- /dev/null
+++ b/Tests/RunCMake/GeneratorToolset/TestToolsetCudaOnly-stdout.txt
@@ -0,0 +1,2 @@
+-- CMAKE_VS_PLATFORM_TOOLSET='(v[0-9]+|Windows7.1SDK)'
+-- CMAKE_VS_PLATFORM_TOOLSET_CUDA='Test Cuda'
diff --git a/Tests/RunCMake/GeneratorToolset/TestToolsetCudaOnly.cmake b/Tests/RunCMake/GeneratorToolset/TestToolsetCudaOnly.cmake
new file mode 100644
index 0000000..befa0af
--- /dev/null
+++ b/Tests/RunCMake/GeneratorToolset/TestToolsetCudaOnly.cmake
@@ -0,0 +1,2 @@
+message(STATUS "CMAKE_VS_PLATFORM_TOOLSET='${CMAKE_VS_PLATFORM_TOOLSET}'")
+message(STATUS "CMAKE_VS_PLATFORM_TOOLSET_CUDA='${CMAKE_VS_PLATFORM_TOOLSET_CUDA}'")
diff --git a/Tests/RunCMake/RuntimePath/A.c b/Tests/RunCMake/RuntimePath/A.c
new file mode 100644
index 0000000..e9d4195
--- /dev/null
+++ b/Tests/RunCMake/RuntimePath/A.c
@@ -0,0 +1,4 @@
+int libA(void)
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/RuntimePath/CMakeLists.txt b/Tests/RunCMake/RuntimePath/CMakeLists.txt
new file mode 100644
index 0000000..a640c56
--- /dev/null
+++ b/Tests/RunCMake/RuntimePath/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.7)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/RuntimePath/RunCMakeTest.cmake b/Tests/RunCMake/RuntimePath/RunCMakeTest.cmake
new file mode 100644
index 0000000..a9a7f05
--- /dev/null
+++ b/Tests/RunCMake/RuntimePath/RunCMakeTest.cmake
@@ -0,0 +1,18 @@
+include(RunCMake)
+
+
+function(run_SymlinkImplicit)
+ # Use a single build tree for a few tests without cleaning.
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/SymlinkImplicit-build)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ if(RunCMake_GENERATOR MATCHES "Make|Ninja")
+ set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug)
+ endif()
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+ run_cmake(SymlinkImplicit)
+ run_cmake_command(SymlinkImplicit-build ${CMAKE_COMMAND} --build . --config Debug)
+ run_cmake_command(SymlinkImplicitCheck
+ ${CMAKE_COMMAND} -Ddir=${RunCMake_TEST_BINARY_DIR} -P ${RunCMake_SOURCE_DIR}/SymlinkImplicitCheck.cmake)
+endfunction()
+run_SymlinkImplicit()
diff --git a/Tests/RunCMake/RuntimePath/SymlinkImplicit.cmake b/Tests/RunCMake/RuntimePath/SymlinkImplicit.cmake
new file mode 100644
index 0000000..6578f8f
--- /dev/null
+++ b/Tests/RunCMake/RuntimePath/SymlinkImplicit.cmake
@@ -0,0 +1,17 @@
+enable_language(C)
+
+set(lib_dir ${CMAKE_CURRENT_BINARY_DIR}/lib)
+set(lib_link ${CMAKE_CURRENT_BINARY_DIR}/libLink)
+set(lib_always ${CMAKE_CURRENT_BINARY_DIR}/libAlways)
+file(MAKE_DIRECTORY ${lib_dir})
+execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink lib ${lib_link})
+execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink lib ${lib_always})
+
+add_library(A SHARED A.c)
+list(APPEND CMAKE_C_IMPLICIT_LINK_DIRECTORIES ${lib_dir})
+set_property(TARGET A PROPERTY LIBRARY_OUTPUT_DIRECTORY ${lib_link})
+
+add_executable(exe main.c)
+target_link_libraries(exe A)
+set_property(TARGET exe PROPERTY RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin)
+set_property(TARGET exe PROPERTY BUILD_RPATH ${lib_always})
diff --git a/Tests/RunCMake/RuntimePath/SymlinkImplicitCheck-result.txt b/Tests/RunCMake/RuntimePath/SymlinkImplicitCheck-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/RuntimePath/SymlinkImplicitCheck-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/RuntimePath/SymlinkImplicitCheck-stderr.txt b/Tests/RunCMake/RuntimePath/SymlinkImplicitCheck-stderr.txt
new file mode 100644
index 0000000..b0ede70
--- /dev/null
+++ b/Tests/RunCMake/RuntimePath/SymlinkImplicitCheck-stderr.txt
@@ -0,0 +1,22 @@
+^CMake Error at .*/Tests/RunCMake/RuntimePath/SymlinkImplicitCheck.cmake:[0-9]+ \(file\):
+ file RPATH_CHANGE could not write new RPATH:
+
+ old-should-not-exist
+
+ to the file:
+
+ [^
+]*/Tests/RunCMake/RuntimePath/SymlinkImplicit-build/exe
+
+ The current (RPATH|RUNPATH) is:
+
+ [^
+]*/Tests/RunCMake/RuntimePath/SymlinkImplicit-build/libAlways(:[^
+]*)?
+
+ which does not contain:
+
+ [^
+]*/Tests/RunCMake/RuntimePath/SymlinkImplicit-build/libLink
+
+ as was expected\.$
diff --git a/Tests/RunCMake/RuntimePath/SymlinkImplicitCheck.cmake b/Tests/RunCMake/RuntimePath/SymlinkImplicitCheck.cmake
new file mode 100644
index 0000000..d34742e
--- /dev/null
+++ b/Tests/RunCMake/RuntimePath/SymlinkImplicitCheck.cmake
@@ -0,0 +1,2 @@
+file(COPY ${dir}/bin/exe DESTINATION ${dir})
+file(RPATH_CHANGE FILE "${dir}/exe" OLD_RPATH "${dir}/libLink" NEW_RPATH "old-should-not-exist")
diff --git a/Tests/RunCMake/RuntimePath/main.c b/Tests/RunCMake/RuntimePath/main.c
new file mode 100644
index 0000000..8488f4e
--- /dev/null
+++ b/Tests/RunCMake/RuntimePath/main.c
@@ -0,0 +1,4 @@
+int main(void)
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake
index f51a107..5f4bdc3 100644
--- a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake
+++ b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake
@@ -187,3 +187,19 @@ if(NOT XCODE_VERSION VERSION_LESS 5)
unset(RunCMake_TEST_NO_CLEAN)
unset(RunCMake_TEST_OPTIONS)
endif()
+
+function(XcodeSchemaGeneration)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/XcodeSchemaGeneration-build)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ set(RunCMake_TEST_OPTIONS "-DCMAKE_XCODE_GENERATE_SCHEME=ON")
+
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+ run_cmake(XcodeSchemaGeneration)
+ run_cmake_command(XcodeSchemaGeneration-build xcodebuild -scheme foo build)
+endfunction()
+
+if(NOT XCODE_VERSION VERSION_LESS 7)
+ XcodeSchemaGeneration()
+endif()
diff --git a/Tests/RunCMake/XcodeProject/XcodeSchemaGeneration.cmake b/Tests/RunCMake/XcodeProject/XcodeSchemaGeneration.cmake
new file mode 100644
index 0000000..2fe5a9f
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/XcodeSchemaGeneration.cmake
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 3.7)
+
+project(XcodeSchemaGeneration CXX)
+
+add_executable(foo main.cpp)
diff --git a/Tests/RunCMake/file/READ_ELF-result.txt b/Tests/RunCMake/file/READ_ELF-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/file/READ_ELF-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file/READ_ELF-stderr.txt b/Tests/RunCMake/file/READ_ELF-stderr.txt
new file mode 100644
index 0000000..7b32804
--- /dev/null
+++ b/Tests/RunCMake/file/READ_ELF-stderr.txt
@@ -0,0 +1,2 @@
+.*file READ_ELF must be called with at least three additional arguments\.
+.*file READ_ELF given FILE "XXX" that does not exist\.
diff --git a/Tests/RunCMake/file/READ_ELF.cmake b/Tests/RunCMake/file/READ_ELF.cmake
new file mode 100644
index 0000000..cd02c9b
--- /dev/null
+++ b/Tests/RunCMake/file/READ_ELF.cmake
@@ -0,0 +1,2 @@
+file(READ_ELF XXX)
+file(READ_ELF XXX RPATH YYY)
diff --git a/Tests/RunCMake/file/RunCMakeTest.cmake b/Tests/RunCMake/file/RunCMakeTest.cmake
index 7497544..3f3c0da 100644
--- a/Tests/RunCMake/file/RunCMakeTest.cmake
+++ b/Tests/RunCMake/file/RunCMakeTest.cmake
@@ -25,6 +25,7 @@ run_cmake(LOCK-error-no-timeout)
run_cmake(LOCK-error-timeout)
run_cmake(LOCK-error-unknown-option)
run_cmake(LOCK-lowercase)
+run_cmake(READ_ELF)
run_cmake(GLOB)
run_cmake(GLOB_RECURSE)
# test is valid both for GLOB and GLOB_RECURSE
diff --git a/Utilities/GitSetup/config b/Utilities/GitSetup/config
index d69a679..2b4f037 100644
--- a/Utilities/GitSetup/config
+++ b/Utilities/GitSetup/config
@@ -1,9 +1,2 @@
[hooks]
- url = https://cmake.org/cmake.git
-[ssh]
- host = cmake.org
- key = id_git_cmake
- request-url = https://www.kitware.com/Admin/SendPassword.cgi
-[stage]
- url = git://cmake.org/stage/cmake.git
- pushurl = git@cmake.org:stage/cmake.git
+ url = https://gitlab.kitware.com/utils/gitsetup.git
diff --git a/Utilities/Release/release_cmake.cmake b/Utilities/Release/release_cmake.cmake
index 0db89b5..ee1a0dc 100644
--- a/Utilities/Release/release_cmake.cmake
+++ b/Utilities/Release/release_cmake.cmake
@@ -32,9 +32,15 @@ if(NOT DEFINED GIT_COMMAND)
set(GIT_COMMAND git)
endif()
-if(${CMAKE_CREATE_VERSION} MATCHES "^(release|maint|next|nightly)$")
+if(CMAKE_CREATE_VERSION MATCHES "^(master|release)$")
+ set(GIT_FETCH "")
set(GIT_BRANCH origin/${CMAKE_CREATE_VERSION})
+elseif(CMAKE_CREATE_VERSION STREQUAL "nightly")
+ set(nightly stage/master/nightly/latest)
+ set(GIT_FETCH "${GIT_COMMAND} fetch origin refs/${nightly}:refs/remotes/origin/${nightly}")
+ set(GIT_BRANCH origin/${nightly})
else()
+ set(GIT_FETCH "")
set(GIT_BRANCH ${CMAKE_CREATE_VERSION})
endif()
diff --git a/Utilities/Release/release_cmake.sh.in b/Utilities/Release/release_cmake.sh.in
index 1465129..f363b3d 100755
--- a/Utilities/Release/release_cmake.sh.in
+++ b/Utilities/Release/release_cmake.sh.in
@@ -94,13 +94,15 @@ cd @CMAKE_RELEASE_DIRECTORY@
if [ ! -z "@GIT_COMMAND@" ]; then
# clone the repo without creating any source files in the directory
# matching the branch being built (i.e. master CMake-2-8, etc)
- @GIT_COMMAND@ clone -n git://cmake.org/cmake.git @CMAKE_CREATE_VERSION@
- check_exit_value $? "Checkout git cmake source" || exit 1
+ @GIT_COMMAND@ clone -n https://gitlab.kitware.com/cmake/cmake.git @CMAKE_CREATE_VERSION@
+ check_exit_value $? "git clone cmake source" || exit 1
# go into the git directory
cd @CMAKE_CREATE_VERSION@
# run any extra commands if they exist
@GIT_EXTRA@
check_exit_value $? "git extra cmake source" || exit 1
+ @GIT_FETCH@
+ check_exit_value $? "git extra fetch" || exit 1
# now checkout a copy on the local branch working
@GIT_COMMAND@ checkout -b working @GIT_BRANCH@
check_exit_value $? "git checkout" || exit 1
diff --git a/Utilities/SetupForDevelopment.sh b/Utilities/SetupForDevelopment.sh
index 39152bc..ff64a84 100755
--- a/Utilities/SetupForDevelopment.sh
+++ b/Utilities/SetupForDevelopment.sh
@@ -3,9 +3,6 @@
cd "${BASH_SOURCE%/*}/.." &&
Utilities/GitSetup/setup-user && echo &&
Utilities/GitSetup/setup-hooks && echo &&
-Utilities/GitSetup/setup-stage && echo &&
-(Utilities/GitSetup/setup-ssh ||
- echo 'Failed to setup SSH. Run this again to retry.') && echo &&
Utilities/GitSetup/tips
# Rebase master by default
@@ -13,5 +10,5 @@ git config rebase.stat true
git config branch.master.rebase true
# Record the version of this setup so Git/pre-commit can check it.
-SetupForDevelopment_VERSION=1
+SetupForDevelopment_VERSION=2
git config hooks.SetupForDevelopment ${SetupForDevelopment_VERSION}
diff --git a/Utilities/Sphinx/conf.py.in b/Utilities/Sphinx/conf.py.in
index 9581458..e3afc78 100644
--- a/Utilities/Sphinx/conf.py.in
+++ b/Utilities/Sphinx/conf.py.in
@@ -18,7 +18,9 @@ release = '@conf_release@' # full version string
primary_domain = 'cmake'
-exclude_patterns = []
+exclude_patterns = [
+ 'dev', # ignore developer-only documentation
+ ]
extensions = ['cmake']
templates_path = ['@conf_path@/templates']
diff --git a/bootstrap b/bootstrap
index 8063edb..4f58365 100755
--- a/bootstrap
+++ b/bootstrap
@@ -404,6 +404,7 @@ CMAKE_CXX_SOURCES="\
cmUnsetCommand \
cmVersion \
cmWhileCommand \
+ cmWorkingDirectory \
cmake \
cmakemain \
cmcmd \