diff options
76 files changed, 1170 insertions, 299 deletions
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index 13b22f8..2c63c4b 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst @@ -184,6 +184,7 @@ Properties on Targets /prop_tgt/HAS_CXX /prop_tgt/IMPLICIT_DEPENDS_INCLUDE_TRANSFORM /prop_tgt/IMPORTED_CONFIGURATIONS + /prop_tgt/IMPORTED_GLOBAL /prop_tgt/IMPORTED_IMPLIB_CONFIG /prop_tgt/IMPORTED_IMPLIB /prop_tgt/IMPORTED_LIBNAME_CONFIG diff --git a/Help/manual/cmake-server.7.rst b/Help/manual/cmake-server.7.rst index 389a6d5..ee8fada 100644 --- a/Help/manual/cmake-server.7.rst +++ b/Help/manual/cmake-server.7.rst @@ -458,6 +458,9 @@ Each project object can have the following keys: "name" contains the (sub-)projects name. +"minimumCMakeVersion" + contains the minimum cmake version allowed for this project, null if the + project doesn't specify one. "hasInstallRule" true if the project contains any install rules, false otherwise. "sourceDirectory" @@ -628,6 +631,79 @@ CMake will reply:: ]== "CMake Server" ==] +Type "ctestInfo" +^^^^^^^^^^^^^^^^ + +The "ctestInfo" request can be used after a project was "compute"d successfully. + +It will list the complete project test structure as it is known to cmake. + +The reply will contain a key "configurations", which will contain a list of +configuration objects. Configuration objects are used to destinquish between +different configurations the build directory might have enabled. While most +generators only support one configuration, others might support several. + +Each configuration object can have the following keys: + +"name" + contains the name of the configuration. The name may be empty. +"projects" + contains a list of project objects, one for each build project. + +Project objects define one (sub-)project defined in the cmake build system. + +Each project object can have the following keys: + +"name" + contains the (sub-)projects name. +"targets" + contains a list of build system target objects. + +Target objects define individual build targets for a certain configuration. + +Each target object can have the following keys: + +"name" + contains the name of the target. +"type" + defines the type of build of the target. Possible values are + "STATIC_LIBRARY", "MODULE_LIBRARY", "SHARED_LIBRARY", "OBJECT_LIBRARY", + "EXECUTABLE", "UTILITY" and "INTERFACE_LIBRARY". +"fullName" + contains the full name of the build result (incl. extensions, etc.). +"hasEnabledTests" + true if testing is enabled for this target. +"ctestInfo" + contains a list of test objects for this target. + +Each test object can have the following keys: + +"ctestName" + contains the name of the test. +"ctestCommand" + contains the test command. +"properties" + contains a list of test property objects. +"backtrace" + contains a list of backtrace objects that specify where the test was defined. + +Each backtrace object can have the following keys: + +"path" + contains the full path to the file containing the statement. +"line" + contains the line number in the file where the statement was defined. +"name" + contains the name of the statement that added the test. + +Each test property object can have the following keys: + +"key" + contains the test property key. +"value" + contains the test property value. + + Type "cmakeInputs" ^^^^^^^^^^^^^^^^^^ diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 0170da1..1927c37 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -159,6 +159,7 @@ Variables that Change Behavior /variable/CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE /variable/CMAKE_INCLUDE_PATH /variable/CMAKE_INSTALL_DEFAULT_COMPONENT_NAME + /variable/CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS /variable/CMAKE_INSTALL_MESSAGE /variable/CMAKE_INSTALL_PREFIX /variable/CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT @@ -529,6 +530,7 @@ Variables for CPack /variable/CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY /variable/CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION /variable/CPACK_INCLUDE_TOPLEVEL_DIRECTORY + /variable/CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS /variable/CPACK_INSTALL_SCRIPT /variable/CPACK_PACKAGING_INSTALL_PREFIX /variable/CPACK_SET_DESTDIR diff --git a/Help/manual/ctest.1.rst b/Help/manual/ctest.1.rst index 423f1ca..d9af3bc 100644 --- a/Help/manual/ctest.1.rst +++ b/Help/manual/ctest.1.rst @@ -3,12 +3,18 @@ ctest(1) ******** +.. contents:: + Synopsis ======== .. parsed-literal:: ctest [<options>] + ctest <path-to-source> <path-to-build> --build-generator <generator> + [<options>...] [-- <build-options>...] [--test-command <test>] + ctest (-D <dashboard> | -M <model> -T <action> | -S <script> | -SP <script>) + [-- <dashboard-options>...] Description =========== @@ -55,17 +61,21 @@ Options ``-F`` Enable failover. - This option allows ctest to resume a test set execution that was + This option allows CTest to resume a test set execution that was previously interrupted. If no interruption occurred, the ``-F`` option will have no effect. ``-j <jobs>, --parallel <jobs>`` Run the tests in parallel using the given number of jobs. - This option tells ctest to run the tests in parallel using given - number of jobs. This option can also be set by setting the + This option tells CTest to run the tests in parallel using given + number of jobs. This option can also be set by setting the environment variable ``CTEST_PARALLEL_LEVEL``. + This option can be used with the :prop_test:`PROCESSORS` test property. + + See `Label and Subproject Summary`_. + ``--test-load <level>`` While running tests in parallel (e.g. with ``-j``), try not to start tests when they may cause the CPU load to pass above a given threshold. @@ -74,7 +84,7 @@ Options ``TestLoad`` option of the `CTest Test Step`_. ``-Q,--quiet`` - Make ctest quiet. + Make CTest quiet. This option will suppress all the output. The output log file will still be generated if the ``--output-log`` is specified. Options such @@ -84,37 +94,37 @@ Options ``-O <file>, --output-log <file>`` Output to log file. - This option tells ctest to write all its output to a log file. + This option tells CTest to write all its output to a log file. ``-N,--show-only`` Disable actual execution of tests. - This option tells ctest to list the tests that would be run but not + This option tells CTest to list the tests that would be run but not actually run them. Useful in conjunction with the ``-R`` and ``-E`` options. ``-L <regex>, --label-regex <regex>`` Run tests with labels matching regular expression. - This option tells ctest to run only the tests whose labels match the + This option tells CTest to run only the tests whose labels match the given regular expression. ``-R <regex>, --tests-regex <regex>`` Run tests matching regular expression. - This option tells ctest to run only the tests whose names match the + This option tells CTest to run only the tests whose names match the given regular expression. ``-E <regex>, --exclude-regex <regex>`` Exclude tests matching regular expression. - This option tells ctest to NOT run the tests whose names match the + This option tells CTest to NOT run the tests whose names match the given regular expression. ``-LE <regex>, --label-exclude <regex>`` Exclude tests with labels matching regular expression. - This option tells ctest to NOT run the tests whose labels match the + This option tells CTest to NOT run the tests whose labels match the given regular expression. ``-FA <regex>, --fixture-exclude-any <regex>`` @@ -137,11 +147,13 @@ Options ``-D <dashboard>, --dashboard <dashboard>`` Execute dashboard test. - This option tells ctest to act as a CDash client and perform a + This option tells CTest to act as a CDash client and perform a dashboard test. All tests are <Mode><Test>, where Mode can be Experimental, Nightly, and Continuous, and Test can be Start, Update, Configure, Build, Test, Coverage, and Submit. + See `Dashboard Client`_. + ``-D <var>:<type>=<value>`` Define a variable for script mode. @@ -153,35 +165,33 @@ Options ``-M <model>, --test-model <model>`` Sets the model for a dashboard. - This option tells ctest to act as a CDash client where the ``<model>`` + This option tells CTest to act as a CDash client where the ``<model>`` can be ``Experimental``, ``Nightly``, and ``Continuous``. Combining ``-M`` and ``-T`` is similar to ``-D``. + See `Dashboard Client`_. + ``-T <action>, --test-action <action>`` Sets the dashboard action to perform. - This option tells ctest to act as a CDash client and perform some + This option tells CTest to act as a CDash client and perform some action such as ``start``, ``build``, ``test`` etc. See `Dashboard Client Steps`_ for the full list of actions. Combining ``-M`` and ``-T`` is similar to ``-D``. -``--track <track>`` - Specify the track to submit dashboard to - - Submit dashboard to specified track instead of default one. By - default, the dashboard is submitted to Nightly, Experimental, or - Continuous track, but by specifying this option, the track can be - arbitrary. + See `Dashboard Client`_. ``-S <script>, --script <script>`` Execute a dashboard for a configuration. - This option tells ctest to load in a configuration script which sets + This option tells CTest to load in a configuration script which sets a number of parameters such as the binary and source directories. - Then ctest will do what is required to create and run a dashboard. + Then CTest will do what is required to create and run a dashboard. This option basically sets up a dashboard and then runs ``ctest -D`` with the appropriate options. + See `Dashboard Client`_. + ``-SP <script>, --script-new-process <script>`` Execute a dashboard for a configuration. @@ -190,16 +200,12 @@ Options script may modify the environment and you do not want the modified environment to impact other ``-S`` scripts. -``-A <file>, --add-notes <file>`` - Add a notes file with submission. - - This option tells ctest to include a notes file when submitting - dashboard. + See `Dashboard Client`_. ``-I [Start,End,Stride,test#,test#|Test file], --tests-information`` Run a specific number of tests by number. - This option causes ctest to run tests starting at number Start, + This option causes CTest to run tests starting at number Start, ending at number End, and incrementing by Stride. Any additional numbers after Stride are considered individual test numbers. Start, End,or stride can be empty. Optionally a file can be given that @@ -214,11 +220,11 @@ Options ``--rerun-failed`` Run only the tests that failed previously. - This option tells ctest to perform only the tests that failed during - its previous run. When this option is specified, ctest ignores all + This option tells CTest to perform only the tests that failed during + its previous run. When this option is specified, CTest ignores all other options intended to modify the list of tests to run (``-L``, ``-R``, ``-E``, ``-LE``, ``-I``, etc). In the event that CTest runs and no tests - fail, subsequent calls to ctest with the ``--rerun-failed`` option will run + fail, subsequent calls to CTest with the ``--rerun-failed`` option will run the set of tests that most recently failed (if any). ``--repeat-until-fail <n>`` @@ -236,7 +242,7 @@ Options ``--interactive-debug-mode [0|1]`` Set the interactive mode to 0 or 1. - This option causes ctest to run tests in either an interactive mode + This option causes CTest to run tests in either an interactive mode or a non-interactive mode. On Windows this means that in non-interactive mode, all system debug pop up windows are blocked. In dashboard mode (Experimental, Nightly, Continuous), the default @@ -246,36 +252,111 @@ Options ``--no-label-summary`` Disable timing summary information for labels. - This option tells ctest not to print summary information for each + This option tells CTest not to print summary information for each label associated with the tests run. If there are no labels on the tests, nothing extra is printed. - ``--no-subproject-summary`` + See `Label and Subproject Summary`_. + +``--no-subproject-summary`` Disable timing summary information for subprojects. - This option tells ctest not to print summary information for each + This option tells CTest not to print summary information for each subproject associated with the tests run. If there are no subprojects on the tests, nothing extra is printed. -``--build-and-test <path-to-source> <path-to-build>`` - Configure, build and run a test. + See `Label and Subproject Summary`_. + +``--build-and-test`` +See `Build and Test Mode`_. + +``--test-output-size-passed <size>`` + Limit the output for passed tests to ``<size>`` bytes. + +``--test-output-size-failed <size>`` + Limit the output for failed tests to ``<size>`` bytes. + +``--overwrite`` + Overwrite CTest configuration option. + + By default CTest uses configuration options from configuration file. + This option will overwrite the configuration option. + +``--force-new-ctest-process`` + Run child CTest instances as new processes. + + By default CTest will run child CTest instances within the same + process. If this behavior is not desired, this argument will + enforce new processes for child CTest processes. + +``--schedule-random`` + Use a random order for scheduling tests. + + This option will run the tests in a random order. It is commonly + used to detect implicit dependencies in a test suite. + +``--submit-index`` + Legacy option for old Dart2 dashboard server feature. + Do not use. + +``--timeout <seconds>`` + Set a global timeout on all tests. + + This option will set a global timeout on all tests that do not + already have a timeout set on them. + +``--stop-time <time>`` + Set a time at which all tests should stop running. + + Set a real time of day at which all tests should timeout. Example: + ``7:00:00 -0400``. Any time format understood by the curl date parser + is accepted. Local time is assumed if no timezone is specified. + +``--print-labels`` + Print all available test labels. + + This option will not run any tests, it will simply print the list of + all labels associated with the test set. + +.. include:: OPTIONS_HELP.txt + +.. _`Label and Subproject Summary`: + +Label and Subproject Summary +============================ - This option tells ctest to configure (i.e. run cmake on), build, - and or execute a test. The configure and test steps are optional. - The arguments to this command line are the source and binary - directories. - The ``--build-generator`` option *must* be provided to use - ``--build-and-test``. If ``--test-command`` is specified then that will be - run after the build is complete. Other options that affect this - mode are ``--build-target``, ``--build-nocmake``, ``--build-run-dir``, - ``--build-two-config``, ``--build-exe-dir``, - ``--build-project``, ``--build-noclean`` and ``--build-options``. +CTest prints timing summary information for each label and subproject +associated with the tests run. The label time summary will not include labels +that are mapped to subprojects. + +When the :prop_test:`PROCESSORS` test property is set, CTest will display a +weighted test timing result in label and subproject summaries. The wall clock +time for the test run will be multiplied by this property to give a better +idea of how much cpu resource CTest allocated for the test. The time is +reported with `sec*proc` instead of just `sec`. + +.. _`Build and Test Mode`: + +Build and Test Mode +=================== + +CTest provides a command-line signature to to configure (i.e. run cmake on), +build, and or execute a test:: + + ctest --build-and-test <path-to-source> <path-to-build> + --build-generator <generator> [<options>...] [-- <build-options>...] + [--test-command <test>] + +The configure and test steps are optional. The arguments to this command line +are the source and binary directories. The ``--build-generator`` option *must* +be provided to use ``--build-and-test``. If ``--test-command`` is specified +then that will be run after the build is complete. Other options that affect +this mode include: ``--build-target`` Specify a specific target to build. - This option goes with the ``--build-and-test`` option, if left out the - ``all`` target is built. + If left out the ``all`` target is built. ``--build-nocmake`` Run the build without running cmake first. @@ -324,67 +405,47 @@ Options ``--test-command`` The test to run with the ``--build-and-test`` option. -``--test-output-size-passed <size>`` - Limit the output for passed tests to ``<size>`` bytes. - -``--test-output-size-failed <size>`` - Limit the output for failed tests to ``<size>`` bytes. - ``--test-timeout`` - The time limit in seconds, internal use only. - -``--tomorrow-tag`` - Nightly or experimental starts with next day tag. + The time limit in seconds - This is useful if the build will not finish in one day. - -``--ctest-config`` - The configuration file used to initialize CTest state when submitting dashboards. - - This option tells CTest to use different initialization file instead - of CTestConfiguration.tcl. This way multiple initialization files - can be used for example to submit to multiple dashboards. - -``--overwrite`` - Overwrite CTest configuration option. +.. _`Dashboard Client`: - By default ctest uses configuration options from configuration file. - This option will overwrite the configuration option. +Dashboard Client +================ -``--extra-submit <file>[;<file>]`` - Submit extra files to the dashboard. +CTest can operate as a client for the `CDash`_ software quality dashboard +application. As a dashboard client, CTest performs a sequence of steps +to configure, build, and test software, and then submits the results to +a `CDash`_ server. The command-line signature used to submit to `CDash`_ is:: - This option will submit extra files to the dashboard. + ctest (-D <dashboard> | -M <model> -T <action> | -S <script> | -SP <script>) + [-- <dashboard-options>...] -``--force-new-ctest-process`` - Run child CTest instances as new processes. +Options for Dashboard Client include: - By default CTest will run child CTest instances within the same - process. If this behavior is not desired, this argument will - enforce new processes for child CTest processes. +``--track <track>`` + Specify the track to submit dashboard to -``--schedule-random`` - Use a random order for scheduling tests. + Submit dashboard to specified track instead of default one. By + default, the dashboard is submitted to Nightly, Experimental, or + Continuous track, but by specifying this option, the track can be + arbitrary. - This option will run the tests in a random order. It is commonly - used to detect implicit dependencies in a test suite. +``-A <file>, --add-notes <file>`` + Add a notes file with submission. -``--submit-index`` - Legacy option for old Dart2 dashboard server feature. - Do not use. + This option tells CTest to include a notes file when submitting + dashboard. -``--timeout <seconds>`` - Set a global timeout on all tests. +``--tomorrow-tag`` + Nightly or experimental starts with next day tag. - This option will set a global timeout on all tests that do not - already have a timeout set on them. + This is useful if the build will not finish in one day. -``--stop-time <time>`` - Set a time at which all tests should stop running. +``--extra-submit <file>[;<file>]`` + Submit extra files to the dashboard. - Set a real time of day at which all tests should timeout. Example: - ``7:00:00 -0400``. Any time format understood by the curl date parser - is accepted. Local time is assumed if no timezone is specified. + This option will submit extra files to the dashboard. ``--http1.0`` Submit using HTTP 1.0. @@ -399,26 +460,6 @@ Options this to maintain compatibility with an older version of CDash which doesn't support compressed test output. -``--print-labels`` - Print all available test labels. - - This option will not run any tests, it will simply print the list of - all labels associated with the test set. - -.. include:: OPTIONS_HELP.txt - -.. _`Dashboard Client`: - -Dashboard Client -================ - -CTest can operate as a client for the `CDash`_ software quality dashboard -application. As a dashboard client, CTest performs a sequence of steps -to configure, build, and test software, and then submits the results to -a `CDash`_ server. - -.. _`CDash`: http://cdash.org/ - Dashboard Client Steps ---------------------- @@ -731,7 +772,6 @@ Configuration settings to specify the version control tool include: * `CTest Script`_ variable: :variable:`CTEST_UPDATE_VERSION_ONLY` - Additional configuration settings include: ``NightlyStartTime`` @@ -773,6 +813,7 @@ Configuration settings include: * `CTest Script`_ variable: :variable:`CTEST_LABELS_FOR_SUBPROJECTS` * :module:`CTest` module variable: ``CTEST_LABELS_FOR_SUBPROJECTS`` + See `Label and Subproject Summary`_. .. _`CTest Build Step`: @@ -804,6 +845,8 @@ Configuration settings include: * `CTest Script`_ variable: :variable:`CTEST_LABELS_FOR_SUBPROJECTS` * :module:`CTest` module variable: ``CTEST_LABELS_FOR_SUBPROJECTS`` + See `Label and Subproject Summary`_. + ``MakeCommand`` Command-line to launch the software build process. It will be executed in the location specified by the @@ -847,6 +890,7 @@ Configuration settings include: * `CTest Script`_ variable: :variable:`CTEST_LABELS_FOR_SUBPROJECTS` * :module:`CTest` module variable: ``CTEST_LABELS_FOR_SUBPROJECTS`` + See `Label and Subproject Summary`_. ``TestLoad`` While running tests in parallel (e.g. with ``-j``), try not to start @@ -1082,3 +1126,5 @@ See Also ======== .. include:: LINKS.txt + +.. _`CDash`: http://cdash.org/ diff --git a/Help/prop_tgt/IMPORTED_GLOBAL.rst b/Help/prop_tgt/IMPORTED_GLOBAL.rst new file mode 100644 index 0000000..1feca04 --- /dev/null +++ b/Help/prop_tgt/IMPORTED_GLOBAL.rst @@ -0,0 +1,22 @@ +IMPORTED_GLOBAL +--------------- + +Indication of whether an :ref:`IMPORTED target <Imported Targets>` is +globally visible. + +The boolean value of this property is True for targets created with the +``IMPORTED`` ``GLOBAL`` options to :command:`add_executable()` or +:command:`add_library()`. It is always False for targets built within the +project. + +For targets created with the ``IMPORTED`` option to +:command:`add_executable()` or :command:`add_library()` but without the +additional option ``GLOBAL`` this is False, too. However, setting this +property for such a locally ``IMPORTED`` target to True promotes that +target to global scope. This promotion can only be done in the same +directory where that ``IMPORTED`` target was created in the first place. + +Once an imported target has been made global, it cannot be changed back to +non-global. Therefore, if a project sets this property, it may only +provide a value of True. CMake will issue an error if the project tries to +set the property to a non-True value, even if the value was already False. diff --git a/Help/release/dev/cmake-default-dir-install-permissions.rst b/Help/release/dev/cmake-default-dir-install-permissions.rst new file mode 100644 index 0000000..8325fda --- /dev/null +++ b/Help/release/dev/cmake-default-dir-install-permissions.rst @@ -0,0 +1,12 @@ +cmake-default-dir-install-permissions +------------------------------------- + +* The :variable:`CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS` variable was added + to enable setting of default permissions for directories created implicitly + during installation of files by :command:`install` and + :command:`file(INSTALL)`. + +* The :variable:`CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS` variable was added + which serves the same purpose during packaging as the + :variable:`CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS` variable serves during + installation (e.g. ``make install``). diff --git a/Help/release/dev/imported-promotion.rst b/Help/release/dev/imported-promotion.rst new file mode 100644 index 0000000..d184178 --- /dev/null +++ b/Help/release/dev/imported-promotion.rst @@ -0,0 +1,15 @@ +imported-promotion +------------------ + +* Added new target-property :prop_tgt:`IMPORTED_GLOBAL` which + indicates if an :ref:`IMPORTED target <Imported Targets>` is + globally visible. + It will be set automatically if such an imported target is + created with the ``GLOBAL`` flag. + +* Additionally, it is now also possible to promote a local imported + target to become globally visible by setting its + :prop_tgt:`IMPORTED_GLOBAL` property to `TRUE`. (However, this + promotion can only succeed if it is done from within the same + directory where the imported target was created in the first + place.) Setting it to `FALSE` is not supported! diff --git a/Help/variable/CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS.rst b/Help/variable/CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS.rst new file mode 100644 index 0000000..f994fbe --- /dev/null +++ b/Help/variable/CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS.rst @@ -0,0 +1,29 @@ +CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS +------------------------------------------- + +Default permissions for directories created implicitly during installation +of files by :command:`install` and :command:`file(INSTALL)`. + +If ``make install`` is invoked and directories are implicitly created they +get permissions set by :variable:`CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS` +variable or platform specific default permissions if the variable is not set. + +Implicitly created directories are created if they are not explicitly installed +by :command:`install` command but are needed to install a file on a certain +path. Example of such locations are directories created due to the setting of +:variable:`CMAKE_INSTALL_PREFIX`. + +Expected content of the :variable:`CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS` +variable is a list of permissions that can be used by :command:`install` command +`PERMISSIONS` section. + +Example usage: + +:: + + set(CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS + OWNER_READ + OWNER_WRITE + OWNER_EXECUTE + GROUP_READ + ) diff --git a/Help/variable/CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS.rst b/Help/variable/CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS.rst new file mode 100644 index 0000000..83d5ce7 --- /dev/null +++ b/Help/variable/CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS.rst @@ -0,0 +1,11 @@ +CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS +------------------------------------------- + +Default permissions for implicitly created directories during packaging. + +This variable serves the same purpose during packaging as the +:variable:`CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS` variable +serves during installation (e.g. ``make install``). + +If `include(CPack)` is used then by default this variable is set to the content +of :variable:`CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS`. diff --git a/Modules/CMakeDetermineCSharpCompiler.cmake b/Modules/CMakeDetermineCSharpCompiler.cmake index 55b2fb3..eb825a5 100644 --- a/Modules/CMakeDetermineCSharpCompiler.cmake +++ b/Modules/CMakeDetermineCSharpCompiler.cmake @@ -23,7 +23,7 @@ if(NOT CMAKE_CSharp_COMPILER_ID_RUN) include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerId.cmake) CMAKE_DETERMINE_COMPILER_ID(CSharp CSFLAGS CMakeCSharpCompilerId.cs) - execute_process(COMMAND "${CMAKE_CSharp_COMPILER}" "/help" OUTPUT_VARIABLE output) + execute_process(COMMAND "${CMAKE_CSharp_COMPILER}" "/help /preferreduilang:en-US" OUTPUT_VARIABLE output) string(REPLACE "\n" ";" output "${output}") foreach(line ${output}) string(TOUPPER ${line} line) diff --git a/Modules/CMakeFortranCompilerId.F.in b/Modules/CMakeFortranCompilerId.F.in index 49789f1..da3d953 100644 --- a/Modules/CMakeFortranCompilerId.F.in +++ b/Modules/CMakeFortranCompilerId.F.in @@ -2,6 +2,26 @@ #if 0 ! Identify the compiler #endif +#if defined(_MSC_VER) + PRINT *, 'INFO:simulate[MSVC]' +# if _MSC_VER >= 1900 + PRINT *, 'INFO:simulate_version[019.00]' +# elif _MSC_VER >= 1800 + PRINT *, 'INFO:simulate_version[018.00]' +# elif _MSC_VER >= 1700 + PRINT *, 'INFO:simulate_version[017.00]' +# elif _MSC_VER >= 1600 + PRINT *, 'INFO:simulate_version[016.00]' +# elif _MSC_VER >= 1500 + PRINT *, 'INFO:simulate_version[015.00]' +# elif _MSC_VER >= 1400 + PRINT *, 'INFO:simulate_version[014.00]' +# elif _MSC_VER >= 1310 + PRINT *, 'INFO:simulate_version[013.01]' +# else + PRINT *, 'INFO:simulate_version[013.00]' +# endif +#endif #if defined(__INTEL_COMPILER) || defined(__ICC) PRINT *, 'INFO:compiler[Intel]' # define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER/100) @@ -14,27 +34,6 @@ # if defined(__INTEL_COMPILER_BUILD_DATE) # define COMPILER_VERSION_TWEAK DEC(__INTEL_COMPILER_BUILD_DATE) # endif - -# if defined(_MSC_VER) - PRINT *, 'INFO:simulate[MSVC]' -# if _MSC_VER >= 1900 - PRINT *, 'INFO:simulate_version[019.00]' -# elif _MSC_VER >= 1800 - PRINT *, 'INFO:simulate_version[018.00]' -# elif _MSC_VER >= 1700 - PRINT *, 'INFO:simulate_version[017.00]' -# elif _MSC_VER >= 1600 - PRINT *, 'INFO:simulate_version[016.00]' -# elif _MSC_VER >= 1500 - PRINT *, 'INFO:simulate_version[015.00]' -# elif _MSC_VER >= 1400 - PRINT *, 'INFO:simulate_version[014.00]' -# elif _MSC_VER >= 1310 - PRINT *, 'INFO:simulate_version[013.01]' -# else - PRINT *, 'INFO:simulate_version[013.00]' -# endif -# endif #elif defined(__SUNPRO_F95) PRINT *, 'INFO:compiler[SunPro]' # define COMPILER_VERSION_MAJOR HEX(__SUNPRO_F95>>8) diff --git a/Modules/CMakeFortranInformation.cmake b/Modules/CMakeFortranInformation.cmake index 8005da6..b315d33 100644 --- a/Modules/CMakeFortranInformation.cmake +++ b/Modules/CMakeFortranInformation.cmake @@ -169,7 +169,7 @@ foreach(c "" _DEBUG _RELEASE _MINSIZEREL _RELWITHDEBINFO) endforeach() set (CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS_INIT}" CACHE STRING - "Flags for Fortran compiler.") + "Flags used by the compiler during all build types.") include(CMakeCommonLanguageInclude) diff --git a/Modules/CMakeParseImplicitLinkInfo.cmake b/Modules/CMakeParseImplicitLinkInfo.cmake index 3b77278..63d18ab 100644 --- a/Modules/CMakeParseImplicitLinkInfo.cmake +++ b/Modules/CMakeParseImplicitLinkInfo.cmake @@ -142,7 +142,7 @@ function(CMAKE_PARSE_IMPLICIT_LINK_INFO text lib_var dir_var fwk_var log_var obj # We remove items that are not language-specific. set(implicit_libs "") foreach(lib IN LISTS implicit_libs_tmp) - if("x${lib}" MATCHES "^x(crt.*\\.o|System.*|.*libclang_rt.*|msvcrt.*|libvcruntime.*|libucrt.*|libcmt.*)$") + if("x${lib}" MATCHES "^x(crt.*\\.o|gcc_eh.*|System.*|.*libclang_rt.*|msvcrt.*|libvcruntime.*|libucrt.*|libcmt.*)$") string(APPEND log " remove lib [${lib}]\n") elseif(IS_ABSOLUTE "${lib}") get_filename_component(abs "${lib}" ABSOLUTE) diff --git a/Modules/CPack.cmake b/Modules/CPack.cmake index 3915943..ea7dc02 100644 --- a/Modules/CPack.cmake +++ b/Modules/CPack.cmake @@ -384,6 +384,12 @@ _cpack_set_default(CPACK_RESOURCE_FILE_WELCOME _cpack_set_default(CPACK_MODULE_PATH "${CMAKE_MODULE_PATH}") +# Set default directory creation permissions mode +if(CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS) + _cpack_set_default(CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS + "${CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS}") +endif() + if(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL) set(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON) endif() diff --git a/Modules/Compiler/Clang.cmake b/Modules/Compiler/Clang.cmake index 9f5e921..7ce1adb 100644 --- a/Modules/Compiler/Clang.cmake +++ b/Modules/Compiler/Clang.cmake @@ -11,7 +11,8 @@ set(__COMPILER_CLANG 1) include(Compiler/CMakeCommonCompilerMacros) if("x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC" - OR "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC") + OR "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC" + OR "x${CMAKE_Fortran_SIMULATE_ID}" STREQUAL "xMSVC") macro(__compiler_clang lang) endmacro() else() diff --git a/Modules/FetchContent.cmake b/Modules/FetchContent.cmake index 132354f..98cdf6c 100644 --- a/Modules/FetchContent.cmake +++ b/Modules/FetchContent.cmake @@ -754,7 +754,9 @@ function(__FetchContent_directPopulate contentName) list(APPEND generatorOpts "-T${CMAKE_GENERATOR_TOOLSET}") endif() - list(APPEND generatorOpts "-DCMAKE_MAKE_PROGRAM:FILE=${CMAKE_MAKE_PROGRAM}") + if(CMAKE_MAKE_PROGRAM) + list(APPEND generatorOpts "-DCMAKE_MAKE_PROGRAM:FILEPATH=${CMAKE_MAKE_PROGRAM}") + endif() else() # Likely we've been invoked via CMake's script mode where no diff --git a/Modules/FindBoost.cmake b/Modules/FindBoost.cmake index 88d14ab..6f60eeb 100644 --- a/Modules/FindBoost.cmake +++ b/Modules/FindBoost.cmake @@ -391,13 +391,8 @@ endmacro() # version with a regex. # function(_Boost_COMPILER_DUMPVERSION _OUTPUT_VERSION) - - exec_program(${CMAKE_CXX_COMPILER} - ARGS ${CMAKE_CXX_COMPILER_ARG1} -dumpversion - OUTPUT_VARIABLE _boost_COMPILER_VERSION - ) - string(REGEX REPLACE "([0-9])\\.([0-9])(\\.[0-9])?" "\\1\\2" - _boost_COMPILER_VERSION ${_boost_COMPILER_VERSION}) + string(REGEX REPLACE "([0-9]+)\\.([0-9]+)(\\.[0-9]+)?" "\\1\\2" + _boost_COMPILER_VERSION ${CMAKE_CXX_COMPILER_VERSION}) set(${_OUTPUT_VERSION} ${_boost_COMPILER_VERSION} PARENT_SCOPE) endfunction() diff --git a/Modules/FindDoxygen.cmake b/Modules/FindDoxygen.cmake index 46bf340..d0dd0f1 100644 --- a/Modules/FindDoxygen.cmake +++ b/Modules/FindDoxygen.cmake @@ -832,7 +832,11 @@ doxygen_add_docs() for target ${targetName}") # and Lucent Bell Labs. The other options in this section have no # effect if this option is set to NO. # Doxygen's default value is: NO. - set(DOXYGEN_HAVE_DOT ${DOXYGEN_DOT_FOUND}) + if(Doxygen_dot_FOUND) + set(DOXYGEN_HAVE_DOT "YES") + else() + set(DOXYGEN_HAVE_DOT "NO") + endif() endif() if(NOT DEFINED DOXYGEN_DOT_MULTI_TARGETS) diff --git a/Modules/FindHDF5.cmake b/Modules/FindHDF5.cmake index 012ae22..41b1002 100644 --- a/Modules/FindHDF5.cmake +++ b/Modules/FindHDF5.cmake @@ -214,7 +214,7 @@ function(_HDF5_test_regular_compiler_C success version is_parallel) ) set(${version} ${CMAKE_MATCH_1}) if(CMAKE_MATCH_3) - set(${version} ${HDF5_CXX_VERSION}.${CMAKE_MATCH_3}) + set(${version} ${HDF5_C_VERSION}.${CMAKE_MATCH_3}) endif() set(${version} ${${version}} PARENT_SCOPE) diff --git a/Modules/FindOpenGL.cmake b/Modules/FindOpenGL.cmake index 59bee41..11843ef 100644 --- a/Modules/FindOpenGL.cmake +++ b/Modules/FindOpenGL.cmake @@ -53,7 +53,7 @@ # Path to the EGL include directory. # ``OPENGL_LIBRARIES`` # Paths to the OpenGL library, windowing system libraries, and GLU libraries. -# On Linux, this assumes glX and is never correct for EGL-based targets. +# On Linux, this assumes GLX and is never correct for EGL-based targets. # Clients are encouraged to use the ``OpenGL::*`` import targets instead. # # Cache variables @@ -80,12 +80,14 @@ # context libraries from OpenGL itself; OpenGL lives in "libOpenGL", and # contexts are defined in "libGLX" or "libEGL". GLVND is currently the only way # to get OpenGL 3+ functionality via EGL in a manner portable across vendors. +# Projects may use GLVND explicitly with target ``OpenGL::OpenGL`` and either +# ``OpenGL::GLX`` or ``OpenGL::EGL``. # -# On Linux systems FindOpenGL defaults to using GLVND if available. Users can -# utilize GLVND explicitly with targets ``OpenGL::OpenGL``, ``OpenGL::GLX``, and -# ``OpenGL::EGL``. Additionally, when GLVND is available the ``OpenGL::GL`` -# target is equivalent to ``OpenGL::OpenGL OpenGL::GLX``. When the system is -# not GLVND-based, ``OpenGL::GL`` expands to libGL as it has historically done. +# Projects may use the ``OpenGL::GL`` target (or ``OPENGL_LIBRARIES`` variable) +# to use legacy GL. By default, these will use the legacy libGL library file. +# If ``OPENGL_gl_LIBRARY`` is empty or not found and GLVND is available, the +# ``OpenGL::GL`` target will use GLVND ``OpenGL::OpenGL`` and ``OpenGL::GLX`` +# (and the ``OPENGL_LIBRARIES`` variable will use the corresponding libraries). # Thus, for non-EGL-based Linux targets, the ``OpenGL::GL`` target is most # portable. # @@ -360,18 +362,8 @@ if(OPENGL_FOUND) "${OPENGL_GLX_INCLUDE_DIR}") endif() - if(TARGET OpenGL::OpenGL AND TARGET OpenGL::GLX AND NOT TARGET OpenGL::GL) - # if GLVND with GLX is available, make ::GL a synonym for 'OpenGL::OpenGL - # OpenGL::GLX'. - add_library(OpenGL::GL INTERFACE IMPORTED) - set_target_properties(OpenGL::GL PROPERTIES INTERFACE_LINK_LIBRARIES - OpenGL::OpenGL) - set_property(TARGET OpenGL::GL APPEND PROPERTY INTERFACE_LINK_LIBRARIES - OpenGL::GLX) - set_target_properties(OpenGL::GL PROPERTIES INTERFACE_INCLUDE_DIRECTORIES - "${OPENGL_INCLUDE_DIR}") - - elseif(NOT TARGET OpenGL::GL) + if(OPENGL_gl_LIBRARY AND NOT TARGET OpenGL::GL) + # A legacy GL library is available, so use it for the legacy GL target. if(IS_ABSOLUTE "${OPENGL_gl_LIBRARY}") add_library(OpenGL::GL UNKNOWN IMPORTED) if(OPENGL_gl_LIBRARY MATCHES "/([^/]+)\\.framework$") @@ -392,6 +384,16 @@ if(OPENGL_FOUND) endif() set_target_properties(OpenGL::GL PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${OPENGL_INCLUDE_DIR}") + elseif(NOT TARGET OpenGL::GL AND TARGET OpenGL::OpenGL AND TARGET OpenGL::GLX) + # A legacy GL library is not available, but we can provide the legacy GL + # target using GLVND OpenGL+GLX. + add_library(OpenGL::GL INTERFACE IMPORTED) + set_target_properties(OpenGL::GL PROPERTIES INTERFACE_LINK_LIBRARIES + OpenGL::OpenGL) + set_property(TARGET OpenGL::GL APPEND PROPERTY INTERFACE_LINK_LIBRARIES + OpenGL::GLX) + set_target_properties(OpenGL::GL PROPERTIES INTERFACE_INCLUDE_DIRECTORIES + "${OPENGL_INCLUDE_DIR}") endif() # ::EGL is a GLVND library, and thus Linux-only: we don't bother checking @@ -440,9 +442,12 @@ if(OPENGL_FOUND) endif() # OPENGL_LIBRARIES mirrors OpenGL::GL's logic ... - set(OPENGL_LIBRARIES ${OPENGL_gl_LIBRARY}) - if(TARGET OpenGL::GLX AND TARGET OpenGL::OpenGL) + if(OPENGL_gl_LIBRARY) + set(OPENGL_LIBRARIES ${OPENGL_gl_LIBRARY}) + elseif(TARGET OpenGL::OpenGL AND TARGET OpenGL::GLX) set(OPENGL_LIBRARIES ${OPENGL_opengl_LIBRARY} ${OPENGL_glx_LIBRARY}) + else() + set(OPENGL_LIBRARIES "") endif() # ... and also includes GLU, if available. if(TARGET OpenGL::GLU) diff --git a/Modules/InstallRequiredSystemLibraries.cmake b/Modules/InstallRequiredSystemLibraries.cmake index ac8c20b..1ba4877 100644 --- a/Modules/InstallRequiredSystemLibraries.cmake +++ b/Modules/InstallRequiredSystemLibraries.cmake @@ -593,15 +593,17 @@ if(_IRSL_HAVE_Intel) endif() endif() if(WIN32) - set(__install_dirs "${_Intel_redistdir}/irml" "${_Intel_redistdir}/irml_c" - "${_Intel_redistdir}/1033" "${_Intel_redistdir}/1041") + set(__install_dirs "${_Intel_redistdir}/1033") + if(_Intel_compiler_ver VERSION_LESS 18) + list(APPEND __install_dirs "${_Intel_redistdir}/irml" "${_Intel_redistdir}/irml_c" "${_Intel_redistdir}/1041") + endif() foreach(__Intel_lib IN ITEMS cilkrts20.dll libchkp.dll libgfxoffload.dll libioffload_host.dll libirngmd.dll libmmd.dll libmmdd.dll libmpx.dll liboffload.dll svml_dispmd.dll) list(APPEND __install_libs "${_Intel_redistdir}/${__Intel_lib}") endforeach() if(CMAKE_Fortran_COMPILER_ID STREQUAL Intel) - foreach(__Intel_lib IN ITEMS libicaf.dll libifcoremd.dll libifcoremdd.dll libifcorert.dll libifcorertd.dll libifportmd.dll) + foreach(__Intel_lib IN ITEMS ifdlg100.dll libicaf.dll libifcoremd.dll libifcoremdd.dll libifcorert.dll libifcorertd.dll libifportmd.dll) list(APPEND __install_libs "${_Intel_redistdir}/${__Intel_lib}") endforeach() diff --git a/Modules/Platform/Windows-Flang-Fortran.cmake b/Modules/Platform/Windows-Flang-Fortran.cmake index 9f20e73..a4b1cf1 100644 --- a/Modules/Platform/Windows-Flang-Fortran.cmake +++ b/Modules/Platform/Windows-Flang-Fortran.cmake @@ -1,2 +1,3 @@ include(Platform/Windows-MSVC) __windows_compiler_msvc(Fortran) +set(CMAKE_Fortran_COMPILE_OBJECT "<CMAKE_Fortran_COMPILER> ${_COMPILE_Fortran} <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>") diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index a8d77b2..54e5063 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -216,6 +216,8 @@ set(SRCS cmFileTimeComparison.cxx cmFileTimeComparison.h cmFortranParserImpl.cxx + cmFSPermissions.cxx + cmFSPermissions.h cmGeneratedFileStream.cxx cmGeneratorExpressionContext.cxx cmGeneratorExpressionContext.h diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index c9ec2ee..654a1bf 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 10) -set(CMake_VERSION_PATCH 20171107) +set(CMake_VERSION_PATCH 20171113) #set(CMake_VERSION_RC 1) diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx index ecb5adb..be75a9f 100644 --- a/Source/CPack/cmCPackGenerator.cxx +++ b/Source/CPack/cmCPackGenerator.cxx @@ -12,6 +12,7 @@ #include "cmCPackComponentGroup.h" #include "cmCPackLog.h" #include "cmCryptoHash.h" +#include "cmFSPermissions.h" #include "cmGeneratedFileStream.h" #include "cmGlobalGenerator.h" #include "cmMakefile.h" @@ -201,6 +202,29 @@ int cmCPackGenerator::InstallProject() cmSystemTools::PutEnv("DESTDIR="); } + // prepare default created directory permissions + mode_t default_dir_mode_v = 0; + mode_t* default_dir_mode = nullptr; + const char* default_dir_install_permissions = + this->GetOption("CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS"); + if (default_dir_install_permissions && *default_dir_install_permissions) { + std::vector<std::string> items; + cmSystemTools::ExpandListArgument(default_dir_install_permissions, items); + for (const auto& arg : items) { + if (!cmFSPermissions::stringToModeT(arg, default_dir_mode_v)) { + cmCPackLogger(cmCPackLog::LOG_ERROR, "Invalid permission value '" + << arg + << "'." + " CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS " + "value is invalid." + << std::endl); + return 0; + } + } + + default_dir_mode = &default_dir_mode_v; + } + // If the CPackConfig file sets CPACK_INSTALL_COMMANDS then run them // as listed if (!this->InstallProjectViaInstallCommands(setDestDir, @@ -218,15 +242,15 @@ int cmCPackGenerator::InstallProject() // If the CPackConfig file sets CPACK_INSTALLED_DIRECTORIES // then glob it and copy it to CPACK_TEMPORARY_DIRECTORY // This is used in Source packaging - if (!this->InstallProjectViaInstalledDirectories(setDestDir, - tempInstallDirectory)) { + if (!this->InstallProjectViaInstalledDirectories( + setDestDir, tempInstallDirectory, default_dir_mode)) { return 0; } // If the project is a CMAKE project then run pre-install // and then read the cmake_install script to run it - if (!this->InstallProjectViaInstallCMakeProjects(setDestDir, - bareTempInstallDirectory)) { + if (!this->InstallProjectViaInstallCMakeProjects( + setDestDir, bareTempInstallDirectory, default_dir_mode)) { return 0; } @@ -274,7 +298,8 @@ int cmCPackGenerator::InstallProjectViaInstallCommands( } int cmCPackGenerator::InstallProjectViaInstalledDirectories( - bool setDestDir, const std::string& tempInstallDirectory) + bool setDestDir, const std::string& tempInstallDirectory, + const mode_t* default_dir_mode) { (void)setDestDir; (void)tempInstallDirectory; @@ -385,7 +410,8 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories( // make sure directory exists for symlink std::string destDir = cmSystemTools::GetFilenamePath(symlinked.second); - if (!destDir.empty() && !cmSystemTools::MakeDirectory(destDir)) { + if (!destDir.empty() && + !cmSystemTools::MakeDirectory(destDir, default_dir_mode)) { cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot create dir: " << destDir << "\nTrying to create symlink: " << symlinked.second << "--> " << symlinked.first @@ -464,7 +490,8 @@ int cmCPackGenerator::InstallProjectViaInstallScript( } int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( - bool setDestDir, const std::string& baseTempInstallDirectory) + bool setDestDir, const std::string& baseTempInstallDirectory, + const mode_t* default_dir_mode) { const char* cmakeProjects = this->GetOption("CPACK_INSTALL_CMAKE_PROJECTS"); const char* cmakeGenerator = this->GetOption("CPACK_CMAKE_GENERATOR"); @@ -631,6 +658,13 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( } } + const char* default_dir_inst_permissions = + this->GetOption("CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS"); + if (default_dir_inst_permissions && *default_dir_inst_permissions) { + mf.AddDefinition("CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS", + default_dir_inst_permissions); + } + if (!setDestDir) { tempInstallDirectory += this->GetPackagingInstallPrefix(); } @@ -690,7 +724,7 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( cmCPackLogger(cmCPackLog::LOG_DEBUG, "- Creating directory: '" << dir << "'" << std::endl); - if (!cmsys::SystemTools::MakeDirectory(dir.c_str())) { + if (!cmsys::SystemTools::MakeDirectory(dir, default_dir_mode)) { cmCPackLogger( cmCPackLog::LOG_ERROR, "Problem creating temporary directory: " << dir << std::endl); @@ -700,8 +734,8 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( mf.AddDefinition("CMAKE_INSTALL_PREFIX", tempInstallDirectory.c_str()); - if (!cmsys::SystemTools::MakeDirectory( - tempInstallDirectory.c_str())) { + if (!cmsys::SystemTools::MakeDirectory(tempInstallDirectory, + default_dir_mode)) { cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem creating temporary directory: " << tempInstallDirectory << std::endl); diff --git a/Source/CPack/cmCPackGenerator.h b/Source/CPack/cmCPackGenerator.h index 4e3a6e0..8100b66 100644 --- a/Source/CPack/cmCPackGenerator.h +++ b/Source/CPack/cmCPackGenerator.h @@ -12,6 +12,7 @@ #include "cmCPackComponentGroup.h" #include "cmSystemTools.h" +#include "cm_sys_stat.h" class cmCPackLog; class cmInstalledFile; @@ -168,9 +169,11 @@ protected: virtual int InstallProjectViaInstallScript( bool setDestDir, const std::string& tempInstallDirectory); virtual int InstallProjectViaInstalledDirectories( - bool setDestDir, const std::string& tempInstallDirectory); + bool setDestDir, const std::string& tempInstallDirectory, + const mode_t* default_dir_mode); virtual int InstallProjectViaInstallCMakeProjects( - bool setDestDir, const std::string& tempInstallDirectory); + bool setDestDir, const std::string& tempInstallDirectory, + const mode_t* default_dir_mode); /** * The various level of support of diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index 37ff901..92da9ab 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx @@ -282,7 +282,6 @@ cmCTest::cmCTest() this->GlobalTimeout = 0; this->LastStopTimeout = 24 * 60 * 60; this->CompressXMLFiles = false; - this->CTestConfigFile.clear(); this->ScheduleType.clear(); this->StopTime.clear(); this->NextDayStopTime = false; @@ -623,12 +622,9 @@ bool cmCTest::UpdateCTestConfiguration() if (this->SuppressUpdatingCTestConfiguration) { return true; } - std::string fileName = this->CTestConfigFile; - if (fileName.empty()) { - fileName = this->BinaryDir + "/CTestConfiguration.ini"; - if (!cmSystemTools::FileExists(fileName.c_str())) { - fileName = this->BinaryDir + "/DartConfiguration.tcl"; - } + std::string fileName = this->BinaryDir + "/CTestConfiguration.ini"; + if (!cmSystemTools::FileExists(fileName.c_str())) { + fileName = this->BinaryDir + "/DartConfiguration.tcl"; } cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, "UpdateCTestConfiguration from :" << fileName << "\n"); diff --git a/Source/cmCTest.h b/Source/cmCTest.h index dbd67dc..a2d6fc3 100644 --- a/Source/cmCTest.h +++ b/Source/cmCTest.h @@ -487,7 +487,6 @@ private: /** Map of configuration properties */ typedef std::map<std::string, std::string> CTestConfigurationMap; - std::string CTestConfigFile; // TODO: The ctest configuration should be a hierarchy of // configuration option sources: command-line, script, ini file. // Then the ini file can get re-loaded whenever it changes without diff --git a/Source/cmFSPermissions.cxx b/Source/cmFSPermissions.cxx new file mode 100644 index 0000000..4015a51 --- /dev/null +++ b/Source/cmFSPermissions.cxx @@ -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. */ +#include "cmFSPermissions.h" + +bool cmFSPermissions::stringToModeT(std::string const& arg, + mode_t& permissions) +{ + if (arg == "OWNER_READ") { + permissions |= mode_owner_read; + } else if (arg == "OWNER_WRITE") { + permissions |= mode_owner_write; + } else if (arg == "OWNER_EXECUTE") { + permissions |= mode_owner_execute; + } else if (arg == "GROUP_READ") { + permissions |= mode_group_read; + } else if (arg == "GROUP_WRITE") { + permissions |= mode_group_write; + } else if (arg == "GROUP_EXECUTE") { + permissions |= mode_group_execute; + } else if (arg == "WORLD_READ") { + permissions |= mode_world_read; + } else if (arg == "WORLD_WRITE") { + permissions |= mode_world_write; + } else if (arg == "WORLD_EXECUTE") { + permissions |= mode_world_execute; + } else if (arg == "SETUID") { + permissions |= mode_setuid; + } else if (arg == "SETGID") { + permissions |= mode_setgid; + } else { + return false; + } + return true; +} diff --git a/Source/cmFSPermissions.h b/Source/cmFSPermissions.h new file mode 100644 index 0000000..7a6e708 --- /dev/null +++ b/Source/cmFSPermissions.h @@ -0,0 +1,45 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#ifndef cmFSPermissions_h +#define cmFSPermissions_h + +#include "cmConfigure.h" // IWYU pragma: keep + +#include "cm_sys_stat.h" + +#include <string> + +namespace cmFSPermissions { + +// Table of permissions flags. +#if defined(_WIN32) && !defined(__CYGWIN__) +static const mode_t mode_owner_read = S_IREAD; +static const mode_t mode_owner_write = S_IWRITE; +static const mode_t mode_owner_execute = S_IEXEC; +static const mode_t mode_group_read = 040; +static const mode_t mode_group_write = 020; +static const mode_t mode_group_execute = 010; +static const mode_t mode_world_read = 04; +static const mode_t mode_world_write = 02; +static const mode_t mode_world_execute = 01; +static const mode_t mode_setuid = 04000; +static const mode_t mode_setgid = 02000; +#else +static const mode_t mode_owner_read = S_IRUSR; +static const mode_t mode_owner_write = S_IWUSR; +static const mode_t mode_owner_execute = S_IXUSR; +static const mode_t mode_group_read = S_IRGRP; +static const mode_t mode_group_write = S_IWGRP; +static const mode_t mode_group_execute = S_IXGRP; +static const mode_t mode_world_read = S_IROTH; +static const mode_t mode_world_write = S_IWOTH; +static const mode_t mode_world_execute = S_IXOTH; +static const mode_t mode_setuid = S_ISUID; +static const mode_t mode_setgid = S_ISGID; +#endif + +bool stringToModeT(std::string const& arg, mode_t& permissions); + +} // ns + +#endif diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index 191a666..88185bd 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -20,6 +20,7 @@ #include "cmAlgorithms.h" #include "cmCommandArgumentsHelper.h" #include "cmCryptoHash.h" +#include "cmFSPermissions.h" #include "cmFileLockPool.h" #include "cmFileTimeComparison.h" #include "cmGeneratorExpression.h" @@ -50,32 +51,7 @@ class cmSystemToolsFileTime; -// Table of permissions flags. -#if defined(_WIN32) && !defined(__CYGWIN__) -static mode_t mode_owner_read = S_IREAD; -static mode_t mode_owner_write = S_IWRITE; -static mode_t mode_owner_execute = S_IEXEC; -static mode_t mode_group_read = 040; -static mode_t mode_group_write = 020; -static mode_t mode_group_execute = 010; -static mode_t mode_world_read = 04; -static mode_t mode_world_write = 02; -static mode_t mode_world_execute = 01; -static mode_t mode_setuid = 04000; -static mode_t mode_setgid = 02000; -#else -static mode_t mode_owner_read = S_IRUSR; -static mode_t mode_owner_write = S_IWUSR; -static mode_t mode_owner_execute = S_IXUSR; -static mode_t mode_group_read = S_IRGRP; -static mode_t mode_group_write = S_IWGRP; -static mode_t mode_group_execute = S_IXGRP; -static mode_t mode_world_read = S_IROTH; -static mode_t mode_world_write = S_IWOTH; -static mode_t mode_world_execute = S_IXOTH; -static mode_t mode_setuid = S_ISUID; -static mode_t mode_setgid = S_ISGID; -#endif +using namespace cmFSPermissions; #if defined(_WIN32) // libcurl doesn't support file:// urls for unicode filenames on Windows. @@ -1099,29 +1075,7 @@ protected: // Translate an argument to a permissions bit. bool CheckPermissions(std::string const& arg, mode_t& permissions) { - if (arg == "OWNER_READ") { - permissions |= mode_owner_read; - } else if (arg == "OWNER_WRITE") { - permissions |= mode_owner_write; - } else if (arg == "OWNER_EXECUTE") { - permissions |= mode_owner_execute; - } else if (arg == "GROUP_READ") { - permissions |= mode_group_read; - } else if (arg == "GROUP_WRITE") { - permissions |= mode_group_write; - } else if (arg == "GROUP_EXECUTE") { - permissions |= mode_group_execute; - } else if (arg == "WORLD_READ") { - permissions |= mode_world_read; - } else if (arg == "WORLD_WRITE") { - permissions |= mode_world_write; - } else if (arg == "WORLD_EXECUTE") { - permissions |= mode_world_execute; - } else if (arg == "SETUID") { - permissions |= mode_setuid; - } else if (arg == "SETGID") { - permissions |= mode_setgid; - } else { + if (!cmFSPermissions::stringToModeT(arg, permissions)) { std::ostringstream e; e << this->Name << " given invalid permission \"" << arg << "\"."; this->FileCommand->SetError(e.str()); @@ -2015,9 +1969,30 @@ bool cmFileInstaller::HandleInstallDestination() this->DestDirLength = int(sdestdir.size()); } + // check if default dir creation permissions were set + mode_t default_dir_mode_v = 0; + mode_t* default_dir_mode = nullptr; + const char* default_dir_install_permissions = this->Makefile->GetDefinition( + "CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS"); + if (default_dir_install_permissions && *default_dir_install_permissions) { + std::vector<std::string> items; + cmSystemTools::ExpandListArgument(default_dir_install_permissions, items); + for (const auto& arg : items) { + if (!this->CheckPermissions(arg, default_dir_mode_v)) { + std::ostringstream e; + e << this->FileCommand->GetError() + << " Set with CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS variable."; + this->FileCommand->SetError(e.str()); + return false; + } + } + + default_dir_mode = &default_dir_mode_v; + } + if (this->InstallType != cmInstallType_DIRECTORY) { if (!cmSystemTools::FileExists(destination.c_str())) { - if (!cmSystemTools::MakeDirectory(destination.c_str())) { + if (!cmSystemTools::MakeDirectory(destination, default_dir_mode)) { std::string errstring = "cannot create directory: " + destination + ". Maybe need administrative privileges."; this->FileCommand->SetError(errstring); diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 12c0cfd..c8d94c0 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -222,7 +222,14 @@ 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; } @@ -231,10 +238,6 @@ 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); @@ -484,6 +487,20 @@ void cmLocalGenerator::GenerateInstallRules() /* clang-format on */ } + // Write default directory permissions. + if (const char* defaultDirPermissions = this->Makefile->GetDefinition( + "CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS")) { + /* clang-format off */ + fout << + "# Set default install directory permissions.\n" + "if(NOT DEFINED CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS)\n" + " set(CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS \"" + << defaultDirPermissions << "\")\n" + "endif()\n" + "\n"; + /* clang-format on */ + } + // Ask each install generator to write its code. std::vector<cmInstallGenerator*> const& installers = this->Makefile->GetInstallGenerators(); diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index e4ec469..4109b90 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -3319,6 +3319,13 @@ cmGlobalGenerator* cmMakefile::GetGlobalGenerator() const return this->GlobalGenerator; } +void cmMakefile::GetTestNames(std::vector<std::string>& testNames) +{ + for (const auto& iter : Tests) { + testNames.push_back(iter.first); + } +} + #ifdef CMAKE_BUILD_WITH_CMAKE cmVariableWatch* cmMakefile::GetVariableWatch() const { diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index bc8c2d1..6867c02 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -617,6 +617,11 @@ public: cmGlobalGenerator* GetGlobalGenerator() const; /** + * Get all the test names this makefile knows about + */ + void GetTestNames(std::vector<std::string>& testNames); + + /** * Get all the source files this makefile knows about */ const std::vector<cmSourceFile*>& GetSourceFiles() const diff --git a/Source/cmServerDictionary.h b/Source/cmServerDictionary.h index 03f1cc1..8cd5e14 100644 --- a/Source/cmServerDictionary.h +++ b/Source/cmServerDictionary.h @@ -23,6 +23,7 @@ static const std::string kPROGRESS_TYPE = "progress"; static const std::string kREPLY_TYPE = "reply"; static const std::string kSET_GLOBAL_SETTINGS_TYPE = "setGlobalSettings"; static const std::string kSIGNAL_TYPE = "signal"; +static const std::string kCTEST_INFO_TYPE = "ctestInfo"; static const std::string kARTIFACTS_KEY = "artifacts"; static const std::string kBUILD_DIRECTORY_KEY = "buildDirectory"; @@ -90,6 +91,11 @@ static const std::string kWATCHED_DIRECTORIES_KEY = "watchedDirectories"; static const std::string kWATCHED_FILES_KEY = "watchedFiles"; static const std::string kHAS_INSTALL_RULE = "hasInstallRule"; static const std::string kINSTALL_PATHS = "installPaths"; +static const std::string kHAS_ENABLED_TESTS = "hasEnabledTests"; +static const std::string kCTEST_NAME = "ctestName"; +static const std::string kCTEST_COMMAND = "ctestCommand"; +static const std::string kCTEST_INFO = "ctestInfo"; +static const std::string kMINIMUM_CMAKE_VERSION = "minimumCMakeVersion"; static const std::string kTARGET_CROSS_REFERENCES_KEY = "crossReferences"; static const std::string kLINE_NUMBER_KEY = "line"; diff --git a/Source/cmServerProtocol.cxx b/Source/cmServerProtocol.cxx index fc06fed..07df488 100644 --- a/Source/cmServerProtocol.cxx +++ b/Source/cmServerProtocol.cxx @@ -14,6 +14,7 @@ #include "cmListFileCache.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" +#include "cmProperty.h" #include "cmServer.h" #include "cmServerDictionary.h" #include "cmSourceFile.h" @@ -23,6 +24,7 @@ #include "cmStateTypes.h" #include "cmSystemTools.h" #include "cmTarget.h" +#include "cmTest.h" #include "cm_uv.h" #include "cmake.h" @@ -479,6 +481,9 @@ const cmServerResponse cmServerProtocol1::Process( if (request.Type == kSET_GLOBAL_SETTINGS_TYPE) { return this->ProcessSetGlobalSettings(request); } + if (request.Type == kCTEST_INFO_TYPE) { + return this->ProcessCTests(request); + } return request.ReportError("Unknown command!"); } @@ -766,6 +771,153 @@ static void DumpBacktraceRange(Json::Value& result, const std::string& type, } } +static Json::Value DumpCTestInfo(const std::string& name, cmTest* testInfo) +{ + Json::Value result = Json::objectValue; + result[kCTEST_NAME] = name; + + // Concat command entries together. After the first should be the arguments + // for the command + std::string command; + for (auto const& cmd : testInfo->GetCommand()) { + command.append(cmd); + command.append(" "); + } + result[kCTEST_COMMAND] = command; + + // Build up the list of properties that may have been specified + Json::Value properties = Json::arrayValue; + for (auto& prop : testInfo->GetProperties()) { + Json::Value entry = Json::objectValue; + entry[kKEY_KEY] = prop.first; + entry[kVALUE_KEY] = prop.second.GetValue(); + properties.append(entry); + } + result[kPROPERTIES_KEY] = properties; + + // Need backtrace to figure out where this test was originally added + result[kBACKTRACE_KEY] = DumpBacktrace(testInfo->GetBacktrace()); + + return result; +} + +static Json::Value DumpCTestTarget(cmGeneratorTarget* target, + const std::string& config) +{ + cmLocalGenerator* lg = target->GetLocalGenerator(); + const cmState* state = lg->GetState(); + + const cmStateEnums::TargetType type = target->GetType(); + const std::string typeName = state->GetTargetTypeName(type); + + Json::Value ttl = Json::arrayValue; + ttl.append("EXECUTABLE"); + ttl.append("STATIC_LIBRARY"); + ttl.append("SHARED_LIBRARY"); + ttl.append("MODULE_LIBRARY"); + ttl.append("OBJECT_LIBRARY"); + ttl.append("UTILITY"); + ttl.append("INTERFACE_LIBRARY"); + + if (!hasString(ttl, typeName) || target->IsImported()) { + return Json::Value(); + } + + Json::Value result = Json::objectValue; + result[kNAME_KEY] = target->GetName(); + result[kTYPE_KEY] = typeName; + + if (type == cmStateEnums::INTERFACE_LIBRARY) { + return result; + } + result[kFULL_NAME_KEY] = target->GetFullName(config); + + if (target->Makefile->IsOn("CMAKE_TESTING_ENABLED")) { + result[kHAS_ENABLED_TESTS] = true; + std::vector<std::string> CTestNames; + + Json::Value testInfo = Json::arrayValue; + std::vector<std::string> testNames; + target->Makefile->GetTestNames(testNames); + for (auto& name : testNames) { + auto test = target->Makefile->GetTest(name); + if (test != nullptr) { + testInfo.append(DumpCTestInfo(name, test)); + } + } + result[kCTEST_INFO] = testInfo; + } + + return result; +} + +static Json::Value DumpCTestTargetsList( + const std::vector<cmLocalGenerator*>& generators, const std::string& config) +{ + Json::Value result = Json::arrayValue; + + std::vector<cmGeneratorTarget*> targetList; + for (const auto& lgIt : generators) { + auto list = lgIt->GetGeneratorTargets(); + targetList.insert(targetList.end(), list.begin(), list.end()); + } + std::sort(targetList.begin(), targetList.end()); + + for (cmGeneratorTarget* target : targetList) { + Json::Value tmp = DumpCTestTarget(target, config); + if (!tmp.isNull()) { + result.append(tmp); + } + } + + return result; +} + +static Json::Value DumpCTestProjectList(const cmake* cm, + std::string const& config) +{ + Json::Value result = Json::arrayValue; + + auto globalGen = cm->GetGlobalGenerator(); + + for (const auto& projectIt : globalGen->GetProjectMap()) { + Json::Value pObj = Json::objectValue; + pObj[kNAME_KEY] = projectIt.first; + + // All Projects must have at least one local generator + assert(!projectIt.second.empty()); + + // Project structure information: + pObj[kTARGETS_KEY] = DumpCTestTargetsList(projectIt.second, config); + + result.append(pObj); + } + + return result; +} + +static Json::Value DumpCTestConfiguration(const cmake* cm, + const std::string& config) +{ + Json::Value result = Json::objectValue; + result[kNAME_KEY] = config; + + result[kPROJECTS_KEY] = DumpCTestProjectList(cm, config); + + return result; +} + +static Json::Value DumpCTestConfigurationsList(const cmake* cm) +{ + Json::Value result = Json::arrayValue; + + for (const std::string& c : getConfigurations(cm)) { + result.append(DumpCTestConfiguration(cm, c)); + } + + return result; +} + static Json::Value DumpTarget(cmGeneratorTarget* target, const std::string& config) { @@ -964,6 +1116,8 @@ static Json::Value DumpProjectList(const cmake* cm, std::string const& config) // Project structure information: const cmMakefile* mf = lg->GetMakefile(); + pObj[kMINIMUM_CMAKE_VERSION] = + mf->GetDefinition("CMAKE_MINIMUM_REQUIRED_VERSION"); pObj[kHAS_INSTALL_RULE] = mf->GetInstallGenerators().empty() == false; pObj[kSOURCE_DIRECTORY_KEY] = mf->GetCurrentSourceDirectory(); pObj[kBUILD_DIRECTORY_KEY] = mf->GetCurrentBinaryDirectory(); @@ -1222,6 +1376,19 @@ cmServerResponse cmServerProtocol1::ProcessFileSystemWatchers( return request.Reply(result); } +cmServerResponse cmServerProtocol1::ProcessCTests( + const cmServerRequest& request) +{ + if (this->m_State < STATE_COMPUTED) { + return request.ReportError("This instance was not yet computed."); + } + + Json::Value result = Json::objectValue; + result[kCONFIGURATIONS_KEY] = + DumpCTestConfigurationsList(this->CMakeInstance()); + return request.Reply(result); +} + cmServerProtocol1::GeneratorInformation::GeneratorInformation( const std::string& generatorName, const std::string& extraGeneratorName, const std::string& toolset, const std::string& platform, diff --git a/Source/cmServerProtocol.h b/Source/cmServerProtocol.h index 124ac7f..df71cff 100644 --- a/Source/cmServerProtocol.h +++ b/Source/cmServerProtocol.h @@ -123,6 +123,7 @@ private: cmServerResponse ProcessGlobalSettings(const cmServerRequest& request); cmServerResponse ProcessSetGlobalSettings(const cmServerRequest& request); cmServerResponse ProcessFileSystemWatchers(const cmServerRequest& request); + cmServerResponse ProcessCTests(const cmServerRequest& request); enum State { diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index c6cd502..9cf835c 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -884,6 +884,13 @@ void cmTarget::SetProperty(const std::string& prop, const char* value) this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); return; } + if (prop == "IMPORTED_GLOBAL" && !this->IsImported()) { + std::ostringstream e; + e << "IMPORTED_GLOBAL property can't be set on non-imported targets (\"" + << this->Name << "\")\n"; + this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); + return; + } if (prop == "INCLUDE_DIRECTORIES") { this->Internal->IncludeDirectoriesEntries.clear(); @@ -933,6 +940,19 @@ void cmTarget::SetProperty(const std::string& prop, const char* value) this->Internal->SourceEntries.push_back(value); this->Internal->SourceBacktraces.push_back(lfbt); } + } else if (prop == "IMPORTED_GLOBAL") { + if (!cmSystemTools::IsOn(value)) { + std::ostringstream e; + e << "IMPORTED_GLOBAL property can't be set to FALSE on targets (\"" + << this->Name << "\")\n"; + this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); + return; + } + /* no need to change anything if value does not change */ + if (!this->ImportedGloballyVisible) { + this->ImportedGloballyVisible = true; + this->GetGlobalGenerator()->IndexTarget(this); + } } else if (cmHasLiteralPrefix(prop, "IMPORTED_LIBNAME") && !this->CheckImportedLibName(prop, value ? value : "")) { /* error was reported by check method */ @@ -977,6 +997,14 @@ void cmTarget::AppendProperty(const std::string& prop, const char* value, this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); return; } + if (prop == "IMPORTED_GLOBAL") { + std::ostringstream e; + e << "IMPORTED_GLOBAL property can't be appended, only set on imported " + "targets (\"" + << this->Name << "\")\n"; + this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); + return; + } if (prop == "INCLUDE_DIRECTORIES") { if (value && *value) { this->Internal->IncludeDirectoriesEntries.push_back(value); @@ -1143,6 +1171,21 @@ static void cmTargetCheckINTERFACE_LINK_LIBRARIES(const char* value, context->IssueMessage(cmake::FATAL_ERROR, e.str()); } +static void cmTargetCheckIMPORTED_GLOBAL(const cmTarget* target, + cmMakefile* context) +{ + std::vector<cmTarget*> targets = context->GetOwnedImportedTargets(); + std::vector<cmTarget*>::const_iterator it = + std::find(targets.begin(), targets.end(), target); + if (it == targets.end()) { + std::ostringstream e; + e << "Attempt to promote imported target \"" << target->GetName() + << "\" to global scope (by setting IMPORTED_GLOBAL) " + "which is not built in this directory."; + context->IssueMessage(cmake::FATAL_ERROR, e.str()); + } +} + void cmTarget::CheckProperty(const std::string& prop, cmMakefile* context) const { @@ -1157,11 +1200,16 @@ void cmTarget::CheckProperty(const std::string& prop, cmTargetCheckLINK_INTERFACE_LIBRARIES(prop, value, context, true); } } - if (cmHasLiteralPrefix(prop, "INTERFACE_LINK_LIBRARIES")) { + if (prop == "INTERFACE_LINK_LIBRARIES") { if (const char* value = this->GetProperty(prop)) { cmTargetCheckINTERFACE_LINK_LIBRARIES(value, context); } } + if (prop == "IMPORTED_GLOBAL") { + if (this->IsImported()) { + cmTargetCheckIMPORTED_GLOBAL(this, context); + } + } } const char* cmTarget::GetComputedProperty( @@ -1182,6 +1230,7 @@ const char* cmTarget::GetProperty(const std::string& prop) const MAKE_STATIC_PROP(COMPILE_OPTIONS); MAKE_STATIC_PROP(COMPILE_DEFINITIONS); MAKE_STATIC_PROP(IMPORTED); + MAKE_STATIC_PROP(IMPORTED_GLOBAL); MAKE_STATIC_PROP(MANUALLY_ADDED_DEPENDENCIES); MAKE_STATIC_PROP(NAME); MAKE_STATIC_PROP(BINARY_DIR); @@ -1196,6 +1245,7 @@ const char* cmTarget::GetProperty(const std::string& prop) const specialProps.insert(propCOMPILE_OPTIONS); specialProps.insert(propCOMPILE_DEFINITIONS); specialProps.insert(propIMPORTED); + specialProps.insert(propIMPORTED_GLOBAL); specialProps.insert(propMANUALLY_ADDED_DEPENDENCIES); specialProps.insert(propNAME); specialProps.insert(propBINARY_DIR); @@ -1264,6 +1314,9 @@ const char* cmTarget::GetProperty(const std::string& prop) const if (prop == propIMPORTED) { return this->IsImported() ? "TRUE" : "FALSE"; } + if (prop == propIMPORTED_GLOBAL) { + return this->IsImportedGloballyVisible() ? "TRUE" : "FALSE"; + } if (prop == propNAME) { return this->GetName().c_str(); } diff --git a/Source/cmTargetPropertyComputer.cxx b/Source/cmTargetPropertyComputer.cxx index 1d2520d..ed9026e 100644 --- a/Source/cmTargetPropertyComputer.cxx +++ b/Source/cmTargetPropertyComputer.cxx @@ -57,6 +57,7 @@ bool cmTargetPropertyComputer::WhiteListedInterfaceProperty( builtIns.insert("COMPATIBLE_INTERFACE_STRING"); builtIns.insert("EXPORT_NAME"); builtIns.insert("IMPORTED"); + builtIns.insert("IMPORTED_GLOBAL"); builtIns.insert("NAME"); builtIns.insert("TYPE"); } diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 1aadf67..6486c8b 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -1689,12 +1689,8 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(cmSourceFile const* sf) } else if (ext == "natvis") { tool = "Natvis"; } else if (ext == "settings") { - // remove path to current source dir (if files are in current source dir) - if (!sourceLink.empty()) { - settingsLastGenOutput = sourceLink; - } else { - settingsLastGenOutput = sf->GetFullPath(); - } + settingsLastGenOutput = + cmsys::SystemTools::GetFilenameName(sf->GetFullPath()); std::size_t pos = settingsLastGenOutput.find(".settings"); settingsLastGenOutput.replace(pos, 9, ".Designer.cs"); settingsGenerator = "SettingsSingleFileGenerator"; diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index ef75b01..449db9d 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -1577,9 +1577,11 @@ std::ostream& operator<<(std::ostream& stream, stream.flags(flags); return stream; } + static bool RunCommand(const char* comment, std::vector<std::string>& command, bool verbose, NumberFormat exitFormat, - int* retCodeOut = nullptr) + int* retCodeOut = nullptr, + bool (*retCodeOkay)(int) = nullptr) { if (verbose) { std::cout << comment << ":\n"; @@ -1589,18 +1591,17 @@ static bool RunCommand(const char* comment, std::vector<std::string>& command, int retCode = 0; bool commandResult = cmSystemTools::RunSingleCommand( command, &output, &output, &retCode, nullptr, cmSystemTools::OUTPUT_NONE); - bool returnValue; + bool const retCodeSuccess = + retCode == 0 || (retCodeOkay && retCodeOkay(retCode)); + bool const success = commandResult && retCodeSuccess; if (retCodeOut) { - if (!commandResult) { - *retCodeOut = (retCode == 0) ? -1 : retCode; - } else { + if (commandResult || !retCodeSuccess) { *retCodeOut = retCode; + } else { + *retCodeOut = -1; } - returnValue = true; // always return true if retCodeOut is requested - } else { - returnValue = commandResult && (retCode == 0); } - if (!commandResult || retCode) { + if (!success) { std::cout << comment << ": command \"" << cmJoin(command, " ") << "\" failed (exit code " << NumberFormatter(exitFormat, retCode) @@ -1613,7 +1614,7 @@ static bool RunCommand(const char* comment, std::vector<std::string>& command, std::cout << output; } } - return returnValue; + return success; } bool cmVSLink::Parse(std::vector<std::string>::const_iterator argBeg, @@ -1711,6 +1712,13 @@ int cmVSLink::Link() return LinkNonIncremental(); } +static bool mtRetIsUpdate(int mtRet) +{ + // 'mt /notify_update' returns a special value (differing between + // Windows and POSIX hosts) when it updated the manifest file. + return mtRet == 0x41020001 || mtRet == 0xbb; +} + int cmVSLink::LinkIncremental() { // This follows the steps listed here: @@ -1782,9 +1790,9 @@ int cmVSLink::LinkIncremental() // Run the manifest tool to create the final manifest. int mtRet = this->RunMT("/out:" + this->ManifestFile, true); - // If mt returns 1090650113 (or 187 on a posix host) then it updated the - // manifest file so we need to embed it again. Otherwise we are done. - if (mtRet != 1090650113 && mtRet != 187) { + // If mt returns a special value then it updated the manifest file so + // we need to embed it again. Otherwise we are done. + if (!mtRetIsUpdate(mtRet)) { return mtRet; } @@ -1837,7 +1845,8 @@ int cmVSLink::RunMT(std::string const& out, bool notify) mtCommand.push_back("/notify_update"); } int mtRet = 0; - if (!RunCommand("MT", mtCommand, this->Verbose, FORMAT_HEX, &mtRet)) { + if (!RunCommand("MT", mtCommand, this->Verbose, FORMAT_HEX, &mtRet, + mtRetIsUpdate)) { return -1; } return mtRet; diff --git a/Source/ctest.cxx b/Source/ctest.cxx index f6466fa..ad5fec0 100644 --- a/Source/ctest.cxx +++ b/Source/ctest.cxx @@ -104,8 +104,6 @@ static const char* cmDocumentationOptions[][2] = { { "--test-timeout", "The time limit in seconds, internal use only." }, { "--test-load", "CPU load threshold for starting new parallel tests." }, { "--tomorrow-tag", "Nightly or experimental starts with next day tag." }, - { "--ctest-config", "The configuration file used to initialize CTest state " - "when submitting dashboards." }, { "--overwrite", "Overwrite CTest configuration option." }, { "--extra-submit <file>[;<file>]", "Submit extra files to the dashboard." }, { "--force-new-ctest-process", diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt index e4406e7..51f4088 100644 --- a/Source/kwsys/CMakeLists.txt +++ b/Source/kwsys/CMakeLists.txt @@ -1150,17 +1150,17 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR) SET(testProcess_COMPILE_FLAGS "") # Some Apple compilers produce bad optimizations in this source. IF(APPLE AND CMAKE_C_COMPILER_ID MATCHES "^(GNU|LLVM)$") - STRING(APPEND testProcess_COMPILE_FLAGS " -O0") + SET(testProcess_COMPILE_FLAGS "${testProcess_COMPILE_FLAGS} -O0") ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "XL" AND NOT (CMAKE_SYSTEM MATCHES "Linux.*ppc64le" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS "13.1.1")) # Tell IBM XL not to warn about our test infinite loop # v13.1.1 and newer on Linux ppc64le is clang based and does not accept # the -qsuppress option - STRING(APPEND testProcess_COMPILE_FLAGS " -qsuppress=1500-010") + SET(testProcess_COMPILE_FLAGS "${testProcess_COMPILE_FLAGS} -qsuppress=1500-010") ENDIF() IF(CMAKE_C_FLAGS MATCHES "-fsanitize=") - STRING(APPEND testProcess_COMPILE_FLAGS " -DCRASH_USING_ABORT") + SET(testProcess_COMPILE_FLAGS "${testProcess_COMPILE_FLAGS} -DCRASH_USING_ABORT") ENDIF() SET_PROPERTY(SOURCE testProcess.c PROPERTY COMPILE_FLAGS "${testProcess_COMPILE_FLAGS}") diff --git a/Source/kwsys/DynamicLoader.hxx.in b/Source/kwsys/DynamicLoader.hxx.in index 7e71a45..dc34692 100644 --- a/Source/kwsys/DynamicLoader.hxx.in +++ b/Source/kwsys/DynamicLoader.hxx.in @@ -35,7 +35,7 @@ namespace @KWSYS_NAMESPACE@ { * or absolute) pathname. Otherwise, the dynamic linker searches for the * library as follows : see ld.so(8) for further details): * Whereas this distinction does not exist on Win32. Therefore ideally you - * should be doing full path to garantee to have a consistent way of dealing + * should be doing full path to guarantee to have a consistent way of dealing * with dynamic loading of shared library. * * \warning the Cygwin implementation do not use the Win32 HMODULE. Put extra @@ -72,7 +72,7 @@ public: static LibraryHandle OpenLibrary(const std::string&); /** Attempt to detach a dynamic library from the - * process. A value of true is returned if it is sucessful. */ + * process. A value of true is returned if it is successful. */ static int CloseLibrary(LibraryHandle); /** Find the address of the symbol in the given library. */ diff --git a/Source/kwsys/Process.h.in b/Source/kwsys/Process.h.in index 6cb9443..daf334a 100644 --- a/Source/kwsys/Process.h.in +++ b/Source/kwsys/Process.h.in @@ -421,7 +421,7 @@ enum kwsysProcess_Pipes_e /** * Block until the child process terminates or the given timeout - * expires. If no process is running, returns immediatly. The + * expires. If no process is running, returns immediately. The * argument is: * * timeout = Specifies the maximum time this call may block. Upon diff --git a/Source/kwsys/RegularExpression.hxx.in b/Source/kwsys/RegularExpression.hxx.in index 606e3da..763fdab 100644 --- a/Source/kwsys/RegularExpression.hxx.in +++ b/Source/kwsys/RegularExpression.hxx.in @@ -109,12 +109,12 @@ namespace @KWSYS_NAMESPACE@ { * object as an argument and creates an object initialized with the * information from the given RegularExpression object. * - * The find member function finds the first occurence of the regualr + * The find member function finds the first occurrence of the regular * expression of that object in the string given to find as an argument. Find * returns a boolean, and if true, mutates the private data appropriately. * Find sets pointers to the beginning and end of the thing last found, they * are pointers into the actual string that was searched. The start and end - * member functions return indicies into the searched string that correspond + * member functions return indices into the searched string that correspond * to the beginning and end pointers respectively. The compile member * function takes a char* and puts the compiled version of the char* argument * into the object's private data fields. The == and != operators only check diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx index 366fe30..ab1f40a 100644 --- a/Source/kwsys/SystemInformation.cxx +++ b/Source/kwsys/SystemInformation.cxx @@ -3633,7 +3633,7 @@ SystemInformationImplementation::GetHostMemoryAvailable( // apply resource limits across groups of processes. // this is of use on certain SMP systems (eg. SGI UV) // where the host has a large amount of ram but a given user's - // access to it is severly restricted. The system will + // access to it is severely restricted. The system will // apply a limit across a set of processes. Units are in KiB. if (hostLimitEnvVarName) { const char* hostLimitEnvVarValue = getenv(hostLimitEnvVarName); diff --git a/Source/kwsys/SystemInformation.hxx.in b/Source/kwsys/SystemInformation.hxx.in index 516c505..5678e8a 100644 --- a/Source/kwsys/SystemInformation.hxx.in +++ b/Source/kwsys/SystemInformation.hxx.in @@ -124,7 +124,7 @@ public: // are the processes comprising an mpi program which is running in // parallel. The amount of memory reported may differ from the host // total if a host wide resource limit is applied. Such reource limits - // are reported to us via an applicaiton specified environment variable. + // are reported to us via an application specified environment variable. LongLong GetHostMemoryAvailable(const char* hostLimitEnvVarName = NULL); // Get total system RAM in units of KiB available to this process. diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx index 72babc3..50aa857 100644 --- a/Source/kwsys/SystemTools.cxx +++ b/Source/kwsys/SystemTools.cxx @@ -27,6 +27,7 @@ #include <iostream> #include <set> #include <sstream> +#include <utility> #include <vector> // Work-around CMake dependency scanning limitation. This must @@ -1691,7 +1692,7 @@ bool SystemTools::StringEndsWith(const std::string& str1, const char* str2) : false; } -// Returns a pointer to the last occurence of str2 in str1 +// Returns a pointer to the last occurrence of str2 in str1 const char* SystemTools::FindLastString(const char* str1, const char* str2) { if (!str1 || !str2) { @@ -3372,7 +3373,7 @@ std::string SystemTools::RelativePath(const std::string& local, } #ifdef _WIN32 -static std::string GetCasePathName(std::string const& pathIn) +static std::pair<std::string, bool> GetCasePathName(std::string const& pathIn) { std::string casePath; std::vector<std::string> path_components; @@ -3381,7 +3382,7 @@ static std::string GetCasePathName(std::string const& pathIn) { // Relative paths cannot be converted. casePath = pathIn; - return casePath; + return std::make_pair(casePath, false); } // Start with root component. @@ -3433,7 +3434,7 @@ static std::string GetCasePathName(std::string const& pathIn) casePath += path_components[idx]; } - return casePath; + return std::make_pair(casePath, converting); } #endif @@ -3448,12 +3449,14 @@ std::string SystemTools::GetActualCaseForPath(const std::string& p) if (i != SystemTools::PathCaseMap->end()) { return i->second; } - std::string casePath = GetCasePathName(p); - if (casePath.size() > MAX_PATH) { - return casePath; + std::pair<std::string, bool> casePath = GetCasePathName(p); + if (casePath.first.size() > MAX_PATH) { + return casePath.first; } - (*SystemTools::PathCaseMap)[p] = casePath; - return casePath; + if (casePath.second) { + (*SystemTools::PathCaseMap)[p] = casePath.first; + } + return casePath.first; #endif } diff --git a/Source/kwsys/SystemTools.hxx.in b/Source/kwsys/SystemTools.hxx.in index 3d109a8..8a02b75 100644 --- a/Source/kwsys/SystemTools.hxx.in +++ b/Source/kwsys/SystemTools.hxx.in @@ -107,7 +107,7 @@ public: } /** - * Replace replace all occurences of the string in the source string. + * Replace replace all occurrences of the string in the source string. */ static void ReplaceString(std::string& source, const char* replace, const char* with); @@ -175,7 +175,7 @@ public: static bool StringEndsWith(const std::string& str1, const char* str2); /** - * Returns a pointer to the last occurence of str2 in str1 + * Returns a pointer to the last occurrence of str2 in str1 */ static const char* FindLastString(const char* str1, const char* str2); @@ -905,7 +905,7 @@ public: /** * Delay the execution for a specified amount of time specified - * in miliseconds + * in milliseconds */ static void Delay(unsigned int msec); diff --git a/Source/kwsys/kwsysPlatformTestsCXX.cxx b/Source/kwsys/kwsysPlatformTestsCXX.cxx index e67d436..f1f9ed3 100644 --- a/Source/kwsys/kwsysPlatformTestsCXX.cxx +++ b/Source/kwsys/kwsysPlatformTestsCXX.cxx @@ -281,7 +281,7 @@ int main() #ifdef TEST_KWSYS_CXX_HAS_BACKTRACE #if defined(__PATHSCALE__) || defined(__PATHCC__) || \ (defined(__LSB_VERSION__) && (__LSB_VERSION__ < 41)) -backtrace doesnt work with this compiler or os +backtrace does not work with this compiler or os #endif #if (defined(__GNUC__) || defined(__PGI)) && !defined(_GNU_SOURCE) #define _GNU_SOURCE diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 1c69805..b9558f1 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -3396,6 +3396,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release # sets "CMake_TEST_CONTRACT_<project>_<var>" variables to configure # the code below. foreach(project + PLplot Trilinos VTK ) diff --git a/Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in b/Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in index d7d881e..65487bb 100644 --- a/Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in +++ b/Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in @@ -525,6 +525,27 @@ set(msys_g77_dirs "C:/some-mingw/lib/gcc/mingw32/3.4.5;C:/some-mingw/lib/gcc;/so list(APPEND platforms msys_g77) #----------------------------------------------------------------------------- +# MSYS2 + +# gcc dummy.c -v +set(msys2_gcc_text " C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/collect2.exe -plugin C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/liblto_plugin-0.dll -plugin-opt=C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/lto-wrapper.exe -plugin-opt=-fresolution=C:/msys64/tmp/ccikz9Wf.res -plugin-opt=-pass-through=-lmingw32 -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_eh -plugin-opt=-pass-through=-lmoldname -plugin-opt=-pass-through=-lmingwex -plugin-opt=-pass-through=-lmsvcrt -plugin-opt=-pass-through=-lpthread -plugin-opt=-pass-through=-ladvapi32 -plugin-opt=-pass-through=-lshell32 -plugin-opt=-pass-through=-luser32 -plugin-opt=-pass-through=-lkernel32 -plugin-opt=-pass-through=-lmingw32 -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_eh -plugin-opt=-pass-through=-lmoldname -plugin-opt=-pass-through=-lmingwex -plugin-opt=-pass-through=-lmsvcrt -m i386pep -Bdynamic C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/../../../../x86_64-w64-mingw32/lib/../lib/crt2.o C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/crtbegin.o -LC:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0 -LC:/msys64/mingw64/bin/../lib/gcc -LC:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/../../../../x86_64-w64-mingw32/lib/../lib -LC:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/../../../../lib -LC:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/../../../../x86_64-w64-mingw32/lib -LC:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/../../.. C:/msys64/tmp/ccK0dTUv.o -lmingw32 -lgcc -lgcc_eh -lmoldname -lmingwex -lmsvcrt -lpthread -ladvapi32 -lshell32 -luser32 -lkernel32 -lmingw32 -lgcc -lgcc_eh -lmoldname -lmingwex -lmsvcrt C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/../../../../x86_64-w64-mingw32/lib/../lib/default-manifest.o C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/crtend.o") +set(msys2_gcc_libs "mingw32;gcc;moldname;mingwex;pthread;advapi32;shell32;user32;kernel32;mingw32;gcc;moldname;mingwex") +set(msys2_gcc_dirs "C:/msys64/mingw64/lib/gcc/x86_64-w64-mingw32/7.2.0;C:/msys64/mingw64/lib/gcc;C:/msys64/mingw64/x86_64-w64-mingw32/lib;C:/msys64/mingw64/lib") +list(APPEND platforms msys2_gcc) + +# g++ dummy.cxx -v +set(msys2_g++_text " C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/collect2.exe -plugin C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/liblto_plugin-0.dll -plugin-opt=C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/lto-wrapper.exe -plugin-opt=-fresolution=C:/msys64/tmp/ccJQgvbN.res -plugin-opt=-pass-through=-lmingw32 -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lmoldname -plugin-opt=-pass-through=-lmingwex -plugin-opt=-pass-through=-lmsvcrt -plugin-opt=-pass-through=-lpthread -plugin-opt=-pass-through=-ladvapi32 -plugin-opt=-pass-through=-lshell32 -plugin-opt=-pass-through=-luser32 -plugin-opt=-pass-through=-lkernel32 -plugin-opt=-pass-through=-lmingw32 -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lmoldname -plugin-opt=-pass-through=-lmingwex -plugin-opt=-pass-through=-lmsvcrt -m i386pep -Bdynamic C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/../../../../x86_64-w64-mingw32/lib/../lib/crt2.o C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/crtbegin.o -LC:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0 -LC:/msys64/mingw64/bin/../lib/gcc -LC:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/../../../../x86_64-w64-mingw32/lib/../lib -LC:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/../../../../lib -LC:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/../../../../x86_64-w64-mingw32/lib -LC:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/../../.. C:/msys64/tmp/ccqPpuVS.o -lstdc++ -lmingw32 -lgcc_s -lgcc -lmoldname -lmingwex -lmsvcrt -lpthread -ladvapi32 -lshell32 -luser32 -lkernel32 -lmingw32 -lgcc_s -lgcc -lmoldname -lmingwex -lmsvcrt C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/../../../../x86_64-w64-mingw32/lib/../lib/default-manifest.o C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/crtend.o") +set(msys2_g++_libs "stdc++;mingw32;gcc_s;gcc;moldname;mingwex;pthread;advapi32;shell32;user32;kernel32;mingw32;gcc_s;gcc;moldname;mingwex") +set(msys2_g++_dirs "C:/msys64/mingw64/lib/gcc/x86_64-w64-mingw32/7.2.0;C:/msys64/mingw64/lib/gcc;C:/msys64/mingw64/x86_64-w64-mingw32/lib;C:/msys64/mingw64/lib") +list(APPEND platforms msys2_g++) + +# gfortran dummy.f90 -v +set(msys2_gfortran_text " C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/collect2.exe -plugin C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/liblto_plugin-0.dll -plugin-opt=C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/lto-wrapper.exe -plugin-opt=-fresolution=C:/msys64/tmp/cczOKIDy.res -plugin-opt=-pass-through=-lmingw32 -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lmoldname -plugin-opt=-pass-through=-lmingwex -plugin-opt=-pass-through=-lmsvcrt -plugin-opt=-pass-through=-lquadmath -plugin-opt=-pass-through=-lm -plugin-opt=-pass-through=-lmingw32 -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lmoldname -plugin-opt=-pass-through=-lmingwex -plugin-opt=-pass-through=-lmsvcrt -plugin-opt=-pass-through=-lpthread -plugin-opt=-pass-through=-ladvapi32 -plugin-opt=-pass-through=-lshell32 -plugin-opt=-pass-through=-luser32 -plugin-opt=-pass-through=-lkernel32 -plugin-opt=-pass-through=-lmingw32 -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lmoldname -plugin-opt=-pass-through=-lmingwex -plugin-opt=-pass-through=-lmsvcrt -m i386pep -Bdynamic C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/../../../../x86_64-w64-mingw32/lib/../lib/crt2.o C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/crtbegin.o -LC:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0 -LC:/msys64/mingw64/bin/../lib/gcc -LC:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/../../../../x86_64-w64-mingw32/lib/../lib -LC:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/../../../../lib -LC:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/../../../../x86_64-w64-mingw32/lib -LC:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/../../.. C:/msys64/tmp/ccyXuCgD.o -lgfortran -lmingw32 -lgcc_s -lgcc -lmoldname -lmingwex -lmsvcrt -lquadmath -lm -lmingw32 -lgcc_s -lgcc -lmoldname -lmingwex -lmsvcrt -lpthread -ladvapi32 -lshell32 -luser32 -lkernel32 -lmingw32 -lgcc_s -lgcc -lmoldname -lmingwex -lmsvcrt C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/../../../../x86_64-w64-mingw32/lib/../lib/default-manifest.o C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/crtend.o") +set(msys2_gfortran_libs "gfortran;mingw32;gcc_s;gcc;moldname;mingwex;quadmath;m;mingw32;gcc_s;gcc;moldname;mingwex;pthread;advapi32;shell32;user32;kernel32;mingw32;gcc_s;gcc;moldname;mingwex") +set(msys2_gfortran_dirs "C:/msys64/mingw64/lib/gcc/x86_64-w64-mingw32/7.2.0;C:/msys64/mingw64/lib/gcc;C:/msys64/mingw64/x86_64-w64-mingw32/lib;C:/msys64/mingw64/lib") +list(APPEND platforms msys2_gfortran) + +#----------------------------------------------------------------------------- # MSVC from NVIDIA CUDA set(nvcc_msvc_text [[cuda-fake-ld cl.exe -nologo "tmp/a_dlink.obj" "tmp/CMakeCUDACompilerId.obj" -link -INCREMENTAL:NO "/LIBPATH:C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v8.0/bin/../lib/x64" cudadevrt.lib cudart_static.lib -Fe"a.exe"]]) @@ -532,7 +553,6 @@ set(nvcc_msvc_libs "cudadevrt.lib;cudart_static.lib") set(nvcc_msvc_dirs "C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v8.0/lib/x64") list(APPEND platforms nvcc_msvc) - #----------------------------------------------------------------------------- # PGI on Windows diff --git a/Tests/CTestTest2/test.cmake.in b/Tests/CTestTest2/test.cmake.in index 825b957..a9bbc52 100644 --- a/Tests/CTestTest2/test.cmake.in +++ b/Tests/CTestTest2/test.cmake.in @@ -34,6 +34,7 @@ CMAKE_C_COMPILER:STRING=@CMAKE_C_COMPILER@ CMAKE_CXX_COMPILER:STRING=@CMAKE_CXX_COMPILER@ CMAKE_C_COMPILER_ARG1:STRING=@CMAKE_C_COMPILER_ARG1@ CMAKE_CXX_COMPILER_ARG1:STRING=@CMAKE_CXX_COMPILER_ARG1@ +KWSYS_ENCODING_DEFAULT_CODEPAGE:STRING=CP_UTF8 # This one is needed for testing advanced ctest features CTEST_TEST_KWSYS:BOOL=ON diff --git a/Tests/CheckFortran.cmake b/Tests/CheckFortran.cmake index b1652ba..16a8ed2 100644 --- a/Tests/CheckFortran.cmake +++ b/Tests/CheckFortran.cmake @@ -15,11 +15,18 @@ file(WRITE \"\${CMAKE_CURRENT_BINARY_DIR}/result.cmake\" \"set(CMAKE_Fortran_COMPILER_SUPPORTS_F90 \\\"\${CMAKE_Fortran_COMPILER_SUPPORTS_F90}\\\")\\n\" ) ") + if(CMAKE_GENERATOR_INSTANCE) + set(_D_CMAKE_GENERATOR_INSTANCE "-DCMAKE_GENERATOR_INSTANCE:INTERNAL=${CMAKE_GENERATOR_INSTANCE}") + else() + set(_D_CMAKE_GENERATOR_INSTANCE "") + endif() execute_process( WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CheckFortran COMMAND ${CMAKE_COMMAND} . -G ${CMAKE_GENERATOR} -A "${CMAKE_GENERATOR_PLATFORM}" -T "${CMAKE_GENERATOR_TOOLSET}" + ${_D_CMAKE_GENERATOR_INSTANCE} + TIMEOUT 60 OUTPUT_VARIABLE output ERROR_VARIABLE output RESULT_VARIABLE result diff --git a/Tests/Contracts/PLplot/CMakeLists.txt b/Tests/Contracts/PLplot/CMakeLists.txt new file mode 100644 index 0000000..b87b4c3 --- /dev/null +++ b/Tests/Contracts/PLplot/CMakeLists.txt @@ -0,0 +1,18 @@ +cmake_minimum_required(VERSION 3.9) +project(PLplotDriver NONE) +include(ExternalProject) +include(${CMAKE_CURRENT_SOURCE_DIR}/../Home.cmake) +set(PLplot_PREFIX "${HOME}/.cmake/Contracts/PLplot") +file(REMOVE_RECURSE "${PLplot_PREFIX}") +separate_arguments(PLplot_CMAKE_ARGS UNIX_COMMAND "${PLplot_CMAKE_FLAGS}") +if(NOT PLplot_GIT_TAG) + set(PLplot_GIT_TAG "plplot-5.13.0") +endif() +ExternalProject_Add(PLplot + GIT_REPOSITORY "https://git.code.sf.net/p/plplot/plplot.git" + GIT_TAG "${PLplot_GIT_TAG}" + PREFIX "${PLplot_PREFIX}" + CMAKE_ARGS + -DCMAKE_INSTALL_PREFIX=<INSTALL_DIR> + ${PLplot_CMAKE_ARGS} + ) diff --git a/Tests/Contracts/PLplot/Configure.cmake b/Tests/Contracts/PLplot/Configure.cmake new file mode 100644 index 0000000..83591d4 --- /dev/null +++ b/Tests/Contracts/PLplot/Configure.cmake @@ -0,0 +1,4 @@ +set(Contracts.PLplot_BUILD_OPTIONS + -DPLplot_CMAKE_FLAGS=${CMake_TEST_CONTRACT_PLplot_CMAKE_FLAGS} + -DPLplot_GIT_TAG=${CMake_TEST_CONTRACT_PLplot_GIT_TAG} + ) diff --git a/Tests/RunCMake/CPack/CPackTestHelpers.cmake b/Tests/RunCMake/CPack/CPackTestHelpers.cmake index f883c69..5337b2c 100644 --- a/Tests/RunCMake/CPack/CPackTestHelpers.cmake +++ b/Tests/RunCMake/CPack/CPackTestHelpers.cmake @@ -68,6 +68,8 @@ function(run_cpack_test_common_ TEST_NAME types build SUBTEST_SUFFIX source PACK set(RunCMake-std${o}-file "tests/${TEST_NAME}/${TEST_TYPE}-${SUBTEST_SUFFIX}-std${o}.txt") elseif(EXISTS ${RunCMake_SOURCE_DIR}/tests/${TEST_NAME}/${TEST_TYPE}-std${o}.txt) set(RunCMake-std${o}-file "tests/${TEST_NAME}/${TEST_TYPE}-std${o}.txt") + elseif(SUBTEST_SUFFIX AND EXISTS ${RunCMake_SOURCE_DIR}/tests/${TEST_NAME}/${SUBTEST_SUFFIX}-std${o}.txt) + set(RunCMake-std${o}-file "tests/${TEST_NAME}/${SUBTEST_SUFFIX}-std${o}.txt") elseif(EXISTS ${RunCMake_SOURCE_DIR}/${TEST_TYPE}/default_expected_std${o}.txt) set(RunCMake-std${o}-file "${TEST_TYPE}/default_expected_std${o}.txt") endif() diff --git a/Tests/RunCMake/CPack/README.txt b/Tests/RunCMake/CPack/README.txt index 5a95927..5877f97 100644 --- a/Tests/RunCMake/CPack/README.txt +++ b/Tests/RunCMake/CPack/README.txt @@ -167,6 +167,7 @@ NOTE: For subtests generator name can also be suffixed with subtest name and/or - generator name + packaging type - generator name + subtest name - generator name + - subtest name - default generator File name format: '<generator_name>-<packaging_type>-<subtest_name>-std<type>.txt' where <type> can either be 'out' or 'err'. diff --git a/Tests/RunCMake/CPack/RunCMakeTest.cmake b/Tests/RunCMake/CPack/RunCMakeTest.cmake index b00e373..4b7f146 100644 --- a/Tests/RunCMake/CPack/RunCMakeTest.cmake +++ b/Tests/RunCMake/CPack/RunCMakeTest.cmake @@ -7,6 +7,7 @@ include("${RunCMake_SOURCE_DIR}/CPackTestHelpers.cmake") run_cpack_test(CUSTOM_BINARY_SPEC_FILE "RPM" false "MONOLITHIC;COMPONENT") run_cpack_test(CUSTOM_NAMES "RPM;DEB;TGZ" true "COMPONENT") run_cpack_test(DEBUGINFO "RPM" true "COMPONENT") +run_cpack_test_subtests(DEFAULT_PERMISSIONS "CMAKE_var_set;CPACK_var_set;both_set;invalid_CMAKE_var;invalid_CPACK_var" "RPM;DEB" false "MONOLITHIC;COMPONENT") run_cpack_test(DEPENDENCIES "RPM;DEB" true "COMPONENT") run_cpack_test(DIST "RPM" false "MONOLITHIC") run_cpack_test(EMPTY_DIR "RPM;DEB;TGZ" true "MONOLITHIC;COMPONENT") diff --git a/Tests/RunCMake/CPack/tests/DEFAULT_PERMISSIONS/ExpectedFiles.cmake b/Tests/RunCMake/CPack/tests/DEFAULT_PERMISSIONS/ExpectedFiles.cmake new file mode 100644 index 0000000..9b8205b --- /dev/null +++ b/Tests/RunCMake/CPack/tests/DEFAULT_PERMISSIONS/ExpectedFiles.cmake @@ -0,0 +1,6 @@ +if(${RunCMake_SUBTEST_SUFFIX} MATCHES "invalid_.*_var") + set(EXPECTED_FILES_COUNT "0") +else() + set(EXPECTED_FILES_COUNT "1") + set(EXPECTED_FILE_CONTENT_1_LIST "/usr;/usr/foo;/usr/foo/CMakeLists.txt") +endif() diff --git a/Tests/RunCMake/CPack/tests/DEFAULT_PERMISSIONS/VerifyResult.cmake b/Tests/RunCMake/CPack/tests/DEFAULT_PERMISSIONS/VerifyResult.cmake new file mode 100644 index 0000000..16ebcdc --- /dev/null +++ b/Tests/RunCMake/CPack/tests/DEFAULT_PERMISSIONS/VerifyResult.cmake @@ -0,0 +1,39 @@ +if(NOT ${RunCMake_SUBTEST_SUFFIX} MATCHES "invalid_.*_var") + if(GENERATOR_TYPE STREQUAL "RPM") + function(checkContentPermissions_ FILE REGEX) + execute_process(COMMAND ${RPM_EXECUTABLE} -qp --dump ${FILE} + WORKING_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}" + OUTPUT_VARIABLE PERMISSIONS_ + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + + if(NOT PERMISSIONS_ MATCHES "${REGEX}") + message(FATAL_ERROR "Permissions in '${FILE}'. Permissions: '${PERMISSIONS_}'") + endif() + endfunction() + + if(${RunCMake_SUBTEST_SUFFIX} MATCHES "CMAKE_var_set") + checkContentPermissions_("${FOUND_FILE_1}" + "/usr/foo .*740 root root.*") + else() + checkContentPermissions_("${FOUND_FILE_1}" + "/usr/foo .*700 root root.*") + endif() + else() # DEB + function(checkContentPermissions_ FILE REGEX) + getPackageContent("${FILE}" PERMISSIONS_) + + if(NOT PERMISSIONS_ MATCHES "${REGEX}") + message(FATAL_ERROR "Permissions in '${FILE}'. Permissions: '${PERMISSIONS_}'") + endif() + endfunction() + + if(${RunCMake_SUBTEST_SUFFIX} MATCHES "CMAKE_var_set") + checkContentPermissions_("${FOUND_FILE_1}" + "drwxr----- root/root .* ./usr/\ndrwxr----- root/root .* ./usr/foo/\n.*") + else() + checkContentPermissions_("${FOUND_FILE_1}" + "drwx------ root/root .* ./usr/\ndrwx------ root/root .* ./usr/foo/\n.*") + endif() + endif() +endif() diff --git a/Tests/RunCMake/CPack/tests/DEFAULT_PERMISSIONS/invalid_CMAKE_var-stderr.txt b/Tests/RunCMake/CPack/tests/DEFAULT_PERMISSIONS/invalid_CMAKE_var-stderr.txt new file mode 100644 index 0000000..541763a --- /dev/null +++ b/Tests/RunCMake/CPack/tests/DEFAULT_PERMISSIONS/invalid_CMAKE_var-stderr.txt @@ -0,0 +1 @@ +.*CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS value is invalid.* diff --git a/Tests/RunCMake/CPack/tests/DEFAULT_PERMISSIONS/invalid_CPACK_var-stderr.txt b/Tests/RunCMake/CPack/tests/DEFAULT_PERMISSIONS/invalid_CPACK_var-stderr.txt new file mode 100644 index 0000000..541763a --- /dev/null +++ b/Tests/RunCMake/CPack/tests/DEFAULT_PERMISSIONS/invalid_CPACK_var-stderr.txt @@ -0,0 +1 @@ +.*CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS value is invalid.* diff --git a/Tests/RunCMake/CPack/tests/DEFAULT_PERMISSIONS/test.cmake b/Tests/RunCMake/CPack/tests/DEFAULT_PERMISSIONS/test.cmake new file mode 100644 index 0000000..afe9390 --- /dev/null +++ b/Tests/RunCMake/CPack/tests/DEFAULT_PERMISSIONS/test.cmake @@ -0,0 +1,34 @@ +if(${RunCMake_SUBTEST_SUFFIX} MATCHES "CMAKE_var_set" OR + ${RunCMake_SUBTEST_SUFFIX} MATCHES "both_set") + + set(CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS + OWNER_READ + OWNER_WRITE + OWNER_EXECUTE + GROUP_READ + ) +endif() + +if(${RunCMake_SUBTEST_SUFFIX} MATCHES "invalid_CMAKE_var") + list(APPEND CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS "INVALID") +endif() + +if(${RunCMake_SUBTEST_SUFFIX} MATCHES "CPACK_var_set" OR + ${RunCMake_SUBTEST_SUFFIX} MATCHES "both_set") + + set(CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS + OWNER_READ + OWNER_WRITE + OWNER_EXECUTE + ) +endif() + +if(${RunCMake_SUBTEST_SUFFIX} MATCHES "invalid_CPACK_var") + list(APPEND CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS "INVALID") +endif() + +install(FILES CMakeLists.txt DESTINATION foo COMPONENT test) + +if(PACKAGING_TYPE STREQUAL "COMPONENT") + set(CPACK_COMPONENTS_ALL test) +endif() diff --git a/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake index e936dab..0fafea5 100644 --- a/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake +++ b/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake @@ -102,7 +102,7 @@ function(run_TestLoad name load) add_test(TestLoad1 \"${CMAKE_COMMAND}\" -E echo \"test of --test-load\") add_test(TestLoad2 \"${CMAKE_COMMAND}\" -E echo \"test of --test-load\") ") - run_cmake_command(${name} ${CMAKE_CTEST_COMMAND} -j2 --test-load ${load} --test-timeout 5) + run_cmake_command(${name} ${CMAKE_CTEST_COMMAND} -j2 --test-load ${load}) endfunction() # Tests for the --test-load feature of ctest diff --git a/Tests/RunCMake/get_property/target_properties-stderr.txt b/Tests/RunCMake/get_property/target_properties-stderr.txt index 6b3c6ca..df7a2f1 100644 --- a/Tests/RunCMake/get_property/target_properties-stderr.txt +++ b/Tests/RunCMake/get_property/target_properties-stderr.txt @@ -7,4 +7,10 @@ get_property: --><-- get_target_property: -->(.*)/Tests/RunCMake/get_property<-- get_property: -->(.*)/Tests/RunCMake/get_property<-- get_target_property: -->(.*)/Tests/RunCMake/get_property/target_properties-build<-- -get_property: -->(.*)/Tests/RunCMake/get_property/target_properties-build<--$ +get_property: -->(.*)/Tests/RunCMake/get_property/target_properties-build<-- +get_target_property: -->FALSE<-- +get_property: -->FALSE<-- +get_target_property: -->FALSE<-- +get_property: -->FALSE<-- +get_target_property: -->TRUE<-- +get_property: -->TRUE<--$ diff --git a/Tests/RunCMake/get_property/target_properties.cmake b/Tests/RunCMake/get_property/target_properties.cmake index 9ff833a..321d5b5 100644 --- a/Tests/RunCMake/get_property/target_properties.cmake +++ b/Tests/RunCMake/get_property/target_properties.cmake @@ -16,3 +16,10 @@ check_target_property(tgt custom) check_target_property(tgt noexist) check_target_property(tgt SOURCE_DIR) check_target_property(tgt BINARY_DIR) + +add_library(imported_local_tgt SHARED IMPORTED) +add_library(imported_global_tgt SHARED IMPORTED GLOBAL) + +check_target_property(tgt IMPORTED_GLOBAL) +check_target_property(imported_local_tgt IMPORTED_GLOBAL) +check_target_property(imported_global_tgt IMPORTED_GLOBAL) diff --git a/Tests/RunCMake/set_property/IMPORTED_GLOBAL-result.txt b/Tests/RunCMake/set_property/IMPORTED_GLOBAL-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/set_property/IMPORTED_GLOBAL-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/set_property/IMPORTED_GLOBAL-stderr.txt b/Tests/RunCMake/set_property/IMPORTED_GLOBAL-stderr.txt new file mode 100644 index 0000000..f21b1de --- /dev/null +++ b/Tests/RunCMake/set_property/IMPORTED_GLOBAL-stderr.txt @@ -0,0 +1,61 @@ +^CMake Error at IMPORTED_GLOBAL.cmake:9 \(set_property\): + IMPORTED_GLOBAL property can't be set to FALSE on targets + \(\"ImportedGlobalTarget\"\) + +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) + + +CMake Error at IMPORTED_GLOBAL.cmake:16 \(set_property\): + IMPORTED_GLOBAL property can't be appended, only set on imported targets + \(\"ImportedGlobalTarget\"\) + +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) + + +CMake Error at IMPORTED_GLOBAL.cmake:26 \(set_property\): + IMPORTED_GLOBAL property can't be set to FALSE on targets + \(\"ImportedLocalTarget\"\) + +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) + + +CMake Error at IMPORTED_GLOBAL.cmake:32 \(set_property\): + IMPORTED_GLOBAL property can't be set on non-imported targets + \(\"NonImportedTarget\"\) + +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) + + +CMake Error at IMPORTED_GLOBAL/CMakeLists.txt:8 \(set_property\): + Attempt to promote imported target \"ImportedLocalTarget2\" to global scope + \(by setting IMPORTED_GLOBAL\) which is not built in this directory. + + +CMake Error in IMPORTED_GLOBAL/CMakeLists.txt: + IMPORTED_GLOBAL property can't be set to FALSE on targets + \(\"ImportedSubdirTarget1\"\) + + + +CMake Error at IMPORTED_GLOBAL.cmake:50 \(set_property\): + Attempt to promote imported target \"ImportedSubdirTarget1\" to global scope + \(by setting IMPORTED_GLOBAL\) which is not built in this directory. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) + + +CMake Error in IMPORTED_GLOBAL/CMakeLists.txt: + IMPORTED_GLOBAL property can't be set to FALSE on targets + \(\"ImportedSubdirTarget2\"\) + + + +CMake Error at IMPORTED_GLOBAL.cmake:52 \(set_property\): + Attempt to promote imported target \"ImportedSubdirTarget2\" to global scope + \(by setting IMPORTED_GLOBAL\) which is not built in this directory. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\)$ diff --git a/Tests/RunCMake/set_property/IMPORTED_GLOBAL-stdout.txt b/Tests/RunCMake/set_property/IMPORTED_GLOBAL-stdout.txt new file mode 100644 index 0000000..c5f1d11 --- /dev/null +++ b/Tests/RunCMake/set_property/IMPORTED_GLOBAL-stdout.txt @@ -0,0 +1,17 @@ +-- ImportedGlobalTarget: Target IMPORTED_GLOBAL is 'TRUE' +-- ImportedGlobalTarget: Target IMPORTED_GLOBAL is 'TRUE' +-- ImportedGlobalTarget: Target IMPORTED_GLOBAL is 'TRUE' +-- ImportedGlobalTarget: Target IMPORTED_GLOBAL is 'TRUE' +-- ImportedGlobalTarget: Target IMPORTED_GLOBAL is 'TRUE' +-- ImportedLocalTarget: Target IMPORTED_GLOBAL is 'FALSE' +-- ImportedLocalTarget: Target IMPORTED_GLOBAL is 'TRUE' +-- ImportedLocalTarget: Target IMPORTED_GLOBAL is 'TRUE' +-- ImportedLocalTarget: Target IMPORTED_GLOBAL is 'TRUE' +-- NonImportedTarget: Target IMPORTED_GLOBAL is 'FALSE' +-- NonImportedTarget: Target IMPORTED_GLOBAL is 'FALSE' +-- ImportedLocalTarget2: Target IMPORTED_GLOBAL is 'FALSE' +-- ImportedLocalTarget2: Target IMPORTED_GLOBAL is 'TRUE' +-- ImportedSubdirTarget1: Target IMPORTED_GLOBAL is 'TRUE' +-- ImportedSubdirTarget2: Target IMPORTED_GLOBAL is 'TRUE' +-- ImportedSubdirTarget1: Target IMPORTED_GLOBAL is 'TRUE' +-- ImportedSubdirTarget2: Target IMPORTED_GLOBAL is 'TRUE' diff --git a/Tests/RunCMake/set_property/IMPORTED_GLOBAL.cmake b/Tests/RunCMake/set_property/IMPORTED_GLOBAL.cmake new file mode 100644 index 0000000..08308eb --- /dev/null +++ b/Tests/RunCMake/set_property/IMPORTED_GLOBAL.cmake @@ -0,0 +1,53 @@ +macro(print_property TARGET PROP) + get_property(val TARGET ${TARGET} PROPERTY ${PROP}) + message(STATUS "${TARGET}: Target ${PROP} is '${val}'") +endmacro() + +# Changing property on IMPORTED target created with `GLOBAL` option. +add_library(ImportedGlobalTarget SHARED IMPORTED GLOBAL) +print_property(ImportedGlobalTarget IMPORTED_GLOBAL) +set_property(TARGET ImportedGlobalTarget PROPERTY IMPORTED_GLOBAL FALSE) +print_property(ImportedGlobalTarget IMPORTED_GLOBAL) +set_property(TARGET ImportedGlobalTarget PROPERTY IMPORTED_GLOBAL TRUE) +print_property(ImportedGlobalTarget IMPORTED_GLOBAL) +set_property(TARGET ImportedGlobalTarget PROPERTY IMPORTED_GLOBAL TRUE) +print_property(ImportedGlobalTarget IMPORTED_GLOBAL) +# Appending property is never allowed! +set_property(TARGET ImportedGlobalTarget APPEND PROPERTY IMPORTED_GLOBAL TRUE) +print_property(ImportedGlobalTarget IMPORTED_GLOBAL) + +# Changing property on IMPORTED target created without `GLOBAL` option. +add_library(ImportedLocalTarget SHARED IMPORTED) +print_property(ImportedLocalTarget IMPORTED_GLOBAL) +set_property(TARGET ImportedLocalTarget PROPERTY IMPORTED_GLOBAL TRUE) +print_property(ImportedLocalTarget IMPORTED_GLOBAL) +set_property(TARGET ImportedLocalTarget PROPERTY IMPORTED_GLOBAL TRUE) +print_property(ImportedLocalTarget IMPORTED_GLOBAL) +set_property(TARGET ImportedLocalTarget PROPERTY IMPORTED_GLOBAL FALSE) +print_property(ImportedLocalTarget IMPORTED_GLOBAL) + +# Setting property on non-IMPORTED target is never allowed! +add_library(NonImportedTarget SHARED test.cpp) +print_property(NonImportedTarget IMPORTED_GLOBAL) +set_property(TARGET NonImportedTarget PROPERTY IMPORTED_GLOBAL TRUE) +print_property(NonImportedTarget IMPORTED_GLOBAL) + +# Local IMPORTED targets can only be promoted from same directory! +add_library(ImportedLocalTarget2 SHARED IMPORTED) +print_property(ImportedLocalTarget2 IMPORTED_GLOBAL) +add_subdirectory(IMPORTED_GLOBAL) +# Note: The value should not have changed. However, it does change because the +# check for the same directory comes after it was changed! (At least, that is +# not really bad because the generation will fail due to this error.) +print_property(ImportedLocalTarget2 IMPORTED_GLOBAL) + +# Global IMPORTED targets from subdir are always visible +# no matter how they became global. +print_property(ImportedSubdirTarget1 IMPORTED_GLOBAL) +print_property(ImportedSubdirTarget2 IMPORTED_GLOBAL) + +# Changing property on IMPORTED target from subdir is never possible. +set_property(TARGET ImportedSubdirTarget1 PROPERTY IMPORTED_GLOBAL FALSE) +print_property(ImportedSubdirTarget1 IMPORTED_GLOBAL) +set_property(TARGET ImportedSubdirTarget2 PROPERTY IMPORTED_GLOBAL FALSE) +print_property(ImportedSubdirTarget2 IMPORTED_GLOBAL) diff --git a/Tests/RunCMake/set_property/IMPORTED_GLOBAL/CMakeLists.txt b/Tests/RunCMake/set_property/IMPORTED_GLOBAL/CMakeLists.txt new file mode 100644 index 0000000..468bf78 --- /dev/null +++ b/Tests/RunCMake/set_property/IMPORTED_GLOBAL/CMakeLists.txt @@ -0,0 +1,8 @@ +add_library(ImportedSubdirTarget1 SHARED IMPORTED GLOBAL) +add_library(ImportedSubdirTarget2 SHARED IMPORTED) + +# Extend visibility of ImportedSubdirTarget2 to global scope. +set_property(TARGET ImportedSubdirTarget2 PROPERTY IMPORTED_GLOBAL TRUE) + +# Only targets from the same directory can be promoted. +set_property(TARGET ImportedLocalTarget2 PROPERTY IMPORTED_GLOBAL TRUE) diff --git a/Tests/RunCMake/set_property/RunCMakeTest.cmake b/Tests/RunCMake/set_property/RunCMakeTest.cmake index 1ddacee..5b5327d 100644 --- a/Tests/RunCMake/set_property/RunCMakeTest.cmake +++ b/Tests/RunCMake/set_property/RunCMakeTest.cmake @@ -3,6 +3,7 @@ include(RunCMake) run_cmake(COMPILE_DEFINITIONS) run_cmake(COMPILE_FEATURES) run_cmake(COMPILE_OPTIONS) +run_cmake(IMPORTED_GLOBAL) run_cmake(INCLUDE_DIRECTORIES) run_cmake(LINK_LIBRARIES) run_cmake(SOURCES) diff --git a/Tests/RunCMake/set_property/test.cpp b/Tests/RunCMake/set_property/test.cpp new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Tests/RunCMake/set_property/test.cpp @@ -311,6 +311,7 @@ CMAKE_CXX_SOURCES="\ cmFindProgramCommand \ cmForEachCommand \ cmFunctionCommand \ + cmFSPermissions \ cmGeneratedFileStream \ cmGeneratorExpression \ cmGeneratorExpressionContext \ |