diff options
246 files changed, 2885 insertions, 607 deletions
diff --git a/.gitlab/ci/configure_fedora34_ninja.cmake b/.gitlab/ci/configure_fedora34_ninja.cmake index 37bc189..629f792 100644 --- a/.gitlab/ci/configure_fedora34_ninja.cmake +++ b/.gitlab/ci/configure_fedora34_ninja.cmake @@ -1,6 +1,10 @@ set(CMake_TEST_ISPC "ON" CACHE STRING "") set(CMake_TEST_GUI "ON" CACHE BOOL "") +# "Release" flags without "-DNDEBUG" so we get assertions. +set(CMAKE_C_FLAGS_RELEASE "-O3" CACHE STRING "") +set(CMAKE_CXX_FLAGS_RELEASE "-O3" CACHE STRING "") + # Cover compilation with C++11 only and not higher standards. set(CMAKE_CXX_STANDARD "11" CACHE STRING "") diff --git a/.gitlab/os-linux.yml b/.gitlab/os-linux.yml index c831530..90c10a2 100644 --- a/.gitlab/os-linux.yml +++ b/.gitlab/os-linux.yml @@ -131,6 +131,7 @@ variables: CMAKE_CONFIGURATION: fedora34_ninja + CMAKE_CI_BUILD_TYPE: Release CTEST_NO_WARNINGS_ALLOWED: 1 .fedora34_ninja_multi: diff --git a/.gitlab/os-macos.yml b/.gitlab/os-macos.yml index 66bbbf3..b0844cb 100644 --- a/.gitlab/os-macos.yml +++ b/.gitlab/os-macos.yml @@ -7,7 +7,7 @@ GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci ext/$CI_CONCURRENT_ID" # TODO: Factor this out so that each job selects the Xcode version to # use so that different versions can be tested in a single pipeline. - DEVELOPER_DIR: "/Applications/Xcode-13.1.app/Contents/Developer" + DEVELOPER_DIR: "/Applications/Xcode-13.2.app/Contents/Developer" # Avoid conflicting with other projects running on the same machine. SCCACHE_SERVER_PORT: 4227 @@ -87,7 +87,7 @@ - cmake # Since this is a bare runner, pin to a project. - macos - shell - - xcode-13.1 + - xcode-13.2 - nonconcurrent .macos_x86_64_builder_tags_package: @@ -95,7 +95,7 @@ - cmake # Since this is a bare runner, pin to a project. - macos - shell - - xcode-13.1 + - xcode-13.2 - nonconcurrent - finder @@ -104,7 +104,7 @@ - cmake # Since this is a bare runner, pin to a project. - macos - shell - - xcode-13.1 + - xcode-13.2 - concurrent .macos_arm64_builder_tags: @@ -112,7 +112,7 @@ - cmake # Since this is a bare runner, pin to a project. - macos-arm64 - shell - - xcode-13.1 + - xcode-13.2 - nonconcurrent .macos_arm64_builder_ext_tags: @@ -120,7 +120,7 @@ - cmake # Since this is a bare runner, pin to a project. - macos-arm64 - shell - - xcode-13.1 + - xcode-13.2 - concurrent ## macOS-specific scripts diff --git a/CMakeLists.txt b/CMakeLists.txt index 428b040..b2ab30e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -655,7 +655,7 @@ macro (CMAKE_BUILD_UTILITIES) if(WIN32) find_package(LibUV 1.38.0) else() - find_package(LibUV 1.10.0) + find_package(LibUV 1.28.0) endif() if(NOT LIBUV_FOUND) message(FATAL_ERROR diff --git a/Help/command/string.rst b/Help/command/string.rst index 29ad082..9b707eb 100644 --- a/Help/command/string.rst +++ b/Help/command/string.rst @@ -490,6 +490,9 @@ specifiers: ``%S`` The second of the current minute. 60 represents a leap second. (00-60) +``%f`` + The microsecond of the current second (000000-999999). + ``%U`` The week number of the current year (00-53). diff --git a/Help/command/target_include_directories.rst b/Help/command/target_include_directories.rst index 3e53b2e..3fc7926 100644 --- a/Help/command/target_include_directories.rst +++ b/Help/command/target_include_directories.rst @@ -27,9 +27,8 @@ The following arguments specify include directories. .. versionadded:: 3.11 Allow setting ``INTERFACE`` items on :ref:`IMPORTED targets <Imported Targets>`. -Specified include directories may be absolute paths or relative paths. -Repeated calls for the same <target> append items in the order called. If -``SYSTEM`` is specified, the compiler will be told the +Repeated calls for the same ``<target>`` append items in the order called. +If ``SYSTEM`` is specified, the compiler will be told the directories are meant as system include directories on some platforms (signalling this setting might achieve effects such as the compiler skipping warnings, or these fixed-install system files not being @@ -43,12 +42,22 @@ with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)` manual for available expressions. See the :manual:`cmake-buildsystem(7)` manual for more on defining buildsystem properties. +Specified include directories may be absolute paths or relative paths. +A relative path will be interpreted as relative to the current source +directory (i.e. :variable:`CMAKE_CURRENT_SOURCE_DIR`) and converted to an +absolute path before storing it in the associated target property. +If the path starts with a generator expression, it will always be assumed +to be an absolute path (with one exception noted below) and will be used +unmodified. + Include directories usage requirements commonly differ between the build-tree -and the install-tree. The ``BUILD_INTERFACE`` and ``INSTALL_INTERFACE`` -generator expressions can be used to describe separate usage requirements -based on the usage location. Relative paths are allowed within the -``INSTALL_INTERFACE`` expression and are interpreted relative to the -installation prefix. For example: +and the install-tree. The :genex:`BUILD_INTERFACE` and +:genex:`INSTALL_INTERFACE` generator expressions can be used to describe +separate usage requirements based on the usage location. Relative paths +are allowed within the :genex:`INSTALL_INTERFACE` expression and are +interpreted as relative to the installation prefix. Relative paths should not +be used in :genex:`BUILD_INTERFACE` expressions because they will not be +converted to absolute. For example: .. code-block:: cmake diff --git a/Help/command/try_compile.rst b/Help/command/try_compile.rst index 06da910..08f8d5b 100644 --- a/Help/command/try_compile.rst +++ b/Help/command/try_compile.rst @@ -19,10 +19,6 @@ Try Compiling Whole Projects Try building a project. The success or failure of the ``try_compile``, i.e. ``TRUE`` or ``FALSE`` respectively, is returned in ``<resultVar>``. -.. versionadded:: 3.14 - The name of the ``<resultVar>`` is defined by the user. Previously, it had - a fixed name ``RESULT_VAR``. - In this form, ``<srcdir>`` should contain a complete CMake project with a ``CMakeLists.txt`` file and all sources. The ``<bindir>`` and ``<srcdir>`` will not be deleted after this command is run. Specify ``<targetName>`` to @@ -51,10 +47,6 @@ Try building an executable or static library from one or more source files variable). The success or failure of the ``try_compile``, i.e. ``TRUE`` or ``FALSE`` respectively, is returned in ``<resultVar>``. -.. versionadded:: 3.14 - The name of the ``<resultVar>`` is defined by the user. Previously, it had - a fixed name ``RESULT_VAR``. - In this form, one or more source files must be provided. If :variable:`CMAKE_TRY_COMPILE_TARGET_TYPE` is unset or is set to ``EXECUTABLE``, the sources must include a definition for ``main`` and CMake will create a diff --git a/Help/command/try_run.rst b/Help/command/try_run.rst index 404de98..fc41cdd 100644 --- a/Help/command/try_run.rst +++ b/Help/command/try_run.rst @@ -30,11 +30,6 @@ executable was built, but failed to run, then ``<runResultVar>`` will be set to ``FAILED_TO_RUN``. See the :command:`try_compile` command for information on how the test project is constructed to build the source file. -.. versionadded:: 3.14 - The names of the result variables ``<runResultVar>`` and - ``<compileResultVar>`` are defined by the user. Previously, they had - fixed names ``RUN_RESULT_VAR`` and ``COMPILE_RESULT_VAR``. - The options are: ``CMAKE_FLAGS <flags>...`` diff --git a/Help/include/INTERFACE_INCLUDE_DIRECTORIES_WARNING.txt b/Help/include/INTERFACE_INCLUDE_DIRECTORIES_WARNING.txt index a54d728..73e1907 100644 --- a/Help/include/INTERFACE_INCLUDE_DIRECTORIES_WARNING.txt +++ b/Help/include/INTERFACE_INCLUDE_DIRECTORIES_WARNING.txt @@ -1,11 +1,11 @@ -Note that it is not advisable to populate the ``INSTALL_INTERFACE`` of the -|INTERFACE_PROPERTY_LINK| of a target with absolute paths to the include +Note that it is not advisable to populate the :genex:`INSTALL_INTERFACE` of +the |INTERFACE_PROPERTY_LINK| of a target with absolute paths to the include directories of dependencies. That would hard-code into installed packages the include directory paths for dependencies **as found on the machine the package was made on**. -The ``INSTALL_INTERFACE`` of the |INTERFACE_PROPERTY_LINK| is only +The :genex:`INSTALL_INTERFACE` of the |INTERFACE_PROPERTY_LINK| is only suitable for specifying the required include directories for headers provided with the target itself, not those provided by the transitive dependencies listed in its :prop_tgt:`INTERFACE_LINK_LIBRARIES` target diff --git a/Help/manual/cmake-presets.7.rst b/Help/manual/cmake-presets.7.rst index e702d97..31bd9c0 100644 --- a/Help/manual/cmake-presets.7.rst +++ b/Help/manual/cmake-presets.7.rst @@ -474,6 +474,42 @@ that may contain the following fields: An optional bool. If true, equivalent to passing ``--clean-first`` on the command line. +``resolvePackageReferences`` + + An optional string that specifies the package resolve mode. This is + allowed in preset files specifying version ``4`` or above. + + This field overwrites the ``--resolve-package-references`` command line + parameter. If there are no targets that define package references, this + option does nothing. Valid values are: + + ``on`` + + Causes package references to be resolved before attempting a build. + + ``off`` + + Package references will not be resolved. Note that this may cause + errors in some build environments, such as .NET SDK style projects. + + ``only`` + + Only resolve package references, but do not perform a build. + + .. note:: + + If this setting is not specified in a preset, CMake will instead + use the setting specified by the ``--resolve-package-references`` + command line parameter. If the command line parameter is not + provided either, an environment-specific cache variable will be + evaluated to decide, if package restoration should be performed. + + When using the Visual Studio generator, package references are + defined using the :prop_tgt:`VS_PACKAGE_REFERENCES` property. + Package references are restored using NuGet. It can be disabled + by setting the ``CMAKE_VS_NUGET_PACKAGE_RESTORE`` variable to + ``OFF``. This can also be done from within a configure preset. + ``verbose`` An optional bool. If true, equivalent to passing ``--verbose`` on the diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index ddb917a..f4efd3c 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst @@ -266,6 +266,8 @@ Properties on Targets /prop_tgt/INTERFACE_LINK_DEPENDS /prop_tgt/INTERFACE_LINK_DIRECTORIES /prop_tgt/INTERFACE_LINK_LIBRARIES + /prop_tgt/INTERFACE_LINK_LIBRARIES_DIRECT + /prop_tgt/INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE /prop_tgt/INTERFACE_LINK_OPTIONS /prop_tgt/INTERFACE_POSITION_INDEPENDENT_CODE /prop_tgt/INTERFACE_PRECOMPILE_HEADERS diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 920bfe0..04c5a53 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -119,6 +119,7 @@ Variables that Provide Information /variable/CMAKE_VS_DEVENV_COMMAND /variable/CMAKE_VS_MSBUILD_COMMAND /variable/CMAKE_VS_NsightTegra_VERSION + /variable/CMAKE_VS_NUGET_PACKAGE_RESTORE /variable/CMAKE_VS_PLATFORM_NAME /variable/CMAKE_VS_PLATFORM_NAME_DEFAULT /variable/CMAKE_VS_PLATFORM_TOOLSET diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst index 04e2eda..1463f0a 100644 --- a/Help/manual/cmake.1.rst +++ b/Help/manual/cmake.1.rst @@ -463,6 +463,30 @@ following options: Build target ``clean`` first, then build. (To clean only, use ``--target clean``.) +``--resolve-package-references=<on|off|only>`` + .. versionadded:: 3.23 + + Resolve remote package references (e.g. NuGet packages) before build. + When set to ``on`` (default), packages will be restored before building a + target. When set to ``only``, the packages will be restored, but no build + will be performed. When set to ``off``, no packages will be restored. + + If the target does not define any package references, this option does + nothing. + + This setting can be specified in a build preset (using + ``resolvePackageReferences``). In this case, the command line option will + be ignored. + + If the no command line parameter or preset option is not provided, an + environment-specific cache variable will be evaluated to decide, if package + restoration should be performed. + + When using the Visual Studio generator, package references are defined + using the :prop_tgt:`VS_PACKAGE_REFERENCES` property. Package references + are restored using NuGet. It can be disabled by setting the + ``CMAKE_VS_NUGET_PACKAGE_RESTORE`` variable to ``OFF``. + ``--use-stderr`` Ignored. Behavior is default in CMake >= 3.0. diff --git a/Help/manual/presets/schema.json b/Help/manual/presets/schema.json index 327291d..12f8b5e 100644 --- a/Help/manual/presets/schema.json +++ b/Help/manual/presets/schema.json @@ -52,7 +52,7 @@ "cmakeMinimumRequired": { "$ref": "#/definitions/cmakeMinimumRequired"}, "vendor": { "$ref": "#/definitions/vendor" }, "configurePresets": { "$ref": "#/definitions/configurePresetsV3"}, - "buildPresets": { "$ref": "#/definitions/buildPresetsV3"}, + "buildPresets": { "$ref": "#/definitions/buildPresetsV4"}, "testPresets": { "$ref": "#/definitions/testPresetsV3"}, "include": { "$ref": "#/definitions/include"} }, @@ -427,9 +427,25 @@ "additionalProperties": false } }, + "buildPresetsItemsV4": { + "type": "array", + "description": "An optional array of build preset objects. Used to specify arguments to cmake --build. Available in version 4 and higher.", + "items": { + "type": "object", + "properties": { + "resolvePackageReferences": { + "type": "string", + "description": "An optional string specifying the package resolve behavior. Valid values are \"on\" (packages are resolved prior to the build), \"off\" (packages are not resolved prior to the build), and \"only\" (packages are resolved, but no build will be performed).", + "enum": [ + "on", "off", "only" + ] + } + } + } + }, "buildPresetsItemsV3": { "type": "array", - "description": "An optional array of build preset objects. Used to specify arguments to cmake --build. Available in version 2 and higher.", + "description": "An optional array of build preset objects. Used to specify arguments to cmake --build. Available in version 3 and higher.", "items": { "type": "object", "properties": { @@ -558,9 +574,44 @@ ] } }, + "buildPresetsV4": { + "type": "array", + "description": "An optional array of build preset objects. Used to specify arguments to cmake --build. Available in version 4 and higher.", + "allOf": [ + { "$ref": "#/definitions/buildPresetsItemsV4" }, + { "$ref": "#/definitions/buildPresetsItemsV3" }, + { "$ref": "#/definitions/buildPresetsItemsV2" } + ], + "items": { + "type": "object", + "properties": { + "name": {}, + "hidden": {}, + "inherits": {}, + "configurePreset": {}, + "vendor": {}, + "displayName": {}, + "description": {}, + "inheritConfigureEnvironment": {}, + "environment": {}, + "jobs": {}, + "targets": {}, + "configuration": {}, + "cleanFirst": {}, + "resolvePackageReferences": {}, + "verbose": {}, + "nativeToolOptions": {}, + "condition": {} + }, + "required": [ + "name" + ], + "additionalProperties": false + } + }, "buildPresetsV3": { "type": "array", - "description": "An optional array of build preset objects. Used to specify arguments to cmake --build. Available in version 2 and higher.", + "description": "An optional array of build preset objects. Used to specify arguments to cmake --build. Available in version 3 and higher.", "allOf": [ { "$ref": "#/definitions/buildPresetsItemsV3" }, { "$ref": "#/definitions/buildPresetsItemsV2" } @@ -624,7 +675,7 @@ }, "testPresetsItemsV3": { "type": "array", - "description": "An optional array of test preset objects. Used to specify arguments to ctest. Available in version 2 and higher.", + "description": "An optional array of test preset objects. Used to specify arguments to ctest. Available in version 3 and higher.", "items": { "type": "object", "properties": { @@ -949,7 +1000,7 @@ }, "testPresetsV3": { "type": "array", - "description": "An optional array of test preset objects. Used to specify arguments to ctest. Available in version 2 and higher.", + "description": "An optional array of test preset objects. Used to specify arguments to ctest. Available in version 3 and higher.", "allOf": [ { "$ref": "#/definitions/testPresetsItemsV2" }, { "$ref": "#/definitions/testPresetsItemsV3" } diff --git a/Help/prop_tgt/INTERFACE_LINK_LIBRARIES.rst b/Help/prop_tgt/INTERFACE_LINK_LIBRARIES.rst index bf7f72f..53f5838 100644 --- a/Help/prop_tgt/INTERFACE_LINK_LIBRARIES.rst +++ b/Help/prop_tgt/INTERFACE_LINK_LIBRARIES.rst @@ -12,6 +12,13 @@ other target also. This property is overridden by the :prop_tgt:`LINK_INTERFACE_LIBRARIES_<CONFIG>` property if policy :policy:`CMP0022` is ``OLD`` or unset. +The value of this property is used by the generators when constructing +the link rule for a dependent target. A dependent target's direct +link dependencies, specified by its :prop_tgt:`LINK_LIBRARIES` target +property, are linked first, followed by indirect dependencies from the +transitive closure of the direct dependencies' +``INTERFACE_LINK_LIBRARIES`` properties. See policy :policy:`CMP0022`. + Contents of ``INTERFACE_LINK_LIBRARIES`` may use "generator expressions" with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)` manual for available expressions. See the :manual:`cmake-buildsystem(7)` @@ -19,6 +26,12 @@ manual for more on defining buildsystem properties. .. include:: LINK_LIBRARIES_INDIRECTION.txt +``INTERFACE_LINK_LIBRARIES`` adds transitive link dependencies for a +target's dependents. In advanced use cases, one may update the +direct link dependencies of a target's dependents by using the +:prop_tgt:`INTERFACE_LINK_LIBRARIES_DIRECT` and +:prop_tgt:`INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE` target properties. + Creating Relocatable Packages ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/Help/prop_tgt/INTERFACE_LINK_LIBRARIES_DIRECT.rst b/Help/prop_tgt/INTERFACE_LINK_LIBRARIES_DIRECT.rst new file mode 100644 index 0000000..1a6ebd1 --- /dev/null +++ b/Help/prop_tgt/INTERFACE_LINK_LIBRARIES_DIRECT.rst @@ -0,0 +1,221 @@ +INTERFACE_LINK_LIBRARIES_DIRECT +------------------------------- + +List of libraries that consumers of this library should treat +as direct link dependencies. + +This target property may be set to *include* items in a dependent +target's final set of direct link dependencies. See the +:prop_tgt:`INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE` target property +to exclude items. + +The initial set of a dependent target's direct link dependencies is +specified by its :prop_tgt:`LINK_LIBRARIES` target property. Indirect +link dependencies are specified by the transitive closure of the direct +link dependencies' :prop_tgt:`INTERFACE_LINK_LIBRARIES` properties. +Any link dependency may specify additional direct link dependencies +using the ``INTERFACE_LINK_LIBRARIES_DIRECT`` target property. +The set of direct link dependencies is then filtered to exclude items named +by any dependency's :prop_tgt:`INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE` +target property. + +.. |INTERFACE_PROPERTY_LINK_DIRECT| replace:: ``INTERFACE_LINK_LIBRARIES_DIRECT`` +.. include:: INTERFACE_LINK_LIBRARIES_DIRECT.txt + +Direct Link Dependencies as Usage Requirements +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The ``INTERFACE_PROPERTY_LINK_DIRECT`` and +``INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE`` target properties +are :ref:`usage requirements <Target Usage Requirements>`. +Their effects propagate to dependent targets transitively, and can +therefore affect the direct link dependencies of every target in a +chain of dependent libraries. Whenever some library target ``X`` links +to another library target ``Y`` whose direct or transitive usage +requirements contain ``INTERFACE_PROPERTY_LINK_DIRECT`` or +``INTERFACE_PROPERTY_LINK_DIRECT_EXCLUDE``, the properties may affect +``X``'s list of direct link dependencies: + +* If ``X`` is a shared library or executable, its dependencies are linked. + They also affect the usage requirements with which ``X``'s sources are + compiled. + +* If ``X`` is a static library or object library, it does not actually + link, so its dependencies at most affect the usage requirements with + which ``X``'s sources are compiled. + +The properties may also affect the list of direct link dependencies +on ``X``'s dependents: + +* If ``X`` links ``Y`` publicly: + + .. code-block:: cmake + + target_link_libraries(X PUBLIC Y) + + then ``Y`` is placed in ``X``'s :prop_tgt:`INTERFACE_LINK_LIBRARIES`, + so ``Y``'s usage requirements, including ``INTERFACE_PROPERTY_LINK_DIRECT`` + and ``INTERFACE_PROPERTY_LINK_DIRECT_EXCLUDE``, are propagated + to ``X``'s dependents. + +* If ``X`` links ``Y`` privately: + + .. code-block:: cmake + + target_link_libraries(X PRIVATE Y) + + then ``Y`` is not placed in ``X``'s :prop_tgt:`INTERFACE_LINK_LIBRARIES`, + so ``Y``'s usage requirements, even ``INTERFACE_PROPERTY_LINK_DIRECT`` + and ``INTERFACE_PROPERTY_LINK_DIRECT_EXCLUDE``, are not propagated + to ``X``'s dependents. + (If ``X`` is a static library or object library, then ``$<LINK_ONLY:Y>`` + is placed in ``X``'s :prop_tgt:`INTERFACE_LINK_LIBRARIES`, but the + :genex:`LINK_ONLY` generator expression block ``Y``'s usage requirements.) + +* In either case, the content of ``X``'s :prop_tgt:`INTERFACE_LINK_LIBRARIES` + is not affected by ``Y``'s ``INTERFACE_PROPERTY_LINK_DIRECT`` or + ``INTERFACE_PROPERTY_LINK_DIRECT_EXCLUDE``. + +One may limit the effects of ``INTERFACE_PROPERTY_LINK_DIRECT`` and +``INTERFACE_PROPERTY_LINK_DIRECT_EXCLUDE`` to a subset of dependent +targets by using the :genex:`TARGET_PROPERTY` generator expression. +For example, to limit the effects to executable targets, use an +entry of the form:: + + "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:...>" + +Similarly, to limit the effects to specific targets, use an entry +of the form:: + + "$<$<BOOL:$<TARGET_PROPERTY:USE_IT>>:...>" + +This entry will only affect targets that set their ``USE_IT`` +target property to a true value. + +Direct Link Dependency Ordering +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The list of direct link dependencies for a target is computed from an +initial ordered list in its :prop_tgt:`LINK_LIBRARIES` target property. +For each item, additional direct link dependencies are discovered from +its direct and transitive ``INTERFACE_LINK_LIBRARIES_DIRECT`` usage +requirements. Each discovered item is injected before the item that +specified it. However, a discovered item is added at most once, +and only if it did not appear anywhere in the initial list. +This gives :prop_tgt:`LINK_LIBRARIES` control over ordering of +those direct link dependencies that it explicitly specifies. + +Once all direct link dependencies have been collected, items named by +all of their :prop_tgt:`INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE` +usage requirements are removed from the final list. This does not +affect the order of the items that remain. + +Example: Static Plugins +^^^^^^^^^^^^^^^^^^^^^^^ + +Consider a static library ``Foo`` that provides a static plugin +``FooPlugin`` to consuming application executables, where the +implementation of the plugin depends on ``Foo`` and other things. +In this case, the application should link to ``FooPlugin`` directly, +before ``Foo``. However, the application author only knows about ``Foo``. +We can express this as follows: + +.. code-block:: cmake + + # Core library used by other components. + add_library(Core STATIC core.cpp) + + # Foo is a static library for use by applications. + # Implementation of Foo depends on Core. + add_library(Foo STATIC foo.cpp foo_plugin_helper.cpp) + target_link_libraries(Foo PRIVATE Core) + + # Extra parts of Foo for use by its static plugins. + # Implementation of Foo's extra parts depends on both Core and Foo. + add_library(FooExtras STATIC foo_extras.cpp) + target_link_libraries(FooExtras PRIVATE Core Foo) + + # The Foo library has an associated static plugin + # that should be linked into the final executable. + # Implementation of the plugin depends on Core, Foo, and FooExtras. + add_library(FooPlugin STATIC foo_plugin.cpp) + target_link_libraries(FooPlugin PRIVATE Core Foo FooExtras) + + # An app that links Foo should link Foo's plugin directly. + set_property(TARGET Foo PROPERTY INTERFACE_LINK_LIBRARIES_DIRECT FooPlugin) + + # An app does not need to link Foo directly because the plugin links it. + set_property(TARGET Foo PROPERTY INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE Foo) + +An application ``app`` only needs to specify that it links to ``Foo``: + +.. code-block:: cmake + + add_executable(app main.cpp) + target_link_libraries(app PRIVATE Foo) + +The ``INTERFACE_LINK_LIBRARIES_DIRECT`` target property on ``Foo`` tells +CMake to pretend that ``app`` also links directly to ``FooPlugin``. +The ``INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE`` target property on ``Foo`` +tells CMake to pretend that ``app`` did *not* link directly to ``Foo``. +Instead, ``Foo`` will be linked as a dependency of ``FooPlugin``. The +final link line for ``app`` will link the libraries in the following +order: + +* ``FooPlugin`` as a direct link dependency of ``app`` + (via ``Foo``'s usage requiremens). +* ``FooExtras`` as a dependency of ``FooPlugin``. +* ``Foo`` as a dependency of ``FooPlugin`` and ``FooExtras``. +* ``Core`` as a dependency of ``FooPlugin``, ``FooExtras``, and ``Foo``. + +Note that without the ``INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE`` target +property, ``Foo`` would be linked twice: once as a direct dependency +of ``app``, and once as a dependency of ``FooPlugin``. + +Example: Opt-In Static Plugins +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +In the above `Example: Static Plugins`_, the ``app`` executable specifies +that it links directly to ``Foo``. In a real application, there might +be an intermediate library: + +.. code-block:: cmake + + add_library(app_impl STATIC app_impl.cpp) + target_link_libraries(app_impl PUBLIC Foo) + + add_executable(app main.cpp) + target_link_libraries(app PRIVATE app_impl) + +In this case we do not want ``Foo``'s ``INTERFACE_LINK_LIBRARIES_DIRECT`` +and ``INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE`` target properties to affect +the direct dependencies of ``app_impl``. To avoid this, we can revise +the property values to make their effects opt-in: + +.. code-block:: cmake + + # An app that links Foo should link Foo's plugin directly. + set_property(TARGET Foo PROPERTY INTERFACE_LINK_LIBRARIES_DIRECT + "$<$<BOOL:$<TARGET_PROPERTY:FOO_STATIC_PLUGINS>>:FooPlugin>" + ) + + # An app does not need to link Foo directly because the plugin links it. + set_property(TARGET Foo PROPERTY INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE + "$<$<BOOL:$<TARGET_PROPERTY:FOO_STATIC_PLUGINS>>:Foo>" + ) + +Now, the ``app`` executable can opt-in to get ``Foo``'s plugin(s): + +.. code-block:: cmake + + set_property(TARGET app PROPERTY FOO_STATIC_PLUGINS 1) + +The final link line for ``app`` will now link the libraries in the following +order: + +* ``FooPlugin`` as a direct link dependency of ``app`` + (via ``Foo``'s usage requiremens). +* ``app_impl`` as a direct link dependency of ``app``. +* ``FooExtras`` as a dependency of ``FooPlugin``. +* ``Foo`` as a dependency of ``app_impl``, ``FooPlugin``, and ``FooExtras``. +* ``Core`` as a dependency of ``FooPlugin``, ``FooExtras``, and ``Foo``. diff --git a/Help/prop_tgt/INTERFACE_LINK_LIBRARIES_DIRECT.txt b/Help/prop_tgt/INTERFACE_LINK_LIBRARIES_DIRECT.txt new file mode 100644 index 0000000..077af42 --- /dev/null +++ b/Help/prop_tgt/INTERFACE_LINK_LIBRARIES_DIRECT.txt @@ -0,0 +1,9 @@ +The value of |INTERFACE_PROPERTY_LINK_DIRECT| may use +:manual:`generator expressions <cmake-generator-expressions(7)>`. + +.. note:: + + The |INTERFACE_PROPERTY_LINK_DIRECT| target property is intended for + advanced use cases such as injection of static plugins into a consuming + executable. It should not be used as a substitute for organizing + normal calls to :command:`target_link_libraries`. diff --git a/Help/prop_tgt/INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE.rst b/Help/prop_tgt/INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE.rst new file mode 100644 index 0000000..ecab8a0 --- /dev/null +++ b/Help/prop_tgt/INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE.rst @@ -0,0 +1,32 @@ +INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE +--------------------------------------- + +List of libraries that consumers of this library should *not* treat +as direct link dependencies. + +This target property may be set to *exclude* items from a dependent +target's final set of direct link dependencies. This property is +processed after the :prop_tgt:`INTERFACE_LINK_LIBRARIES_DIRECT` +target property of all other dependencies of the dependent target, so +exclusion from direct link dependence takes priority over inclusion. + +The initial set of a dependent target's direct link dependencies is +specified by its :prop_tgt:`LINK_LIBRARIES` target property. Indirect +link dependencies are specified by the transitive closure of the direct +link dependencies' :prop_tgt:`INTERFACE_LINK_LIBRARIES` properties. +Any link dependency may specify additional direct link dependencies +using the :prop_tgt:`INTERFACE_LINK_LIBRARIES_DIRECT` target property. +The set of direct link dependencies is then filtered to exclude items named +by any dependency's ``INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE`` target +property. + +Excluding an item from a dependent target's direct link dependencies +does not mean the dependent target won't link the item. The item +may still be linked as an indirect link dependency via the +:prop_tgt:`INTERFACE_LINK_LIBRARIES` property on other dependencies. + +.. |INTERFACE_PROPERTY_LINK_DIRECT| replace:: ``INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE`` +.. include:: INTERFACE_LINK_LIBRARIES_DIRECT.txt + +See the :prop_tgt:`INTERFACE_LINK_LIBRARIES_DIRECT` target property +documentation for more details and examples. diff --git a/Help/prop_tgt/LINKER_LANGUAGE.rst b/Help/prop_tgt/LINKER_LANGUAGE.rst index b0a572b..f47b488 100644 --- a/Help/prop_tgt/LINKER_LANGUAGE.rst +++ b/Help/prop_tgt/LINKER_LANGUAGE.rst @@ -7,8 +7,10 @@ For executables, shared libraries, and modules, this sets the language whose compiler is used to link the target (such as "C" or "CXX"). A typical value for an executable is the language of the source file providing the program entry point (main). If not set, the language -with the highest linker preference value is the default. See -documentation of :variable:`CMAKE_<LANG>_LINKER_PREFERENCE` variables. +with the highest linker preference value is the default. Details of +the linker preferences are considered internal, but some limited +discussion can be found under the internal +:variable:`CMAKE_<LANG>_LINKER_PREFERENCE` variables. If this property is not set by the user, it will be calculated at generate-time by CMake. diff --git a/Help/prop_tgt/LINK_LIBRARIES.rst b/Help/prop_tgt/LINK_LIBRARIES.rst index d88e798..ae5334a 100644 --- a/Help/prop_tgt/LINK_LIBRARIES.rst +++ b/Help/prop_tgt/LINK_LIBRARIES.rst @@ -8,8 +8,11 @@ used for linking. In addition to accepting values from the :command:`target_link_libraries` command, values may be set directly on any target using the :command:`set_property` command. -The value of this property is used by the generators to set the link -libraries for the compiler. +The value of this property is used by the generators to construct the +link rule for the target. The direct link dependencies are linked first, +followed by indirect dependencies from the transitive closure of the +direct dependencies' :prop_tgt:`INTERFACE_LINK_LIBRARIES` properties. +See policy :policy:`CMP0022`. Contents of ``LINK_LIBRARIES`` may use "generator expressions" with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)` manual @@ -17,3 +20,8 @@ for available expressions. See the :manual:`cmake-buildsystem(7)` manual for more on defining buildsystem properties. .. include:: LINK_LIBRARIES_INDIRECTION.txt + +In advanced use cases, the list of direct link dependencies specified +by this property may be updated by usage requirements from dependencies. +See the :prop_tgt:`INTERFACE_LINK_LIBRARIES_DIRECT` and +:prop_tgt:`INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE` target properties. diff --git a/Help/release/3.22.rst b/Help/release/3.22.rst index fcb655d..a82d396 100644 --- a/Help/release/3.22.rst +++ b/Help/release/3.22.rst @@ -142,3 +142,16 @@ Other Changes This became available as of VS 16.10 (toolchain version 14.29.30037). * The :cpack_gen:`CPack NSIS Generator` now requires NSIS 3.03 or later. + +3.22.1 +------ + +This version made no changes to documented features or interfaces. +Some implementation updates were made to support ecosystem changes +and/or fix regressions. + +3.22.2 +------ + +* The ``OLD`` behavior of :policy:`CMP0128` was fixed to add flags even when + the specified standard matches the compiler default. diff --git a/Help/release/dev/cuda-compiler-detection-robustness.rst b/Help/release/dev/cuda-compiler-detection-robustness.rst new file mode 100644 index 0000000..cc49a8d --- /dev/null +++ b/Help/release/dev/cuda-compiler-detection-robustness.rst @@ -0,0 +1,11 @@ +cuda-compiler-detection-robustness +---------------------------------- + +* CUDA compiler detection now issues an error in all cases when it's unable to + compute the default architecture(s) if required (see :policy:`CMP0104`). + +* CUDA compiler detection now correctly handles ``OFF`` for + :variable:`CMAKE_CUDA_ARCHITECTURES` on Clang. + +* CUDA compiler detection now supports the theoretical case of multiple default + architectures. diff --git a/Help/release/dev/cuda-invalid-architectures.rst b/Help/release/dev/cuda-invalid-architectures.rst new file mode 100644 index 0000000..3313dbb --- /dev/null +++ b/Help/release/dev/cuda-invalid-architectures.rst @@ -0,0 +1,5 @@ +cuda-invalid-architectures +-------------------------- + +* CUDA compiler detection now tries to detect invalid architectures and issue + an error. diff --git a/Help/release/dev/ibmclang-compiler.rst b/Help/release/dev/ibmclang-compiler.rst new file mode 100644 index 0000000..2a9b5ad --- /dev/null +++ b/Help/release/dev/ibmclang-compiler.rst @@ -0,0 +1,5 @@ +ibmclang-compiler +----------------- + +* The IBM Open XL C/C++ compiler, based on LLVM, is now supported with + compiler id ``IBMClang``. diff --git a/Help/release/dev/link-interface-direct.rst b/Help/release/dev/link-interface-direct.rst new file mode 100644 index 0000000..2e9a59e --- /dev/null +++ b/Help/release/dev/link-interface-direct.rst @@ -0,0 +1,7 @@ +link-interface-direct +--------------------- + +* The :prop_tgt:`INTERFACE_LINK_LIBRARIES_DIRECT` and + :prop_tgt:`INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE` target properties + were added to express usage requirements affecting a consumer's + direct link dependencies. diff --git a/Help/release/dev/timestamp-microseconds.rst b/Help/release/dev/timestamp-microseconds.rst new file mode 100644 index 0000000..0c95eb4 --- /dev/null +++ b/Help/release/dev/timestamp-microseconds.rst @@ -0,0 +1,5 @@ +timestamp-microseconds +---------------------- + +* The :command:`string(TIMESTAMP)` and :command:`file(TIMESTAMP)` commands now + support the ``%f`` specifier for microseconds. diff --git a/Help/release/dev/vs-package-restore.rst b/Help/release/dev/vs-package-restore.rst new file mode 100644 index 0000000..e8b5f0c --- /dev/null +++ b/Help/release/dev/vs-package-restore.rst @@ -0,0 +1,13 @@ +vs-package-restore +------------------ + +* Targets with :prop_tgt:`VS_PACKAGE_REFERENCES` will now automatically attempt + to restore the package references from NuGet. The cache variable + :variable:`CMAKE_VS_NUGET_PACKAGE_RESTORE` was added to toggle automatic + package restore off. + +* :manual:`cmake(1)` gained the ``--resolve-package-references=<on|off|only>`` + command-line option to control automatic package restoration. + +* :manual:`cmake-presets(7)` gained support for specifying the + ``resolvePackageReferences`` command line option in a build preset. diff --git a/Help/variable/CMAKE_CURRENT_BINARY_DIR.rst b/Help/variable/CMAKE_CURRENT_BINARY_DIR.rst index 40496b5..8fc85ee 100644 --- a/Help/variable/CMAKE_CURRENT_BINARY_DIR.rst +++ b/Help/variable/CMAKE_CURRENT_BINARY_DIR.rst @@ -3,7 +3,7 @@ CMAKE_CURRENT_BINARY_DIR The path to the binary directory currently being processed. -This the full path to the build directory that is currently being +This is the full path to the build directory that is currently being processed by cmake. Each directory added by :command:`add_subdirectory` will create a binary directory in the build tree, and as it is being processed this variable will be set. For in-source builds this is the diff --git a/Help/variable/CMAKE_CURRENT_SOURCE_DIR.rst b/Help/variable/CMAKE_CURRENT_SOURCE_DIR.rst index c1b755a..1a25efc 100644 --- a/Help/variable/CMAKE_CURRENT_SOURCE_DIR.rst +++ b/Help/variable/CMAKE_CURRENT_SOURCE_DIR.rst @@ -3,7 +3,7 @@ CMAKE_CURRENT_SOURCE_DIR The path to the source directory currently being processed. -This the full path to the source directory that is currently being +This is the full path to the source directory that is currently being processed by cmake. When run in -P script mode, CMake sets the variables diff --git a/Help/variable/CMAKE_LANG_COMPILER_ID.rst b/Help/variable/CMAKE_LANG_COMPILER_ID.rst index 1db42c7..cd7d5cd 100644 --- a/Help/variable/CMAKE_LANG_COMPILER_ID.rst +++ b/Help/variable/CMAKE_LANG_COMPILER_ID.rst @@ -41,6 +41,7 @@ include: TinyCC = Tiny C Compiler (tinycc.org) XL, VisualAge, zOS = IBM XL (ibm.com) XLClang = IBM Clang-based XL (ibm.com) + IBMClang = IBM LLVM-based Compiler (ibm.com) This variable is not guaranteed to be defined for all compilers or languages. diff --git a/Help/variable/CMAKE_VS_NUGET_PACKAGE_RESTORE.rst b/Help/variable/CMAKE_VS_NUGET_PACKAGE_RESTORE.rst new file mode 100644 index 0000000..7160726 --- /dev/null +++ b/Help/variable/CMAKE_VS_NUGET_PACKAGE_RESTORE.rst @@ -0,0 +1,22 @@ +CMAKE_VS_NUGET_PACKAGE_RESTORE +------------------------------ + +.. versionadded:: 3.23 + +When using a Visual Studio generator, this cache variable controls +if msbuild should automatically attempt to restore NuGet packages +prior to a build. NuGet packages can be defined using the +:prop_tgt:`VS_PACKAGE_REFERENCES` property on a target. If no +package references are defined, this setting will do nothing. + +The command line option ``--resolve-package-references`` can be used +alternatively to control the resolve behavior globally. This option +will take precedence over the cache variable. + +Targets that use the :prop_tgt:`DOTNET_SDK` are required to run a +restore before building. Disabling this option may cause the build +to fail in such projects. + +This setting is stored as a cache entry. Default value is ``ON``. + +See also the :prop_tgt:`VS_PACKAGE_REFERENCES` property. diff --git a/Modules/CMakeCCompilerId.c.in b/Modules/CMakeCCompilerId.c.in index 30ad9824..0cb8724 100644 --- a/Modules/CMakeCCompilerId.c.in +++ b/Modules/CMakeCCompilerId.c.in @@ -61,7 +61,7 @@ const char* info_language_standard_default = const char* info_language_extensions_default = "INFO" ":" "extensions_default[" /* !defined(_MSC_VER) to exclude Clang's MSVC compatibility mode. */ -#if (defined(__clang__) || defined(__GNUC__) || \ +#if (defined(__clang__) || defined(__GNUC__) || defined(__xlC__) || \ defined(__TI_COMPILER_VERSION__)) && \ !defined(__STRICT_ANSI__) && !defined(_MSC_VER) "ON" diff --git a/Modules/CMakeCXXCompilerId.cpp.in b/Modules/CMakeCXXCompilerId.cpp.in index e7a5487..4904249 100644 --- a/Modules/CMakeCXXCompilerId.cpp.in +++ b/Modules/CMakeCXXCompilerId.cpp.in @@ -67,7 +67,7 @@ const char* info_language_standard_default = "INFO" ":" "standard_default[" const char* info_language_extensions_default = "INFO" ":" "extensions_default[" /* !defined(_MSC_VER) to exclude Clang's MSVC compatibility mode. */ -#if (defined(__clang__) || defined(__GNUC__) || \ +#if (defined(__clang__) || defined(__GNUC__) || defined(__xlC__) || \ defined(__TI_COMPILER_VERSION__)) && \ !defined(__STRICT_ANSI__) && !defined(_MSC_VER) "ON" diff --git a/Modules/CMakeCompilerIdDetection.cmake b/Modules/CMakeCompilerIdDetection.cmake index 044326c..f15974a 100644 --- a/Modules/CMakeCompilerIdDetection.cmake +++ b/Modules/CMakeCompilerIdDetection.cmake @@ -59,6 +59,7 @@ function(compiler_id_detection outvar lang) HP Compaq zOS + IBMClang XLClang XL VisualAge diff --git a/Modules/CMakeDetermineCUDACompiler.cmake b/Modules/CMakeDetermineCUDACompiler.cmake index df71799..8fe07fe 100644 --- a/Modules/CMakeDetermineCUDACompiler.cmake +++ b/Modules/CMakeDetermineCUDACompiler.cmake @@ -257,7 +257,7 @@ if(NOT CMAKE_CUDA_COMPILER_ID_RUN) endif() # Append user-specified architectures. - if(CMAKE_CUDA_ARCHITECTURES) + if(DEFINED CMAKE_CUDA_ARCHITECTURES) if("x${CMAKE_CUDA_ARCHITECTURES}" STREQUAL "xall") string(APPEND nvcc_test_flags " -arch=all") set(architectures_mode all) @@ -279,11 +279,18 @@ if(NOT CMAKE_CUDA_COMPILER_ID_RUN) set(CMAKE_CUDA_COMPILER_ID_REQUIRE_SUCCESS ON) endif() + # Rest of the code treats an empty value as equivalent to "use the defaults". + # Error out early to prevent confusing errors as a result of this. + # Note that this also catches invalid non-numerical values such as "a". + if(architectures_mode STREQUAL "explicit" AND "${tested_architectures}" STREQUAL "") + message(FATAL_ERROR "CMAKE_CUDA_ARCHITECTURES must be valid if set.") + endif() + if(CMAKE_CUDA_COMPILER_ID STREQUAL "Clang") if(NOT CMAKE_CUDA_ARCHITECTURES) # Clang doesn't automatically select an architecture supported by the SDK. # Try in reverse order of deprecation with the most recent at front (i.e. the most likely to work for new setups). - foreach(arch "20" "30" "52") + foreach(arch "52" "30" "20") list(APPEND CMAKE_CUDA_COMPILER_ID_TEST_FLAGS_FIRST "${clang_test_flags} --cuda-gpu-arch=sm_${arch}") endforeach() endif() @@ -346,18 +353,12 @@ if(${CMAKE_GENERATOR} MATCHES "Visual Studio") set(_SET_CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT "set(CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT \"${CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT}\")") elseif(CMAKE_CUDA_COMPILER_ID STREQUAL "Clang") - if(NOT CMAKE_CUDA_ARCHITECTURES) - # Find the architecture that we successfully compiled using and set it as the default. - string(REGEX MATCH "-target-cpu sm_([0-9]+)" dont_care "${CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT}") - set(detected_architecture "${CMAKE_MATCH_1}") - else() - string(REGEX MATCHALL "-target-cpu sm_([0-9]+)" target_cpus "${CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT}") + string(REGEX MATCHALL "-target-cpu sm_([0-9]+)" target_cpus "${CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT}") - foreach(cpu ${target_cpus}) - string(REGEX MATCH "-target-cpu sm_([0-9]+)" dont_care "${cpu}") - list(APPEND architectures "${CMAKE_MATCH_1}") - endforeach() - endif() + foreach(cpu ${target_cpus}) + string(REGEX MATCH "-target-cpu sm_([0-9]+)" dont_care "${cpu}") + list(APPEND architectures_detected "${CMAKE_MATCH_1}") + endforeach() # Find target directory when crosscompiling. if(CMAKE_CROSSCOMPILING) @@ -583,28 +584,25 @@ if(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA") "Failed to detect CUDA nvcc include information:\n${_nvcc_log}\n\n") endif() - # Parse default CUDA architecture. - cmake_policy(GET CMP0104 _CUDA_CMP0104) - if(NOT CMAKE_CUDA_ARCHITECTURES AND _CUDA_CMP0104 STREQUAL "NEW") - string(REGEX MATCH "arch[ =]compute_([0-9]+)" dont_care "${CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT}") - set(detected_architecture "${CMAKE_MATCH_1}") - elseif(CMAKE_CUDA_ARCHITECTURES) - string(REGEX MATCHALL "-arch compute_([0-9]+)" target_cpus "${CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT}") - - foreach(cpu ${target_cpus}) - string(REGEX MATCH "-arch compute_([0-9]+)" dont_care "${cpu}") - list(APPEND architectures "${CMAKE_MATCH_1}") - endforeach() - endif() + string(REGEX MATCHALL "-arch compute_([0-9]+)" target_cpus "${CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT}") + + foreach(cpu ${target_cpus}) + string(REGEX MATCH "-arch compute_([0-9]+)" dont_care "${cpu}") + list(APPEND architectures_detected "${CMAKE_MATCH_1}") + endforeach() endif() # If the user didn't set the architectures, then set them to a default. # If the user did, then make sure those architectures worked. -if(DEFINED detected_architecture AND "${CMAKE_CUDA_ARCHITECTURES}" STREQUAL "") - set(CMAKE_CUDA_ARCHITECTURES "${detected_architecture}" CACHE STRING "CUDA architectures") +if("${CMAKE_CUDA_ARCHITECTURES}" STREQUAL "") + cmake_policy(GET CMP0104 _CUDA_CMP0104) + + if(NOT CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA" OR _CUDA_CMP0104 STREQUAL "NEW") + set(CMAKE_CUDA_ARCHITECTURES "${architectures_detected}" CACHE STRING "CUDA architectures") - if(NOT CMAKE_CUDA_ARCHITECTURES) - message(FATAL_ERROR "Failed to find a working CUDA architecture.") + if(NOT CMAKE_CUDA_ARCHITECTURES) + message(FATAL_ERROR "Failed to detect a default CUDA architecture.\n\nCompiler output:\n${CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT}") + endif() endif() elseif(architectures AND (architectures_mode STREQUAL "xall" OR architectures_mode STREQUAL "xall-major")) @@ -617,9 +615,9 @@ elseif(architectures AND (architectures_mode STREQUAL "xall" OR "instead.") endif() -elseif(architectures AND architectures_mode STREQUAL "xexplicit") +elseif(architectures_mode STREQUAL "xexplicit") # Sort since order mustn't matter. - list(SORT architectures) + list(SORT architectures_detected) list(SORT tested_architectures) # We don't distinguish real/virtual architectures during testing. @@ -627,12 +625,19 @@ elseif(architectures AND architectures_mode STREQUAL "xexplicit") # Thus we need to remove duplicates before checking if they're equal. list(REMOVE_DUPLICATES tested_architectures) - if(NOT "${architectures}" STREQUAL "${tested_architectures}") + # Print the actual architectures for generic values (all and all-major). + if(NOT DEFINED architectures_explicit) + set(architectures_error "${CMAKE_CUDA_ARCHITECTURES} (${tested_architectures})") + else() + set(architectures_error "${tested_architectures}") + endif() + + if(NOT "${architectures_detected}" STREQUAL "${tested_architectures}") message(FATAL_ERROR "The CMAKE_CUDA_ARCHITECTURES:\n" " ${CMAKE_CUDA_ARCHITECTURES}\n" "do not all work with this compiler. Try:\n" - " ${architectures}\n" + " ${architectures_detected}\n" "instead.") endif() endif() diff --git a/Modules/Compiler/IAR-CXX.cmake b/Modules/Compiler/IAR-CXX.cmake index a3f1dbc..7df74ad 100644 --- a/Modules/Compiler/IAR-CXX.cmake +++ b/Modules/Compiler/IAR-CXX.cmake @@ -16,14 +16,17 @@ endif() # Whenever needed, override this default behavior using CMAKE_IAR_CXX_FLAG in your toolchain file. if(NOT CMAKE_IAR_CXX_FLAG) - set(_CMAKE_IAR_MODERNCXX_LIST 14 17) - if(${CMAKE_CXX_STANDARD_COMPUTED_DEFAULT} IN_LIST _CMAKE_IAR_MODERNCXX_LIST OR + cmake_policy(PUSH) + cmake_policy(SET CMP0057 NEW) # if IN_LIST + + if(${CMAKE_CXX_STANDARD_COMPUTED_DEFAULT} IN_LIST "14;17" OR ("${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}" STREQUAL "ARM" AND ${CMAKE_CXX_STANDARD_COMPUTED_DEFAULT} EQUAL 98)) string(PREPEND CMAKE_CXX_FLAGS "--c++ ") else() string(PREPEND CMAKE_CXX_FLAGS "--eec++ ") endif() - unset(_CMAKE_IAR_MODERNCXX_LIST) + + cmake_policy(POP) endif() set(CMAKE_CXX_STANDARD_COMPILE_OPTION "") diff --git a/Modules/Compiler/IBMClang-ASM.cmake b/Modules/Compiler/IBMClang-ASM.cmake new file mode 100644 index 0000000..dffc085 --- /dev/null +++ b/Modules/Compiler/IBMClang-ASM.cmake @@ -0,0 +1,5 @@ +include(Compiler/IBMClang) + +set(CMAKE_ASM_SOURCE_FILE_EXTENSIONS s;S;asm) + +__compiler_ibmclang(ASM) diff --git a/Modules/Compiler/IBMClang-C-DetermineCompiler.cmake b/Modules/Compiler/IBMClang-C-DetermineCompiler.cmake new file mode 100644 index 0000000..623c8af --- /dev/null +++ b/Modules/Compiler/IBMClang-C-DetermineCompiler.cmake @@ -0,0 +1,8 @@ +set(_compiler_id_pp_test "defined(__open_xl__) && defined(__clang__)") + +set(_compiler_id_version_compute " +# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@(__open_xl_version__) +# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@(__open_xl_release__) +# define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@(__open_xl_modification__) +# define @PREFIX@COMPILER_VERSION_TWEAK @MACRO_DEC@(__open_xl_ptf_fix_level__) +") diff --git a/Modules/Compiler/IBMClang-C.cmake b/Modules/Compiler/IBMClang-C.cmake new file mode 100644 index 0000000..b69b1b8 --- /dev/null +++ b/Modules/Compiler/IBMClang-C.cmake @@ -0,0 +1,30 @@ +include(Compiler/IBMClang) +__compiler_ibmclang(C) + +set(CMAKE_C_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -x c) + +if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER) + AND CMAKE_GENERATOR MATCHES "Makefiles|WMake" + AND CMAKE_DEPFILE_FLAGS_C) + # dependencies are computed by the compiler itself + set(CMAKE_C_DEPFILE_FORMAT gcc) + set(CMAKE_C_DEPENDS_USE_COMPILER TRUE) +endif() + +set(CMAKE_C90_STANDARD__HAS_FULL_SUPPORT ON) +set(CMAKE_C90_STANDARD_COMPILE_OPTION "-std=c90") +set(CMAKE_C90_EXTENSION_COMPILE_OPTION "-std=gnu90") + +set(CMAKE_C99_STANDARD__HAS_FULL_SUPPORT ON) +set(CMAKE_C99_STANDARD_COMPILE_OPTION "-std=c99") +set(CMAKE_C99_EXTENSION_COMPILE_OPTION "-std=gnu99") + +set(CMAKE_C11_STANDARD__HAS_FULL_SUPPORT ON) +set(CMAKE_C11_STANDARD_COMPILE_OPTION "-std=c11") +set(CMAKE_C11_EXTENSION_COMPILE_OPTION "-std=gnu11") + +if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 17.1.0) + set(CMAKE_C17_STANDARD_COMPILE_OPTION "-std=c17") + set(CMAKE_C17_EXTENSION_COMPILE_OPTION "-std=gnu17") +endif () +__compiler_check_default_language_standard(C 17.1.0 17) diff --git a/Modules/Compiler/IBMClang-CXX-DetermineCompiler.cmake b/Modules/Compiler/IBMClang-CXX-DetermineCompiler.cmake new file mode 100644 index 0000000..623c8af --- /dev/null +++ b/Modules/Compiler/IBMClang-CXX-DetermineCompiler.cmake @@ -0,0 +1,8 @@ +set(_compiler_id_pp_test "defined(__open_xl__) && defined(__clang__)") + +set(_compiler_id_version_compute " +# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@(__open_xl_version__) +# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@(__open_xl_release__) +# define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@(__open_xl_modification__) +# define @PREFIX@COMPILER_VERSION_TWEAK @MACRO_DEC@(__open_xl_ptf_fix_level__) +") diff --git a/Modules/Compiler/IBMClang-CXX.cmake b/Modules/Compiler/IBMClang-CXX.cmake new file mode 100644 index 0000000..5431b17 --- /dev/null +++ b/Modules/Compiler/IBMClang-CXX.cmake @@ -0,0 +1,39 @@ +include(Compiler/IBMClang) +__compiler_ibmclang(CXX) + +if("x${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU") + if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER) + AND CMAKE_GENERATOR MATCHES "Makefiles|WMake" + AND CMAKE_DEPFILE_FLAGS_CXX) + # dependencies are computed by the compiler itself + set(CMAKE_CXX_DEPFILE_FORMAT gcc) + set(CMAKE_CXX_DEPENDS_USE_COMPILER TRUE) + endif() + + set(CMAKE_CXX_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -x c++) + set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden") +endif() + +set(CMAKE_CXX98_STANDARD__HAS_FULL_SUPPORT ON) +set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "-std=c++98") +set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION "-std=gnu++98") + +set(CMAKE_CXX11_STANDARD__HAS_FULL_SUPPORT ON) +set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "-std=c++11") +set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-std=gnu++11") + +set(CMAKE_CXX14_STANDARD__HAS_FULL_SUPPORT ON) +set(CMAKE_CXX14_STANDARD_COMPILE_OPTION "-std=c++14") +set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "-std=gnu++14") + +if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 17.1.0) + set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "-std=c++17") + set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-std=gnu++17") + set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "-std=c++20") + set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "-std=gnu++20") +endif() + +__compiler_check_default_language_standard(CXX 17.1.0 17) + +set(CMAKE_CXX_COMPILE_OBJECT + "<CMAKE_CXX_COMPILER> -x c++ <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>") diff --git a/Modules/Compiler/IBMClang.cmake b/Modules/Compiler/IBMClang.cmake new file mode 100644 index 0000000..9ed7658 --- /dev/null +++ b/Modules/Compiler/IBMClang.cmake @@ -0,0 +1,79 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + + +# This module is shared by multiple languages; use include blocker. +if(__COMPILER_IBMClang) + return() +endif() +set(__COMPILER_IBMClang 1) + +include(Compiler/CMakeCommonCompilerMacros) + +set(__pch_header_C "c-header") +set(__pch_header_CXX "c++-header") +set(__pch_header_OBJC "objective-c-header") +set(__pch_header_OBJCXX "objective-c++-header") + +include(Compiler/GNU) + +macro(__compiler_ibmclang lang) + __compiler_gnu(${lang}) + + # Feature flags. + set(CMAKE_${lang}_VERBOSE_FLAG "-v") + set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "-fPIC") + set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "-fPIC") + set(CMAKE_${lang}_RESPONSE_FILE_FLAG "@") + set(CMAKE_${lang}_RESPONSE_FILE_LINK_FLAG "@") + + set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang} "-isystem ") + set(CMAKE_${lang}_COMPILE_OPTIONS_VISIBILITY "-fvisibility=") + + set(CMAKE_${lang}_COMPILE_OPTIONS_TARGET "--target=") + set(CMAKE_${lang}_COMPILE_OPTIONS_EXTERNAL_TOOLCHAIN "--gcc-toolchain=") + + set(CMAKE_${lang}_LINKER_WRAPPER_FLAG "-Xlinker" " ") + set(CMAKE_${lang}_LINKER_WRAPPER_FLAG_SEP) + + if(CMAKE_${lang}_COMPILER_TARGET) + list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "--target=${CMAKE_${lang}_COMPILER_TARGET}") + endif() + + set(_CMAKE_${lang}_IPO_SUPPORTED_BY_CMAKE YES) + set(_CMAKE_${lang}_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES) + + set(_CMAKE_LTO_THIN TRUE) + + if(_CMAKE_LTO_THIN) + set(CMAKE_${lang}_COMPILE_OPTIONS_IPO "-flto=thin") + else() + set(CMAKE_${lang}_COMPILE_OPTIONS_IPO "-flto") + endif() + + set(__ar "${CMAKE_${lang}_COMPILER_AR}") + set(__ranlib "${CMAKE_${lang}_COMPILER_RANLIB}") + + set(CMAKE_${lang}_ARCHIVE_CREATE_IPO + "\"${__ar}\" cr <TARGET> <LINK_FLAGS> <OBJECTS>" + ) + + set(CMAKE_${lang}_ARCHIVE_APPEND_IPO + "\"${__ar}\" r <TARGET> <LINK_FLAGS> <OBJECTS>" + ) + + set(CMAKE_${lang}_ARCHIVE_FINISH_IPO + "\"${__ranlib}\" <TARGET>" + ) + + list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "-dM" "-E" "-c" "${CMAKE_ROOT}/Modules/CMakeCXXCompilerABI.cpp") + + set(CMAKE_PCH_EXTENSION .pch) + + set(CMAKE_PCH_PROLOGUE "#pragma clang system_header") + + set(CMAKE_${lang}_COMPILE_OPTIONS_INSTANTIATE_TEMPLATES_PCH -fpch-instantiate-templates) + + set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -Xclang -include-pch -Xclang <PCH_FILE> -Xclang -include -Xclang <PCH_HEADER>) + set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH -Xclang -emit-pch -Xclang -include -Xclang <PCH_HEADER> -x ${__pch_header_${lang}}) +endmacro() diff --git a/Modules/FindCUDA.cmake b/Modules/FindCUDA.cmake index dd795f4..af5f798 100644 --- a/Modules/FindCUDA.cmake +++ b/Modules/FindCUDA.cmake @@ -926,8 +926,8 @@ mark_as_advanced(CUDA_NVCC_EXECUTABLE) if(CUDA_NVCC_EXECUTABLE AND NOT CUDA_VERSION) # Compute the version. execute_process (COMMAND ${CUDA_NVCC_EXECUTABLE} "--version" OUTPUT_VARIABLE NVCC_OUT) - string(REGEX REPLACE ".*release ([0-9]+)\\.([0-9]+).*" "\\1" CUDA_VERSION_MAJOR ${NVCC_OUT}) - string(REGEX REPLACE ".*release ([0-9]+)\\.([0-9]+).*" "\\2" CUDA_VERSION_MINOR ${NVCC_OUT}) + string(REGEX REPLACE ".*release ([0-9]+)\\.([0-9]+).*" "\\1" CUDA_VERSION_MAJOR "${NVCC_OUT}") + string(REGEX REPLACE ".*release ([0-9]+)\\.([0-9]+).*" "\\2" CUDA_VERSION_MINOR "${NVCC_OUT}") set(CUDA_VERSION "${CUDA_VERSION_MAJOR}.${CUDA_VERSION_MINOR}" CACHE STRING "Version of CUDA as computed from nvcc.") mark_as_advanced(CUDA_VERSION) else() diff --git a/Modules/FindCUDAToolkit.cmake b/Modules/FindCUDAToolkit.cmake index d1cd38d..573f956 100644 --- a/Modules/FindCUDAToolkit.cmake +++ b/Modules/FindCUDAToolkit.cmake @@ -143,13 +143,11 @@ CUDA Driver Library """""""""""""""""""" The CUDA Driver library (cuda) are used by applications that use calls -such as `cuMemAlloc`, and `cuMemFree`. This is generally used by advanced - +such as `cuMemAlloc`, and `cuMemFree`. Targets Created: - ``CUDA::cuda_driver`` -- ``CUDA::cuda_driver`` .. _`cuda_toolkit_cuBLAS`: diff --git a/Modules/FindMPI/test_mpi.c b/Modules/FindMPI/test_mpi.c index 70d7e1d..36b5dfd 100644 --- a/Modules/FindMPI/test_mpi.c +++ b/Modules/FindMPI/test_mpi.c @@ -7,7 +7,7 @@ #endif #if defined(MPI_VERSION) && defined(MPI_SUBVERSION) -const static char mpiver_str[] = { 'I', 'N', +static const char mpiver_str[] = { 'I', 'N', 'F', 'O', ':', 'M', 'P', 'I', diff --git a/Modules/FindOpenSSL.cmake b/Modules/FindOpenSSL.cmake index 85e386a..5a8bfef 100644 --- a/Modules/FindOpenSSL.cmake +++ b/Modules/FindOpenSSL.cmake @@ -124,7 +124,11 @@ function(_OpenSSL_target_add_dependencies target) set_property( TARGET ${target} APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${CMAKE_DL_LIBS} ) endif() if(WIN32 AND OPENSSL_USE_STATIC_LIBS) - set_property( TARGET ${target} APPEND PROPERTY INTERFACE_LINK_LIBRARIES ws2_32 ) + if(WINCE) + set_property( TARGET ${target} APPEND PROPERTY INTERFACE_LINK_LIBRARIES ws2 ) + else() + set_property( TARGET ${target} APPEND PROPERTY INTERFACE_LINK_LIBRARIES ws2_32 ) + endif() set_property( TARGET ${target} APPEND PROPERTY INTERFACE_LINK_LIBRARIES crypt32 ) endif() endfunction() diff --git a/Modules/FindRuby.cmake b/Modules/FindRuby.cmake index 759f57c..a80758d 100644 --- a/Modules/FindRuby.cmake +++ b/Modules/FindRuby.cmake @@ -8,7 +8,7 @@ FindRuby Find Ruby This module finds if Ruby is installed and determines where the -include files and libraries are. Ruby 1.8 through 2.7 are +include files and libraries are. Ruby 1.8 through 3.1 are supported. The minimum required version of Ruby can be specified using the @@ -139,13 +139,13 @@ set(Ruby_FIND_VERSION_SHORT_NODOT "${Ruby_FIND_VERSION_MAJOR}${Ruby_FIND_VERSION # Set name of possible executables, ignoring the minor # Eg: -# 2.1.1 => from ruby27 to ruby21 included -# 2.1 => from ruby27 to ruby21 included -# 2 => from ruby26 to ruby20 included -# empty => from ruby27 to ruby18 included +# 2.1.1 => from ruby31 to ruby21 included +# 2.1 => from ruby31 to ruby21 included +# 2 => from ruby31 to ruby20 included +# empty => from ruby31 to ruby18 included if(NOT Ruby_FIND_VERSION_EXACT) - foreach(_ruby_version RANGE 27 18 -1) + foreach(_ruby_version RANGE 31 18 -1) string(SUBSTRING "${_ruby_version}" 0 1 _ruby_major_version) string(SUBSTRING "${_ruby_version}" 1 1 _ruby_minor_version) @@ -266,9 +266,20 @@ while(1) _RUBY_VALIDATE_INTERPRETER (${Ruby_FIND_VERSION}) if (Ruby_EXECUTABLE) break() + else() + # Remove first entry from names list. + LIST(REMOVE_AT _Ruby_POSSIBLE_EXECUTABLE_NAMES 0) + + # If the list is now empty, abort. + if (NOT _Ruby_POSSIBLE_EXECUTABLE_NAMES) + break() + else() + # Otherwise, continue with the remaining list. Make sure that we clear + # the cached variable. + unset(Ruby_EXECUTABLE CACHE) + endif() endif() - break() endwhile() if(Ruby_EXECUTABLE AND NOT Ruby_VERSION_MAJOR) @@ -398,6 +409,16 @@ if(Ruby_EXECUTABLE AND NOT Ruby_VERSION_MAJOR) set(Ruby_VERSION_MAJOR 2) set(Ruby_VERSION_MINOR 7) endif() + # check whether we found 3.0.x + if(${Ruby_EXECUTABLE} MATCHES "ruby3\\.?0") + set(Ruby_VERSION_MAJOR 3) + set(Ruby_VERSION_MINOR 0) + endif() + # check whether we found 3.1.x + if(${Ruby_EXECUTABLE} MATCHES "ruby3\\.?1") + set(Ruby_VERSION_MAJOR 3) + set(Ruby_VERSION_MINOR 1) + endif() endif() if(Ruby_VERSION_MAJOR) diff --git a/Modules/FindXercesC.cmake b/Modules/FindXercesC.cmake index af1b0b4..d39bbf6 100644 --- a/Modules/FindXercesC.cmake +++ b/Modules/FindXercesC.cmake @@ -91,11 +91,13 @@ if(NOT XercesC_LIBRARY) NAMES "xerces-c" "xerces-c_${XercesC_VERSION_MAJOR}" "xerces-c-${XercesC_VERSION_MAJOR}.${XercesC_VERSION_MINOR}" + NAMES_PER_DIR DOC "Xerces-C++ libraries (release)") find_library(XercesC_LIBRARY_DEBUG NAMES "xerces-cd" "xerces-c_${XercesC_VERSION_MAJOR}D" "xerces-c_${XercesC_VERSION_MAJOR}_${XercesC_VERSION_MINOR}D" + NAMES_PER_DIR DOC "Xerces-C++ libraries (debug)") include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake) select_library_configurations(XercesC) diff --git a/Modules/GenerateExportHeader.cmake b/Modules/GenerateExportHeader.cmake index a9a9c59..7461a3e 100644 --- a/Modules/GenerateExportHeader.cmake +++ b/Modules/GenerateExportHeader.cmake @@ -231,7 +231,7 @@ macro(_test_compiler_hidden_visibility) AND NOT _INTEL_TOO_OLD AND NOT WIN32 AND NOT CYGWIN - AND NOT CMAKE_CXX_COMPILER_ID MATCHES XL + AND NOT CMAKE_CXX_COMPILER_ID MATCHES "^(IBMClang|XLClang|XL)$" AND NOT CMAKE_CXX_COMPILER_ID MATCHES "^(PGI|NVHPC)$" AND NOT CMAKE_CXX_COMPILER_ID MATCHES Watcom) if (CMAKE_CXX_COMPILER_LOADED) diff --git a/Modules/Internal/CPack/NSIS.template.in b/Modules/Internal/CPack/NSIS.template.in index 8a0c972..e3abf22 100644 --- a/Modules/Internal/CPack/NSIS.template.in +++ b/Modules/Internal/CPack/NSIS.template.in @@ -531,7 +531,6 @@ FunctionEnd @CPACK_NSIS_INSTALLER_ICON_CODE@ @CPACK_NSIS_INSTALLER_MUI_WELCOMEFINISH_CODE@ @CPACK_NSIS_INSTALLER_MUI_UNWELCOMEFINISH_CODE@ -@CPACK_NSIS_INSTALLER_MUI_COMPONENTS_DESC@ @CPACK_NSIS_INSTALLER_MUI_FINISHPAGE_RUN_CODE@ ;-------------------------------- @@ -648,7 +647,7 @@ FunctionEnd ;-------------------------------- ; Component sections @CPACK_NSIS_COMPONENT_SECTIONS@ - +@CPACK_NSIS_INSTALLER_MUI_COMPONENTS_DESC@ ;-------------------------------- ;Installer Sections diff --git a/Modules/Platform/AIX-IBMClang-C.cmake b/Modules/Platform/AIX-IBMClang-C.cmake new file mode 100644 index 0000000..db21f29 --- /dev/null +++ b/Modules/Platform/AIX-IBMClang-C.cmake @@ -0,0 +1,2 @@ +include(Platform/AIX-IBMClang) +__aix_compiler_ibmclang(C) diff --git a/Modules/Platform/AIX-IBMClang-CXX.cmake b/Modules/Platform/AIX-IBMClang-CXX.cmake new file mode 100644 index 0000000..bf580ec --- /dev/null +++ b/Modules/Platform/AIX-IBMClang-CXX.cmake @@ -0,0 +1,3 @@ +include(Platform/AIX-IBMClang) +__aix_compiler_ibmclang(CXX) +unset(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN) diff --git a/Modules/Platform/AIX-IBMClang.cmake b/Modules/Platform/AIX-IBMClang.cmake new file mode 100644 index 0000000..4e5205e --- /dev/null +++ b/Modules/Platform/AIX-IBMClang.cmake @@ -0,0 +1,16 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + + +# This module is shared by multiple languages; use include blocker. +if(__AIX_COMPILER_IBMCLANG) + return() +endif() +set(__AIX_COMPILER_IBMCLANG 1) + +include(Platform/AIX-GNU) + +macro(__aix_compiler_ibmclang lang) + __aix_compiler_gnu(${lang}) + unset(CMAKE_${lang}_COMPILE_OPTIONS_VISIBILITY) +endmacro() diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index b31b8dc..ddcdd7e 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -155,6 +155,7 @@ set(SRCS cmBinUtilsWindowsPELinker.h cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.cxx cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.h + cmBuildOptions.h cmCacheManager.cxx cmCacheManager.h cmCLocaleEnvironmentScope.h diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 4182eb4..91333c9 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,7 +1,7 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 22) -set(CMake_VERSION_PATCH 20220124) +set(CMake_VERSION_PATCH 20220201) #set(CMake_VERSION_RC 0) set(CMake_VERSION_IS_DIRTY 0) diff --git a/Source/CTest/cmCTestBuildAndTestHandler.cxx b/Source/CTest/cmCTestBuildAndTestHandler.cxx index adfc8ef..e09b4dd 100644 --- a/Source/CTest/cmCTestBuildAndTestHandler.cxx +++ b/Source/CTest/cmCTestBuildAndTestHandler.cxx @@ -9,6 +9,7 @@ #include "cmsys/Process.h" +#include "cmBuildOptions.h" #include "cmCTest.h" #include "cmCTestTestHandler.h" #include "cmGlobalGenerator.h" @@ -263,10 +264,13 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring) if (!config) { config = "Debug"; } + + cmBuildOptions buildOptions(!this->BuildNoClean, false, + PackageResolveMode::Disable); int retVal = cm.GetGlobalGenerator()->Build( cmake::NO_BUILD_PARALLEL_LEVEL, this->SourceDir, this->BinaryDir, this->BuildProject, { tar }, output, this->BuildMakeProgram, config, - !this->BuildNoClean, false, false, remainingTime); + buildOptions, false, remainingTime); out << output; // if the build failed then return if (retVal) { diff --git a/Source/CursesDialog/form/CMakeLists.txt b/Source/CursesDialog/form/CMakeLists.txt index 22a2e84..68d28c8 100644 --- a/Source/CursesDialog/form/CMakeLists.txt +++ b/Source/CursesDialog/form/CMakeLists.txt @@ -5,7 +5,7 @@ project(CMAKE_FORM) # Disable warnings to avoid changing 3rd party code. if(CMAKE_C_COMPILER_ID MATCHES - "^(GNU|LCC|Clang|AppleClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM|NVHPC)$") + "^(GNU|LCC|Clang|AppleClang|IBMClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM|NVHPC)$") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w") elseif(CMAKE_C_COMPILER_ID STREQUAL "PathScale") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -woffall") diff --git a/Source/cmBuildOptions.h b/Source/cmBuildOptions.h new file mode 100644 index 0000000..58baeef --- /dev/null +++ b/Source/cmBuildOptions.h @@ -0,0 +1,44 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#pragma once + +#include "cmConfigure.h" // IWYU pragma: keep + +/** \brief Defines how to resolve packages **/ +enum class PackageResolveMode +{ + /** \brief Defines behavior based on cache variable (e.g. + CMAKE_VS_NUGET_PACKAGE_RESTORE). This is the default. **/ + FromCacheVariable, + + /** \brief Ignore behavior defined by cache variable and forces packages to + be resolved prior to build. **/ + Force, + + /** \brief Ignore behavior defined by cache variable and forces packages to + be resolved, but skip the actual build. **/ + OnlyResolve, + + /** \brief Ignore behavior defined by cache variable and dont resolve any + packages **/ + Disable +}; + +struct cmBuildOptions +{ +public: + cmBuildOptions() noexcept = default; + explicit cmBuildOptions(bool clean, bool fast, + PackageResolveMode resolveMode) noexcept + : Clean(clean) + , Fast(fast) + , ResolveMode(resolveMode) + { + } + explicit cmBuildOptions(const cmBuildOptions&) noexcept = default; + cmBuildOptions& operator=(const cmBuildOptions&) noexcept = default; + + bool Clean = false; + bool Fast = false; + PackageResolveMode ResolveMode = PackageResolveMode::FromCacheVariable; +}; diff --git a/Source/cmCMakePresetsGraph.cxx b/Source/cmCMakePresetsGraph.cxx index 238aa68..79e8191 100644 --- a/Source/cmCMakePresetsGraph.cxx +++ b/Source/cmCMakePresetsGraph.cxx @@ -724,6 +724,9 @@ cmCMakePresetsGraph::BuildPreset::VisitPresetInherit( InheritOptionalValue(preset.CleanFirst, parent.CleanFirst); InheritOptionalValue(preset.Verbose, parent.Verbose); InheritVector(preset.NativeToolOptions, parent.NativeToolOptions); + if (!preset.ResolvePackageReferences) { + preset.ResolvePackageReferences = parent.ResolvePackageReferences; + } return ReadFileResult::READ_OK; } diff --git a/Source/cmCMakePresetsGraph.h b/Source/cmCMakePresetsGraph.h index 8581809..d3a5cfc 100644 --- a/Source/cmCMakePresetsGraph.h +++ b/Source/cmCMakePresetsGraph.h @@ -14,6 +14,8 @@ #include <cm/optional> +enum class PackageResolveMode; + class cmCMakePresetsGraph { public: @@ -181,6 +183,7 @@ public: cm::optional<bool> CleanFirst; cm::optional<bool> Verbose; std::vector<std::string> NativeToolOptions; + cm::optional<PackageResolveMode> ResolvePackageReferences; ReadFileResult VisitPresetInherit(const Preset& parent) override; ReadFileResult VisitPresetAfterInherit(int /* version */) override; diff --git a/Source/cmCMakePresetsGraphReadJSONBuildPresets.cxx b/Source/cmCMakePresetsGraphReadJSONBuildPresets.cxx index ef605d1..eefe2fe 100644 --- a/Source/cmCMakePresetsGraphReadJSONBuildPresets.cxx +++ b/Source/cmCMakePresetsGraphReadJSONBuildPresets.cxx @@ -12,6 +12,7 @@ #include <cm3p/json/value.h> +#include "cmBuildOptions.h" #include "cmCMakePresetsGraph.h" #include "cmCMakePresetsGraphInternal.h" #include "cmJSONHelpers.h" @@ -20,6 +21,37 @@ namespace { using ReadFileResult = cmCMakePresetsGraph::ReadFileResult; using BuildPreset = cmCMakePresetsGraph::BuildPreset; +ReadFileResult PackageResolveModeHelper(cm::optional<PackageResolveMode>& out, + const Json::Value* value) +{ + if (!value) { + out = cm::nullopt; + return ReadFileResult::READ_OK; + } + + if (!value->isString()) { + return ReadFileResult::INVALID_PRESET; + } + + if (value->asString() == "on") { + out = PackageResolveMode::Force; + } else if (value->asString() == "off") { + out = PackageResolveMode::Disable; + } else if (value->asString() == "only") { + out = PackageResolveMode::OnlyResolve; + } else { + return ReadFileResult::INVALID_PRESET; + } + + return ReadFileResult::READ_OK; +} + +std::function<ReadFileResult(BuildPreset&, const Json::Value*)> const + ResolvePackageReferencesHelper = + [](BuildPreset& out, const Json::Value* value) -> ReadFileResult { + return PackageResolveModeHelper(out.ResolvePackageReferences, value); +}; + auto const BuildPresetHelper = cmJSONObjectHelper<BuildPreset, ReadFileResult>( ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) @@ -59,7 +91,8 @@ auto const BuildPresetHelper = .Bind("nativeToolOptions"_s, &BuildPreset::NativeToolOptions, cmCMakePresetsGraphInternal::PresetVectorStringHelper, false) .Bind("condition"_s, &BuildPreset::ConditionEvaluator, - cmCMakePresetsGraphInternal::PresetConditionHelper, false); + cmCMakePresetsGraphInternal::PresetConditionHelper, false) + .Bind("resolvePackageReferences"_s, ResolvePackageReferencesHelper, false); } namespace cmCMakePresetsGraphInternal { diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index 896240c..412d104 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -2,6 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmExportFileGenerator.h" +#include <array> #include <cassert> #include <cstring> #include <sstream> @@ -175,18 +176,24 @@ bool cmExportFileGenerator::PopulateInterfaceLinkLibrariesProperty( if (!target->IsLinkable()) { return false; } - cmValue input = target->GetProperty("INTERFACE_LINK_LIBRARIES"); - if (input) { - std::string prepro = - cmGeneratorExpression::Preprocess(*input, preprocessRule); - if (!prepro.empty()) { - this->ResolveTargetsInGeneratorExpressions( - prepro, target, missingTargets, ReplaceFreeTargets); - properties["INTERFACE_LINK_LIBRARIES"] = prepro; - return true; + static const std::array<std::string, 3> linkIfaceProps = { + { "INTERFACE_LINK_LIBRARIES", "INTERFACE_LINK_LIBRARIES_DIRECT", + "INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE" } + }; + bool hadINTERFACE_LINK_LIBRARIES = false; + for (std::string const& linkIfaceProp : linkIfaceProps) { + if (cmValue input = target->GetProperty(linkIfaceProp)) { + std::string prepro = + cmGeneratorExpression::Preprocess(*input, preprocessRule); + if (!prepro.empty()) { + this->ResolveTargetsInGeneratorExpressions( + prepro, target, missingTargets, ReplaceFreeTargets); + properties[linkIfaceProp] = prepro; + hadINTERFACE_LINK_LIBRARIES = true; + } } } - return false; + return hadINTERFACE_LINK_LIBRARIES; } static bool isSubDirectory(std::string const& a, std::string const& b) diff --git a/Source/cmExportTryCompileFileGenerator.cxx b/Source/cmExportTryCompileFileGenerator.cxx index db9b05b..e98aa05 100644 --- a/Source/cmExportTryCompileFileGenerator.cxx +++ b/Source/cmExportTryCompileFileGenerator.cxx @@ -111,6 +111,8 @@ void cmExportTryCompileFileGenerator::PopulateProperties( std::vector<std::string> props = target->GetPropertyKeys(); // Include special properties that might be relevant here. props.emplace_back("INTERFACE_LINK_LIBRARIES"); + props.emplace_back("INTERFACE_LINK_LIBRARIES_DIRECT"); + props.emplace_back("INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE"); for (std::string const& p : props) { cmValue v = target->GetProperty(p); if (!v) { diff --git a/Source/cmFileAPIToolchains.cxx b/Source/cmFileAPIToolchains.cxx index b3540c9..fe2972f 100644 --- a/Source/cmFileAPIToolchains.cxx +++ b/Source/cmFileAPIToolchains.cxx @@ -30,10 +30,6 @@ class Toolchains cmFileAPI& FileAPI; unsigned long Version; - static const std::vector<ToolchainVariable> CompilerVariables; - static const std::vector<ToolchainVariable> CompilerImplicitVariables; - static const ToolchainVariable SourceFileExtensionsVariable; - Json::Value DumpToolchains(); Json::Value DumpToolchain(std::string const& lang); Json::Value DumpToolchainVariables( @@ -48,24 +44,6 @@ public: Json::Value Dump(); }; -const std::vector<ToolchainVariable> Toolchains::CompilerVariables{ - { "path", "COMPILER", false }, - { "id", "COMPILER_ID", false }, - { "version", "COMPILER_VERSION", false }, - { "target", "COMPILER_TARGET", false }, -}; - -const std::vector<ToolchainVariable> Toolchains::CompilerImplicitVariables{ - { "includeDirectories", "IMPLICIT_INCLUDE_DIRECTORIES", true }, - { "linkDirectories", "IMPLICIT_LINK_DIRECTORIES", true }, - { "linkFrameworkDirectories", "IMPLICIT_LINK_FRAMEWORK_DIRECTORIES", true }, - { "linkLibraries", "IMPLICIT_LINK_LIBRARIES", true }, -}; - -const ToolchainVariable Toolchains::SourceFileExtensionsVariable{ - "sourceFileExtensions", "SOURCE_FILE_EXTENSIONS", true -}; - Toolchains::Toolchains(cmFileAPI& fileAPI, unsigned long version) : FileAPI(fileAPI) , Version(version) @@ -94,6 +72,25 @@ Json::Value Toolchains::DumpToolchains() Json::Value Toolchains::DumpToolchain(std::string const& lang) { + static const std::vector<ToolchainVariable> CompilerVariables{ + { "path", "COMPILER", false }, + { "id", "COMPILER_ID", false }, + { "version", "COMPILER_VERSION", false }, + { "target", "COMPILER_TARGET", false }, + }; + + static const std::vector<ToolchainVariable> CompilerImplicitVariables{ + { "includeDirectories", "IMPLICIT_INCLUDE_DIRECTORIES", true }, + { "linkDirectories", "IMPLICIT_LINK_DIRECTORIES", true }, + { "linkFrameworkDirectories", "IMPLICIT_LINK_FRAMEWORK_DIRECTORIES", + true }, + { "linkLibraries", "IMPLICIT_LINK_LIBRARIES", true }, + }; + + static const ToolchainVariable SourceFileExtensionsVariable{ + "sourceFileExtensions", "SOURCE_FILE_EXTENSIONS", true + }; + const auto& mf = this->FileAPI.GetCMakeInstance()->GetGlobalGenerator()->GetMakefiles()[0]; Json::Value toolchain = Json::objectValue; diff --git a/Source/cmFunctionBlocker.cxx b/Source/cmFunctionBlocker.cxx index d4666d7..40e692d 100644 --- a/Source/cmFunctionBlocker.cxx +++ b/Source/cmFunctionBlocker.cxx @@ -27,7 +27,7 @@ bool cmFunctionBlocker::IsFunctionBlocked(const cmListFileFunction& lff, if (!this->ArgumentsMatch(lff, mf)) { cmListFileContext const& lfc = this->GetStartingContext(); cmListFileContext closingContext = - cmListFileContext::FromCommandContext(lff, lfc.FilePath); + cmListFileContext::FromListFileFunction(lff, lfc.FilePath); std::ostringstream e; /* clang-format off */ e << "A logical block opening on the line\n" diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx index a1fce55..d4b02a5 100644 --- a/Source/cmGeneratorExpressionDAGChecker.cxx +++ b/Source/cmGeneratorExpressionDAGChecker.cxx @@ -188,11 +188,13 @@ bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries( return top->Target == tgt && prop == "LINK_LIBRARIES"_s; } - return prop == "LINK_LIBRARIES"_s || prop == "LINK_INTERFACE_LIBRARIES"_s || + return prop == "LINK_LIBRARIES"_s || prop == "INTERFACE_LINK_LIBRARIES"_s || + prop == "INTERFACE_LINK_LIBRARIES_DIRECT"_s || + prop == "INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE"_s || + prop == "LINK_INTERFACE_LIBRARIES"_s || prop == "IMPORTED_LINK_INTERFACE_LIBRARIES"_s || cmHasLiteralPrefix(prop, "LINK_INTERFACE_LIBRARIES_") || - cmHasLiteralPrefix(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES_") || - prop == "INTERFACE_LINK_LIBRARIES"_s; + cmHasLiteralPrefix(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES_"); } cmGeneratorExpressionDAGChecker const* cmGeneratorExpressionDAGChecker::Top() diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 421e136..c4f1a13 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -57,6 +57,11 @@ using LinkInterfaceFor = cmGeneratorTarget::LinkInterfaceFor; const cmsys::RegularExpression FrameworkRegularExpression( "^(.*/)?([^/]*)\\.framework/(.*)$"); +const std::string kINTERFACE_LINK_LIBRARIES = "INTERFACE_LINK_LIBRARIES"; +const std::string kINTERFACE_LINK_LIBRARIES_DIRECT = + "INTERFACE_LINK_LIBRARIES_DIRECT"; +const std::string kINTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE = + "INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE"; } template <> @@ -749,6 +754,12 @@ void cmGeneratorTarget::ClearSourcesCache() this->LinkImplMap.clear(); } +void cmGeneratorTarget::ClearLinkInterfaceCache() +{ + this->LinkInterfaceMap.clear(); + this->LinkInterfaceUsageRequirementsOnlyMap.clear(); +} + void cmGeneratorTarget::AddSourceCommon(const std::string& src, bool before) { this->SourceEntries.insert( @@ -3645,7 +3656,7 @@ void processIncludeDirectories(cmGeneratorTarget const* tgt, cmLinkImplItem const& item = entry.LinkImplItem; std::string const& targetName = item.AsStr(); bool const fromImported = item.Target && item.Target->IsImported(); - bool const checkCMP0027 = item.FromGenex; + bool const checkCMP0027 = item.CheckCMP0027; std::string usedIncludes; for (std::string& entryInclude : entry.Values) { @@ -6638,7 +6649,7 @@ bool cmGeneratorTarget::IsLinkLookupScope(std::string const& n, cm::optional<cmLinkItem> cmGeneratorTarget::LookupLinkItem( std::string const& n, cmListFileBacktrace const& bt, - LookupLinkItemScope* scope) const + LookupLinkItemScope* scope, LookupSelf lookupSelf) const { cm::optional<cmLinkItem> maybeItem; if (this->IsLinkLookupScope(n, scope->LG)) { @@ -6646,20 +6657,22 @@ cm::optional<cmLinkItem> cmGeneratorTarget::LookupLinkItem( } std::string name = this->CheckCMP0004(n); - if (name == this->GetName() || name.empty()) { + if (name.empty() || + (lookupSelf == LookupSelf::No && name == this->GetName())) { return maybeItem; } maybeItem = this->ResolveLinkItem(BT<std::string>(name, bt), scope->LG); return maybeItem; } -void cmGeneratorTarget::ExpandLinkItems(std::string const& prop, - cmBTStringRange entries, - std::string const& config, - cmGeneratorTarget const* headTarget, - LinkInterfaceFor interfaceFor, - cmLinkInterface& iface) const +void cmGeneratorTarget::ExpandLinkItems( + std::string const& prop, cmBTStringRange entries, std::string const& config, + cmGeneratorTarget const* headTarget, LinkInterfaceFor interfaceFor, + LinkInterfaceField field, cmLinkInterface& iface) const { + if (entries.empty()) { + return; + } // Keep this logic in sync with ComputeLinkImplementationLibraries. cmGeneratorExpressionDAGChecker dagChecker(this, prop, nullptr, nullptr); // The $<LINK_ONLY> expression may be in a link interface to specify @@ -6678,10 +6691,20 @@ void cmGeneratorTarget::ExpandLinkItems(std::string const& prop, cge->Evaluate(this->LocalGenerator, config, headTarget, &dagChecker, this, headTarget->LinkerLanguage)); for (std::string const& lib : libs) { - if (cm::optional<cmLinkItem> maybeItem = - this->LookupLinkItem(lib, cge->GetBacktrace(), &scope)) { + if (cm::optional<cmLinkItem> maybeItem = this->LookupLinkItem( + lib, cge->GetBacktrace(), &scope, + field == LinkInterfaceField::Libraries ? LookupSelf::No + : LookupSelf::Yes)) { cmLinkItem item = std::move(*maybeItem); + if (field == LinkInterfaceField::HeadInclude) { + iface.HeadInclude.emplace_back(std::move(item)); + continue; + } + if (field == LinkInterfaceField::HeadExclude) { + iface.HeadExclude.emplace_back(std::move(item)); + continue; + } if (!item.Target) { // Report explicitly linked object files separately. std::string const& maybeObj = item.AsStr(); @@ -6736,17 +6759,16 @@ cmLinkInterface const* cmGeneratorTarget::GetLinkInterface( // Lookup any existing link interface for this configuration. cmHeadToLinkInterfaceMap& hm = this->GetHeadToLinkInterfaceMap(config); - if (secondPass) { - hm.erase(head); - } - // If the link interface does not depend on the head target - // then return the one we computed first. + // then re-use the one from the head we computed first. if (!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition) { - return &hm.begin()->second; + head = hm.begin()->first; } cmOptionalLinkInterface& iface = hm[head]; + if (secondPass) { + iface = cmOptionalLinkInterface(); + } if (!iface.LibrariesDone) { iface.LibrariesDone = true; this->ComputeLinkInterfaceLibraries(config, iface, head, @@ -6865,9 +6887,9 @@ const cmLinkInterfaceLibraries* cmGeneratorTarget::GetLinkInterfaceLibraries( : this->GetHeadToLinkInterfaceMap(config)); // If the link interface does not depend on the head target - // then return the one we computed first. + // then re-use the one from the head we computed first. if (!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition) { - return &hm.begin()->second; + head = hm.begin()->first; } cmOptionalLinkInterface& iface = hm[head]; @@ -7146,59 +7168,66 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries( // An explicit list of interface libraries may be set for shared // libraries and executables that export symbols. - cmValue explicitLibraries = nullptr; - std::string linkIfaceProp; + bool haveExplicitLibraries = false; + cmValue explicitLibrariesCMP0022OLD; + std::string linkIfacePropCMP0022OLD; bool const cmp0022NEW = (this->GetPolicyStatusCMP0022() != cmPolicies::OLD && this->GetPolicyStatusCMP0022() != cmPolicies::WARN); if (cmp0022NEW) { // CMP0022 NEW behavior is to use INTERFACE_LINK_LIBRARIES. - linkIfaceProp = "INTERFACE_LINK_LIBRARIES"; - explicitLibraries = this->GetProperty(linkIfaceProp); - } else if (this->GetType() == cmStateEnums::SHARED_LIBRARY || - this->IsExecutableWithExports()) { + haveExplicitLibraries = !this->Target->GetLinkInterfaceEntries().empty() || + !this->Target->GetLinkInterfaceDirectEntries().empty() || + !this->Target->GetLinkInterfaceDirectExcludeEntries().empty(); + } else { // CMP0022 OLD behavior is to use LINK_INTERFACE_LIBRARIES if set on a // shared lib or executable. - - // Lookup the per-configuration property. - linkIfaceProp = cmStrCat("LINK_INTERFACE_LIBRARIES", suffix); - explicitLibraries = this->GetProperty(linkIfaceProp); - - // If not set, try the generic property. - if (!explicitLibraries) { - linkIfaceProp = "LINK_INTERFACE_LIBRARIES"; - explicitLibraries = this->GetProperty(linkIfaceProp); + if (this->GetType() == cmStateEnums::SHARED_LIBRARY || + this->IsExecutableWithExports()) { + // Lookup the per-configuration property. + linkIfacePropCMP0022OLD = cmStrCat("LINK_INTERFACE_LIBRARIES", suffix); + explicitLibrariesCMP0022OLD = this->GetProperty(linkIfacePropCMP0022OLD); + + // If not set, try the generic property. + if (!explicitLibrariesCMP0022OLD) { + linkIfacePropCMP0022OLD = "LINK_INTERFACE_LIBRARIES"; + explicitLibrariesCMP0022OLD = + this->GetProperty(linkIfacePropCMP0022OLD); + } } - } - if (explicitLibraries && - this->GetPolicyStatusCMP0022() == cmPolicies::WARN && - !this->PolicyWarnedCMP0022) { - // Compare the explicitly set old link interface properties to the - // preferred new link interface property one and warn if different. - cmValue newExplicitLibraries = - this->GetProperty("INTERFACE_LINK_LIBRARIES"); - if (newExplicitLibraries && - (*newExplicitLibraries != *explicitLibraries)) { - std::ostringstream w; - /* clang-format off */ - w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0022) << "\n" - "Target \"" << this->GetName() << "\" has an " - "INTERFACE_LINK_LIBRARIES property which differs from its " << - linkIfaceProp << " properties." - "\n" - "INTERFACE_LINK_LIBRARIES:\n" - " " << *newExplicitLibraries << "\n" << - linkIfaceProp << ":\n" - " " << *explicitLibraries << "\n"; - /* clang-format on */ - this->LocalGenerator->IssueMessage(MessageType::AUTHOR_WARNING, w.str()); - this->PolicyWarnedCMP0022 = true; + if (explicitLibrariesCMP0022OLD && + this->GetPolicyStatusCMP0022() == cmPolicies::WARN && + !this->PolicyWarnedCMP0022) { + // Compare the explicitly set old link interface properties to the + // preferred new link interface property one and warn if different. + cmValue newExplicitLibraries = + this->GetProperty("INTERFACE_LINK_LIBRARIES"); + if (newExplicitLibraries && + (*newExplicitLibraries != *explicitLibrariesCMP0022OLD)) { + std::ostringstream w; + /* clang-format off */ + w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0022) << "\n" + "Target \"" << this->GetName() << "\" has an " + "INTERFACE_LINK_LIBRARIES property which differs from its " << + linkIfacePropCMP0022OLD << " properties." + "\n" + "INTERFACE_LINK_LIBRARIES:\n" + " " << *newExplicitLibraries << "\n" << + linkIfacePropCMP0022OLD << ":\n" + " " << *explicitLibrariesCMP0022OLD << "\n"; + /* clang-format on */ + this->LocalGenerator->IssueMessage(MessageType::AUTHOR_WARNING, + w.str()); + this->PolicyWarnedCMP0022 = true; + } } + + haveExplicitLibraries = static_cast<bool>(explicitLibrariesCMP0022OLD); } // There is no implicit link interface for executables or modules // so if none was explicitly set then there is no link interface. - if (!explicitLibraries && + if (!haveExplicitLibraries && (this->GetType() == cmStateEnums::EXECUTABLE || (this->GetType() == cmStateEnums::MODULE_LIBRARY))) { return; @@ -7208,22 +7237,29 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries( // If CMP0022 is NEW then the plain tll signature sets the // INTERFACE_LINK_LIBRARIES property. Even if the project // clears it, the link interface is still explicit. - iface.Explicit = cmp0022NEW || explicitLibraries; - - if (explicitLibraries) { - // The interface libraries have been explicitly set. - if (cmp0022NEW) { - // The explicitLibraries came from INTERFACE_LINK_LIBRARIES. - // Use its special representation directly to get backtraces. - this->ExpandLinkItems(linkIfaceProp, - this->Target->GetLinkInterfaceEntries(), config, - headTarget, interfaceFor, iface); - } else { - std::vector<BT<std::string>> entries; - entries.emplace_back(*explicitLibraries); - this->ExpandLinkItems(linkIfaceProp, cmMakeRange(entries), config, - headTarget, interfaceFor, iface); - } + iface.Explicit = cmp0022NEW || explicitLibrariesCMP0022OLD; + + if (cmp0022NEW) { + // The interface libraries are specified by INTERFACE_LINK_LIBRARIES. + // Use its special representation directly to get backtraces. + this->ExpandLinkItems( + kINTERFACE_LINK_LIBRARIES, this->Target->GetLinkInterfaceEntries(), + config, headTarget, interfaceFor, LinkInterfaceField::Libraries, iface); + this->ExpandLinkItems(kINTERFACE_LINK_LIBRARIES_DIRECT, + this->Target->GetLinkInterfaceDirectEntries(), + config, headTarget, interfaceFor, + LinkInterfaceField::HeadInclude, iface); + this->ExpandLinkItems(kINTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE, + this->Target->GetLinkInterfaceDirectExcludeEntries(), + config, headTarget, interfaceFor, + LinkInterfaceField::HeadExclude, iface); + } else if (explicitLibrariesCMP0022OLD) { + // The interface libraries have been explicitly set in pre-CMP0022 style. + std::vector<BT<std::string>> entries; + entries.emplace_back(*explicitLibrariesCMP0022OLD); + this->ExpandLinkItems(linkIfacePropCMP0022OLD, cmMakeRange(entries), + config, headTarget, interfaceFor, + LinkInterfaceField::Libraries, iface); } // If the link interface is explicit, do not fall back to the link impl. @@ -7241,13 +7277,10 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries( // Compare the link implementation fallback link interface to the // preferred new link interface property and warn if different. cmLinkInterface ifaceNew; - static const std::string newProp = "INTERFACE_LINK_LIBRARIES"; - if (cmValue newExplicitLibraries = this->GetProperty(newProp)) { - std::vector<BT<std::string>> entries; - entries.emplace_back(*newExplicitLibraries); - this->ExpandLinkItems(linkIfaceProp, cmMakeRange(entries), config, - headTarget, interfaceFor, ifaceNew); - } + this->ExpandLinkItems(kINTERFACE_LINK_LIBRARIES, + this->Target->GetLinkInterfaceEntries(), config, + headTarget, interfaceFor, + LinkInterfaceField::Libraries, ifaceNew); if (ifaceNew.Libraries != iface.Libraries) { std::string oldLibraries = cmJoin(impl->Libraries, ";"); std::string newLibraries = cmJoin(ifaceNew.Libraries, ";"); @@ -7372,29 +7405,37 @@ const cmLinkInterface* cmGeneratorTarget::GetImportLinkInterface( ? this->GetHeadToLinkInterfaceUsageRequirementsMap(config) : this->GetHeadToLinkInterfaceMap(config)); - if (secondPass) { - hm.erase(headTarget); - } - // If the link interface does not depend on the head target - // then return the one we computed first. + // then re-use the one from the head we computed first. if (!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition) { - return &hm.begin()->second; + headTarget = hm.begin()->first; } cmOptionalLinkInterface& iface = hm[headTarget]; + if (secondPass) { + iface = cmOptionalLinkInterface(); + } if (!iface.AllDone) { iface.AllDone = true; iface.LibrariesDone = true; iface.Multiplicity = info->Multiplicity; cmExpandList(info->Languages, iface.Languages); + this->ExpandLinkItems(kINTERFACE_LINK_LIBRARIES_DIRECT, + cmMakeRange(info->LibrariesHeadInclude), config, + headTarget, interfaceFor, + LinkInterfaceField::HeadInclude, iface); + this->ExpandLinkItems(kINTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE, + cmMakeRange(info->LibrariesHeadExclude), config, + headTarget, interfaceFor, + LinkInterfaceField::HeadExclude, iface); this->ExpandLinkItems(info->LibrariesProp, cmMakeRange(info->Libraries), - config, headTarget, interfaceFor, iface); + config, headTarget, interfaceFor, + LinkInterfaceField::Libraries, iface); std::vector<std::string> deps = cmExpandedList(info->SharedDeps); LookupLinkItemScope scope{ this->LocalGenerator }; for (std::string const& dep : deps) { - if (cm::optional<cmLinkItem> maybeItem = - this->LookupLinkItem(dep, cmListFileBacktrace(), &scope)) { + if (cm::optional<cmLinkItem> maybeItem = this->LookupLinkItem( + dep, cmListFileBacktrace(), &scope, LookupSelf::No)) { iface.SharedDeps.emplace_back(std::move(*maybeItem)); } } @@ -7482,6 +7523,14 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config, } } } + for (BT<std::string> const& entry : + this->Target->GetLinkInterfaceDirectEntries()) { + info.LibrariesHeadInclude.emplace_back(entry); + } + for (BT<std::string> const& entry : + this->Target->GetLinkInterfaceDirectExcludeEntries()) { + info.LibrariesHeadExclude.emplace_back(entry); + } if (this->GetType() == cmStateEnums::INTERFACE_LIBRARY) { if (loc) { info.LibName = *loc; @@ -7896,9 +7945,9 @@ cmGeneratorTarget::GetLinkImplementationLibrariesInternal( this->LinkImplMap[cmSystemTools::UpperCase(config)]; // If the link implementation does not depend on the head target - // then return the one we computed first. + // then re-use the one from the head we computed first. if (!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition) { - return &hm.begin()->second; + head = hm.begin()->first; } cmOptionalLinkImplementation& impl = hm[head]; @@ -7915,6 +7964,112 @@ bool cmGeneratorTarget::IsNullImpliedByLinkLibraries( return cm::contains(this->LinkImplicitNullProperties, p); } +namespace { +class TransitiveLinkImpl +{ + cmGeneratorTarget const* Self; + std::string const& Config; + cmLinkImplementation& Impl; + + std::set<cmLinkItem> Emitted; + std::set<cmLinkItem> Excluded; + std::unordered_set<cmGeneratorTarget const*> Followed; + + void Follow(cmGeneratorTarget const* target); + +public: + TransitiveLinkImpl(cmGeneratorTarget const* self, std::string const& config, + cmLinkImplementation& impl) + : Self(self) + , Config(config) + , Impl(impl) + { + } + + void Compute(); +}; + +void TransitiveLinkImpl::Follow(cmGeneratorTarget const* target) +{ + if (!target || !this->Followed.insert(target).second || + target->GetPolicyStatusCMP0022() == cmPolicies::OLD || + target->GetPolicyStatusCMP0022() == cmPolicies::WARN) { + return; + } + + // Get this target's usage requirements. + cmLinkInterfaceLibraries const* iface = target->GetLinkInterfaceLibraries( + this->Config, this->Self, LinkInterfaceFor::Usage); + if (!iface) { + return; + } + if (iface->HadContextSensitiveCondition) { + this->Impl.HadContextSensitiveCondition = true; + } + + // Process 'INTERFACE_LINK_LIBRARIES_DIRECT' usage requirements. + for (cmLinkItem const& item : iface->HeadInclude) { + // Inject direct dependencies from the item's usage requirements + // before the item itself. + this->Follow(item.Target); + + // Add the item itself, but at most once. + if (this->Emitted.insert(item).second) { + this->Impl.Libraries.emplace_back(item, /* checkCMP0027= */ false); + } + } + + // Follow transitive dependencies. + for (cmLinkItem const& item : iface->Libraries) { + this->Follow(item.Target); + } + + // Record exclusions from 'INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE' + // usage requirements. + for (cmLinkItem const& item : iface->HeadExclude) { + this->Excluded.insert(item); + } +} + +void TransitiveLinkImpl::Compute() +{ + // Save the original items and start with an empty list. + std::vector<cmLinkImplItem> original = std::move(this->Impl.Libraries); + + // Avoid injecting any original items as usage requirements. + // This gives LINK_LIBRARIES final control over the order + // if it explicitly lists everything. + this->Emitted.insert(original.cbegin(), original.cend()); + + // Process each original item. + for (cmLinkImplItem& item : original) { + // Inject direct dependencies listed in 'INTERFACE_LINK_LIBRARIES_DIRECT' + // usage requirements before the item itself. + this->Follow(item.Target); + + // Add the item itself. + this->Impl.Libraries.emplace_back(std::move(item)); + } + + // Remove items listed in 'INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE' + // usage requirements found through any dependency above. + this->Impl.Libraries.erase( + std::remove_if(this->Impl.Libraries.begin(), this->Impl.Libraries.end(), + [this](cmLinkImplItem const& item) { + return this->Excluded.find(item) != this->Excluded.end(); + }), + this->Impl.Libraries.end()); +} + +void ComputeLinkImplTransitive(cmGeneratorTarget const* self, + std::string const& config, + cmLinkImplementation& impl) +{ + TransitiveLinkImpl transitiveLinkImpl(self, config, impl); + transitiveLinkImpl.Compute(); +} +} + void cmGeneratorTarget::ComputeLinkImplementationLibraries( const std::string& config, cmOptionalLinkImplementation& impl, cmGeneratorTarget const* head) const @@ -7935,7 +8090,7 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries( std::string const& evaluated = cge->Evaluate(this->LocalGenerator, config, head, &dagChecker, nullptr, this->LinkerLanguage); - bool const fromGenex = evaluated != entry.Value; + bool const checkCMP0027 = evaluated != entry.Value; cmExpandList(evaluated, llibs); if (cge->GetHadHeadSensitiveCondition()) { impl.HadHeadSensitiveCondition = true; @@ -8009,7 +8164,7 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries( } } - impl.Libraries.emplace_back(std::move(item), fromGenex); + impl.Libraries.emplace_back(std::move(item), checkCMP0027); } std::set<std::string> const& seenProps = cge->GetSeenTargetProperties(); @@ -8021,6 +8176,11 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries( cge->GetMaxLanguageStandard(this, this->MaxLanguageStandards); } + // Update the list of direct link dependencies from usage requirements. + if (head == this) { + ComputeLinkImplTransitive(this, config, impl); + } + // Get the list of configurations considered to be DEBUG. std::vector<std::string> debugConfigs = this->Makefile->GetCMakeInstance()->GetDebugConfigs(); @@ -8102,6 +8262,26 @@ cmLinkItem cmGeneratorTarget::ResolveLinkItem(BT<std::string> const& name, return cmLinkItem(resolved.Target, false, bt); } +bool cmGeneratorTarget::HasPackageReferences() const +{ + return this->IsInBuildSystem() && + !this->GetProperty("VS_PACKAGE_REFERENCES")->empty(); +} + +std::vector<std::string> cmGeneratorTarget::GetPackageReferences() const +{ + std::vector<std::string> packageReferences; + + if (this->IsInBuildSystem()) { + if (cmValue vsPackageReferences = + this->GetProperty("VS_PACKAGE_REFERENCES")) { + cmExpandList(*vsPackageReferences, packageReferences); + } + } + + return packageReferences; +} + std::string cmGeneratorTarget::GetPDBDirectory(const std::string& config) const { if (OutputInfo const* info = this->GetOutputInfo(config)) { diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index 71212c4..45639c0 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -424,6 +424,9 @@ public: cmLinkItem ResolveLinkItem(BT<std::string> const& name, cmLocalGenerator const* lg) const; + bool HasPackageReferences() const; + std::vector<std::string> GetPackageReferences() const; + // Compute the set of languages compiled by the target. This is // computed every time it is called because the languages can change // when source file properties are changed and we do not have enough @@ -664,6 +667,9 @@ public: */ void ClearSourcesCache(); + // Do not use. This is only for a specific call site with a FIXME comment. + void ClearLinkInterfaceCache(); + void AddSource(const std::string& src, bool before = false); void AddTracedSources(std::vector<std::string> const& srcs); @@ -998,8 +1004,10 @@ private: std::string ImportLibrary; std::string LibName; std::string Languages; - std::vector<BT<std::string>> Libraries; std::string LibrariesProp; + std::vector<BT<std::string>> Libraries; + std::vector<BT<std::string>> LibrariesHeadInclude; + std::vector<BT<std::string>> LibrariesHeadExclude; std::string SharedDeps; }; @@ -1060,19 +1068,31 @@ private: bool IsLinkLookupScope(std::string const& n, cmLocalGenerator const*& lg) const; + enum class LinkInterfaceField + { + Libraries, + HeadExclude, + HeadInclude, + }; void ExpandLinkItems(std::string const& prop, cmBTStringRange entries, std::string const& config, const cmGeneratorTarget* headTarget, - LinkInterfaceFor interfaceFor, + LinkInterfaceFor interfaceFor, LinkInterfaceField field, cmLinkInterface& iface) const; struct LookupLinkItemScope { cmLocalGenerator const* LG; }; + enum class LookupSelf + { + No, + Yes, + }; cm::optional<cmLinkItem> LookupLinkItem(std::string const& n, cmListFileBacktrace const& bt, - LookupLinkItemScope* scope) const; + LookupLinkItemScope* scope, + LookupSelf lookupSelf) const; std::vector<BT<std::string>> GetSourceFilePaths( std::string const& config) const; diff --git a/Source/cmGlobalBorlandMakefileGenerator.cxx b/Source/cmGlobalBorlandMakefileGenerator.cxx index 5503619..776ee40 100644 --- a/Source/cmGlobalBorlandMakefileGenerator.cxx +++ b/Source/cmGlobalBorlandMakefileGenerator.cxx @@ -71,12 +71,13 @@ std::vector<cmGlobalGenerator::GeneratedMakeCommand> cmGlobalBorlandMakefileGenerator::GenerateBuildCommand( const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, std::vector<std::string> const& targetNames, - const std::string& config, bool fast, int /*jobs*/, bool verbose, + const std::string& config, int /*jobs*/, bool verbose, + const cmBuildOptions& buildOptions, std::vector<std::string> const& makeOptions) { return this->cmGlobalUnixMakefileGenerator3::GenerateBuildCommand( - makeProgram, projectName, projectDir, targetNames, config, fast, - cmake::NO_BUILD_PARALLEL_LEVEL, verbose, makeOptions); + makeProgram, projectName, projectDir, targetNames, config, + cmake::NO_BUILD_PARALLEL_LEVEL, verbose, buildOptions, makeOptions); } void cmGlobalBorlandMakefileGenerator::PrintBuildCommandAdvice( diff --git a/Source/cmGlobalBorlandMakefileGenerator.h b/Source/cmGlobalBorlandMakefileGenerator.h index 646dfff..a280b81 100644 --- a/Source/cmGlobalBorlandMakefileGenerator.h +++ b/Source/cmGlobalBorlandMakefileGenerator.h @@ -59,7 +59,8 @@ protected: std::vector<GeneratedMakeCommand> GenerateBuildCommand( const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, std::vector<std::string> const& targetNames, - const std::string& config, bool fast, int jobs, bool verbose, + const std::string& config, int jobs, bool verbose, + const cmBuildOptions& buildOptions = cmBuildOptions(), std::vector<std::string> const& makeOptions = std::vector<std::string>()) override; diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 6433681..156ecce 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -1994,16 +1994,19 @@ int cmGlobalGenerator::TryCompile(int jobs, const std::string& srcdir, } std::string config = mf->GetSafeDefinition("CMAKE_TRY_COMPILE_CONFIGURATION"); + cmBuildOptions defaultBuildOptions(false, fast, PackageResolveMode::Disable); + return this->Build(jobs, srcdir, bindir, projectName, newTarget, output, "", - config, false, fast, false, this->TryCompileTimeout); + config, defaultBuildOptions, false, + this->TryCompileTimeout); } std::vector<cmGlobalGenerator::GeneratedMakeCommand> cmGlobalGenerator::GenerateBuildCommand( const std::string& /*unused*/, const std::string& /*unused*/, const std::string& /*unused*/, std::vector<std::string> const& /*unused*/, - const std::string& /*unused*/, bool /*unused*/, int /*unused*/, - bool /*unused*/, std::vector<std::string> const& /*unused*/) + const std::string& /*unused*/, int /*unused*/, bool /*unused*/, + const cmBuildOptions& /*unused*/, std::vector<std::string> const& /*unused*/) { GeneratedMakeCommand makeCommand; makeCommand.Add("cmGlobalGenerator::GenerateBuildCommand not implemented"); @@ -2021,7 +2024,7 @@ int cmGlobalGenerator::Build( int jobs, const std::string& /*unused*/, const std::string& bindir, const std::string& projectName, const std::vector<std::string>& targets, std::string& output, const std::string& makeCommandCSTR, - const std::string& config, bool clean, bool fast, bool verbose, + const std::string& config, const cmBuildOptions& buildOptions, bool verbose, cmDuration timeout, cmSystemTools::OutputOption outputflag, std::vector<std::string> const& nativeOptions) { @@ -2053,9 +2056,9 @@ int cmGlobalGenerator::Build( std::string outputBuffer; std::string* outputPtr = &outputBuffer; - std::vector<GeneratedMakeCommand> makeCommand = - this->GenerateBuildCommand(makeCommandCSTR, projectName, bindir, targets, - realConfig, fast, jobs, verbose, nativeOptions); + std::vector<GeneratedMakeCommand> makeCommand = this->GenerateBuildCommand( + makeCommandCSTR, projectName, bindir, targets, realConfig, jobs, verbose, + buildOptions, nativeOptions); // Workaround to convince some commands to produce output. if (outputflag == cmSystemTools::OUTPUT_PASSTHROUGH && @@ -2064,10 +2067,11 @@ int cmGlobalGenerator::Build( } // should we do a clean first? - if (clean) { + if (buildOptions.Clean) { std::vector<GeneratedMakeCommand> cleanCommand = this->GenerateBuildCommand(makeCommandCSTR, projectName, bindir, - { "clean" }, realConfig, fast, jobs, verbose); + { "clean" }, realConfig, jobs, verbose, + buildOptions); output += "\nRun Clean Command:"; output += cleanCommand.front().Printable(); output += "\n"; diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 2406798..a43d4a6 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -20,6 +20,7 @@ #include "cm_codecvt.hxx" +#include "cmBuildOptions.h" #include "cmCustomCommandLines.h" #include "cmDuration.h" #include "cmExportSet.h" @@ -229,8 +230,8 @@ public: int jobs, const std::string& srcdir, const std::string& bindir, const std::string& projectName, std::vector<std::string> const& targetNames, std::string& output, - const std::string& makeProgram, const std::string& config, bool clean, - bool fast, bool verbose, cmDuration timeout, + const std::string& makeProgram, const std::string& config, + const cmBuildOptions& buildOptions, bool verbose, cmDuration timeout, cmSystemTools::OutputOption outputflag = cmSystemTools::OUTPUT_NONE, std::vector<std::string> const& nativeOptions = std::vector<std::string>()); @@ -248,7 +249,8 @@ public: virtual std::vector<GeneratedMakeCommand> GenerateBuildCommand( const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, std::vector<std::string> const& targetNames, - const std::string& config, bool fast, int jobs, bool verbose, + const std::string& config, int jobs, bool verbose, + const cmBuildOptions& buildOptions = cmBuildOptions(), std::vector<std::string> const& makeOptions = std::vector<std::string>()); virtual void PrintBuildCommandAdvice(std::ostream& os, int jobs) const; diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx index bf537b7..5e51dd2 100644 --- a/Source/cmGlobalGhsMultiGenerator.cxx +++ b/Source/cmGlobalGhsMultiGenerator.cxx @@ -510,7 +510,8 @@ std::vector<cmGlobalGenerator::GeneratedMakeCommand> cmGlobalGhsMultiGenerator::GenerateBuildCommand( const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, std::vector<std::string> const& targetNames, - const std::string& /*config*/, bool /*fast*/, int jobs, bool /*verbose*/, + const std::string& /*config*/, int jobs, bool /*verbose*/, + const cmBuildOptions& /*buildOptions*/, std::vector<std::string> const& makeOptions) { GeneratedMakeCommand makeCommand = {}; diff --git a/Source/cmGlobalGhsMultiGenerator.h b/Source/cmGlobalGhsMultiGenerator.h index 9076e0e..26ea3c7 100644 --- a/Source/cmGlobalGhsMultiGenerator.h +++ b/Source/cmGlobalGhsMultiGenerator.h @@ -9,6 +9,7 @@ #include <utility> #include <vector> +#include "cmBuildOptions.h" #include "cmGlobalGenerator.h" #include "cmGlobalGeneratorFactory.h" #include "cmTargetDepend.h" @@ -87,7 +88,8 @@ protected: std::vector<GeneratedMakeCommand> GenerateBuildCommand( const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, std::vector<std::string> const& targetNames, - const std::string& config, bool fast, int jobs, bool verbose, + const std::string& config, int jobs, bool verbose, + const cmBuildOptions& buildOptions = cmBuildOptions(), std::vector<std::string> const& makeOptions = std::vector<std::string>()) override; diff --git a/Source/cmGlobalJOMMakefileGenerator.cxx b/Source/cmGlobalJOMMakefileGenerator.cxx index 1b406a6..1a625cc 100644 --- a/Source/cmGlobalJOMMakefileGenerator.cxx +++ b/Source/cmGlobalJOMMakefileGenerator.cxx @@ -63,7 +63,8 @@ std::vector<cmGlobalGenerator::GeneratedMakeCommand> cmGlobalJOMMakefileGenerator::GenerateBuildCommand( const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, std::vector<std::string> const& targetNames, - const std::string& config, bool fast, int jobs, bool verbose, + const std::string& config, int jobs, bool verbose, + const cmBuildOptions& buildOptions, std::vector<std::string> const& makeOptions) { std::vector<std::string> jomMakeOptions; @@ -81,6 +82,6 @@ cmGlobalJOMMakefileGenerator::GenerateBuildCommand( } return cmGlobalUnixMakefileGenerator3::GenerateBuildCommand( - makeProgram, projectName, projectDir, targetNames, config, fast, jobs, - verbose, jomMakeOptions); + makeProgram, projectName, projectDir, targetNames, config, jobs, verbose, + buildOptions, jomMakeOptions); } diff --git a/Source/cmGlobalJOMMakefileGenerator.h b/Source/cmGlobalJOMMakefileGenerator.h index 8229745..332d1cf 100644 --- a/Source/cmGlobalJOMMakefileGenerator.h +++ b/Source/cmGlobalJOMMakefileGenerator.h @@ -52,7 +52,8 @@ protected: std::vector<GeneratedMakeCommand> GenerateBuildCommand( const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, std::vector<std::string> const& targetNames, - const std::string& config, bool fast, int jobs, bool verbose, + const std::string& config, int jobs, bool verbose, + const cmBuildOptions& buildOptions = cmBuildOptions(), std::vector<std::string> const& makeOptions = std::vector<std::string>()) override; diff --git a/Source/cmGlobalNMakeMakefileGenerator.cxx b/Source/cmGlobalNMakeMakefileGenerator.cxx index 9f3d30e..55748cf 100644 --- a/Source/cmGlobalNMakeMakefileGenerator.cxx +++ b/Source/cmGlobalNMakeMakefileGenerator.cxx @@ -106,7 +106,8 @@ std::vector<cmGlobalGenerator::GeneratedMakeCommand> cmGlobalNMakeMakefileGenerator::GenerateBuildCommand( const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, std::vector<std::string> const& targetNames, - const std::string& config, bool fast, int /*jobs*/, bool verbose, + const std::string& config, int /*jobs*/, bool verbose, + const cmBuildOptions& buildOptions, std::vector<std::string> const& makeOptions) { std::vector<std::string> nmakeMakeOptions; @@ -117,8 +118,8 @@ cmGlobalNMakeMakefileGenerator::GenerateBuildCommand( cm::append(nmakeMakeOptions, makeOptions); return this->cmGlobalUnixMakefileGenerator3::GenerateBuildCommand( - makeProgram, projectName, projectDir, targetNames, config, fast, - cmake::NO_BUILD_PARALLEL_LEVEL, verbose, nmakeMakeOptions); + makeProgram, projectName, projectDir, targetNames, config, + cmake::NO_BUILD_PARALLEL_LEVEL, verbose, buildOptions, nmakeMakeOptions); } void cmGlobalNMakeMakefileGenerator::PrintBuildCommandAdvice(std::ostream& os, diff --git a/Source/cmGlobalNMakeMakefileGenerator.h b/Source/cmGlobalNMakeMakefileGenerator.h index ca5b8d6..b3574eb 100644 --- a/Source/cmGlobalNMakeMakefileGenerator.h +++ b/Source/cmGlobalNMakeMakefileGenerator.h @@ -58,7 +58,8 @@ protected: std::vector<GeneratedMakeCommand> GenerateBuildCommand( const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, std::vector<std::string> const& targetNames, - const std::string& config, bool fast, int jobs, bool verbose, + const std::string& config, int jobs, bool verbose, + const cmBuildOptions& buildOptions = cmBuildOptions(), std::vector<std::string> const& makeOptions = std::vector<std::string>()) override; diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 19c4ee3..4245037 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -166,14 +166,18 @@ std::string cmGlobalNinjaGenerator::EncodeRuleName(std::string const& name) std::string cmGlobalNinjaGenerator::EncodeLiteral(const std::string& lit) { std::string result = lit; - cmSystemTools::ReplaceString(result, "$", "$$"); - cmSystemTools::ReplaceString(result, "\n", "$\n"); + EncodeLiteralInplace(result); + return result; +} + +void cmGlobalNinjaGenerator::EncodeLiteralInplace(std::string& lit) +{ + cmSystemTools::ReplaceString(lit, "$", "$$"); + cmSystemTools::ReplaceString(lit, "\n", "$\n"); if (this->IsMultiConfig()) { - cmSystemTools::ReplaceString(result, - cmStrCat('$', this->GetCMakeCFGIntDir()), + cmSystemTools::ReplaceString(lit, cmStrCat('$', this->GetCMakeCFGIntDir()), this->GetCMakeCFGIntDir()); } - return result; } std::string cmGlobalNinjaGenerator::EncodePath(const std::string& path) @@ -185,7 +189,7 @@ std::string cmGlobalNinjaGenerator::EncodePath(const std::string& path) else std::replace(result.begin(), result.end(), '/', '\\'); #endif - result = this->EncodeLiteral(result); + this->EncodeLiteralInplace(result); cmSystemTools::ReplaceString(result, " ", "$ "); cmSystemTools::ReplaceString(result, ":", "$:"); return result; @@ -955,7 +959,7 @@ cmGlobalNinjaGenerator::GenerateBuildCommand( const std::string& makeProgram, const std::string& /*projectName*/, const std::string& /*projectDir*/, std::vector<std::string> const& targetNames, const std::string& config, - bool /*fast*/, int jobs, bool verbose, + int jobs, bool verbose, const cmBuildOptions& /*buildOptions*/, std::vector<std::string> const& makeOptions) { GeneratedMakeCommand makeCommand; @@ -1021,6 +1025,19 @@ bool cmGlobalNinjaGenerator::OpenBuildFileStreams() return false; } + // New buffer size 8 MiB + constexpr auto buildFileStreamBufferSize = 8 * 1024 * 1024; + + // Ensure the buffer is allocated + if (!this->BuildFileStreamBuffer) { + this->BuildFileStreamBuffer = + cm::make_unique<char[]>(buildFileStreamBufferSize); + } + + // Enlarge the internal buffer of the `BuildFileStream` + this->BuildFileStream->rdbuf()->pubsetbuf(this->BuildFileStreamBuffer.get(), + buildFileStreamBufferSize); + // Write a comment about this file. *this->BuildFileStream << "# This file contains all the build statements describing the\n" diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index 84fc06c..aa2df4d 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -18,6 +18,7 @@ #include "cm_codecvt.hxx" +#include "cmBuildOptions.h" #include "cmGeneratedFileStream.h" #include "cmGlobalCommonGenerator.h" #include "cmGlobalGeneratorFactory.h" @@ -77,6 +78,7 @@ public: static std::string EncodeRuleName(std::string const& name); std::string EncodeLiteral(const std::string& lit); + void EncodeLiteralInplace(std::string& lit); std::string EncodePath(const std::string& path); std::unique_ptr<cmLinkLineComputer> CreateLinkLineComputer( @@ -199,7 +201,8 @@ public: std::vector<GeneratedMakeCommand> GenerateBuildCommand( const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, std::vector<std::string> const& targetNames, - const std::string& config, bool fast, int jobs, bool verbose, + const std::string& config, int jobs, bool verbose, + const cmBuildOptions& buildOptions = cmBuildOptions(), std::vector<std::string> const& makeOptions = std::vector<std::string>()) override; @@ -526,6 +529,7 @@ private: /// The file containing the build statement. (the relationship of the /// compilation DAG). std::unique_ptr<cmGeneratedFileStream> BuildFileStream; + std::unique_ptr<char[]> BuildFileStreamBuffer; /// The file containing the rule statements. (The action attached to each /// edge of the compilation DAG). std::unique_ptr<cmGeneratedFileStream> RulesFileStream; diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx index 0556540..ab9ca50 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.cxx +++ b/Source/cmGlobalUnixMakefileGenerator3.cxx @@ -518,7 +518,7 @@ cmGlobalUnixMakefileGenerator3::GenerateBuildCommand( const std::string& makeProgram, const std::string& /*projectName*/, const std::string& /*projectDir*/, std::vector<std::string> const& targetNames, const std::string& /*config*/, - bool fast, int jobs, bool verbose, + int jobs, bool verbose, const cmBuildOptions& buildOptions, std::vector<std::string> const& makeOptions) { GeneratedMakeCommand makeCommand; @@ -548,7 +548,7 @@ cmGlobalUnixMakefileGenerator3::GenerateBuildCommand( makeCommand.Add(makeOptions.begin(), makeOptions.end()); for (auto tname : targetNames) { if (!tname.empty()) { - if (fast) { + if (buildOptions.Fast) { tname += "/fast"; } cmSystemTools::ConvertToOutputSlashes(tname); diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h index 94ee476..5157826 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.h +++ b/Source/cmGlobalUnixMakefileGenerator3.h @@ -12,6 +12,7 @@ #include <string> #include <vector> +#include "cmBuildOptions.h" #include "cmGeneratorTarget.h" #include "cmGlobalCommonGenerator.h" #include "cmGlobalGeneratorFactory.h" @@ -163,7 +164,8 @@ public: std::vector<GeneratedMakeCommand> GenerateBuildCommand( const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, std::vector<std::string> const& targetNames, - const std::string& config, bool fast, int jobs, bool verbose, + const std::string& config, int jobs, bool verbose, + const cmBuildOptions& buildOptions = cmBuildOptions(), std::vector<std::string> const& makeOptions = std::vector<std::string>()) override; diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx index d7bc05d..a52c831 100644 --- a/Source/cmGlobalVisualStudio10Generator.cxx +++ b/Source/cmGlobalVisualStudio10Generator.cxx @@ -170,7 +170,7 @@ cmGlobalVisualStudio10Generator::cmGlobalVisualStudio10Generator( this->DefaultNasmFlagTableName = "v10"; this->DefaultRCFlagTableName = "v10"; - this->Version = VS10; + this->Version = VSVersion::VS10; this->PlatformToolsetNeedsDebugEnum = false; } @@ -277,8 +277,8 @@ bool cmGlobalVisualStudio10Generator::SetGeneratorToolset( } this->SupportsUnityBuilds = - this->Version >= cmGlobalVisualStudioGenerator::VS16 || - (this->Version == cmGlobalVisualStudioGenerator::VS15 && + this->Version >= cmGlobalVisualStudioGenerator::VSVersion::VS16 || + (this->Version == cmGlobalVisualStudioGenerator::VSVersion::VS15 && cmSystemTools::PathExists(this->VCTargetsPath + "/Microsoft.Cpp.Unity.targets")); @@ -591,7 +591,7 @@ bool cmGlobalVisualStudio10Generator::InitializeWindowsCE(cmMakefile* mf) this->DefaultPlatformToolset = this->SelectWindowsCEToolset(); - if (this->GetVersion() == cmGlobalVisualStudioGenerator::VS12) { + if (this->GetVersion() == cmGlobalVisualStudioGenerator::VSVersion::VS12) { // VS 12 .NET CF defaults to .NET framework 3.9 for Windows CE. this->DefaultTargetFrameworkVersion = "v3.9"; this->DefaultTargetFrameworkIdentifier = "WindowsEmbeddedCompact"; @@ -724,6 +724,10 @@ void cmGlobalVisualStudio10Generator::Generate() /* clang-format on */ lg->IssueMessage(MessageType::WARNING, e.str()); } + if (cmValue cached = this->CMakeInstance->GetState()->GetCacheEntryValue( + "CMAKE_VS_NUGET_PACKAGE_RESTORE")) { + this->CMakeInstance->MarkCliAsUsed("CMAKE_VS_NUGET_PACKAGE_RESTORE"); + } } void cmGlobalVisualStudio10Generator::EnableLanguage( @@ -1099,7 +1103,8 @@ std::vector<cmGlobalGenerator::GeneratedMakeCommand> cmGlobalVisualStudio10Generator::GenerateBuildCommand( const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, std::vector<std::string> const& targetNames, - const std::string& config, bool fast, int jobs, bool verbose, + const std::string& config, int jobs, bool verbose, + const cmBuildOptions& buildOptions, std::vector<std::string> const& makeOptions) { std::vector<GeneratedMakeCommand> makeCommands; @@ -1145,8 +1150,8 @@ cmGlobalVisualStudio10Generator::GenerateBuildCommand( if (useDevEnv) { // Use devenv to build solutions containing Intel Fortran projects. return cmGlobalVisualStudio7Generator::GenerateBuildCommand( - makeProgram, projectName, projectDir, targetNames, config, fast, jobs, - verbose, makeOptions); + makeProgram, projectName, projectDir, targetNames, config, jobs, verbose, + buildOptions, makeOptions); } std::vector<std::string> realTargetNames = targetNames; @@ -1178,8 +1183,66 @@ cmGlobalVisualStudio10Generator::GenerateBuildCommand( cmSystemTools::ConvertToUnixSlashes(targetProject); } } - makeCommand.Add(std::move(targetProject)); + makeCommand.Add(targetProject); + + // Check if we do need a restore at all (i.e. if there are package + // references and restore has not been disabled by a command line option. + PackageResolveMode restoreMode = buildOptions.ResolveMode; + bool requiresRestore = true; + + if (restoreMode == PackageResolveMode::Disable) { + requiresRestore = false; + } else if (cmValue cached = + this->CMakeInstance->GetState()->GetCacheEntryValue( + tname + "_REQUIRES_VS_PACKAGE_RESTORE")) { + requiresRestore = cached.IsOn(); + } else { + // There are no package references defined. + requiresRestore = false; + } + + // If a restore is required, evaluate the restore mode. + if (requiresRestore) { + if (restoreMode == PackageResolveMode::OnlyResolve) { + // Only invoke the restore target on the project. + makeCommand.Add("/t:Restore"); + } else { + // Invoke restore target, unless it has been explicitly disabled. + bool restorePackages = true; + + if (this->Version < VSVersion::VS15) { + // Package restore is only supported starting from Visual Studio + // 2017. Package restore must be executed manually using NuGet + // shell for older versions. + this->CMakeInstance->IssueMessage( + MessageType::WARNING, + "Restoring package references is only supported for Visual " + "Studio 2017 and later. You have to manually restore the " + "packages using NuGet before building the project."); + restorePackages = false; + } else if (restoreMode == PackageResolveMode::FromCacheVariable) { + // Decide if a restore is performed, based on a cache variable. + if (cmValue cached = + this->CMakeInstance->GetState()->GetCacheEntryValue( + "CMAKE_VS_NUGET_PACKAGE_RESTORE")) + restorePackages = cached.IsOn(); + } + + if (restorePackages) { + if (this->IsMsBuildRestoreSupported()) { + makeCommand.Add("/restore"); + } else { + GeneratedMakeCommand restoreCommand; + restoreCommand.Add(makeProgramSelected); + restoreCommand.Add(targetProject); + restoreCommand.Add("/t:Restore"); + makeCommands.emplace_back(restoreCommand); + } + } + } + } } + std::string configArg = "/p:Configuration="; if (!config.empty()) { configArg += config; @@ -1284,23 +1347,23 @@ std::string cmGlobalVisualStudio10Generator::Encoding() const char* cmGlobalVisualStudio10Generator::GetToolsVersion() const { switch (this->Version) { - case cmGlobalVisualStudioGenerator::VS9: - case cmGlobalVisualStudioGenerator::VS10: - case cmGlobalVisualStudioGenerator::VS11: + case cmGlobalVisualStudioGenerator::VSVersion::VS9: + case cmGlobalVisualStudioGenerator::VSVersion::VS10: + case cmGlobalVisualStudioGenerator::VSVersion::VS11: return "4.0"; // in Visual Studio 2013 they detached the MSBuild tools version // from the .Net Framework version and instead made it have it's own // version number - case cmGlobalVisualStudioGenerator::VS12: + case cmGlobalVisualStudioGenerator::VSVersion::VS12: return "12.0"; - case cmGlobalVisualStudioGenerator::VS14: + case cmGlobalVisualStudioGenerator::VSVersion::VS14: return "14.0"; - case cmGlobalVisualStudioGenerator::VS15: + case cmGlobalVisualStudioGenerator::VSVersion::VS15: return "15.0"; - case cmGlobalVisualStudioGenerator::VS16: + case cmGlobalVisualStudioGenerator::VSVersion::VS16: return "16.0"; - case cmGlobalVisualStudioGenerator::VS17: + case cmGlobalVisualStudioGenerator::VSVersion::VS17: return "17.0"; } return ""; @@ -1559,6 +1622,18 @@ cmIDEFlagTable const* cmGlobalVisualStudio10Generator::GetNasmFlagTable() const return LoadFlagTable(std::string(), this->DefaultNasmFlagTableName, "NASM"); } +bool cmGlobalVisualStudio10Generator::IsMsBuildRestoreSupported() const +{ + if (this->Version >= VSVersion::VS16) { + return true; + } + + static std::string const vsVer15_7_5 = "15.7.27703.2042"; + cm::optional<std::string> vsVer = this->GetVSInstanceVersion(); + return (vsVer && + cmSystemTools::VersionCompareGreaterEq(*vsVer, vsVer15_7_5)); +} + std::string cmGlobalVisualStudio10Generator::GetClFlagTableName() const { std::string const& toolset = this->GetPlatformToolsetString(); diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h index c8fd149..4977a84 100644 --- a/Source/cmGlobalVisualStudio10Generator.h +++ b/Source/cmGlobalVisualStudio10Generator.h @@ -43,7 +43,8 @@ public: std::vector<GeneratedMakeCommand> GenerateBuildCommand( const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, std::vector<std::string> const& targetNames, - const std::string& config, bool fast, int jobs, bool verbose, + const std::string& config, int jobs, bool verbose, + const cmBuildOptions& buildOptions = cmBuildOptions(), std::vector<std::string> const& makeOptions = std::vector<std::string>()) override; @@ -172,6 +173,8 @@ public: cmIDEFlagTable const* GetMasmFlagTable() const; cmIDEFlagTable const* GetNasmFlagTable() const; + bool IsMsBuildRestoreSupported() const; + protected: cmGlobalVisualStudio10Generator(cmake* cm, const std::string& name, std::string const& platformInGeneratorName); diff --git a/Source/cmGlobalVisualStudio11Generator.cxx b/Source/cmGlobalVisualStudio11Generator.cxx index 6126cb4..10dc258 100644 --- a/Source/cmGlobalVisualStudio11Generator.cxx +++ b/Source/cmGlobalVisualStudio11Generator.cxx @@ -148,7 +148,7 @@ cmGlobalVisualStudio11Generator::cmGlobalVisualStudio11Generator( this->DefaultLinkFlagTableName = "v11"; this->DefaultMasmFlagTableName = "v11"; this->DefaultRCFlagTableName = "v11"; - this->Version = VS11; + this->Version = VSVersion::VS11; } bool cmGlobalVisualStudio11Generator::MatchesGeneratorName( diff --git a/Source/cmGlobalVisualStudio12Generator.cxx b/Source/cmGlobalVisualStudio12Generator.cxx index d8c1b43..12ffa5b 100644 --- a/Source/cmGlobalVisualStudio12Generator.cxx +++ b/Source/cmGlobalVisualStudio12Generator.cxx @@ -122,7 +122,7 @@ cmGlobalVisualStudio12Generator::cmGlobalVisualStudio12Generator( this->DefaultLinkFlagTableName = "v12"; this->DefaultMasmFlagTableName = "v12"; this->DefaultRCFlagTableName = "v12"; - this->Version = VS12; + this->Version = VSVersion::VS12; } bool cmGlobalVisualStudio12Generator::MatchesGeneratorName( diff --git a/Source/cmGlobalVisualStudio14Generator.cxx b/Source/cmGlobalVisualStudio14Generator.cxx index 014668f..9f94cca 100644 --- a/Source/cmGlobalVisualStudio14Generator.cxx +++ b/Source/cmGlobalVisualStudio14Generator.cxx @@ -125,7 +125,7 @@ cmGlobalVisualStudio14Generator::cmGlobalVisualStudio14Generator( this->DefaultLinkFlagTableName = "v140"; this->DefaultMasmFlagTableName = "v14"; this->DefaultRCFlagTableName = "v14"; - this->Version = VS14; + this->Version = VSVersion::VS14; } bool cmGlobalVisualStudio14Generator::MatchesGeneratorName( diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx index c72b109..134937e 100644 --- a/Source/cmGlobalVisualStudio7Generator.cxx +++ b/Source/cmGlobalVisualStudio7Generator.cxx @@ -212,7 +212,7 @@ cmGlobalVisualStudio7Generator::GenerateBuildCommand( const std::string& makeProgram, const std::string& projectName, const std::string& /*projectDir*/, std::vector<std::string> const& targetNames, const std::string& config, - bool /*fast*/, int /*jobs*/, bool /*verbose*/, + int /*jobs*/, bool /*verbose*/, const cmBuildOptions& /*buildOptions*/, std::vector<std::string> const& makeOptions) { // Select the caller- or user-preferred make program, else devenv. @@ -304,7 +304,8 @@ void cmGlobalVisualStudio7Generator::Generate() GetSLNFile(this->LocalGenerators[0].get())); } - if (this->Version == VS10 && !this->CMakeInstance->GetIsInTryCompile()) { + if (this->Version == VSVersion::VS10 && + !this->CMakeInstance->GetIsInTryCompile()) { std::string cmakeWarnVS10; if (cmValue cached = this->CMakeInstance->GetState()->GetCacheEntryValue( "CMAKE_WARN_VS10")) { diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h index d1fb804..33f1063 100644 --- a/Source/cmGlobalVisualStudio7Generator.h +++ b/Source/cmGlobalVisualStudio7Generator.h @@ -69,7 +69,8 @@ public: std::vector<GeneratedMakeCommand> GenerateBuildCommand( const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, std::vector<std::string> const& targetNames, - const std::string& config, bool fast, int jobs, bool verbose, + const std::string& config, int jobs, bool verbose, + const cmBuildOptions& buildOptions = cmBuildOptions(), std::vector<std::string> const& makeOptions = std::vector<std::string>()) override; diff --git a/Source/cmGlobalVisualStudio9Generator.cxx b/Source/cmGlobalVisualStudio9Generator.cxx index 5f867f5..e03e665 100644 --- a/Source/cmGlobalVisualStudio9Generator.cxx +++ b/Source/cmGlobalVisualStudio9Generator.cxx @@ -124,7 +124,7 @@ cmGlobalVisualStudio9Generator::cmGlobalVisualStudio9Generator( std::string const& platformInGeneratorName) : cmGlobalVisualStudio8Generator(cm, name, platformInGeneratorName) { - this->Version = VS9; + this->Version = VSVersion::VS9; std::string vc9Express; this->ExpressEdition = cmSystemTools::ReadRegistryValue( "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\9.0\\Setup\\VC;" diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx index 948fa53..141b5eb 100644 --- a/Source/cmGlobalVisualStudioGenerator.cxx +++ b/Source/cmGlobalVisualStudioGenerator.cxx @@ -97,21 +97,21 @@ std::string const& cmGlobalVisualStudioGenerator::GetPlatformName() const const char* cmGlobalVisualStudioGenerator::GetIDEVersion() const { switch (this->Version) { - case cmGlobalVisualStudioGenerator::VS9: + case cmGlobalVisualStudioGenerator::VSVersion::VS9: return "9.0"; - case cmGlobalVisualStudioGenerator::VS10: + case cmGlobalVisualStudioGenerator::VSVersion::VS10: return "10.0"; - case cmGlobalVisualStudioGenerator::VS11: + case cmGlobalVisualStudioGenerator::VSVersion::VS11: return "11.0"; - case cmGlobalVisualStudioGenerator::VS12: + case cmGlobalVisualStudioGenerator::VSVersion::VS12: return "12.0"; - case cmGlobalVisualStudioGenerator::VS14: + case cmGlobalVisualStudioGenerator::VSVersion::VS14: return "14.0"; - case cmGlobalVisualStudioGenerator::VS15: + case cmGlobalVisualStudioGenerator::VSVersion::VS15: return "15.0"; - case cmGlobalVisualStudioGenerator::VS16: + case cmGlobalVisualStudioGenerator::VSVersion::VS16: return "16.0"; - case cmGlobalVisualStudioGenerator::VS17: + case cmGlobalVisualStudioGenerator::VSVersion::VS17: return "17.0"; } return ""; @@ -124,11 +124,11 @@ void cmGlobalVisualStudioGenerator::WriteSLNHeader(std::ostream& fout) fout << '\n'; switch (this->Version) { - case cmGlobalVisualStudioGenerator::VS9: + case cmGlobalVisualStudioGenerator::VSVersion::VS9: fout << "Microsoft Visual Studio Solution File, Format Version 10.00\n"; fout << "# Visual Studio 2008\n"; break; - case cmGlobalVisualStudioGenerator::VS10: + case cmGlobalVisualStudioGenerator::VSVersion::VS10: fout << "Microsoft Visual Studio Solution File, Format Version 11.00\n"; if (this->ExpressEdition) { fout << "# Visual C++ Express 2010\n"; @@ -136,7 +136,7 @@ void cmGlobalVisualStudioGenerator::WriteSLNHeader(std::ostream& fout) fout << "# Visual Studio 2010\n"; } break; - case cmGlobalVisualStudioGenerator::VS11: + case cmGlobalVisualStudioGenerator::VSVersion::VS11: fout << "Microsoft Visual Studio Solution File, Format Version 12.00\n"; if (this->ExpressEdition) { fout << "# Visual Studio Express 2012 for Windows Desktop\n"; @@ -144,7 +144,7 @@ void cmGlobalVisualStudioGenerator::WriteSLNHeader(std::ostream& fout) fout << "# Visual Studio 2012\n"; } break; - case cmGlobalVisualStudioGenerator::VS12: + case cmGlobalVisualStudioGenerator::VSVersion::VS12: fout << "Microsoft Visual Studio Solution File, Format Version 12.00\n"; if (this->ExpressEdition) { fout << "# Visual Studio Express 2013 for Windows Desktop\n"; @@ -152,7 +152,7 @@ void cmGlobalVisualStudioGenerator::WriteSLNHeader(std::ostream& fout) fout << "# Visual Studio 2013\n"; } break; - case cmGlobalVisualStudioGenerator::VS14: + case cmGlobalVisualStudioGenerator::VSVersion::VS14: // Visual Studio 14 writes .sln format 12.00 fout << "Microsoft Visual Studio Solution File, Format Version 12.00\n"; if (this->ExpressEdition) { @@ -161,7 +161,7 @@ void cmGlobalVisualStudioGenerator::WriteSLNHeader(std::ostream& fout) fout << "# Visual Studio 14\n"; } break; - case cmGlobalVisualStudioGenerator::VS15: + case cmGlobalVisualStudioGenerator::VSVersion::VS15: // Visual Studio 15 writes .sln format 12.00 fout << "Microsoft Visual Studio Solution File, Format Version 12.00\n"; if (this->ExpressEdition) { @@ -170,7 +170,7 @@ void cmGlobalVisualStudioGenerator::WriteSLNHeader(std::ostream& fout) fout << "# Visual Studio 15\n"; } break; - case cmGlobalVisualStudioGenerator::VS16: + case cmGlobalVisualStudioGenerator::VSVersion::VS16: // Visual Studio 16 writes .sln format 12.00 fout << "Microsoft Visual Studio Solution File, Format Version 12.00\n"; if (this->ExpressEdition) { @@ -179,7 +179,7 @@ void cmGlobalVisualStudioGenerator::WriteSLNHeader(std::ostream& fout) fout << "# Visual Studio Version 16\n"; } break; - case cmGlobalVisualStudioGenerator::VS17: + case cmGlobalVisualStudioGenerator::VSVersion::VS17: // Visual Studio 17 writes .sln format 12.00 fout << "Microsoft Visual Studio Solution File, Format Version 12.00\n"; if (this->ExpressEdition) { diff --git a/Source/cmGlobalVisualStudioGenerator.h b/Source/cmGlobalVisualStudioGenerator.h index 1eff135..cb1b14b 100644 --- a/Source/cmGlobalVisualStudioGenerator.h +++ b/Source/cmGlobalVisualStudioGenerator.h @@ -32,7 +32,7 @@ class cmGlobalVisualStudioGenerator : public cmGlobalGenerator { public: /** Known versions of Visual Studio. */ - enum VSVersion + enum class VSVersion : uint16_t { VS9 = 90, VS10 = 100, diff --git a/Source/cmGlobalVisualStudioVersionedGenerator.cxx b/Source/cmGlobalVisualStudioVersionedGenerator.cxx index ef8fee1..bc38335 100644 --- a/Source/cmGlobalVisualStudioVersionedGenerator.cxx +++ b/Source/cmGlobalVisualStudioVersionedGenerator.cxx @@ -75,21 +75,21 @@ static unsigned int VSVersionToMajor( cmGlobalVisualStudioGenerator::VSVersion v) { switch (v) { - case cmGlobalVisualStudioGenerator::VS9: + case cmGlobalVisualStudioGenerator::VSVersion::VS9: return 9; - case cmGlobalVisualStudioGenerator::VS10: + case cmGlobalVisualStudioGenerator::VSVersion::VS10: return 10; - case cmGlobalVisualStudioGenerator::VS11: + case cmGlobalVisualStudioGenerator::VSVersion::VS11: return 11; - case cmGlobalVisualStudioGenerator::VS12: + case cmGlobalVisualStudioGenerator::VSVersion::VS12: return 12; - case cmGlobalVisualStudioGenerator::VS14: + case cmGlobalVisualStudioGenerator::VSVersion::VS14: return 14; - case cmGlobalVisualStudioGenerator::VS15: + case cmGlobalVisualStudioGenerator::VSVersion::VS15: return 15; - case cmGlobalVisualStudioGenerator::VS16: + case cmGlobalVisualStudioGenerator::VSVersion::VS16: return 16; - case cmGlobalVisualStudioGenerator::VS17: + case cmGlobalVisualStudioGenerator::VSVersion::VS17: return 17; } return 0; @@ -99,21 +99,21 @@ static const char* VSVersionToToolset( cmGlobalVisualStudioGenerator::VSVersion v) { switch (v) { - case cmGlobalVisualStudioGenerator::VS9: + case cmGlobalVisualStudioGenerator::VSVersion::VS9: return "v90"; - case cmGlobalVisualStudioGenerator::VS10: + case cmGlobalVisualStudioGenerator::VSVersion::VS10: return "v100"; - case cmGlobalVisualStudioGenerator::VS11: + case cmGlobalVisualStudioGenerator::VSVersion::VS11: return "v110"; - case cmGlobalVisualStudioGenerator::VS12: + case cmGlobalVisualStudioGenerator::VSVersion::VS12: return "v120"; - case cmGlobalVisualStudioGenerator::VS14: + case cmGlobalVisualStudioGenerator::VSVersion::VS14: return "v140"; - case cmGlobalVisualStudioGenerator::VS15: + case cmGlobalVisualStudioGenerator::VSVersion::VS15: return "v141"; - case cmGlobalVisualStudioGenerator::VS16: + case cmGlobalVisualStudioGenerator::VSVersion::VS16: return "v142"; - case cmGlobalVisualStudioGenerator::VS17: + case cmGlobalVisualStudioGenerator::VSVersion::VS17: return "v143"; } return ""; @@ -123,21 +123,21 @@ static std::string VSVersionToMajorString( cmGlobalVisualStudioGenerator::VSVersion v) { switch (v) { - case cmGlobalVisualStudioGenerator::VS9: + case cmGlobalVisualStudioGenerator::VSVersion::VS9: return "9"; - case cmGlobalVisualStudioGenerator::VS10: + case cmGlobalVisualStudioGenerator::VSVersion::VS10: return "10"; - case cmGlobalVisualStudioGenerator::VS11: + case cmGlobalVisualStudioGenerator::VSVersion::VS11: return "11"; - case cmGlobalVisualStudioGenerator::VS12: + case cmGlobalVisualStudioGenerator::VSVersion::VS12: return "12"; - case cmGlobalVisualStudioGenerator::VS14: + case cmGlobalVisualStudioGenerator::VSVersion::VS14: return "14"; - case cmGlobalVisualStudioGenerator::VS15: + case cmGlobalVisualStudioGenerator::VSVersion::VS15: return "15"; - case cmGlobalVisualStudioGenerator::VS16: + case cmGlobalVisualStudioGenerator::VSVersion::VS16: return "16"; - case cmGlobalVisualStudioGenerator::VS17: + case cmGlobalVisualStudioGenerator::VSVersion::VS17: return "17"; } return ""; @@ -147,16 +147,16 @@ static const char* VSVersionToAndroidToolset( cmGlobalVisualStudioGenerator::VSVersion v) { switch (v) { - case cmGlobalVisualStudioGenerator::VS9: - case cmGlobalVisualStudioGenerator::VS10: - case cmGlobalVisualStudioGenerator::VS11: - case cmGlobalVisualStudioGenerator::VS12: + case cmGlobalVisualStudioGenerator::VSVersion::VS9: + case cmGlobalVisualStudioGenerator::VSVersion::VS10: + case cmGlobalVisualStudioGenerator::VSVersion::VS11: + case cmGlobalVisualStudioGenerator::VSVersion::VS12: return ""; - case cmGlobalVisualStudioGenerator::VS14: + case cmGlobalVisualStudioGenerator::VSVersion::VS14: return "Clang_3_8"; - case cmGlobalVisualStudioGenerator::VS15: - case cmGlobalVisualStudioGenerator::VS16: - case cmGlobalVisualStudioGenerator::VS17: + case cmGlobalVisualStudioGenerator::VSVersion::VS15: + case cmGlobalVisualStudioGenerator::VSVersion::VS16: + case cmGlobalVisualStudioGenerator::VSVersion::VS17: return "Clang_5_0"; } return ""; @@ -194,7 +194,7 @@ public: if (!*p) { return std::unique_ptr<cmGlobalGenerator>( new cmGlobalVisualStudioVersionedGenerator( - cmGlobalVisualStudioGenerator::VS15, cm, genName, "")); + cmGlobalVisualStudioGenerator::VSVersion::VS15, cm, genName, "")); } if (!allowArch || *p++ != ' ') { return std::unique_ptr<cmGlobalGenerator>(); @@ -202,12 +202,12 @@ public: if (strcmp(p, "Win64") == 0) { return std::unique_ptr<cmGlobalGenerator>( new cmGlobalVisualStudioVersionedGenerator( - cmGlobalVisualStudioGenerator::VS15, cm, genName, "x64")); + cmGlobalVisualStudioGenerator::VSVersion::VS15, cm, genName, "x64")); } if (strcmp(p, "ARM") == 0) { return std::unique_ptr<cmGlobalGenerator>( new cmGlobalVisualStudioVersionedGenerator( - cmGlobalVisualStudioGenerator::VS15, cm, genName, "ARM")); + cmGlobalVisualStudioGenerator::VSVersion::VS15, cm, genName, "ARM")); } return std::unique_ptr<cmGlobalGenerator>(); } @@ -303,7 +303,7 @@ public: if (!*p) { return std::unique_ptr<cmGlobalGenerator>( new cmGlobalVisualStudioVersionedGenerator( - cmGlobalVisualStudioGenerator::VS16, cm, genName, "")); + cmGlobalVisualStudioGenerator::VSVersion::VS16, cm, genName, "")); } return std::unique_ptr<cmGlobalGenerator>(); } @@ -368,7 +368,7 @@ public: if (!*p) { return std::unique_ptr<cmGlobalGenerator>( new cmGlobalVisualStudioVersionedGenerator( - cmGlobalVisualStudioGenerator::VS17, cm, genName, "")); + cmGlobalVisualStudioGenerator::VSVersion::VS17, cm, genName, "")); } return std::unique_ptr<cmGlobalGenerator>(); } @@ -431,11 +431,11 @@ cmGlobalVisualStudioVersionedGenerator::cmGlobalVisualStudioVersionedGenerator( this->DefaultCLFlagTableName = VSVersionToToolset(this->Version); this->DefaultCSharpFlagTableName = VSVersionToToolset(this->Version); this->DefaultLinkFlagTableName = VSVersionToToolset(this->Version); - if (this->Version >= cmGlobalVisualStudioGenerator::VS16) { + if (this->Version >= cmGlobalVisualStudioGenerator::VSVersion::VS16) { this->DefaultPlatformName = VSHostPlatformName(); this->DefaultPlatformToolsetHostArchitecture = VSHostArchitecture(); } - if (this->Version >= cmGlobalVisualStudioGenerator::VS17) { + if (this->Version >= cmGlobalVisualStudioGenerator::VSVersion::VS17) { // FIXME: Search for an existing framework? Under '%ProgramFiles(x86)%', // see 'Reference Assemblies\Microsoft\Framework\.NETFramework'. // Use a version installed by VS 2022 without a separate component. @@ -448,23 +448,23 @@ bool cmGlobalVisualStudioVersionedGenerator::MatchesGeneratorName( { std::string genName; switch (this->Version) { - case cmGlobalVisualStudioGenerator::VS9: - case cmGlobalVisualStudioGenerator::VS10: - case cmGlobalVisualStudioGenerator::VS11: - case cmGlobalVisualStudioGenerator::VS12: - case cmGlobalVisualStudioGenerator::VS14: + case cmGlobalVisualStudioGenerator::VSVersion::VS9: + case cmGlobalVisualStudioGenerator::VSVersion::VS10: + case cmGlobalVisualStudioGenerator::VSVersion::VS11: + case cmGlobalVisualStudioGenerator::VSVersion::VS12: + case cmGlobalVisualStudioGenerator::VSVersion::VS14: break; - case cmGlobalVisualStudioGenerator::VS15: + case cmGlobalVisualStudioGenerator::VSVersion::VS15: if (cmVS15GenName(name, genName)) { return genName == this->GetName(); } break; - case cmGlobalVisualStudioGenerator::VS16: + case cmGlobalVisualStudioGenerator::VSVersion::VS16: if (cmVS16GenName(name, genName)) { return genName == this->GetName(); } break; - case cmGlobalVisualStudioGenerator::VS17: + case cmGlobalVisualStudioGenerator::VSVersion::VS17: if (cmVS17GenName(name, genName)) { return genName == this->GetName(); } @@ -691,16 +691,16 @@ cmGlobalVisualStudioVersionedGenerator::GetAndroidApplicationTypeRevision() const { switch (this->Version) { - case cmGlobalVisualStudioGenerator::VS9: - case cmGlobalVisualStudioGenerator::VS10: - case cmGlobalVisualStudioGenerator::VS11: - case cmGlobalVisualStudioGenerator::VS12: + case cmGlobalVisualStudioGenerator::VSVersion::VS9: + case cmGlobalVisualStudioGenerator::VSVersion::VS10: + case cmGlobalVisualStudioGenerator::VSVersion::VS11: + case cmGlobalVisualStudioGenerator::VSVersion::VS12: return ""; - case cmGlobalVisualStudioGenerator::VS14: + case cmGlobalVisualStudioGenerator::VSVersion::VS14: return "2.0"; - case cmGlobalVisualStudioGenerator::VS15: - case cmGlobalVisualStudioGenerator::VS16: - case cmGlobalVisualStudioGenerator::VS17: + case cmGlobalVisualStudioGenerator::VSVersion::VS15: + case cmGlobalVisualStudioGenerator::VSVersion::VS16: + case cmGlobalVisualStudioGenerator::VSVersion::VS17: return "3.0"; } return ""; @@ -806,7 +806,7 @@ bool cmGlobalVisualStudioVersionedGenerator::InitializeWindows(cmMakefile* mf) // the target Windows version. if (this->IsWin81SDKInstalled()) { // VS 2019 does not default to 8.1 so specify it explicitly when needed. - if (this->Version >= cmGlobalVisualStudioGenerator::VS16 && + if (this->Version >= cmGlobalVisualStudioGenerator::VSVersion::VS16 && !cmSystemTools::VersionCompareGreater(this->SystemVersion, "8.1")) { this->SetWindowsTargetPlatformVersion("8.1", mf); return true; @@ -894,7 +894,7 @@ std::string cmGlobalVisualStudioVersionedGenerator::FindMSBuildCommand() // Ask Visual Studio Installer tool. std::string vs; if (vsSetupAPIHelper.GetVSInstanceInfo(vs)) { - if (this->Version >= cmGlobalVisualStudioGenerator::VS17) { + if (this->Version >= cmGlobalVisualStudioGenerator::VSVersion::VS17) { msbuild = vs + "/MSBuild/Current/Bin/amd64/MSBuild.exe"; if (cmSystemTools::FileExists(msbuild)) { return msbuild; diff --git a/Source/cmGlobalWatcomWMakeGenerator.cxx b/Source/cmGlobalWatcomWMakeGenerator.cxx index 3e2d92d..fb2a8b6 100644 --- a/Source/cmGlobalWatcomWMakeGenerator.cxx +++ b/Source/cmGlobalWatcomWMakeGenerator.cxx @@ -65,12 +65,13 @@ std::vector<cmGlobalGenerator::GeneratedMakeCommand> cmGlobalWatcomWMakeGenerator::GenerateBuildCommand( const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, std::vector<std::string> const& targetNames, - const std::string& config, bool fast, int /*jobs*/, bool verbose, + const std::string& config, int /*jobs*/, bool verbose, + const cmBuildOptions& buildOptions, std::vector<std::string> const& makeOptions) { return this->cmGlobalUnixMakefileGenerator3::GenerateBuildCommand( - makeProgram, projectName, projectDir, targetNames, config, fast, - cmake::NO_BUILD_PARALLEL_LEVEL, verbose, makeOptions); + makeProgram, projectName, projectDir, targetNames, config, + cmake::NO_BUILD_PARALLEL_LEVEL, verbose, buildOptions, makeOptions); } void cmGlobalWatcomWMakeGenerator::PrintBuildCommandAdvice(std::ostream& os, diff --git a/Source/cmGlobalWatcomWMakeGenerator.h b/Source/cmGlobalWatcomWMakeGenerator.h index da39d3f..eb93934 100644 --- a/Source/cmGlobalWatcomWMakeGenerator.h +++ b/Source/cmGlobalWatcomWMakeGenerator.h @@ -9,6 +9,7 @@ #include <string> #include <vector> +#include "cmBuildOptions.h" #include "cmGlobalGeneratorFactory.h" #include "cmGlobalUnixMakefileGenerator3.h" @@ -57,7 +58,8 @@ protected: std::vector<GeneratedMakeCommand> GenerateBuildCommand( const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, std::vector<std::string> const& targetNames, - const std::string& config, bool fast, int jobs, bool verbose, + const std::string& config, int jobs, bool verbose, + const cmBuildOptions& buildOptions = cmBuildOptions(), std::vector<std::string> const& makeOptions = std::vector<std::string>()) override; diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index bc2a6f7..203addd 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -478,7 +478,7 @@ cmGlobalXCodeGenerator::GenerateBuildCommand( const std::string& makeProgram, const std::string& projectName, const std::string& /*projectDir*/, std::vector<std::string> const& targetNames, const std::string& config, - bool /*fast*/, int jobs, bool /*verbose*/, + int jobs, bool /*verbose*/, const cmBuildOptions& /*buildOptions*/, std::vector<std::string> const& makeOptions) { GeneratedMakeCommand makeCommand; diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h index 5917db3..ff6ffe8 100644 --- a/Source/cmGlobalXCodeGenerator.h +++ b/Source/cmGlobalXCodeGenerator.h @@ -80,7 +80,8 @@ public: std::vector<GeneratedMakeCommand> GenerateBuildCommand( const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, std::vector<std::string> const& targetNames, - const std::string& config, bool fast, int jobs, bool verbose, + const std::string& config, int jobs, bool verbose, + const cmBuildOptions& buildOptions = cmBuildOptions(), std::vector<std::string> const& makeOptions = std::vector<std::string>()) override; diff --git a/Source/cmLinkItem.cxx b/Source/cmLinkItem.cxx index 62e7ef4..2dc40ff 100644 --- a/Source/cmLinkItem.cxx +++ b/Source/cmLinkItem.cxx @@ -68,8 +68,8 @@ cmLinkImplItem::cmLinkImplItem() { } -cmLinkImplItem::cmLinkImplItem(cmLinkItem item, bool fromGenex) +cmLinkImplItem::cmLinkImplItem(cmLinkItem item, bool checkCMP0027) : cmLinkItem(std::move(item)) - , FromGenex(fromGenex) + , CheckCMP0027(checkCMP0027) { } diff --git a/Source/cmLinkItem.h b/Source/cmLinkItem.h index 0863edd..262728b 100644 --- a/Source/cmLinkItem.h +++ b/Source/cmLinkItem.h @@ -40,8 +40,8 @@ class cmLinkImplItem : public cmLinkItem { public: cmLinkImplItem(); - cmLinkImplItem(cmLinkItem item, bool fromGenex); - bool FromGenex = false; + cmLinkImplItem(cmLinkItem item, bool checkCMP0027); + bool CheckCMP0027 = false; }; /** The link implementation specifies the direct library @@ -70,6 +70,12 @@ struct cmLinkInterfaceLibraries // Object files listed in the interface. std::vector<cmLinkItem> Objects; + // Items to be included as if directly linked by the head target. + std::vector<cmLinkItem> HeadInclude; + + // Items to be excluded from direct linking by the head target. + std::vector<cmLinkItem> HeadExclude; + // Whether the list depends on a genex referencing the head target. bool HadHeadSensitiveCondition = false; diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx index 9f8a18f..3da266d 100644 --- a/Source/cmListFileCache.cxx +++ b/Source/cmListFileCache.cxx @@ -369,68 +369,68 @@ cm::optional<cmListFileContext> cmListFileParser::CheckNesting() const if (name == "if") { stack.push_back({ NestingStateEnum::If, - cmListFileContext::FromCommandContext(func, this->FileName), + cmListFileContext::FromListFileFunction(func, this->FileName), }); } else if (name == "elseif") { if (!TopIs(stack, NestingStateEnum::If)) { - return cmListFileContext::FromCommandContext(func, this->FileName); + return cmListFileContext::FromListFileFunction(func, this->FileName); } stack.back() = { NestingStateEnum::If, - cmListFileContext::FromCommandContext(func, this->FileName), + cmListFileContext::FromListFileFunction(func, this->FileName), }; } else if (name == "else") { if (!TopIs(stack, NestingStateEnum::If)) { - return cmListFileContext::FromCommandContext(func, this->FileName); + return cmListFileContext::FromListFileFunction(func, this->FileName); } stack.back() = { NestingStateEnum::Else, - cmListFileContext::FromCommandContext(func, this->FileName), + cmListFileContext::FromListFileFunction(func, this->FileName), }; } else if (name == "endif") { if (!TopIs(stack, NestingStateEnum::If) && !TopIs(stack, NestingStateEnum::Else)) { - return cmListFileContext::FromCommandContext(func, this->FileName); + return cmListFileContext::FromListFileFunction(func, this->FileName); } stack.pop_back(); } else if (name == "while") { stack.push_back({ NestingStateEnum::While, - cmListFileContext::FromCommandContext(func, this->FileName), + cmListFileContext::FromListFileFunction(func, this->FileName), }); } else if (name == "endwhile") { if (!TopIs(stack, NestingStateEnum::While)) { - return cmListFileContext::FromCommandContext(func, this->FileName); + return cmListFileContext::FromListFileFunction(func, this->FileName); } stack.pop_back(); } else if (name == "foreach") { stack.push_back({ NestingStateEnum::Foreach, - cmListFileContext::FromCommandContext(func, this->FileName), + cmListFileContext::FromListFileFunction(func, this->FileName), }); } else if (name == "endforeach") { if (!TopIs(stack, NestingStateEnum::Foreach)) { - return cmListFileContext::FromCommandContext(func, this->FileName); + return cmListFileContext::FromListFileFunction(func, this->FileName); } stack.pop_back(); } else if (name == "function") { stack.push_back({ NestingStateEnum::Function, - cmListFileContext::FromCommandContext(func, this->FileName), + cmListFileContext::FromListFileFunction(func, this->FileName), }); } else if (name == "endfunction") { if (!TopIs(stack, NestingStateEnum::Function)) { - return cmListFileContext::FromCommandContext(func, this->FileName); + return cmListFileContext::FromListFileFunction(func, this->FileName); } stack.pop_back(); } else if (name == "macro") { stack.push_back({ NestingStateEnum::Macro, - cmListFileContext::FromCommandContext(func, this->FileName), + cmListFileContext::FromListFileFunction(func, this->FileName), }); } else if (name == "endmacro") { if (!TopIs(stack, NestingStateEnum::Macro)) { - return cmListFileContext::FromCommandContext(func, this->FileName); + return cmListFileContext::FromListFileFunction(func, this->FileName); } stack.pop_back(); } diff --git a/Source/cmListFileCache.h b/Source/cmListFileCache.h index 4a52876..5d45027 100644 --- a/Source/cmListFileCache.h +++ b/Source/cmListFileCache.h @@ -23,28 +23,6 @@ class cmMessenger; -struct cmCommandContext -{ - struct cmCommandName - { - std::string Original; - std::string Lower; - cmCommandName() = default; - cmCommandName(std::string name) - : Original(std::move(name)) - , Lower(cmSystemTools::LowerCase(this->Original)) - { - } - } Name; - long Line = 0; - cmCommandContext() = default; - cmCommandContext(std::string name, long line) - : Name(std::move(name)) - , Line(line) - { - } -}; - struct cmListFileArgument { enum Delimiter @@ -70,6 +48,54 @@ struct cmListFileArgument long Line = 0; }; +class cmListFileFunction +{ +public: + cmListFileFunction(std::string name, long line, + std::vector<cmListFileArgument> args) + : Impl{ std::make_shared<Implementation>(std::move(name), line, + std::move(args)) } + { + } + + std::string const& OriginalName() const noexcept + { + return this->Impl->OriginalName; + } + + std::string const& LowerCaseName() const noexcept + { + return this->Impl->LowerCaseName; + } + + long Line() const noexcept { return this->Impl->Line; } + + std::vector<cmListFileArgument> const& Arguments() const noexcept + { + return this->Impl->Arguments; + } + +private: + struct Implementation + { + Implementation(std::string name, long line, + std::vector<cmListFileArgument> args) + : OriginalName{ std::move(name) } + , LowerCaseName{ cmSystemTools::LowerCase(this->OriginalName) } + , Line{ line } + , Arguments{ std::move(args) } + { + } + + std::string OriginalName; + std::string LowerCaseName; + long Line = 0; + std::vector<cmListFileArgument> Arguments; + }; + + std::shared_ptr<Implementation const> Impl; +}; + class cmListFileContext { public: @@ -99,14 +125,14 @@ public: { } - static cmListFileContext FromCommandContext( - cmCommandContext const& lfcc, std::string const& fileName, + static cmListFileContext FromListFileFunction( + cmListFileFunction const& lff, std::string const& fileName, cm::optional<std::string> deferId = {}) { cmListFileContext lfc; lfc.FilePath = fileName; - lfc.Line = lfcc.Line; - lfc.Name = lfcc.Name.Original; + lfc.Line = lff.Line(); + lfc.Name = lff.OriginalName(); lfc.DeferId = std::move(deferId); return lfc; } @@ -117,50 +143,6 @@ bool operator<(const cmListFileContext& lhs, const cmListFileContext& rhs); bool operator==(cmListFileContext const& lhs, cmListFileContext const& rhs); bool operator!=(cmListFileContext const& lhs, cmListFileContext const& rhs); -class cmListFileFunction -{ -public: - cmListFileFunction(std::string name, long line, - std::vector<cmListFileArgument> args) - : Impl{ std::make_shared<Implementation>(std::move(name), line, - std::move(args)) } - { - } - - std::string const& OriginalName() const noexcept - { - return this->Impl->Name.Original; - } - - std::string const& LowerCaseName() const noexcept - { - return this->Impl->Name.Lower; - } - - long Line() const noexcept { return this->Impl->Line; } - - std::vector<cmListFileArgument> const& Arguments() const noexcept - { - return this->Impl->Arguments; - } - - operator cmCommandContext const&() const noexcept { return *this->Impl; } - -private: - struct Implementation : public cmCommandContext - { - Implementation(std::string name, long line, - std::vector<cmListFileArgument> args) - : cmCommandContext{ std::move(name), line } - , Arguments{ std::move(args) } - { - } - std::vector<cmListFileArgument> Arguments; - }; - - std::shared_ptr<Implementation const> Impl; -}; - // Represent a backtrace (call stack). Provide value semantics // but use efficient reference-counting underneath to avoid copies. class cmListFileBacktrace diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 5b3aad3..2adb232 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -2615,10 +2615,15 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target) true); } else if (reuseTarget->GetType() == cmStateEnums::OBJECT_LIBRARY) { + // FIXME: This can propagate more than one level, unlike + // the rest of the object files in an object library. + // Find another way to do this. target->Target->AppendProperty( "INTERFACE_LINK_LIBRARIES", cmStrCat("$<$<CONFIG:", config, ">:$<LINK_ONLY:", pchSourceObj, ">>")); + // We updated the link interface, so ensure it is recomputed. + target->ClearLinkInterfaceCache(); } } } else { @@ -3430,21 +3435,27 @@ void cmLocalGenerator::GenerateTargetInstallRules( static bool cmLocalGeneratorShortenObjectName(std::string& objName, std::string::size_type max_len) { + // Check if the path can be shortened using an md5 sum replacement for + // a portion of the path. + std::string::size_type md5Len = 32; + std::string::size_type numExtraChars = objName.size() - max_len + md5Len; + std::string::size_type pos = objName.find('/', numExtraChars); + if (pos == std::string::npos) { + pos = objName.rfind('/', numExtraChars); + if (pos == std::string::npos || pos <= md5Len) { + return false; + } + } + // Replace the beginning of the path portion of the object name with // its own md5 sum. - std::string::size_type pos = - objName.find('/', objName.size() - max_len + 32); - if (pos != std::string::npos) { - cmCryptoHash md5(cmCryptoHash::AlgoMD5); - std::string md5name = cmStrCat(md5.HashString(objName.substr(0, pos)), - cm::string_view(objName).substr(pos)); - objName = md5name; + cmCryptoHash md5(cmCryptoHash::AlgoMD5); + std::string md5name = cmStrCat(md5.HashString(objName.substr(0, pos)), + cm::string_view(objName).substr(pos)); + objName = md5name; - // The object name is now short enough. - return true; - } - // The object name could not be shortened enough. - return false; + // The object name is now shorter, check if it is short enough. + return pos >= numExtraChars; } bool cmLocalGeneratorCheckObjectName(std::string& objName, diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index 2700ded..0f8cdca 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -1274,7 +1274,7 @@ std::string cmLocalUnixMakefileGenerator3::CreateMakeVariable( cmSystemTools::ReplaceString(ret, "-", "__"); cmSystemTools::ReplaceString(ret, "+", "___"); int ni = 0; - char buffer[5]; + char buffer[12]; // make sure the _ version is not already used, if // it is used then add number to the end of the variable while (this->ShortMakeVariableMap.count(ret) && ni < 1000) { @@ -1302,7 +1302,7 @@ std::string cmLocalUnixMakefileGenerator3::CreateMakeVariable( if (static_cast<int>(str1.size()) + static_cast<int>(str2.size()) > size) { str1 = str1.substr(0, size - str2.size()); } - char buffer[5]; + char buffer[12]; int ni = 0; snprintf(buffer, sizeof(buffer), "%04d", ni); ret = str1 + str2 + buffer; diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index 4bf8df6..ed7e888 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -198,8 +198,8 @@ void cmLocalVisualStudio7Generator::GenerateTarget(cmGeneratorTarget* target) // Intel Fortran for VS10 uses VS9 format ".vfproj" files. cmGlobalVisualStudioGenerator::VSVersion realVersion = gg->GetVersion(); if (this->FortranProject && - gg->GetVersion() >= cmGlobalVisualStudioGenerator::VS10) { - gg->SetVersion(cmGlobalVisualStudioGenerator::VS9); + gg->GetVersion() >= cmGlobalVisualStudioGenerator::VSVersion::VS10) { + gg->SetVersion(cmGlobalVisualStudioGenerator::VSVersion::VS9); } // add to the list of projects @@ -1106,7 +1106,8 @@ void cmLocalVisualStudio7Generator::OutputBuildTool( fout << "\t\t\t\tGenerateDebugInformation=\"true\"\n"; } if (this->WindowsCEProject) { - if (this->GetVersion() < cmGlobalVisualStudioGenerator::VS9) { + if (this->GetVersion() < + cmGlobalVisualStudioGenerator::VSVersion::VS9) { fout << "\t\t\t\tSubSystem=\"9\"\n"; } else { fout << "\t\t\t\tSubSystem=\"8\"\n"; @@ -1183,7 +1184,8 @@ void cmLocalVisualStudio7Generator::OutputBuildTool( fout << "\t\t\t\tGenerateDebugInformation=\"true\"\n"; } if (this->WindowsCEProject) { - if (this->GetVersion() < cmGlobalVisualStudioGenerator::VS9) { + if (this->GetVersion() < + cmGlobalVisualStudioGenerator::VSVersion::VS9) { fout << "\t\t\t\tSubSystem=\"9\"\n"; } else { fout << "\t\t\t\tSubSystem=\"8\"\n"; @@ -2026,7 +2028,8 @@ void cmLocalVisualStudio7Generator::WriteProjectStart( << "<VisualStudioProject\n" << "\tProjectType=\"Visual C++\"\n"; /* clang-format on */ - fout << "\tVersion=\"" << (gg->GetVersion() / 10) << ".00\"\n"; + fout << "\tVersion=\"" << (static_cast<uint16_t>(gg->GetVersion()) / 10) + << ".00\"\n"; cmValue p = target->GetProperty("PROJECT_LABEL"); const std::string projLabel = p ? *p : libName; p = target->GetProperty("VS_KEYWORD"); diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index cc687b1..68e61bb 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -339,7 +339,7 @@ public: cm::optional<std::string> deferId, cmExecutionStatus& status) : Makefile(mf) { - cmListFileContext const& lfc = cmListFileContext::FromCommandContext( + cmListFileContext const& lfc = cmListFileContext::FromListFileFunction( lff, this->Makefile->StateSnapshot.GetExecutionListFile(), std::move(deferId)); this->Makefile->Backtrace = this->Makefile->Backtrace.Push(lfc); diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 5d306ec..1c92c7f 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -16,6 +16,8 @@ #include <cmext/algorithm> #include <cmext/string_view> +#include "cm_codecvt.hxx" + #include "cmComputeLinkInformation.h" #include "cmCustomCommand.h" #include "cmCustomCommandGenerator.h" @@ -2077,11 +2079,22 @@ std::string cmMakefileTargetGenerator::CreateResponseFile( const char* name, std::string const& options, std::vector<std::string>& makefile_depends) { + // FIXME: Find a better way to determine the response file encoding, + // perhaps using tool-specific platform information variables. + // For now, use the makefile encoding as a heuristic. + codecvt::Encoding responseEncoding = + this->GlobalGenerator->GetMakefileEncoding(); + // Non-MSVC tooling may not understand a BOM. + if (responseEncoding == codecvt::UTF8_WITH_BOM && + !this->Makefile->IsOn("MSVC")) { + responseEncoding = codecvt::UTF8; + } + // Create the response file. std::string responseFileNameFull = cmStrCat(this->TargetBuildDirectoryFull, '/', name); - cmGeneratedFileStream responseStream( - responseFileNameFull, false, this->GlobalGenerator->GetMakefileEncoding()); + cmGeneratedFileStream responseStream(responseFileNameFull, false, + responseEncoding); responseStream.SetCopyIfDifferent(true); responseStream << options << "\n"; diff --git a/Source/cmOutputConverter.cxx b/Source/cmOutputConverter.cxx index 4503038..b143170 100644 --- a/Source/cmOutputConverter.cxx +++ b/Source/cmOutputConverter.cxx @@ -8,6 +8,11 @@ #include <set> #include <vector> +#ifdef _WIN32 +# include <unordered_map> +# include <utility> +#endif + #include "cmState.h" #include "cmStateDirectory.h" #include "cmStringAlgorithms.h" @@ -117,17 +122,34 @@ std::string cmOutputConverter::MaybeRelativeToCurBinDir( std::string cmOutputConverter::ConvertToOutputForExisting( const std::string& remote, OutputFormat format) const { +#ifdef _WIN32 + // Cache the Short Paths since we only convert the same few paths anyway and + // calling `GetShortPathNameW` is really expensive. + static std::unordered_map<std::string, std::string> shortPathCache{}; + // If this is a windows shell, the result has a space, and the path // already exists, we can use a short-path to reference it without a // space. if (this->GetState()->UseWindowsShell() && remote.find_first_of(" #") != std::string::npos && cmSystemTools::FileExists(remote)) { - std::string tmp; - if (cmSystemTools::GetShortPath(remote, tmp)) { - return this->ConvertToOutputFormat(tmp, format); - } + + std::string shortPath = [&]() { + auto cachedShortPathIt = shortPathCache.find(remote); + + if (cachedShortPathIt != shortPathCache.end()) { + return cachedShortPathIt->second; + } + + std::string tmp{}; + cmSystemTools::GetShortPath(remote, tmp); + shortPathCache[remote] = tmp; + return tmp; + }(); + + return this->ConvertToOutputFormat(shortPath, format); } +#endif // Otherwise, perform standard conversion. return this->ConvertToOutputFormat(remote, format); diff --git a/Source/cmStandardLevelResolver.cxx b/Source/cmStandardLevelResolver.cxx index c027e29..785f356 100644 --- a/Source/cmStandardLevelResolver.cxx +++ b/Source/cmStandardLevelResolver.cxx @@ -210,8 +210,9 @@ struct StandardLevelComputer // If the standard requested is older than the compiler's default or the // extension mode doesn't match then we need to use a flag. - if (stdIt < defaultStdIt || - (cmp0128 == cmPolicies::NEW && ext != defaultExt)) { + if ((cmp0128 != cmPolicies::NEW && stdIt <= defaultStdIt) || + (cmp0128 == cmPolicies::NEW && + (stdIt < defaultStdIt || ext != defaultExt))) { auto offset = std::distance(cm::cbegin(stds), stdIt); return cmStrCat("CMAKE_", this->Language, stdsStrings[offset], "_", type, "_COMPILE_OPTION"); diff --git a/Source/cmStandardLexer.h b/Source/cmStandardLexer.h index 417f14d..2722528 100644 --- a/Source/cmStandardLexer.h +++ b/Source/cmStandardLexer.h @@ -50,6 +50,10 @@ # endif #endif +#if defined(__LCC__) +# pragma diag_suppress 1873 /* comparison between signed and unsigned */ +#endif + #if defined(__NVCOMPILER) # pragma diag_suppress 111 /* statement is unreachable */ # pragma diag_suppress 550 /* variable set but never used */ diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index ad19e03..87fce92 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -202,6 +202,8 @@ public: std::vector<BT<std::string>> LinkDirectoriesEntries; std::vector<BT<std::string>> LinkImplementationPropertyEntries; std::vector<BT<std::string>> LinkInterfacePropertyEntries; + std::vector<BT<std::string>> LinkInterfaceDirectPropertyEntries; + std::vector<BT<std::string>> LinkInterfaceDirectExcludePropertyEntries; std::vector<BT<std::string>> HeaderSetsEntries; std::vector<BT<std::string>> InterfaceHeaderSetsEntries; std::vector<std::pair<cmTarget::TLLSignature, cmListFileContext>> @@ -1138,6 +1140,16 @@ cmBTStringRange cmTarget::GetLinkInterfaceEntries() const return cmMakeRange(this->impl->LinkInterfacePropertyEntries); } +cmBTStringRange cmTarget::GetLinkInterfaceDirectEntries() const +{ + return cmMakeRange(this->impl->LinkInterfaceDirectPropertyEntries); +} + +cmBTStringRange cmTarget::GetLinkInterfaceDirectExcludeEntries() const +{ + return cmMakeRange(this->impl->LinkInterfaceDirectExcludePropertyEntries); +} + cmBTStringRange cmTarget::GetHeaderSetsEntries() const { return cmMakeRange(this->impl->HeaderSetsEntries); @@ -1182,6 +1194,8 @@ MAKE_PROP(HEADER_SET); MAKE_PROP(HEADER_SETS); MAKE_PROP(INTERFACE_HEADER_SETS); MAKE_PROP(INTERFACE_LINK_LIBRARIES); +MAKE_PROP(INTERFACE_LINK_LIBRARIES_DIRECT); +MAKE_PROP(INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE); #undef MAKE_PROP } @@ -1313,6 +1327,19 @@ void cmTarget::StoreProperty(const std::string& prop, ValueType value) cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); this->impl->LinkInterfacePropertyEntries.emplace_back(value, lfbt); } + } else if (prop == propINTERFACE_LINK_LIBRARIES_DIRECT) { + this->impl->LinkInterfaceDirectPropertyEntries.clear(); + if (value) { + cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); + this->impl->LinkInterfaceDirectPropertyEntries.emplace_back(value, lfbt); + } + } else if (prop == propINTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE) { + this->impl->LinkInterfaceDirectExcludePropertyEntries.clear(); + if (value) { + cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); + this->impl->LinkInterfaceDirectExcludePropertyEntries.emplace_back(value, + lfbt); + } } else if (prop == propSOURCES) { this->impl->SourceEntries.clear(); if (value) { @@ -1571,6 +1598,17 @@ void cmTarget::AppendProperty(const std::string& prop, cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); this->impl->LinkInterfacePropertyEntries.emplace_back(value, lfbt); } + } else if (prop == propINTERFACE_LINK_LIBRARIES_DIRECT) { + if (!value.empty()) { + cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); + this->impl->LinkInterfaceDirectPropertyEntries.emplace_back(value, lfbt); + } + } else if (prop == propINTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE) { + if (!value.empty()) { + cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); + this->impl->LinkInterfaceDirectExcludePropertyEntries.emplace_back(value, + lfbt); + } } else if (prop == "SOURCES") { cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); this->impl->SourceEntries.emplace_back(value, lfbt); @@ -1881,6 +1919,8 @@ cmValue cmTarget::GetProperty(const std::string& prop) const propHEADER_SETS, propINTERFACE_HEADER_SETS, propINTERFACE_LINK_LIBRARIES, + propINTERFACE_LINK_LIBRARIES_DIRECT, + propINTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE, }; if (specialProps.count(prop)) { if (prop == propC_STANDARD || prop == propCXX_STANDARD || @@ -1910,6 +1950,25 @@ cmValue cmTarget::GetProperty(const std::string& prop) const output = cmJoin(this->impl->LinkInterfacePropertyEntries, ";"); return cmValue(output); } + if (prop == propINTERFACE_LINK_LIBRARIES_DIRECT) { + if (this->impl->LinkInterfaceDirectPropertyEntries.empty()) { + return nullptr; + } + + static std::string output; + output = cmJoin(this->impl->LinkInterfaceDirectPropertyEntries, ";"); + return cmValue(output); + } + if (prop == propINTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE) { + if (this->impl->LinkInterfaceDirectExcludePropertyEntries.empty()) { + return nullptr; + } + + static std::string output; + output = + cmJoin(this->impl->LinkInterfaceDirectExcludePropertyEntries, ";"); + return cmValue(output); + } // the type property returns what type the target is if (prop == propTYPE) { return cmValue(cmState::GetTargetTypeName(this->GetType())); diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 1173f49..18e39c7 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -266,6 +266,8 @@ public: cmBTStringRange GetLinkImplementationEntries() const; cmBTStringRange GetLinkInterfaceEntries() const; + cmBTStringRange GetLinkInterfaceDirectEntries() const; + cmBTStringRange GetLinkInterfaceDirectExcludeEntries() const; cmBTStringRange GetHeaderSetsEntries() const; diff --git a/Source/cmTimestamp.cxx b/Source/cmTimestamp.cxx index 3826577..e2b6c20 100644 --- a/Source/cmTimestamp.cxx +++ b/Source/cmTimestamp.cxx @@ -17,18 +17,27 @@ #include <cstdlib> #include <cstring> #include <sstream> +#include <utility> #ifdef __MINGW32__ # include <libloaderapi.h> #endif +#include <cm3p/uv.h> + #include "cmStringAlgorithms.h" #include "cmSystemTools.h" std::string cmTimestamp::CurrentTime(const std::string& formatString, bool utcFlag) const { - time_t currentTimeT = time(nullptr); + // get current time with microsecond resolution + uv_timeval64_t timeval; + uv_gettimeofday(&timeval); + auto currentTimeT = static_cast<time_t>(timeval.tv_sec); + auto microseconds = static_cast<uint32_t>(timeval.tv_usec); + + // check for override via SOURCE_DATE_EPOCH for reproducible builds std::string source_date_epoch; cmSystemTools::GetEnv("SOURCE_DATE_EPOCH", source_date_epoch); if (!source_date_epoch.empty()) { @@ -38,12 +47,15 @@ std::string cmTimestamp::CurrentTime(const std::string& formatString, cmSystemTools::Error("Cannot parse SOURCE_DATE_EPOCH as integer"); exit(27); } + // SOURCE_DATE_EPOCH has only a resolution in the seconds range + microseconds = 0; } if (currentTimeT == time_t(-1)) { return std::string(); } - return this->CreateTimestampFromTimeT(currentTimeT, formatString, utcFlag); + return this->CreateTimestampFromTimeT(currentTimeT, microseconds, + formatString, utcFlag); } std::string cmTimestamp::FileModificationTime(const char* path, @@ -57,11 +69,32 @@ std::string cmTimestamp::FileModificationTime(const char* path, return std::string(); } - time_t mtime = cmsys::SystemTools::ModifiedTime(real_path); - return this->CreateTimestampFromTimeT(mtime, formatString, utcFlag); + // use libuv's implementation of stat(2) to get the file information + time_t mtime = 0; + uint32_t microseconds = 0; + uv_fs_t req; + if (uv_fs_stat(nullptr, &req, real_path.c_str(), nullptr) == 0) { + mtime = static_cast<time_t>(req.statbuf.st_mtim.tv_sec); + // tv_nsec has nanosecond resolution, but we truncate it to microsecond + // resolution in order to be consistent with cmTimestamp::CurrentTime() + microseconds = static_cast<uint32_t>(req.statbuf.st_mtim.tv_nsec / 1000); + } + uv_fs_req_cleanup(&req); + + return this->CreateTimestampFromTimeT(mtime, microseconds, formatString, + utcFlag); +} + +std::string cmTimestamp::CreateTimestampFromTimeT(time_t timeT, + std::string formatString, + bool utcFlag) const +{ + return this->CreateTimestampFromTimeT(timeT, 0, std::move(formatString), + utcFlag); } std::string cmTimestamp::CreateTimestampFromTimeT(time_t timeT, + const uint32_t microseconds, std::string formatString, bool utcFlag) const { @@ -95,7 +128,8 @@ std::string cmTimestamp::CreateTimestampFromTimeT(time_t timeT, : static_cast<char>(0); if (c1 == '%' && c2 != 0) { - result += this->AddTimestampComponent(c2, timeStruct, timeT); + result += + this->AddTimestampComponent(c2, timeStruct, timeT, microseconds); ++i; } else { result += c1; @@ -144,9 +178,9 @@ time_t cmTimestamp::CreateUtcTimeTFromTm(struct tm& tm) const #endif } -std::string cmTimestamp::AddTimestampComponent(char flag, - struct tm& timeStruct, - const time_t timeT) const +std::string cmTimestamp::AddTimestampComponent( + char flag, struct tm& timeStruct, const time_t timeT, + const uint32_t microseconds) const { std::string formatString = cmStrCat('%', flag); @@ -180,13 +214,19 @@ std::string cmTimestamp::AddTimestampComponent(char flag, const time_t unixEpoch = this->CreateUtcTimeTFromTm(tmUnixEpoch); if (unixEpoch == -1) { cmSystemTools::Error( - "Error generating UNIX epoch in " - "STRING(TIMESTAMP ...). Please, file a bug report against CMake"); + "Error generating UNIX epoch in string(TIMESTAMP ...) or " + "file(TIMESTAMP ...). Please, file a bug report against CMake"); return std::string(); } return std::to_string(static_cast<long int>(difftime(timeT, unixEpoch))); } + case 'f': // microseconds + { + // clip number to 6 digits and pad with leading zeros + std::string microsecs = std::to_string(microseconds % 1000000); + return std::string(6 - microsecs.length(), '0') + microsecs; + } default: { return formatString; } diff --git a/Source/cmTimestamp.h b/Source/cmTimestamp.h index 0e2c200..ada5006 100644 --- a/Source/cmTimestamp.h +++ b/Source/cmTimestamp.h @@ -4,6 +4,7 @@ #include "cmConfigure.h" // IWYU pragma: keep +#include <cstdint> #include <ctime> #include <string> @@ -23,9 +24,14 @@ public: std::string CreateTimestampFromTimeT(time_t timeT, std::string formatString, bool utcFlag) const; + std::string CreateTimestampFromTimeT(time_t timeT, uint32_t microseconds, + std::string formatString, + bool utcFlag) const; + private: time_t CreateUtcTimeTFromTm(struct tm& timeStruct) const; std::string AddTimestampComponent(char flag, struct tm& timeStruct, - time_t timeT) const; + time_t timeT, + uint32_t microseconds = 0) const; }; diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 96dcf0b..f325994 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -419,7 +419,7 @@ void cmVisualStudio10TargetGenerator::Generate() if (this->ProjectType == VsProjectType::csproj && this->GeneratorTarget->IsDotNetSdkTarget() && this->GlobalGenerator->GetVersion() >= - cmGlobalVisualStudioGenerator::VS16) { + cmGlobalVisualStudioGenerator::VSVersion::VS16) { this->WriteSdkStyleProjectFile(BuildFileStream); } else { this->WriteClassicMsBuildProjectFile(BuildFileStream); @@ -431,6 +431,9 @@ void cmVisualStudio10TargetGenerator::Generate() // The groups are stored in a separate file for VS 10 this->WriteGroups(); + + // Update cache with project-specific entries. + this->UpdateCache(); } void cmVisualStudio10TargetGenerator::WriteClassicMsBuildProjectFile( @@ -443,7 +446,7 @@ void cmVisualStudio10TargetGenerator::WriteClassicMsBuildProjectFile( e0.Attribute("DefaultTargets", "Build"); const char* toolsVersion = this->GlobalGenerator->GetToolsVersion(); if (this->GlobalGenerator->GetVersion() == - cmGlobalVisualStudioGenerator::VS12 && + cmGlobalVisualStudioGenerator::VSVersion::VS12 && this->GlobalGenerator->TargetsWindowsCE()) { toolsVersion = "4.0"; } @@ -609,7 +612,7 @@ void cmVisualStudio10TargetGenerator::WriteClassicMsBuildProjectFile( // project using an older toolset version is opened in a newer version of // the IDE (respected by VS 2013 and above). if (this->GlobalGenerator->GetVersion() >= - cmGlobalVisualStudioGenerator::VS12) { + cmGlobalVisualStudioGenerator::VSVersion::VS12) { e1.Element("VCProjectUpgraderObjectName", "NoUpgrade"); } @@ -620,7 +623,7 @@ void cmVisualStudio10TargetGenerator::WriteClassicMsBuildProjectFile( if (this->Managed) { if (this->LocalGenerator->GetVersion() >= - cmGlobalVisualStudioGenerator::VS17) { + cmGlobalVisualStudioGenerator::VSVersion::VS17) { e1.Element("ManagedAssembly", "true"); } std::string outputType; @@ -1000,11 +1003,9 @@ bool cmVisualStudio10TargetGenerator::HasCustomCommands() const void cmVisualStudio10TargetGenerator::WritePackageReferences(Elem& e0) { - std::vector<std::string> packageReferences; - if (cmValue vsPackageReferences = - this->GeneratorTarget->GetProperty("VS_PACKAGE_REFERENCES")) { - cmExpandList(*vsPackageReferences, packageReferences); - } + std::vector<std::string> packageReferences = + this->GeneratorTarget->GetPackageReferences(); + if (!packageReferences.empty()) { Elem e1(e0, "ItemGroup"); for (std::string const& ri : packageReferences) { @@ -1750,13 +1751,13 @@ void cmVisualStudio10TargetGenerator::WriteCustomRuleCpp( e2.WritePlatformConfigTag("AdditionalInputs", cond, additional_inputs); e2.WritePlatformConfigTag("Outputs", cond, outputs); if (this->LocalGenerator->GetVersion() > - cmGlobalVisualStudioGenerator::VS10) { + cmGlobalVisualStudioGenerator::VSVersion::VS10) { // VS >= 11 let us turn off linking of custom command outputs. e2.WritePlatformConfigTag("LinkObjects", cond, "false"); } if (symbolic && this->LocalGenerator->GetVersion() >= - cmGlobalVisualStudioGenerator::VS16) { + cmGlobalVisualStudioGenerator::VSVersion::VS16) { // VS >= 16.4 warn if outputs are not created, but one of our // outputs is marked SYMBOLIC and not expected to be created. e2.WritePlatformConfigTag("VerifyInputsAndOutputsExist", cond, "false"); @@ -2319,7 +2320,7 @@ void cmVisualStudio10TargetGenerator::WriteSource(Elem& e2, bool forceRelative = sf->GetLanguage() == "CUDA"; std::string sourceFile = this->ConvertPath(sf->GetFullPath(), forceRelative); if (this->LocalGenerator->GetVersion() == - cmGlobalVisualStudioGenerator::VS10 && + cmGlobalVisualStudioGenerator::VSVersion::VS10 && cmSystemTools::FileIsFullPath(sourceFile)) { // Normal path conversion resulted in a full path. VS 10 (but not 11) // refuses to show the property page in the IDE for a source file with a @@ -2417,7 +2418,7 @@ void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0) case cmGeneratorTarget::SourceKindExternalObject: tool = "Object"; if (this->LocalGenerator->GetVersion() < - cmGlobalVisualStudioGenerator::VS11) { + cmGlobalVisualStudioGenerator::VSVersion::VS11) { // For VS == 10 we cannot use LinkObjects to avoid linking custom // command outputs. If an object file is generated in this target, // then vs10 will use it in the build, and we have to list it as @@ -3105,7 +3106,7 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions( if (this->ProjectType == VsProjectType::vcxproj) { clOptions.FixExceptionHandlingDefault(); if (this->GlobalGenerator->GetVersion() >= - cmGlobalVisualStudioGenerator::VS15) { + cmGlobalVisualStudioGenerator::VSVersion::VS15) { // Toolsets that come with VS 2017 may now enable UseFullPaths // by default and there is no negative /FC option that projects // can use to switch it back. Older toolsets disable this by @@ -5375,3 +5376,32 @@ void cmVisualStudio10TargetGenerator::WriteStdOutEncodingUtf8(Elem& e1) e1.Element("StdOutEncoding", "UTF-8"); } } + +void cmVisualStudio10TargetGenerator::UpdateCache() +{ + std::vector<std::string> packageReferences; + + if (this->GeneratorTarget->HasPackageReferences()) { + // Store a cache entry that later determines, if a package restore is + // required. + this->GeneratorTarget->Makefile->AddCacheDefinition( + this->GeneratorTarget->GetName() + "_REQUIRES_VS_PACKAGE_RESTORE", "ON", + "Value Computed by CMake", cmStateEnums::STATIC); + } else { + // If there are any dependencies that require package restore, inherit the + // cache variable. + cmGlobalGenerator::TargetDependSet const& unordered = + this->GlobalGenerator->GetTargetDirectDepends(this->GeneratorTarget); + using OrderedTargetDependSet = + cmGlobalVisualStudioGenerator::OrderedTargetDependSet; + OrderedTargetDependSet depends(unordered, CMAKE_CHECK_BUILD_SYSTEM_TARGET); + + for (cmGeneratorTarget const* dt : depends) { + if (dt->HasPackageReferences()) { + this->GeneratorTarget->Makefile->AddCacheDefinition( + this->GeneratorTarget->GetName() + "_REQUIRES_VS_PACKAGE_RESTORE", + "ON", "Value Computed by CMake", cmStateEnums::STATIC); + } + } + } +} diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h index 79aa5e8..8d777a3 100644 --- a/Source/cmVisualStudio10TargetGenerator.h +++ b/Source/cmVisualStudio10TargetGenerator.h @@ -198,6 +198,7 @@ private: std::string GetCSharpSourceLink(cmSourceFile const* source); void WriteStdOutEncodingUtf8(Elem& e1); + void UpdateCache(); private: friend class cmVS10GeneratorOptions; diff --git a/Source/cmVisualStudioGeneratorOptions.cxx b/Source/cmVisualStudioGeneratorOptions.cxx index e495db0..9045a4d 100644 --- a/Source/cmVisualStudioGeneratorOptions.cxx +++ b/Source/cmVisualStudioGeneratorOptions.cxx @@ -75,13 +75,13 @@ void cmVisualStudioGeneratorOptions::FixExceptionHandlingDefault() // the flag to disable exception handling. When the user does // remove the flag we need to override the IDE default of on. switch (this->Version) { - case cmGlobalVisualStudioGenerator::VS10: - case cmGlobalVisualStudioGenerator::VS11: - case cmGlobalVisualStudioGenerator::VS12: - case cmGlobalVisualStudioGenerator::VS14: - case cmGlobalVisualStudioGenerator::VS15: - case cmGlobalVisualStudioGenerator::VS16: - case cmGlobalVisualStudioGenerator::VS17: + case cmGlobalVisualStudioGenerator::VSVersion::VS10: + case cmGlobalVisualStudioGenerator::VSVersion::VS11: + case cmGlobalVisualStudioGenerator::VSVersion::VS12: + case cmGlobalVisualStudioGenerator::VSVersion::VS14: + case cmGlobalVisualStudioGenerator::VSVersion::VS15: + case cmGlobalVisualStudioGenerator::VSVersion::VS16: + case cmGlobalVisualStudioGenerator::VSVersion::VS17: // by default VS puts <ExceptionHandling></ExceptionHandling> empty // for a project, to make our projects look the same put a new line // and space over for the closing </ExceptionHandling> as the default @@ -108,7 +108,8 @@ void cmVisualStudioGeneratorOptions::SetVerboseMakefile(bool verbose) if (verbose && this->FlagMap.find("SuppressStartupBanner") == this->FlagMap.end()) { this->FlagMap["SuppressStartupBanner"] = - this->Version < cmGlobalVisualStudioGenerator::VS10 ? "FALSE" : ""; + this->Version < cmGlobalVisualStudioGenerator::VSVersion::VS10 ? "FALSE" + : ""; } } @@ -181,6 +182,10 @@ void cmVisualStudioGeneratorOptions::FixCudaCodeGeneration() // First entries for the -arch=<arch> [-code=<code>,...] pair. if (!arch.empty()) { std::string arch_name = arch[0]; + if (arch_name == "all" || arch_name == "all-major") { + AppendFlagString("AdditionalOptions", "-arch=" + arch_name); + return; + } std::vector<std::string> codes; if (!code.empty()) { codes = cmTokenize(code[0], ","); @@ -425,7 +430,7 @@ void cmVisualStudioGeneratorOptions::OutputPreprocessorDefinitions( } std::ostringstream oss; - if (this->Version >= cmGlobalVisualStudioGenerator::VS10) { + if (this->Version >= cmGlobalVisualStudioGenerator::VSVersion::VS10) { oss << "%(" << tag << ")"; } std::vector<std::string>::const_iterator de = @@ -433,13 +438,13 @@ void cmVisualStudioGeneratorOptions::OutputPreprocessorDefinitions( for (std::string const& di : cmMakeRange(this->Defines.cbegin(), de)) { // Escape the definition for the compiler. std::string define; - if (this->Version < cmGlobalVisualStudioGenerator::VS10) { + if (this->Version < cmGlobalVisualStudioGenerator::VSVersion::VS10) { define = this->LocalGenerator->EscapeForShell(di, true); } else { define = di; } // Escape this flag for the MSBuild. - if (this->Version >= cmGlobalVisualStudioGenerator::VS10) { + if (this->Version >= cmGlobalVisualStudioGenerator::VSVersion::VS10) { cmVS10EscapeForMSBuild(define); if (lang == "RC") { cmSystemTools::ReplaceString(define, "\"", "\\\""); @@ -481,7 +486,7 @@ void cmVisualStudioGeneratorOptions::OutputAdditionalIncludeDirectories( } // Escape this include for the MSBuild. - if (this->Version >= cmGlobalVisualStudioGenerator::VS10) { + if (this->Version >= cmGlobalVisualStudioGenerator::VSVersion::VS10) { cmVS10EscapeForMSBuild(include); } oss << sep << include; @@ -493,7 +498,7 @@ void cmVisualStudioGeneratorOptions::OutputAdditionalIncludeDirectories( } } - if (this->Version >= cmGlobalVisualStudioGenerator::VS10) { + if (this->Version >= cmGlobalVisualStudioGenerator::VSVersion::VS10) { oss << sep << "%(" << tag << ")"; } @@ -507,7 +512,7 @@ void cmVisualStudioGeneratorOptions::OutputFlagMap(std::ostream& fout, std::ostringstream oss; const char* sep = ""; for (std::string i : m.second) { - if (this->Version >= cmGlobalVisualStudioGenerator::VS10) { + if (this->Version >= cmGlobalVisualStudioGenerator::VSVersion::VS10) { cmVS10EscapeForMSBuild(i); } oss << sep << i; diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 72b26e1..ef4e37b 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -28,6 +28,7 @@ #include "cm_sys_stat.h" +#include "cmBuildOptions.h" #include "cmCMakePath.h" #include "cmCMakePresetsGraph.h" #include "cmCommandLineArgument.h" @@ -3244,8 +3245,8 @@ std::vector<std::string> cmake::GetDebugConfigs() int cmake::Build(int jobs, std::string dir, std::vector<std::string> targets, std::string config, std::vector<std::string> nativeOptions, - bool clean, bool verbose, const std::string& presetName, - bool listPresets) + cmBuildOptions& buildOptions, bool verbose, + const std::string& presetName, bool listPresets) { this->SetHomeDirectory(""); this->SetHomeOutputDirectory(""); @@ -3351,8 +3352,12 @@ int cmake::Build(int jobs, std::string dir, std::vector<std::string> targets, config = expandedPreset->Configuration; } - if (!clean && expandedPreset->CleanFirst) { - clean = *expandedPreset->CleanFirst; + if (!buildOptions.Clean && expandedPreset->CleanFirst) { + buildOptions.Clean = *expandedPreset->CleanFirst; + } + + if (expandedPreset->ResolvePackageReferences) { + buildOptions.ResolveMode = *expandedPreset->ResolvePackageReferences; } if (!verbose && expandedPreset->Verbose) { @@ -3491,7 +3496,7 @@ int cmake::Build(int jobs, std::string dir, std::vector<std::string> targets, this->GlobalGenerator->PrintBuildCommandAdvice(std::cerr, jobs); return this->GlobalGenerator->Build( - jobs, "", dir, projName, targets, output, "", config, clean, false, + jobs, "", dir, projName, targets, output, "", config, buildOptions, verbose, cmDuration::zero(), cmSystemTools::OUTPUT_PASSTHROUGH, nativeOptions); } diff --git a/Source/cmake.h b/Source/cmake.h index aee9c04..1187be5 100644 --- a/Source/cmake.h +++ b/Source/cmake.h @@ -45,6 +45,7 @@ class cmMakefileProfilingData; #endif class cmMessenger; class cmVariableWatch; +struct cmBuildOptions; struct cmDocumentationEntry; /** \brief Represents a cmake invocation. @@ -587,8 +588,8 @@ public: //! run the --build option int Build(int jobs, std::string dir, std::vector<std::string> targets, std::string config, std::vector<std::string> nativeOptions, - bool clean, bool verbose, const std::string& presetName, - bool listPresets); + cmBuildOptions& buildOptions, bool verbose, + const std::string& presetName, bool listPresets); //! run the --open option bool Open(const std::string& dir, bool dryRun); diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index 00aafdc..f3d5536 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx @@ -5,6 +5,7 @@ #include <algorithm> #include <cassert> +#include <cctype> #include <climits> #include <cstdio> #include <cstring> @@ -19,6 +20,7 @@ #include <cm3p/uv.h> +#include "cmBuildOptions.h" #include "cmCommandLineArgument.h" #include "cmConsoleBuf.h" #include "cmDocumentationEntry.h" // IWYU pragma: keep @@ -165,11 +167,11 @@ void cmakemainMessageCallback(const std::string& m, // cannot use it to print messages. Another implementation will // be needed to print colored messages on Windows. static_cast<void>(md); - std::cerr << m << cmakemainGetStack(cm) << "\n"; + std::cerr << m << cmakemainGetStack(cm) << '\n' << std::flush; #else cmsysTerminal_cfprintf(md.desiredColor, stderr, "%s", m.c_str()); fflush(stderr); // stderr is buffered in some cases. - std::cerr << cmakemainGetStack(cm) << "\n"; + std::cerr << cmakemainGetStack(cm) << '\n' << std::flush; #endif } @@ -445,6 +447,7 @@ int do_build(int ac, char const* const* av) bool cleanFirst = false; bool foundClean = false; bool foundNonClean = false; + PackageResolveMode resolveMode = PackageResolveMode::FromCacheVariable; bool verbose = cmSystemTools::HasEnv("VERBOSE"); std::string presetName; bool listPresets = false; @@ -478,6 +481,22 @@ int do_build(int ac, char const* const* av) } return false; }; + auto resolvePackagesLambda = [&](std::string const& value) -> bool { + std::string v = value; + std::transform(v.begin(), v.end(), v.begin(), ::tolower); + + if (v == "on") { + resolveMode = PackageResolveMode::Force; + } else if (v == "only") { + resolveMode = PackageResolveMode::OnlyResolve; + } else if (v == "off") { + resolveMode = PackageResolveMode::Disable; + } else { + return false; + } + + return true; + }; auto verboseLambda = [&](std::string const&) -> bool { verbose = true; return true; @@ -514,6 +533,8 @@ int do_build(int ac, char const* const* av) cleanFirst = true; return true; } }, + CommandArgument{ "--resolve-package-references", + CommandArgument::Values::One, resolvePackagesLambda }, CommandArgument{ "-v", CommandArgument::Values::Zero, verboseLambda }, CommandArgument{ "--verbose", CommandArgument::Values::Zero, verboseLambda }, @@ -639,6 +660,8 @@ int do_build(int ac, char const* const* av) " --config <cfg> = For multi-configuration tools, choose <cfg>.\n" " --clean-first = Build target 'clean' first, then build.\n" " (To clean only, use --target 'clean'.)\n" + " --resolve-package-references={on|only|off}\n" + " = Restore/resolve package references during build.\n" " --verbose, -v = Enable verbose output - if supported - including\n" " the build commands to be executed. \n" " -- = Pass remaining options to the native tool.\n" @@ -656,8 +679,10 @@ int do_build(int ac, char const* const* av) cmakemainProgressCallback(msg, prog, &cm); }); + cmBuildOptions buildOptions(cleanFirst, false, resolveMode); + return cm.Build(jobs, std::move(dir), std::move(targets), std::move(config), - std::move(nativeOptions), cleanFirst, verbose, presetName, + std::move(nativeOptions), buildOptions, verbose, presetName, listPresets); #endif } diff --git a/Source/kwsys/ProcessUNIX.c b/Source/kwsys/ProcessUNIX.c index 1963b27..19bf982 100644 --- a/Source/kwsys/ProcessUNIX.c +++ b/Source/kwsys/ProcessUNIX.c @@ -41,6 +41,12 @@ do. /* Increase the file descriptor limit for select() before including related system headers. (Default: 64) */ # define FD_SETSIZE 16384 +#elif defined(__APPLE__) +/* Increase the file descriptor limit for select() before including + related system headers. (Default: 1024) */ +# define _DARWIN_UNLIMITED_SELECT +# include <limits.h> /* OPEN_MAX */ +# define FD_SETSIZE OPEN_MAX #endif #include <assert.h> /* assert */ diff --git a/Source/kwsys/testSystemTools.cxx b/Source/kwsys/testSystemTools.cxx index e88a481..21d6f04 100644 --- a/Source/kwsys/testSystemTools.cxx +++ b/Source/kwsys/testSystemTools.cxx @@ -295,12 +295,15 @@ static bool CheckFileOperations() // Reset umask #ifdef __MSYS__ mode_t fullMask = S_IWRITE; + mode_t testPerm = S_IREAD; #elif defined(_WIN32) && !defined(__CYGWIN__) // NOTE: Windows doesn't support toggling _S_IREAD. mode_t fullMask = _S_IWRITE; + mode_t testPerm = 0; #else // On a normal POSIX platform, we can toggle all permissions. mode_t fullMask = S_IRWXU | S_IRWXG | S_IRWXO; + mode_t testPerm = S_IRUSR; #endif // Test file permissions without umask @@ -311,7 +314,7 @@ static bool CheckFileOperations() res = false; } - if (!kwsys::SystemTools::SetPermissions(testNewFile, 0)) { + if (!kwsys::SystemTools::SetPermissions(testNewFile, testPerm)) { std::cerr << "Problem with SetPermissions (1) for: " << testNewFile << std::endl; res = false; @@ -323,10 +326,10 @@ static bool CheckFileOperations() res = false; } - if ((thisPerm & fullMask) != 0) { + if ((thisPerm & fullMask) != testPerm) { std::cerr << "SetPermissions failed to set permissions (1) for: " << testNewFile << ": actual = " << thisPerm - << "; expected = " << 0 << std::endl; + << "; expected = " << testPerm << std::endl; res = false; } diff --git a/Tests/CMakeCommands/target_compile_options/CMakeLists.txt b/Tests/CMakeCommands/target_compile_options/CMakeLists.txt index 869a941..2e3760a 100644 --- a/Tests/CMakeCommands/target_compile_options/CMakeLists.txt +++ b/Tests/CMakeCommands/target_compile_options/CMakeLists.txt @@ -11,11 +11,11 @@ add_executable(target_compile_options "${CMAKE_CURRENT_SOURCE_DIR}/main.cpp" ) target_compile_options(target_compile_options - PRIVATE $<$<CXX_COMPILER_ID:AppleClang,Clang,GNU,LCC>:-DMY_PRIVATE_DEFINE> + PRIVATE $<$<CXX_COMPILER_ID:AppleClang,IBMClang,Clang,GNU,LCC>:-DMY_PRIVATE_DEFINE> PUBLIC $<$<COMPILE_LANG_AND_ID:CXX,GNU,LCC>:-DMY_PUBLIC_DEFINE> - PUBLIC $<$<COMPILE_LANG_AND_ID:CXX,GNU,LCC,Clang,AppleClang>:-DMY_MUTLI_COMP_PUBLIC_DEFINE> + PUBLIC $<$<COMPILE_LANG_AND_ID:CXX,GNU,LCC,Clang,AppleClang,IBMClang>:-DMY_MUTLI_COMP_PUBLIC_DEFINE> INTERFACE $<$<CXX_COMPILER_ID:GNU,LCC>:-DMY_INTERFACE_DEFINE> - INTERFACE $<$<CXX_COMPILER_ID:GNU,LCC,Clang,AppleClang>:-DMY_MULTI_COMP_INTERFACE_DEFINE> + INTERFACE $<$<CXX_COMPILER_ID:GNU,LCC,Clang,AppleClang,IBMClang>:-DMY_MULTI_COMP_INTERFACE_DEFINE> ) if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|LCC") @@ -51,7 +51,7 @@ if(CMAKE_GENERATOR MATCHES "Visual Studio") endif() target_compile_options(consumer - PRIVATE $<$<CXX_COMPILER_ID:GNU,LCC,Clang,AppleClang>:$<TARGET_PROPERTY:target_compile_options,INTERFACE_COMPILE_OPTIONS>> + PRIVATE $<$<CXX_COMPILER_ID:GNU,LCC,Clang,AppleClang,IBMClang>:$<TARGET_PROPERTY:target_compile_options,INTERFACE_COMPILE_OPTIONS>> ) if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|LCC") diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index b1f473b..da6219e 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -3691,6 +3691,8 @@ if(BUILD_TESTING) --test-command InterfaceLinkLibraries) list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/InterfaceLinkLibraries") + ADD_TEST_MACRO(InterfaceLinkLibrariesDirect) + if(NOT CMake_TEST_EXTERNAL_CMAKE) add_subdirectory(CMakeTests) endif() diff --git a/Tests/CompileFeatures/CMakeLists.txt b/Tests/CompileFeatures/CMakeLists.txt index 20988ac..c6d1e8a 100644 --- a/Tests/CompileFeatures/CMakeLists.txt +++ b/Tests/CompileFeatures/CMakeLists.txt @@ -18,7 +18,7 @@ macro(run_test feature lang) endif() endmacro() -if(NOT CMAKE_C_COMPILER_ID MATCHES "^(Cray|PGI|NVHPC|XL|XLClang|IntelLLVM|Fujitsu|FujitsuClang)$") +if(NOT CMAKE_C_COMPILER_ID MATCHES "^(Cray|PGI|NVHPC|XL|XLClang|IBMClang|IntelLLVM|Fujitsu|FujitsuClang)$") get_property(c_features GLOBAL PROPERTY CMAKE_C_KNOWN_FEATURES) list(FILTER c_features EXCLUDE REGEX "^c_std_[0-9][0-9]") foreach(feature ${c_features}) @@ -26,7 +26,7 @@ if(NOT CMAKE_C_COMPILER_ID MATCHES "^(Cray|PGI|NVHPC|XL|XLClang|IntelLLVM|Fujits endforeach() endif() -if(NOT CMAKE_CXX_COMPILER_ID MATCHES "^(Cray|PGI|NVHPC|XL|XLClang|IntelLLVM|Fujitsu|FujitsuClang)$") +if(NOT CMAKE_CXX_COMPILER_ID MATCHES "^(Cray|PGI|NVHPC|XL|XLClang|IBMClang|IntelLLVM|Fujitsu|FujitsuClang)$") get_property(cxx_features GLOBAL PROPERTY CMAKE_CXX_KNOWN_FEATURES) list(FILTER cxx_features EXCLUDE REGEX "^cxx_std_[0-9][0-9]") foreach(feature ${cxx_features}) diff --git a/Tests/ExportImport/Export/CMakeLists.txt b/Tests/ExportImport/Export/CMakeLists.txt index a79efd0..c9e41f5 100644 --- a/Tests/ExportImport/Export/CMakeLists.txt +++ b/Tests/ExportImport/Export/CMakeLists.txt @@ -163,6 +163,16 @@ install( cmake_policy(PUSH) cmake_policy(SET CMP0022 NEW) + +# Test control over direct linking. +include(../../InterfaceLinkLibrariesDirect/testStaticLibPlugin.cmake) +include(../../InterfaceLinkLibrariesDirect/testSharedLibWithHelper.cmake) +include(../../InterfaceLinkLibrariesDirect/testExeWithPluginHelper.cmake) +if(NOT maybe_OBJECTS_DESTINATION) + target_compile_definitions(testSharedLibHelperObj INTERFACE testSharedLibHelperObj_NO_OBJECT) + target_compile_definitions(testExePluginHelperObj INTERFACE testExePluginHelperObj_NO_OBJECT) +endif() + # Test exporting dependent libraries into different exports add_library(testLibRequired testLibRequired.c) add_library(testLibDepends testLibDepends.c) @@ -544,6 +554,9 @@ install( testLibDeprecation testLibCycleA testLibCycleB testLibNoSONAME + testStaticLibWithPlugin testStaticLibPluginExtra testStaticLibPlugin + testSharedLibWithHelper testSharedLibHelperObj + testExeWithPluginHelper testExePluginHelperObj testMod1 testMod2 cmp0022NEW cmp0022OLD TopDirLib SubDirLinkA @@ -619,6 +632,9 @@ export(TARGETS testExe2 testLib4 testLib5 testLib6 testLib7 testExe3 testExe4 te testLib4lib testLib4libdbg testLib4libopt testLibCycleA testLibCycleB testLibNoSONAME + testStaticLibWithPlugin testStaticLibPluginExtra testStaticLibPlugin + testSharedLibWithHelper testSharedLibHelperObj + testExeWithPluginHelper testExePluginHelperObj testMod1 testMod2 testLibPerConfigDest NAMESPACE bld_ diff --git a/Tests/ExportImport/Import/A/CMakeLists.txt b/Tests/ExportImport/Import/A/CMakeLists.txt index d6cc8d0..272c7a9 100644 --- a/Tests/ExportImport/Import/A/CMakeLists.txt +++ b/Tests/ExportImport/Import/A/CMakeLists.txt @@ -68,16 +68,23 @@ target_link_libraries(imp_testExe1 exp_testLib7 exp_testLibCycleA exp_testLibPerConfigDest + exp_testStaticLibWithPlugin ) add_library(imp_testInterfaceInclude1 STATIC imp_testInterfaceInclude1.c) target_include_directories(imp_testInterfaceInclude1 SYSTEM PRIVATE testInterfaceIncludeSystem) target_link_libraries(imp_testInterfaceInclude1 PRIVATE exp_testInterfaceIncludeUser) +add_executable(imp_UseSharedLibWithHelper1 ../../../InterfaceLinkLibrariesDirect/UseSharedLibWithHelper.c) +target_link_libraries(imp_UseSharedLibWithHelper1 PRIVATE exp_testSharedLibWithHelper testSharedLibHelperExclude) + # Try building a plugin to an executable imported from the install tree. add_library(imp_mod1 MODULE imp_mod1.c) target_link_libraries(imp_mod1 exp_testExe2) +add_library(imp_ExePlugin1 MODULE ../../../InterfaceLinkLibrariesDirect/ExePlugin.c) +target_link_libraries(imp_ExePlugin1 PRIVATE exp_testExeWithPluginHelper testExePluginHelperExclude) + # Try referencing an executable imported from the build tree. add_custom_command( OUTPUT ${Import_BINARY_DIR}/bld_generated.c @@ -112,6 +119,7 @@ target_link_libraries(imp_testExe1b bld_testLib7 bld_testLibCycleA bld_testLibPerConfigDest + bld_testStaticLibWithPlugin ) add_library(imp_testInterfaceInclude1b STATIC imp_testInterfaceInclude1.c) @@ -183,10 +191,16 @@ target_link_libraries(SubDirLink_bld PRIVATE bld_TopDirLib bld_SubDirLinkA) add_executable(SubDirLink_exp SubDirLink.c) target_link_libraries(SubDirLink_exp PRIVATE exp_TopDirLib exp_SubDirLinkA) +add_executable(imp_UseSharedLibWithHelper1b ../../../InterfaceLinkLibrariesDirect/UseSharedLibWithHelper.c) +target_link_libraries(imp_UseSharedLibWithHelper1b PRIVATE bld_testSharedLibWithHelper testSharedLibHelperExclude) + # Try building a plugin to an executable imported from the build tree. add_library(imp_mod1b MODULE imp_mod1.c) target_link_libraries(imp_mod1b bld_testExe2) +add_library(imp_ExePlugin1b MODULE ../../../InterfaceLinkLibrariesDirect/ExePlugin.c) +target_link_libraries(imp_ExePlugin1b PRIVATE bld_testExeWithPluginHelper testExePluginHelperExclude) + # Export/CMakeLists.txt pretends the RelWithDebInfo (as well as Debug) # configuration should link to debug libs. foreach(c DEBUG RELWITHDEBINFO) diff --git a/Tests/ExportImport/Import/A/imp_testExe1.c b/Tests/ExportImport/Import/A/imp_testExe1.c index 8173557..7490a80 100644 --- a/Tests/ExportImport/Import/A/imp_testExe1.c +++ b/Tests/ExportImport/Import/A/imp_testExe1.c @@ -10,6 +10,7 @@ extern int testLib6(void); extern int testLib7(void); extern int testLibCycleA1(void); extern int testLibPerConfigDest(void); +extern int testStaticLibPlugin(void); /* Switch a symbol between debug and optimized builds to make sure the proper library is found from the testLib4 link interface. */ @@ -24,6 +25,7 @@ int main() { return (testLib2() + generated_by_testExe1() + testLib3() + testLib4() + testLib5() + testLib6() + testLib7() + testLibCycleA1() + - testLibPerConfigDest() + generated_by_testExe3() + - generated_by_testExe4() + testLib4lib() + testLib4libcfg()); + testLibPerConfigDest() + testStaticLibPlugin() + + generated_by_testExe3() + generated_by_testExe4() + testLib4lib() + + testLib4libcfg()); } diff --git a/Tests/InterfaceLinkLibrariesDirect/CMakeLists.txt b/Tests/InterfaceLinkLibrariesDirect/CMakeLists.txt new file mode 100644 index 0000000..b06a2fb --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/CMakeLists.txt @@ -0,0 +1,156 @@ +cmake_minimum_required(VERSION 3.21) +project(InterfaceLinkLibrariesDirect C) + +include(testStaticLibPlugin.cmake) +add_executable(InterfaceLinkLibrariesDirect main.c) +target_link_libraries(InterfaceLinkLibrariesDirect PRIVATE testStaticLibWithPlugin) + +include(testSharedLibWithHelper.cmake) +add_executable(UseSharedLibWithHelper UseSharedLibWithHelper.c) +target_link_libraries(UseSharedLibWithHelper PRIVATE testSharedLibWithHelper testSharedLibHelperExclude) + +include(testExeWithPluginHelper.cmake) +add_library(ExePlugin MODULE ExePlugin.c) +target_link_libraries(ExePlugin PRIVATE testExeWithPluginHelper testExePluginHelperExclude) + +#---------------------------------------------------------------------------- + +# Offer usage requirements and symbols to be used through static libs below. +add_library(A STATIC + a_always.c + + # Good symbols that direct_from_A libraries poison if incorrectly used. + a_not_direct_from_A.c + a_not_direct_from_A_for_exe.c + a_not_direct_from_A_optional.c + + # Bad symbols in direct_from_A libraries below to ensure they come first. + a_poison_direct_from_A.c + a_poison_direct_from_A_for_exe.c + a_poison_direct_from_A_optional.c + ) + +# Propagates as usage requirement from A. +add_library(direct_from_A STATIC direct_from_A.c direct_from_A_poison.c) +target_compile_definitions(direct_from_A INTERFACE DEF_DIRECT_FROM_A) +set_property(TARGET A APPEND PROPERTY INTERFACE_LINK_LIBRARIES_DIRECT direct_from_A) + +# Propagates as usage requirement from A, but only for executables. +add_library(direct_from_A_for_exe STATIC direct_from_A_for_exe.c direct_from_A_for_exe_poison.c) +target_compile_definitions(direct_from_A_for_exe INTERFACE DEF_DIRECT_FROM_A_FOR_EXE) +set_property(TARGET A APPEND PROPERTY INTERFACE_LINK_LIBRARIES_DIRECT + "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:direct_from_A_for_exe>") + +# Propagates as usage requirement from A, but only for targets that opt-in. +add_library(direct_from_A_optional STATIC direct_from_A_optional.c direct_from_A_optional_poison.c) +target_compile_definitions(direct_from_A_optional INTERFACE DEF_DIRECT_FROM_A_OPTIONAL) +set_property(TARGET A APPEND PROPERTY INTERFACE_LINK_LIBRARIES_DIRECT + "$<$<BOOL:$<TARGET_PROPERTY:A_LINK_OPTIONAL>>:direct_from_A_optional>") + +# Uses and propagates A's usage requirements. +# Does not use the exe-only or optional usage requirements. +add_library(static_A_public STATIC static_A_public.c) +target_link_libraries(static_A_public PUBLIC A) + +# Uses A's usage requirements, but does not propagate them. +# Does not use the exe-only usage requirement. Does use the optional one. +add_library(static_A_private STATIC static_A_private.c) +target_link_libraries(static_A_private PRIVATE A) +set_property(TARGET static_A_private PROPERTY A_LINK_OPTIONAL 1) + +# Uses A's usage requirements, including an optional one. +add_executable(exe_use_static_A_public exe_use_static_A_public.c) +target_link_libraries(exe_use_static_A_public PRIVATE static_A_public) +set_property(TARGET exe_use_static_A_public PROPERTY A_LINK_OPTIONAL 1) + +# Does not use A's usage requirements. +add_executable(exe_use_static_A_private exe_use_static_A_private.c) +target_link_libraries(exe_use_static_A_private PRIVATE static_A_private) + +#---------------------------------------------------------------------------- + +# Test how original and injected dependencies get ordered. + +# A bunch of static libraries that need to be linked in alphabetic order. +# Each library has an extra source to poison all symbols meant to be +# provided by earlier libraries. This enforces ordering on platforms +# whose linkers re-visit static libraries. +add_library(order_A STATIC order_A.c) +add_library(order_B STATIC order_B.c order_B_poison.c) +add_library(order_C STATIC order_C.c order_C_poison.c) +add_library(order_D STATIC order_D.c order_D_poison.c) +add_library(order_E STATIC order_E.c order_E_poison.c) +add_library(order_F STATIC order_F.c order_F_poison.c) +add_library(order_G STATIC order_G.c order_G_poison.c) +add_library(order_H STATIC order_H.c order_H_poison.c) +add_library(order_I STATIC order_I.c order_I_poison.c) +add_library(order_J STATIC order_J.c order_J_poison.c) + +# An executable to drive linking. +add_executable(order_main order_main.c) + +# In the following diagram, connection by a slash means the top +# target lists the bottom target in a link interface property: +# +# \ => INTERFACE_LINK_LIBRARIES +# / => INTERFACE_LINK_LIBRARIES_DIRECT +# +# The top of each tree represents an entry in the exe's LINK_LIBRARIES. +# CMake should evaluate this graph to generate the proper link order. +# +# D H +# / \ / \ +# B J F I +# / / / / \ +# A C E G J +set_property(TARGET order_main PROPERTY LINK_LIBRARIES order_D order_H) +set_property(TARGET order_D PROPERTY INTERFACE_LINK_LIBRARIES_DIRECT order_B) +set_property(TARGET order_D PROPERTY INTERFACE_LINK_LIBRARIES order_J) +set_property(TARGET order_B PROPERTY INTERFACE_LINK_LIBRARIES_DIRECT order_A) +set_property(TARGET order_J PROPERTY INTERFACE_LINK_LIBRARIES_DIRECT order_C) +set_property(TARGET order_H PROPERTY INTERFACE_LINK_LIBRARIES_DIRECT order_F) +set_property(TARGET order_H PROPERTY INTERFACE_LINK_LIBRARIES order_I) +set_property(TARGET order_F PROPERTY INTERFACE_LINK_LIBRARIES_DIRECT order_E) +set_property(TARGET order_I PROPERTY INTERFACE_LINK_LIBRARIES_DIRECT order_G) +set_property(TARGET order_I PROPERTY INTERFACE_LINK_LIBRARIES order_J) + +#---------------------------------------------------------------------------- + +# Test that the original LINK_LIBRARIES cannot be re-ordered by injection +# from usage requirements. + +# A bunch of static libraries that need to be linked in alphabetic order. +# Each library has an extra source to poison all symbols meant to be +# provided by earlier libraries. This enforces ordering on platforms +# whose linkers re-visit static libraries. +add_library(force_A STATIC order_A.c) +add_library(force_B STATIC order_B.c order_B_poison.c) +add_library(force_C STATIC order_C.c order_C_poison.c) +add_library(force_D STATIC order_D.c order_D_poison.c) +add_library(force_E STATIC order_E.c order_E_poison.c) +add_library(force_F STATIC order_F.c order_F_poison.c) +add_library(force_G STATIC order_G.c order_G_poison.c) +add_library(force_H STATIC order_H.c order_H_poison.c) +add_library(force_I STATIC order_I.c order_I_poison.c) +add_library(force_J STATIC order_J.c order_J_poison.c) + +# An executable to drive linking. +add_executable(force_main order_main.c) + +# The executable explicitly lists all the libraries in the right order. +target_link_libraries(force_main PRIVATE force_A force_B force_C force_D force_E force_F force_G force_H) + +# Add legitimate normal dependencies. +set_property(TARGET force_D PROPERTY INTERFACE_LINK_LIBRARIES force_J) +set_property(TARGET force_H PROPERTY INTERFACE_LINK_LIBRARIES force_I) +set_property(TARGET force_I PROPERTY INTERFACE_LINK_LIBRARIES force_J) + +# Add bogus injected direct dependencies to verify that they do not +# change the original order of LINK_LIBRARIES. +set_property(TARGET force_A PROPERTY INTERFACE_LINK_LIBRARIES_DIRECT force_B) +set_property(TARGET force_B PROPERTY INTERFACE_LINK_LIBRARIES_DIRECT force_C) +set_property(TARGET force_C PROPERTY INTERFACE_LINK_LIBRARIES_DIRECT force_D) +set_property(TARGET force_D PROPERTY INTERFACE_LINK_LIBRARIES_DIRECT force_E) +set_property(TARGET force_E PROPERTY INTERFACE_LINK_LIBRARIES_DIRECT force_F) +set_property(TARGET force_F PROPERTY INTERFACE_LINK_LIBRARIES_DIRECT force_G) +set_property(TARGET force_G PROPERTY INTERFACE_LINK_LIBRARIES_DIRECT force_H) diff --git a/Tests/InterfaceLinkLibrariesDirect/ExePlugin.c b/Tests/InterfaceLinkLibrariesDirect/ExePlugin.c new file mode 100644 index 0000000..40a261c --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/ExePlugin.c @@ -0,0 +1,21 @@ +extern int testExePluginHelperObj(int n); + +#ifdef testExePluginHelperObj_NO_OBJECT +int testExePluginHelperObj(int n) +{ + return n; +} +#endif + +#if defined(_WIN32) +__declspec(dllimport) +#endif + int testExePluginAPI(int n); + +#if defined(_WIN32) +__declspec(dllexport) +#endif + int testExePlugin(int n) +{ + return testExePluginAPI(n) + testExePluginHelperObj(n); +} diff --git a/Tests/InterfaceLinkLibrariesDirect/UseSharedLibWithHelper.c b/Tests/InterfaceLinkLibrariesDirect/UseSharedLibWithHelper.c new file mode 100644 index 0000000..832e31f --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/UseSharedLibWithHelper.c @@ -0,0 +1,18 @@ +extern int testSharedLibHelperObj(int n); + +#ifdef testSharedLibHelperObj_NO_OBJECT +int testSharedLibHelperObj(int n) +{ + return n; +} +#endif + +#if defined(_WIN32) +__declspec(dllimport) +#endif + int testSharedLibWithHelper(int n); + +int main(void) +{ + return testSharedLibWithHelper(0) + testSharedLibHelperObj(0); +} diff --git a/Tests/InterfaceLinkLibrariesDirect/a_always.c b/Tests/InterfaceLinkLibrariesDirect/a_always.c new file mode 100644 index 0000000..007680d --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/a_always.c @@ -0,0 +1,3 @@ +void a_always(void) +{ +} diff --git a/Tests/InterfaceLinkLibrariesDirect/a_not_direct_from_A.c b/Tests/InterfaceLinkLibrariesDirect/a_not_direct_from_A.c new file mode 100644 index 0000000..732d36e --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/a_not_direct_from_A.c @@ -0,0 +1,3 @@ +void not_direct_from_A(void) +{ +} diff --git a/Tests/InterfaceLinkLibrariesDirect/a_not_direct_from_A_for_exe.c b/Tests/InterfaceLinkLibrariesDirect/a_not_direct_from_A_for_exe.c new file mode 100644 index 0000000..9aed296 --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/a_not_direct_from_A_for_exe.c @@ -0,0 +1,3 @@ +void not_direct_from_A_for_exe(void) +{ +} diff --git a/Tests/InterfaceLinkLibrariesDirect/a_not_direct_from_A_optional.c b/Tests/InterfaceLinkLibrariesDirect/a_not_direct_from_A_optional.c new file mode 100644 index 0000000..3572e51 --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/a_not_direct_from_A_optional.c @@ -0,0 +1,3 @@ +void not_direct_from_A_optional(void) +{ +} diff --git a/Tests/InterfaceLinkLibrariesDirect/a_poison_direct_from_A.c b/Tests/InterfaceLinkLibrariesDirect/a_poison_direct_from_A.c new file mode 100644 index 0000000..6d1963d --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/a_poison_direct_from_A.c @@ -0,0 +1,5 @@ +extern void poison_direct_from_A(void); +void direct_from_A(void) +{ + poison_direct_from_A(); +} diff --git a/Tests/InterfaceLinkLibrariesDirect/a_poison_direct_from_A_for_exe.c b/Tests/InterfaceLinkLibrariesDirect/a_poison_direct_from_A_for_exe.c new file mode 100644 index 0000000..623fc07 --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/a_poison_direct_from_A_for_exe.c @@ -0,0 +1,5 @@ +extern void poison_direct_from_A_for_exe(void); +void direct_from_A_for_exe(void) +{ + poison_direct_from_A_for_exe(); +} diff --git a/Tests/InterfaceLinkLibrariesDirect/a_poison_direct_from_A_optional.c b/Tests/InterfaceLinkLibrariesDirect/a_poison_direct_from_A_optional.c new file mode 100644 index 0000000..0f1328e --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/a_poison_direct_from_A_optional.c @@ -0,0 +1,5 @@ +extern void poison_direct_from_A_optional(void); +void direct_from_A_optional(void) +{ + poison_direct_from_A_optional(); +} diff --git a/Tests/InterfaceLinkLibrariesDirect/direct_from_A.c b/Tests/InterfaceLinkLibrariesDirect/direct_from_A.c new file mode 100644 index 0000000..d6d0df3 --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/direct_from_A.c @@ -0,0 +1,3 @@ +void direct_from_A(void) +{ +} diff --git a/Tests/InterfaceLinkLibrariesDirect/direct_from_A_for_exe.c b/Tests/InterfaceLinkLibrariesDirect/direct_from_A_for_exe.c new file mode 100644 index 0000000..dfa6db1 --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/direct_from_A_for_exe.c @@ -0,0 +1,3 @@ +void direct_from_A_for_exe(void) +{ +} diff --git a/Tests/InterfaceLinkLibrariesDirect/direct_from_A_for_exe_poison.c b/Tests/InterfaceLinkLibrariesDirect/direct_from_A_for_exe_poison.c new file mode 100644 index 0000000..c0ecb0b --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/direct_from_A_for_exe_poison.c @@ -0,0 +1,5 @@ +extern void poison_not_direct_from_A_for_exe(void); +void not_direct_from_A_for_exe(void) +{ + poison_not_direct_from_A_for_exe(); +} diff --git a/Tests/InterfaceLinkLibrariesDirect/direct_from_A_optional.c b/Tests/InterfaceLinkLibrariesDirect/direct_from_A_optional.c new file mode 100644 index 0000000..affdaeb --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/direct_from_A_optional.c @@ -0,0 +1,3 @@ +void direct_from_A_optional(void) +{ +} diff --git a/Tests/InterfaceLinkLibrariesDirect/direct_from_A_optional_poison.c b/Tests/InterfaceLinkLibrariesDirect/direct_from_A_optional_poison.c new file mode 100644 index 0000000..c7c3528 --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/direct_from_A_optional_poison.c @@ -0,0 +1,5 @@ +extern void poison_not_direct_from_A_optional(void); +void not_direct_from_A_optional(void) +{ + poison_not_direct_from_A_optional(); +} diff --git a/Tests/InterfaceLinkLibrariesDirect/direct_from_A_poison.c b/Tests/InterfaceLinkLibrariesDirect/direct_from_A_poison.c new file mode 100644 index 0000000..b03cdf7 --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/direct_from_A_poison.c @@ -0,0 +1,5 @@ +extern void poison_not_direct_from_A(void); +void not_direct_from_A(void) +{ + poison_not_direct_from_A(); +} diff --git a/Tests/InterfaceLinkLibrariesDirect/exe_use_static_A_private.c b/Tests/InterfaceLinkLibrariesDirect/exe_use_static_A_private.c new file mode 100644 index 0000000..024e96e --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/exe_use_static_A_private.c @@ -0,0 +1,23 @@ +#ifdef DEF_DIRECT_FROM_A +# error "DEF_DIRECT_FROM_A incorrectly defined" +#endif +#ifdef DEF_DIRECT_FROM_A_FOR_EXE +# error "DEF_DIRECT_FROM_A_FOR_EXE incorrectly defined" +#endif +#ifdef DEF_DIRECT_FROM_A_OPTIONAL +# error "DEF_DIRECT_FROM_A_OPTIONAL incorrectly defined" +#endif + +extern void static_A_private(void); +extern void not_direct_from_A(void); +extern void not_direct_from_A_for_exe(void); +extern void not_direct_from_A_optional(void); + +int main(void) +{ + static_A_private(); + not_direct_from_A(); + not_direct_from_A_for_exe(); + not_direct_from_A_optional(); + return 0; +} diff --git a/Tests/InterfaceLinkLibrariesDirect/exe_use_static_A_public.c b/Tests/InterfaceLinkLibrariesDirect/exe_use_static_A_public.c new file mode 100644 index 0000000..b3b0a56 --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/exe_use_static_A_public.c @@ -0,0 +1,23 @@ +#ifndef DEF_DIRECT_FROM_A +# error "DEF_DIRECT_FROM_A incorrectly not defined" +#endif +#ifndef DEF_DIRECT_FROM_A_FOR_EXE +# error "DEF_DIRECT_FROM_A_FOR_EXE incorrectly not defined" +#endif +#ifndef DEF_DIRECT_FROM_A_OPTIONAL +# error "DEF_DIRECT_FROM_A_OPTIONAL incorrectly not defined" +#endif + +extern void static_A_public(void); +extern void direct_from_A(void); +extern void direct_from_A_for_exe(void); +extern void direct_from_A_optional(void); + +int main(void) +{ + static_A_public(); + direct_from_A(); + direct_from_A_for_exe(); + direct_from_A_optional(); + return 0; +} diff --git a/Tests/InterfaceLinkLibrariesDirect/main.c b/Tests/InterfaceLinkLibrariesDirect/main.c new file mode 100644 index 0000000..53f0e6d --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/main.c @@ -0,0 +1,5 @@ +extern int testStaticLibPlugin(void); +int main(void) +{ + return testStaticLibPlugin(); +} diff --git a/Tests/InterfaceLinkLibrariesDirect/order_A.c b/Tests/InterfaceLinkLibrariesDirect/order_A.c new file mode 100644 index 0000000..2cd4d60 --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/order_A.c @@ -0,0 +1,5 @@ +extern void order_B(void); +void order_A(void) +{ + order_B(); +} diff --git a/Tests/InterfaceLinkLibrariesDirect/order_B.c b/Tests/InterfaceLinkLibrariesDirect/order_B.c new file mode 100644 index 0000000..1787f1d --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/order_B.c @@ -0,0 +1,5 @@ +extern void order_C(void); +void order_B(void) +{ + order_C(); +} diff --git a/Tests/InterfaceLinkLibrariesDirect/order_B_poison.c b/Tests/InterfaceLinkLibrariesDirect/order_B_poison.c new file mode 100644 index 0000000..bcb7b4b --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/order_B_poison.c @@ -0,0 +1,6 @@ +extern void order_B_poison(void); + +void order_A(void) +{ + order_B_poison(); +} diff --git a/Tests/InterfaceLinkLibrariesDirect/order_C.c b/Tests/InterfaceLinkLibrariesDirect/order_C.c new file mode 100644 index 0000000..e67e719 --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/order_C.c @@ -0,0 +1,5 @@ +extern void order_D(void); +void order_C(void) +{ + order_D(); +} diff --git a/Tests/InterfaceLinkLibrariesDirect/order_C_poison.c b/Tests/InterfaceLinkLibrariesDirect/order_C_poison.c new file mode 100644 index 0000000..fc31104 --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/order_C_poison.c @@ -0,0 +1,11 @@ +extern void order_C_poison(void); + +void order_A(void) +{ + order_C_poison(); +} + +void order_B(void) +{ + order_C_poison(); +} diff --git a/Tests/InterfaceLinkLibrariesDirect/order_D.c b/Tests/InterfaceLinkLibrariesDirect/order_D.c new file mode 100644 index 0000000..f5bb2d6 --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/order_D.c @@ -0,0 +1,5 @@ +extern void order_E(void); +void order_D(void) +{ + order_E(); +} diff --git a/Tests/InterfaceLinkLibrariesDirect/order_D_poison.c b/Tests/InterfaceLinkLibrariesDirect/order_D_poison.c new file mode 100644 index 0000000..d2d64e6 --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/order_D_poison.c @@ -0,0 +1,16 @@ +extern void order_D_poison(void); + +void order_A(void) +{ + order_D_poison(); +} + +void order_B(void) +{ + order_D_poison(); +} + +void order_C(void) +{ + order_D_poison(); +} diff --git a/Tests/InterfaceLinkLibrariesDirect/order_E.c b/Tests/InterfaceLinkLibrariesDirect/order_E.c new file mode 100644 index 0000000..2a56443 --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/order_E.c @@ -0,0 +1,5 @@ +extern void order_F(void); +void order_E(void) +{ + order_F(); +} diff --git a/Tests/InterfaceLinkLibrariesDirect/order_E_poison.c b/Tests/InterfaceLinkLibrariesDirect/order_E_poison.c new file mode 100644 index 0000000..7d8b53e --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/order_E_poison.c @@ -0,0 +1,21 @@ +extern void order_E_poison(void); + +void order_A(void) +{ + order_E_poison(); +} + +void order_B(void) +{ + order_E_poison(); +} + +void order_C(void) +{ + order_E_poison(); +} + +void order_D(void) +{ + order_E_poison(); +} diff --git a/Tests/InterfaceLinkLibrariesDirect/order_F.c b/Tests/InterfaceLinkLibrariesDirect/order_F.c new file mode 100644 index 0000000..d242284 --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/order_F.c @@ -0,0 +1,5 @@ +extern void order_G(void); +void order_F(void) +{ + order_G(); +} diff --git a/Tests/InterfaceLinkLibrariesDirect/order_F_poison.c b/Tests/InterfaceLinkLibrariesDirect/order_F_poison.c new file mode 100644 index 0000000..285f247 --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/order_F_poison.c @@ -0,0 +1,26 @@ +extern void order_F_poison(void); + +void order_A(void) +{ + order_F_poison(); +} + +void order_B(void) +{ + order_F_poison(); +} + +void order_C(void) +{ + order_F_poison(); +} + +void order_D(void) +{ + order_F_poison(); +} + +void order_E(void) +{ + order_F_poison(); +} diff --git a/Tests/InterfaceLinkLibrariesDirect/order_G.c b/Tests/InterfaceLinkLibrariesDirect/order_G.c new file mode 100644 index 0000000..ff71038 --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/order_G.c @@ -0,0 +1,5 @@ +extern void order_H(void); +void order_G(void) +{ + order_H(); +} diff --git a/Tests/InterfaceLinkLibrariesDirect/order_G_poison.c b/Tests/InterfaceLinkLibrariesDirect/order_G_poison.c new file mode 100644 index 0000000..3a1fe1d --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/order_G_poison.c @@ -0,0 +1,31 @@ +extern void order_G_poison(void); + +void order_A(void) +{ + order_G_poison(); +} + +void order_B(void) +{ + order_G_poison(); +} + +void order_C(void) +{ + order_G_poison(); +} + +void order_D(void) +{ + order_G_poison(); +} + +void order_E(void) +{ + order_G_poison(); +} + +void order_F(void) +{ + order_G_poison(); +} diff --git a/Tests/InterfaceLinkLibrariesDirect/order_H.c b/Tests/InterfaceLinkLibrariesDirect/order_H.c new file mode 100644 index 0000000..9c62bb1 --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/order_H.c @@ -0,0 +1,5 @@ +extern void order_I(void); +void order_H(void) +{ + order_I(); +} diff --git a/Tests/InterfaceLinkLibrariesDirect/order_H_poison.c b/Tests/InterfaceLinkLibrariesDirect/order_H_poison.c new file mode 100644 index 0000000..0c6b84f --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/order_H_poison.c @@ -0,0 +1,36 @@ +extern void order_H_poison(void); + +void order_A(void) +{ + order_H_poison(); +} + +void order_B(void) +{ + order_H_poison(); +} + +void order_C(void) +{ + order_H_poison(); +} + +void order_D(void) +{ + order_H_poison(); +} + +void order_E(void) +{ + order_H_poison(); +} + +void order_F(void) +{ + order_H_poison(); +} + +void order_G(void) +{ + order_H_poison(); +} diff --git a/Tests/InterfaceLinkLibrariesDirect/order_I.c b/Tests/InterfaceLinkLibrariesDirect/order_I.c new file mode 100644 index 0000000..96152de --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/order_I.c @@ -0,0 +1,5 @@ +extern void order_J(void); +void order_I(void) +{ + order_J(); +} diff --git a/Tests/InterfaceLinkLibrariesDirect/order_I_poison.c b/Tests/InterfaceLinkLibrariesDirect/order_I_poison.c new file mode 100644 index 0000000..3fabe1f --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/order_I_poison.c @@ -0,0 +1,41 @@ +extern void order_I_poison(void); + +void order_A(void) +{ + order_I_poison(); +} + +void order_B(void) +{ + order_I_poison(); +} + +void order_C(void) +{ + order_I_poison(); +} + +void order_D(void) +{ + order_I_poison(); +} + +void order_E(void) +{ + order_I_poison(); +} + +void order_F(void) +{ + order_I_poison(); +} + +void order_G(void) +{ + order_I_poison(); +} + +void order_H(void) +{ + order_I_poison(); +} diff --git a/Tests/InterfaceLinkLibrariesDirect/order_J.c b/Tests/InterfaceLinkLibrariesDirect/order_J.c new file mode 100644 index 0000000..49eec47 --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/order_J.c @@ -0,0 +1,3 @@ +void order_J(void) +{ +} diff --git a/Tests/InterfaceLinkLibrariesDirect/order_J_poison.c b/Tests/InterfaceLinkLibrariesDirect/order_J_poison.c new file mode 100644 index 0000000..9724fd5 --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/order_J_poison.c @@ -0,0 +1,46 @@ +extern void order_J_poison(void); + +void order_A(void) +{ + order_J_poison(); +} + +void order_B(void) +{ + order_J_poison(); +} + +void order_C(void) +{ + order_J_poison(); +} + +void order_D(void) +{ + order_J_poison(); +} + +void order_E(void) +{ + order_J_poison(); +} + +void order_F(void) +{ + order_J_poison(); +} + +void order_G(void) +{ + order_J_poison(); +} + +void order_H(void) +{ + order_J_poison(); +} + +void order_I(void) +{ + order_J_poison(); +} diff --git a/Tests/InterfaceLinkLibrariesDirect/order_main.c b/Tests/InterfaceLinkLibrariesDirect/order_main.c new file mode 100644 index 0000000..eed2453 --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/order_main.c @@ -0,0 +1,6 @@ +extern void order_A(void); +int main(void) +{ + order_A(); + return 0; +} diff --git a/Tests/InterfaceLinkLibrariesDirect/static_A_private.c b/Tests/InterfaceLinkLibrariesDirect/static_A_private.c new file mode 100644 index 0000000..d98a22c --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/static_A_private.c @@ -0,0 +1,16 @@ +#ifndef DEF_DIRECT_FROM_A +# error "DEF_DIRECT_FROM_A incorrectly not defined" +#endif +#ifdef DEF_DIRECT_FROM_A_FOR_EXE +# error "DEF_DIRECT_FROM_A_FOR_EXE incorrectly defined" +#endif +#ifndef DEF_DIRECT_FROM_A_OPTIONAL +# error "DEF_DIRECT_FROM_A_OPTIONAL incorrectly not defined" +#endif + +extern void a_always(void); + +void static_A_private(void) +{ + a_always(); +} diff --git a/Tests/InterfaceLinkLibrariesDirect/static_A_public.c b/Tests/InterfaceLinkLibrariesDirect/static_A_public.c new file mode 100644 index 0000000..ed88ca6 --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/static_A_public.c @@ -0,0 +1,16 @@ +#ifndef DEF_DIRECT_FROM_A +# error "DEF_DIRECT_FROM_A incorrectly not defined" +#endif +#ifdef DEF_DIRECT_FROM_A_FOR_EXE +# error "DEF_DIRECT_FROM_A_FOR_EXE incorrectly defined" +#endif +#ifdef DEF_DIRECT_FROM_A_OPTIONAL +# error "DEF_DIRECT_FROM_A_OPTIONAL incorrectly defined" +#endif + +extern void a_always(void); + +void static_A_public(void) +{ + a_always(); +} diff --git a/Tests/InterfaceLinkLibrariesDirect/testExePluginHelperObj.c b/Tests/InterfaceLinkLibrariesDirect/testExePluginHelperObj.c new file mode 100644 index 0000000..49c495f --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/testExePluginHelperObj.c @@ -0,0 +1,4 @@ +int testExePluginHelperObj(int n) +{ + return n; +} diff --git a/Tests/InterfaceLinkLibrariesDirect/testExeWithPluginHelper.c b/Tests/InterfaceLinkLibrariesDirect/testExeWithPluginHelper.c new file mode 100644 index 0000000..f8787db --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/testExeWithPluginHelper.c @@ -0,0 +1,12 @@ +#ifdef _WIN32 +__declspec(dllexport) +#endif + int testExePluginAPI(int n) +{ + return n; +} + +int main(void) +{ + return 0; +} diff --git a/Tests/InterfaceLinkLibrariesDirect/testExeWithPluginHelper.cmake b/Tests/InterfaceLinkLibrariesDirect/testExeWithPluginHelper.cmake new file mode 100644 index 0000000..97c5b65 --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/testExeWithPluginHelper.cmake @@ -0,0 +1,7 @@ +# Logic common to InterfaceLinkLibrariesDirect and ExportImport tests. +set(src ${CMAKE_CURRENT_LIST_DIR}) +add_executable(testExeWithPluginHelper ${src}/testExeWithPluginHelper.c) +add_library(testExePluginHelperObj OBJECT ${src}/testExePluginHelperObj.c) +set_property(TARGET testExeWithPluginHelper PROPERTY ENABLE_EXPORTS 1) +set_property(TARGET testExeWithPluginHelper PROPERTY INTERFACE_LINK_LIBRARIES_DIRECT $<TARGET_NAME:testExePluginHelperObj>) +set_property(TARGET testExeWithPluginHelper PROPERTY INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE $<1:testExePluginHelperExclude>) diff --git a/Tests/InterfaceLinkLibrariesDirect/testSharedLibHelperObj.c b/Tests/InterfaceLinkLibrariesDirect/testSharedLibHelperObj.c new file mode 100644 index 0000000..9d55fcb --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/testSharedLibHelperObj.c @@ -0,0 +1,4 @@ +int testSharedLibHelperObj(int n) +{ + return n; +} diff --git a/Tests/InterfaceLinkLibrariesDirect/testSharedLibWithHelper.c b/Tests/InterfaceLinkLibrariesDirect/testSharedLibWithHelper.c new file mode 100644 index 0000000..f942b54 --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/testSharedLibWithHelper.c @@ -0,0 +1,7 @@ +#ifdef _WIN32 +__declspec(dllexport) +#endif + int testSharedLibWithHelper(int n) +{ + return n; +} diff --git a/Tests/InterfaceLinkLibrariesDirect/testSharedLibWithHelper.cmake b/Tests/InterfaceLinkLibrariesDirect/testSharedLibWithHelper.cmake new file mode 100644 index 0000000..c51751c --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/testSharedLibWithHelper.cmake @@ -0,0 +1,6 @@ +# Logic common to InterfaceLinkLibrariesDirect and ExportImport tests. +set(src ${CMAKE_CURRENT_LIST_DIR}) +add_library(testSharedLibWithHelper SHARED ${src}/testSharedLibWithHelper.c) +add_library(testSharedLibHelperObj OBJECT ${src}/testSharedLibHelperObj.c) +set_property(TARGET testSharedLibWithHelper PROPERTY INTERFACE_LINK_LIBRARIES_DIRECT $<TARGET_NAME:testSharedLibHelperObj>) +set_property(TARGET testSharedLibWithHelper PROPERTY INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE $<1:testSharedLibHelperExclude>) diff --git a/Tests/InterfaceLinkLibrariesDirect/testStaticLibPlugin.c b/Tests/InterfaceLinkLibrariesDirect/testStaticLibPlugin.c new file mode 100644 index 0000000..17f643f --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/testStaticLibPlugin.c @@ -0,0 +1,6 @@ +extern int testStaticLibWithPlugin1(void); +extern int testStaticLibPluginExtra(void); +int testStaticLibPlugin(void) +{ + return testStaticLibWithPlugin1() + testStaticLibPluginExtra(); +} diff --git a/Tests/InterfaceLinkLibrariesDirect/testStaticLibPlugin.cmake b/Tests/InterfaceLinkLibrariesDirect/testStaticLibPlugin.cmake new file mode 100644 index 0000000..907872f --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/testStaticLibPlugin.cmake @@ -0,0 +1,14 @@ +# Logic common to InterfaceLinkLibrariesDirect and ExportImport tests. +set(src ${CMAKE_CURRENT_LIST_DIR}) +add_library(testStaticLibWithPlugin STATIC + ${src}/testStaticLibWithPlugin1.c # used by testStaticLibPlugin + ${src}/testStaticLibWithPlugin2.c # used by testStaticLibPluginExtra + ${src}/testStaticLibWithPluginBad1.c # link error if not after testStaticLibPlugin + ${src}/testStaticLibWithPluginBad2.c # link error if not after testStaticLibPluginExtra + ) +add_library(testStaticLibPluginExtra STATIC ${src}/testStaticLibPluginExtra.c) +add_library(testStaticLibPlugin STATIC ${src}/testStaticLibPlugin.c) +target_link_libraries(testStaticLibPlugin PUBLIC testStaticLibWithPlugin testStaticLibPluginExtra) +target_link_libraries(testStaticLibPluginExtra PUBLIC testStaticLibWithPlugin) +set_property(TARGET testStaticLibWithPlugin PROPERTY INTERFACE_LINK_LIBRARIES_DIRECT testStaticLibPlugin) +set_property(TARGET testStaticLibWithPlugin PROPERTY INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE testStaticLibWithPlugin) diff --git a/Tests/InterfaceLinkLibrariesDirect/testStaticLibPluginExtra.c b/Tests/InterfaceLinkLibrariesDirect/testStaticLibPluginExtra.c new file mode 100644 index 0000000..11fe0f8 --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/testStaticLibPluginExtra.c @@ -0,0 +1,5 @@ +extern int testStaticLibWithPlugin2(void); +int testStaticLibPluginExtra(void) +{ + return testStaticLibWithPlugin2(); +} diff --git a/Tests/InterfaceLinkLibrariesDirect/testStaticLibWithPlugin1.c b/Tests/InterfaceLinkLibrariesDirect/testStaticLibWithPlugin1.c new file mode 100644 index 0000000..5e75dce --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/testStaticLibWithPlugin1.c @@ -0,0 +1,4 @@ +int testStaticLibWithPlugin1(void) +{ + return 0; +} diff --git a/Tests/InterfaceLinkLibrariesDirect/testStaticLibWithPlugin2.c b/Tests/InterfaceLinkLibrariesDirect/testStaticLibWithPlugin2.c new file mode 100644 index 0000000..74ac1ae --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/testStaticLibWithPlugin2.c @@ -0,0 +1,4 @@ +int testStaticLibWithPlugin2(void) +{ + return 0; +} diff --git a/Tests/InterfaceLinkLibrariesDirect/testStaticLibWithPluginBad1.c b/Tests/InterfaceLinkLibrariesDirect/testStaticLibWithPluginBad1.c new file mode 100644 index 0000000..b41abc9 --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/testStaticLibWithPluginBad1.c @@ -0,0 +1,6 @@ +/* Produce an error if if the object compiled from this source is used. */ +extern int testStaticLibWithPlugin_linked_before_testStaticLibPlugin(void); +int testStaticLibPlugin(void) +{ + return testStaticLibWithPlugin_linked_before_testStaticLibPlugin(); +} diff --git a/Tests/InterfaceLinkLibrariesDirect/testStaticLibWithPluginBad2.c b/Tests/InterfaceLinkLibrariesDirect/testStaticLibWithPluginBad2.c new file mode 100644 index 0000000..43337a5 --- /dev/null +++ b/Tests/InterfaceLinkLibrariesDirect/testStaticLibWithPluginBad2.c @@ -0,0 +1,7 @@ +/* Produce an error if if the object compiled from this source is used. */ +extern int testStaticLibWithPlugin_linked_before_testStaticLibPluginExtra( + void); +int testStaticLibPluginExtra(void) +{ + return testStaticLibWithPlugin_linked_before_testStaticLibPluginExtra(); +} diff --git a/Tests/Module/WriteCompilerDetectionHeader/CMakeLists.txt b/Tests/Module/WriteCompilerDetectionHeader/CMakeLists.txt index 8898f3b..0df05b9 100644 --- a/Tests/Module/WriteCompilerDetectionHeader/CMakeLists.txt +++ b/Tests/Module/WriteCompilerDetectionHeader/CMakeLists.txt @@ -55,7 +55,7 @@ endmacro() # detailed features tables, not just meta-features if (CMAKE_C_COMPILE_FEATURES) - if (NOT CMAKE_C_COMPILER_ID MATCHES "^(LCC|Cray|PGI|NVHPC|XL|XLClang|IntelLLVM|Fujitsu|FujitsuClang)$") + if (NOT CMAKE_C_COMPILER_ID MATCHES "^(LCC|Cray|PGI|NVHPC|XL|XLClang|IBMClang|IntelLLVM|Fujitsu|FujitsuClang)$") set(C_expected_features ${CMAKE_C_COMPILE_FEATURES}) list(FILTER C_expected_features EXCLUDE REGEX "^c_std_[0-9][0-9]") endif() @@ -98,7 +98,7 @@ if (C_expected_features) endif() if (CMAKE_CXX_COMPILE_FEATURES) - if (NOT CMAKE_CXX_COMPILER_ID MATCHES "^(LCC|Cray|PGI|NVHPC|XL|XLClang|IntelLLVM|Fujitsu|FujitsuClang)$") + if (NOT CMAKE_CXX_COMPILER_ID MATCHES "^(LCC|Cray|PGI|NVHPC|XL|XLClang|IBMClang|IntelLLVM|Fujitsu|FujitsuClang)$") set(CXX_expected_features ${CMAKE_CXX_COMPILE_FEATURES}) list(FILTER CXX_expected_features EXCLUDE REGEX "^cxx_std_[0-9][0-9]") endif() diff --git a/Tests/ObjectLibrary/Transitive/BarMain.c b/Tests/ObjectLibrary/Transitive/BarMain.c new file mode 100644 index 0000000..aec3e48 --- /dev/null +++ b/Tests/ObjectLibrary/Transitive/BarMain.c @@ -0,0 +1,6 @@ +extern int BarObject1(void); + +int main(void) +{ + return BarObject1(); +} diff --git a/Tests/ObjectLibrary/Transitive/BarObject1.c b/Tests/ObjectLibrary/Transitive/BarObject1.c new file mode 100644 index 0000000..2f68386 --- /dev/null +++ b/Tests/ObjectLibrary/Transitive/BarObject1.c @@ -0,0 +1,5 @@ +extern int BarObject2(void); +int BarObject1(void) +{ + return BarObject2(); +} diff --git a/Tests/ObjectLibrary/Transitive/BarObject2.c b/Tests/ObjectLibrary/Transitive/BarObject2.c new file mode 100644 index 0000000..881c64a --- /dev/null +++ b/Tests/ObjectLibrary/Transitive/BarObject2.c @@ -0,0 +1,5 @@ +extern int BarObject3(void); +int BarObject2(void) +{ + return BarObject3(); +} diff --git a/Tests/ObjectLibrary/Transitive/BarObject3.c b/Tests/ObjectLibrary/Transitive/BarObject3.c new file mode 100644 index 0000000..e557dbc --- /dev/null +++ b/Tests/ObjectLibrary/Transitive/BarObject3.c @@ -0,0 +1,4 @@ +int BarObject3(void) +{ + return 0; +} diff --git a/Tests/ObjectLibrary/Transitive/CMakeLists.txt b/Tests/ObjectLibrary/Transitive/CMakeLists.txt index d616cda..17247eb 100644 --- a/Tests/ObjectLibrary/Transitive/CMakeLists.txt +++ b/Tests/ObjectLibrary/Transitive/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_policy(SET CMP0022 NEW) add_library(FooStatic STATIC FooStatic.c) add_library(FooObject1 OBJECT FooObject.c) @@ -10,3 +9,17 @@ add_library(FooObject2 OBJECT FooObject.c) target_link_libraries(FooObject2 INTERFACE FooStatic) add_executable(Transitive2 Transitive.c) target_link_libraries(Transitive2 PRIVATE FooObject2) + +add_library(FooObjectDirect OBJECT FooObject.c) +add_library(FooStaticDirect STATIC FooStatic.c) +set_property(TARGET FooStaticDirect PROPERTY INTERFACE_LINK_LIBRARIES_DIRECT FooObjectDirect) +add_executable(TransitiveDirect Transitive.c) +target_link_libraries(TransitiveDirect PRIVATE FooStaticDirect) + +add_library(BarObject1 OBJECT BarObject1.c) +add_library(BarObject2 OBJECT BarObject2.c) +add_library(BarObject3 OBJECT BarObject3.c) +set_property(TARGET BarObject1 PROPERTY INTERFACE_LINK_LIBRARIES_DIRECT BarObject2) +set_property(TARGET BarObject2 PROPERTY INTERFACE_LINK_LIBRARIES_DIRECT BarObject3) +add_executable(BarMain BarMain.c) +target_link_libraries(BarMain PRIVATE BarObject1) diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index dd786b8..e12ffba 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -330,7 +330,7 @@ add_RunCMake_test(TargetPropertyGeneratorExpressions) add_RunCMake_test(Languages) add_RunCMake_test(LinkItemValidation) add_RunCMake_test(LinkStatic) -if(CMAKE_CXX_COMPILER_ID MATCHES "^(Cray|PGI|NVHPC|XL|XLClang|Fujitsu|FujitsuClang)$") +if(CMAKE_CXX_COMPILER_ID MATCHES "^(Cray|PGI|NVHPC|XL|XLClang|IBMClang|Fujitsu|FujitsuClang)$") add_RunCMake_test(MetaCompileFeatures) endif() if(MSVC) @@ -534,6 +534,10 @@ add_RunCMake_test(no_install_prefix) add_RunCMake_test(configure_file) add_RunCMake_test(CTestTimeout -DTIMEOUT=${CTestTestTimeout_TIME}) add_RunCMake_test(CTestTimeoutAfterMatch) +if(CMake_TEST_CUDA) + add_RunCMake_test(CUDA_architectures) + set_property(TEST RunCMake.CUDA_architectures APPEND PROPERTY LABELS "CUDA") +endif() add_RunCMake_test(DependencyGraph -DCMAKE_Fortran_COMPILER=${CMAKE_Fortran_COMPILER}) # ctresalloc links against CMakeLib and CTestLib, which means it can't be built @@ -619,6 +623,7 @@ endif() if(CMAKE_GENERATOR MATCHES "^Visual Studio (1[6-9]|[2-9][0-9])") add_RunCMake_test(VsDotnetSdk) + add_RunCMake_test(VsNugetPackageRestore) endif() if(XCODE_VERSION) diff --git a/Tests/RunCMake/CMakePresetsBuild/Good.json.in b/Tests/RunCMake/CMakePresetsBuild/Good.json.in index c7f318c..568907c 100644 --- a/Tests/RunCMake/CMakePresetsBuild/Good.json.in +++ b/Tests/RunCMake/CMakePresetsBuild/Good.json.in @@ -1,5 +1,5 @@ { - "version": 2, + "version": 4, "configurePresets": [ { "name": "default", @@ -78,6 +78,12 @@ "name": "singleTarget", "inherits": "build-default", "targets": "good" + }, + { + "name": "initResolve", + "inherits": "build-default", + "targets": "good", + "resolvePackageReferences": "off" } ] } diff --git a/Tests/RunCMake/CMakePresetsBuild/RunCMakeTest.cmake b/Tests/RunCMake/CMakePresetsBuild/RunCMakeTest.cmake index b37c770..2fe0407 100644 --- a/Tests/RunCMake/CMakePresetsBuild/RunCMakeTest.cmake +++ b/Tests/RunCMake/CMakePresetsBuild/RunCMakeTest.cmake @@ -70,7 +70,7 @@ else() set(Good_json_jobs [["jobs": 0,]]) endif() -run_cmake_build_presets(Good "default;other" "build-other;withEnvironment;noEnvironment;macros;vendorObject;singleTarget") +run_cmake_build_presets(Good "default;other" "build-other;withEnvironment;noEnvironment;macros;vendorObject;singleTarget;initResolve") run_cmake_build_presets(InvalidConfigurePreset "default" "badConfigurePreset") run_cmake_build_presets(Condition "default" "enabled;disabled") diff --git a/Tests/RunCMake/CUDA_architectures/CMakeLists.txt b/Tests/RunCMake/CUDA_architectures/CMakeLists.txt new file mode 100644 index 0000000..d8200fc --- /dev/null +++ b/Tests/RunCMake/CUDA_architectures/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.22) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/CUDA_architectures/RunCMakeTest.cmake b/Tests/RunCMake/CUDA_architectures/RunCMakeTest.cmake new file mode 100644 index 0000000..cbbf57c --- /dev/null +++ b/Tests/RunCMake/CUDA_architectures/RunCMakeTest.cmake @@ -0,0 +1,4 @@ +include(RunCMake) + +run_cmake(architectures-empty) +run_cmake(architectures-invalid) diff --git a/Tests/RunCMake/CUDA_architectures/architectures-empty-result.txt b/Tests/RunCMake/CUDA_architectures/architectures-empty-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CUDA_architectures/architectures-empty-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CUDA_architectures/architectures-empty-stderr.txt b/Tests/RunCMake/CUDA_architectures/architectures-empty-stderr.txt new file mode 100644 index 0000000..39640fa --- /dev/null +++ b/Tests/RunCMake/CUDA_architectures/architectures-empty-stderr.txt @@ -0,0 +1,5 @@ +^CMake Error at .*/Modules/CMakeDetermineCUDACompiler\.cmake:[0-9]+ \(message\): + CMAKE_CUDA_ARCHITECTURES must be valid if set\. +Call Stack \(most recent call first\): + architectures-empty\.cmake:2 \(enable_language\) + CMakeLists\.txt:3 \(include\) diff --git a/Tests/RunCMake/CUDA_architectures/architectures-empty.cmake b/Tests/RunCMake/CUDA_architectures/architectures-empty.cmake new file mode 100644 index 0000000..4915248 --- /dev/null +++ b/Tests/RunCMake/CUDA_architectures/architectures-empty.cmake @@ -0,0 +1,2 @@ +set(CMAKE_CUDA_ARCHITECTURES "") +enable_language(CUDA) diff --git a/Tests/RunCMake/CUDA_architectures/architectures-invalid-result.txt b/Tests/RunCMake/CUDA_architectures/architectures-invalid-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CUDA_architectures/architectures-invalid-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CUDA_architectures/architectures-invalid-stderr.txt b/Tests/RunCMake/CUDA_architectures/architectures-invalid-stderr.txt new file mode 100644 index 0000000..7608730 --- /dev/null +++ b/Tests/RunCMake/CUDA_architectures/architectures-invalid-stderr.txt @@ -0,0 +1,5 @@ +^CMake Error at .*/Modules/CMakeDetermineCUDACompiler\.cmake:[0-9]+ \(message\): + CMAKE_CUDA_ARCHITECTURES must be valid if set\. +Call Stack \(most recent call first\): + architectures-invalid\.cmake:2 \(enable_language\) + CMakeLists\.txt:3 \(include\)$ diff --git a/Tests/RunCMake/CUDA_architectures/architectures-invalid.cmake b/Tests/RunCMake/CUDA_architectures/architectures-invalid.cmake new file mode 100644 index 0000000..e5c8628 --- /dev/null +++ b/Tests/RunCMake/CUDA_architectures/architectures-invalid.cmake @@ -0,0 +1,2 @@ +set(CMAKE_CUDA_ARCHITECTURES "invalid") +enable_language(CUDA) diff --git a/Tests/RunCMake/CommandLine/build-invalid-package-resolve-arg-result.txt b/Tests/RunCMake/CommandLine/build-invalid-package-resolve-arg-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CommandLine/build-invalid-package-resolve-arg-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CommandLine/build-invalid-package-resolve-arg-stderr.txt b/Tests/RunCMake/CommandLine/build-invalid-package-resolve-arg-stderr.txt new file mode 100644 index 0000000..4811bea --- /dev/null +++ b/Tests/RunCMake/CommandLine/build-invalid-package-resolve-arg-stderr.txt @@ -0,0 +1 @@ +^Usage: cmake --build <dir> +\[options\] \[-- \[native-options\]\] diff --git a/Tests/RunCMake/CompileFeatures/ExtensionsStandardUnset.cmake b/Tests/RunCMake/CompileFeatures/CMP0128Common.cmake index 99bb3f0..b309d74 100644 --- a/Tests/RunCMake/CompileFeatures/ExtensionsStandardUnset.cmake +++ b/Tests/RunCMake/CompileFeatures/CMP0128Common.cmake @@ -4,5 +4,4 @@ enable_language(@lang@) string(REPLACE "${CMAKE_START_TEMP_FILE}" "" CMAKE_@lang@_COMPILE_OBJECT "${CMAKE_@lang@_COMPILE_OBJECT}") string(REPLACE "${CMAKE_END_TEMP_FILE}" "" CMAKE_@lang@_COMPILE_OBJECT "${CMAKE_@lang@_COMPILE_OBJECT}") -set(CMAKE_@lang@_EXTENSIONS @extensions_opposite@) add_library(foo "@RunCMake_SOURCE_DIR@/empty.@ext@") diff --git a/Tests/RunCMake/CompileFeatures/ExtensionsStandardDefault-build-check.cmake b/Tests/RunCMake/CompileFeatures/CMP0128NewExtensionsStandardDefault-build-check.cmake index 4e85397..4e85397 100644 --- a/Tests/RunCMake/CompileFeatures/ExtensionsStandardDefault-build-check.cmake +++ b/Tests/RunCMake/CompileFeatures/CMP0128NewExtensionsStandardDefault-build-check.cmake diff --git a/Tests/RunCMake/CompileFeatures/CMP0128NewExtensionsStandardDefault.cmake b/Tests/RunCMake/CompileFeatures/CMP0128NewExtensionsStandardDefault.cmake new file mode 100644 index 0000000..5b7358a --- /dev/null +++ b/Tests/RunCMake/CompileFeatures/CMP0128NewExtensionsStandardDefault.cmake @@ -0,0 +1,2 @@ +set(CMAKE_@lang@_EXTENSIONS @extensions_opposite@) +set(CMAKE_@lang@_STANDARD @standard_default@) diff --git a/Tests/RunCMake/CompileFeatures/ExtensionsStandardUnset-build-check.cmake b/Tests/RunCMake/CompileFeatures/CMP0128NewExtensionsStandardUnset-build-check.cmake index abe293c..abe293c 100644 --- a/Tests/RunCMake/CompileFeatures/ExtensionsStandardUnset-build-check.cmake +++ b/Tests/RunCMake/CompileFeatures/CMP0128NewExtensionsStandardUnset-build-check.cmake diff --git a/Tests/RunCMake/CompileFeatures/CMP0128NewExtensionsStandardUnset.cmake b/Tests/RunCMake/CompileFeatures/CMP0128NewExtensionsStandardUnset.cmake new file mode 100644 index 0000000..6923c11 --- /dev/null +++ b/Tests/RunCMake/CompileFeatures/CMP0128NewExtensionsStandardUnset.cmake @@ -0,0 +1 @@ +set(CMAKE_@lang@_EXTENSIONS @extensions_opposite@) diff --git a/Tests/RunCMake/CompileFeatures/NoUnnecessaryFlag-build-check.cmake b/Tests/RunCMake/CompileFeatures/CMP0128NewNoUnnecessaryFlag-build-check.cmake index 4f767fa..4f767fa 100644 --- a/Tests/RunCMake/CompileFeatures/NoUnnecessaryFlag-build-check.cmake +++ b/Tests/RunCMake/CompileFeatures/CMP0128NewNoUnnecessaryFlag-build-check.cmake diff --git a/Tests/RunCMake/CompileFeatures/CMP0128NewNoUnnecessaryFlag.cmake b/Tests/RunCMake/CompileFeatures/CMP0128NewNoUnnecessaryFlag.cmake new file mode 100644 index 0000000..73c0641 --- /dev/null +++ b/Tests/RunCMake/CompileFeatures/CMP0128NewNoUnnecessaryFlag.cmake @@ -0,0 +1,2 @@ +set(CMAKE_@lang@_EXTENSIONS @extensions_default@) +set(CMAKE_@lang@_STANDARD @standard_default@) diff --git a/Tests/RunCMake/CompileFeatures/CMP0128OldSameStandard-build-check.cmake b/Tests/RunCMake/CompileFeatures/CMP0128OldSameStandard-build-check.cmake new file mode 100644 index 0000000..8074b9d --- /dev/null +++ b/Tests/RunCMake/CompileFeatures/CMP0128OldSameStandard-build-check.cmake @@ -0,0 +1,12 @@ +foreach(flag @flags@) + string(FIND "${actual_stdout}" "${flag}" position) + + if(NOT position EQUAL -1) + set(found TRUE) + break() + endif() +endforeach() + +if(NOT found) + set(RunCMake_TEST_FAILED "No compile flags from \"@flags@\" found for LANG_STANDARD=default.") +endif() diff --git a/Tests/RunCMake/CompileFeatures/CMP0128OldSameStandard.cmake b/Tests/RunCMake/CompileFeatures/CMP0128OldSameStandard.cmake new file mode 100644 index 0000000..3be0f10 --- /dev/null +++ b/Tests/RunCMake/CompileFeatures/CMP0128OldSameStandard.cmake @@ -0,0 +1 @@ +set(CMAKE_@lang@_STANDARD @standard_default@) diff --git a/Tests/RunCMake/CompileFeatures/CMP0128WarnMatch.cmake b/Tests/RunCMake/CompileFeatures/CMP0128WarnMatch.cmake index 0a5606a..7974093 100644 --- a/Tests/RunCMake/CompileFeatures/CMP0128WarnMatch.cmake +++ b/Tests/RunCMake/CompileFeatures/CMP0128WarnMatch.cmake @@ -1,7 +1,5 @@ -enable_language(@lang@) cmake_policy(SET CMP0128 OLD) set(CMAKE_POLICY_WARNING_CMP0128 ON) set(CMAKE_@lang@_EXTENSIONS @extensions_default@) set(CMAKE_@lang@_STANDARD @standard_default@) -add_library(foo "@RunCMake_SOURCE_DIR@/empty.@ext@") diff --git a/Tests/RunCMake/CompileFeatures/CMP0128WarnUnset.cmake b/Tests/RunCMake/CompileFeatures/CMP0128WarnUnset.cmake index cd7af2c..33425a1 100644 --- a/Tests/RunCMake/CompileFeatures/CMP0128WarnUnset.cmake +++ b/Tests/RunCMake/CompileFeatures/CMP0128WarnUnset.cmake @@ -1,6 +1,4 @@ -enable_language(@lang@) cmake_policy(SET CMP0128 OLD) set(CMAKE_POLICY_WARNING_CMP0128 ON) set(CMAKE_@lang@_EXTENSIONS @extensions_opposite@) -add_library(foo "@RunCMake_SOURCE_DIR@/empty.@ext@") diff --git a/Tests/RunCMake/CompileFeatures/ExtensionsStandardDefault.cmake b/Tests/RunCMake/CompileFeatures/ExtensionsStandardDefault.cmake deleted file mode 100644 index 32578d1..0000000 --- a/Tests/RunCMake/CompileFeatures/ExtensionsStandardDefault.cmake +++ /dev/null @@ -1,9 +0,0 @@ -enable_language(@lang@) - -# Make sure the compile command is not hidden. -string(REPLACE "${CMAKE_START_TEMP_FILE}" "" CMAKE_@lang@_COMPILE_OBJECT "${CMAKE_@lang@_COMPILE_OBJECT}") -string(REPLACE "${CMAKE_END_TEMP_FILE}" "" CMAKE_@lang@_COMPILE_OBJECT "${CMAKE_@lang@_COMPILE_OBJECT}") - -set(CMAKE_@lang@_EXTENSIONS @extensions_opposite@) -set(CMAKE_@lang@_STANDARD @standard_default@) -add_library(foo "@RunCMake_SOURCE_DIR@/empty.@ext@") diff --git a/Tests/RunCMake/CompileFeatures/NoUnnecessaryFlag.cmake b/Tests/RunCMake/CompileFeatures/NoUnnecessaryFlag.cmake deleted file mode 100644 index 8ef3a72..0000000 --- a/Tests/RunCMake/CompileFeatures/NoUnnecessaryFlag.cmake +++ /dev/null @@ -1,9 +0,0 @@ -enable_language(@lang@) - -# Make sure the compile command is not hidden. -string(REPLACE "${CMAKE_START_TEMP_FILE}" "" CMAKE_@lang@_COMPILE_OBJECT "${CMAKE_@lang@_COMPILE_OBJECT}") -string(REPLACE "${CMAKE_END_TEMP_FILE}" "" CMAKE_@lang@_COMPILE_OBJECT "${CMAKE_@lang@_COMPILE_OBJECT}") - -set(CMAKE_@lang@_EXTENSIONS @extensions_default@) -set(CMAKE_@lang@_STANDARD @standard_default@) -add_library(foo "@RunCMake_SOURCE_DIR@/empty.@ext@") diff --git a/Tests/RunCMake/CompileFeatures/RunCMakeTest.cmake b/Tests/RunCMake/CompileFeatures/RunCMakeTest.cmake index ebd981b..ad9619e 100644 --- a/Tests/RunCMake/CompileFeatures/RunCMakeTest.cmake +++ b/Tests/RunCMake/CompileFeatures/RunCMakeTest.cmake @@ -35,11 +35,13 @@ elseif (cxx_std_98 IN_LIST CXX_FEATURES AND cxx_std_11 IN_LIST CXX_FEATURES) endif() configure_file("${RunCMake_SOURCE_DIR}/CMakeLists.txt" "${RunCMake_BINARY_DIR}/CMakeLists.txt" COPYONLY) +file(READ "${RunCMake_SOURCE_DIR}/CMP0128Common.cmake" cmp0128_common) function(test_build) set(test ${name}-${lang}) - configure_file("${RunCMake_SOURCE_DIR}/${name}.cmake" "${RunCMake_BINARY_DIR}/${test}.cmake" @ONLY) + file(READ "${RunCMake_SOURCE_DIR}/${name}.cmake" cmake) + file(CONFIGURE OUTPUT "${RunCMake_BINARY_DIR}/${test}.cmake" CONTENT "${cmake}${cmp0128_common}" @ONLY) if(EXISTS "${RunCMake_SOURCE_DIR}/${name}-build-check.cmake") configure_file("${RunCMake_SOURCE_DIR}/${name}-build-check.cmake" "${RunCMake_BINARY_DIR}/${test}-build-check.cmake" @ONLY) endif() @@ -68,7 +70,24 @@ macro(mangle_flags variable) list(APPEND flags "${result}") endmacro() -function(test_extensions_opposite) +function(test_cmp0128_old_same_standard) + if(extensions_default) + set(flag_ext "_EXT") + endif() + + set(flag "${${lang}${${lang}_STANDARD_DEFAULT}${flag_ext}_FLAG}") + + if(NOT flag) + return() + endif() + + mangle_flags(flag) + + set(name CMP0128OldSameStandard) + test_build(--verbose) +endfunction() + +function(test_cmp0128_new_extensions_opposite) if(extensions_opposite) set(flag_ext "_EXT") endif() @@ -83,16 +102,16 @@ function(test_extensions_opposite) # Make sure we enable/disable extensions when: # 1. LANG_STANDARD is unset. - set(name ExtensionsStandardUnset) + set(name CMP0128NewExtensionsStandardUnset) set(RunCMake_TEST_OPTIONS -DCMAKE_POLICY_DEFAULT_CMP0128=NEW) test_build(--verbose) # 2. LANG_STANDARD matches CMAKE_LANG_STANDARD_DEFAULT. - set(name ExtensionsStandardDefault) + set(name CMP0128NewExtensionsStandardDefault) test_build(--verbose) endfunction() -function(test_no_unnecessary_flag) +function(test_cmp0128_new_no_unnecessary_flag) set(standard_flag "${${lang}${${lang}_STANDARD_DEFAULT}_FLAG}") set(extension_flag "${${lang}${${lang}_STANDARD_DEFAULT}_EXT_FLAG}") @@ -103,7 +122,7 @@ function(test_no_unnecessary_flag) mangle_flags(standard_flag) mangle_flags(extension_flag) - set(name NoUnnecessaryFlag) + set(name CMP0128NewNoUnnecessaryFlag) set(RunCMake_TEST_OPTIONS -DCMAKE_POLICY_DEFAULT_CMP0128=NEW) test_build(--verbose) endfunction() @@ -144,8 +163,9 @@ function(test_lang lang ext) set(extensions_opposite ON) endif() - test_extensions_opposite() - test_no_unnecessary_flag() + test_cmp0128_new_extensions_opposite() + test_cmp0128_new_no_unnecessary_flag() + test_cmp0128_old_same_standard() test_cmp0128_warn_match() test_cmp0128_warn_unset() endfunction() diff --git a/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake b/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake index a4244e3..48f8b23 100644 --- a/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake +++ b/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake @@ -112,7 +112,7 @@ function(__ep_test_with_build_with_server testName) file(READ ${URL_FILE} SERVER_URL) message(STATUS "URL : ${URL_FILE} - ${SERVER_URL}") - run_cmake_with_options(${testName} ${CMAKE_COMMAND} -DSERVER_URL=${SERVER_URL} ) + run_cmake_with_options(${testName} -DSERVER_URL=${SERVER_URL}) run_cmake_command(${testName}-clean ${CMAKE_COMMAND} --build . --target clean) run_cmake_command(${testName}-build ${CMAKE_COMMAND} --build .) endfunction() diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-check.py b/Tests/RunCMake/FileAPI/codemodel-v2-check.py index b31088d..d5f596e 100644 --- a/Tests/RunCMake/FileAPI/codemodel-v2-check.py +++ b/Tests/RunCMake/FileAPI/codemodel-v2-check.py @@ -760,7 +760,7 @@ def gen_check_targets(c, g, inSource): read_codemodel_json_data("targets/c_headers_2.json"), ] - if cxx_compiler_id in ['Clang', 'AppleClang', 'LCC', 'GNU', 'Intel', 'IntelLLVM', 'MSVC', 'Embarcadero'] and g["name"] != "Xcode": + if cxx_compiler_id in ['Clang', 'AppleClang', 'LCC', 'GNU', 'Intel', 'IntelLLVM', 'MSVC', 'Embarcadero', 'IBMClang'] and g["name"] != "Xcode": for e in expected: if e["name"] == "cxx_exe": if matches(g["name"], "^(Visual Studio |Ninja Multi-Config)"): diff --git a/Tests/RunCMake/VsNugetPackageRestore/CMakeLists.txt b/Tests/RunCMake/VsNugetPackageRestore/CMakeLists.txt new file mode 100644 index 0000000..d8200fc --- /dev/null +++ b/Tests/RunCMake/VsNugetPackageRestore/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.22) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/VsNugetPackageRestore/Package/CMakeLists.txt b/Tests/RunCMake/VsNugetPackageRestore/Package/CMakeLists.txt new file mode 100644 index 0000000..56920d9 --- /dev/null +++ b/Tests/RunCMake/VsNugetPackageRestore/Package/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 3.12) + +project(NuGetTestProject VERSION 1.0.0 LANGUAGES CSharp) + +add_library(NuGetPackage SHARED "Library.cs") +set_target_properties(NuGetPackage PROPERTIES + VS_DOTNET_TARGET_FRAMEWORK_VERSION "v4.7.2" + VS_DOTNET_REFERENCES "System") +install(TARGETS NuGetPackage) + +set(CPACK_GENERATOR "NuGet") +set(CPACK_PACKAGE_NAME "NuGetTestProject") +set(CPACK_PACKAGE_VERSION "${PROJECT_VERSION}") +set(CPACK_PACKAGE_DESCRIPTION "Package to test automatic NuGet package restore.") +set(CPACK_PACKAGE_VENDOR "CMake.org") + +include(CPack) diff --git a/Tests/RunCMake/VsNugetPackageRestore/Package/Library.cs b/Tests/RunCMake/VsNugetPackageRestore/Package/Library.cs new file mode 100644 index 0000000..d9ae85a --- /dev/null +++ b/Tests/RunCMake/VsNugetPackageRestore/Package/Library.cs @@ -0,0 +1,9 @@ +using System; + +namespace CMake +{ + public class NuGetTest + { + public static int GetNumber() => 42; + } +} diff --git a/Tests/RunCMake/VsNugetPackageRestore/Program.cs b/Tests/RunCMake/VsNugetPackageRestore/Program.cs new file mode 100644 index 0000000..681461f --- /dev/null +++ b/Tests/RunCMake/VsNugetPackageRestore/Program.cs @@ -0,0 +1,14 @@ +using System; +using CMake; + +namespace Test +{ + public class Program + { + public static void Main(string[] args) + { + Console.WriteLine(NuGetTest.GetNumber()); + Console.ReadKey(); + } + } +} diff --git a/Tests/RunCMake/VsNugetPackageRestore/Repository/NuGetTestProject/1.0.0/.nupkg.metadata b/Tests/RunCMake/VsNugetPackageRestore/Repository/NuGetTestProject/1.0.0/.nupkg.metadata new file mode 100644 index 0000000..6a87d0a --- /dev/null +++ b/Tests/RunCMake/VsNugetPackageRestore/Repository/NuGetTestProject/1.0.0/.nupkg.metadata @@ -0,0 +1,5 @@ +{ + "version": 2, + "contentHash": "2sG1Ws4da8r6qj7rUAZ1GaOjkELonH0X+vR9yfDwgg+QxG0cpRIfGqEXKAkGT+UCwU24ogJcm8IA9dXv5zmLXg==", + "source": null +} diff --git a/Tests/RunCMake/VsNugetPackageRestore/Repository/NuGetTestProject/1.0.0/nugettestproject.1.0.0.nupkg b/Tests/RunCMake/VsNugetPackageRestore/Repository/NuGetTestProject/1.0.0/nugettestproject.1.0.0.nupkg Binary files differnew file mode 100644 index 0000000..5569a29 --- /dev/null +++ b/Tests/RunCMake/VsNugetPackageRestore/Repository/NuGetTestProject/1.0.0/nugettestproject.1.0.0.nupkg diff --git a/Tests/RunCMake/VsNugetPackageRestore/Repository/NuGetTestProject/1.0.0/nugettestproject.1.0.0.nupkg.sha512 b/Tests/RunCMake/VsNugetPackageRestore/Repository/NuGetTestProject/1.0.0/nugettestproject.1.0.0.nupkg.sha512 new file mode 100644 index 0000000..5526b76 --- /dev/null +++ b/Tests/RunCMake/VsNugetPackageRestore/Repository/NuGetTestProject/1.0.0/nugettestproject.1.0.0.nupkg.sha512 @@ -0,0 +1 @@ +2sG1Ws4da8r6qj7rUAZ1GaOjkELonH0X+vR9yfDwgg+QxG0cpRIfGqEXKAkGT+UCwU24ogJcm8IA9dXv5zmLXg== diff --git a/Tests/RunCMake/VsNugetPackageRestore/Repository/NuGetTestProject/1.0.0/nugettestproject.nuspec b/Tests/RunCMake/VsNugetPackageRestore/Repository/NuGetTestProject/1.0.0/nugettestproject.nuspec new file mode 100644 index 0000000..9a943a8 --- /dev/null +++ b/Tests/RunCMake/VsNugetPackageRestore/Repository/NuGetTestProject/1.0.0/nugettestproject.nuspec @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8"?> +<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd"> + <metadata> + <id>NuGetTestProject</id> + <version>1.0.0</version> + <authors>CMake.org</authors> + <requireLicenseAcceptance>false</requireLicenseAcceptance> + <description>Package to test automatic NuGet package restore.</description> + <summary>NuGetTestProject built using CMake</summary> + </metadata> +</package> diff --git a/Tests/RunCMake/VsNugetPackageRestore/RunCMakeTest.cmake b/Tests/RunCMake/VsNugetPackageRestore/RunCMakeTest.cmake new file mode 100644 index 0000000..625167c --- /dev/null +++ b/Tests/RunCMake/VsNugetPackageRestore/RunCMakeTest.cmake @@ -0,0 +1,12 @@ +cmake_policy(SET CMP0053 NEW) +include(RunCMake) + +set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/VsNugetPackageRestore) +run_cmake(VsNugetPackageRestore) + +set(RunCMake_TEST_NO_CLEAN 1) +run_cmake_command(vs-nuget-package-restore-off ${CMAKE_COMMAND} --build ${RunCMake_TEST_BINARY_DIR} --resolve-package-references=off) +run_cmake_command(vs-nuget-package-restore-only ${CMAKE_COMMAND} --build ${RunCMake_TEST_BINARY_DIR} --resolve-package-references=only) +run_cmake_command(vs-nuget-package-restore-on ${CMAKE_COMMAND} --build ${RunCMake_TEST_BINARY_DIR} --resolve-package-references=on) +run_cmake_command(vs-nuget-package-restore-wrong ${CMAKE_COMMAND} --build ${RunCMake_TEST_BINARY_DIR} --resolve-package-references=wrong) +set(RunCMake_TEST_NO_CLEAN 0) diff --git a/Tests/RunCMake/VsNugetPackageRestore/VsNugetPackageRestore.cmake b/Tests/RunCMake/VsNugetPackageRestore/VsNugetPackageRestore.cmake new file mode 100644 index 0000000..a0227df --- /dev/null +++ b/Tests/RunCMake/VsNugetPackageRestore/VsNugetPackageRestore.cmake @@ -0,0 +1,9 @@ +enable_language(CSharp) + +add_executable(TestProgram "Program.cs") +configure_file("nuget.config.in" "nuget.config") +set_target_properties(TestProgram PROPERTIES + VS_DOTNET_TARGET_FRAMEWORK_VERSION "v4.7.2" + VS_DOTNET_REFERENCES "System" + VS_PACKAGE_REFERENCES "NuGetTestProject_1.0.0" +) diff --git a/Tests/RunCMake/VsNugetPackageRestore/nuget.config.in b/Tests/RunCMake/VsNugetPackageRestore/nuget.config.in new file mode 100644 index 0000000..2e54c8f --- /dev/null +++ b/Tests/RunCMake/VsNugetPackageRestore/nuget.config.in @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8"?> +<configuration> + <packageSources> + <clear /> + <add key="local" value="@CMAKE_CURRENT_SOURCE_DIR@/Repository/" /> + </packageSources> +</configuration> diff --git a/Tests/RunCMake/VsNugetPackageRestore/vs-nuget-package-restore-off-result.txt b/Tests/RunCMake/VsNugetPackageRestore/vs-nuget-package-restore-off-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/VsNugetPackageRestore/vs-nuget-package-restore-off-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/VsNugetPackageRestore/vs-nuget-package-restore-off-stderr.txt b/Tests/RunCMake/VsNugetPackageRestore/vs-nuget-package-restore-off-stderr.txt new file mode 100644 index 0000000..10f3293 --- /dev/null +++ b/Tests/RunCMake/VsNugetPackageRestore/vs-nuget-package-restore-off-stderr.txt @@ -0,0 +1 @@ +^$ diff --git a/Tests/RunCMake/VsNugetPackageRestore/vs-nuget-package-restore-wrong-result.txt b/Tests/RunCMake/VsNugetPackageRestore/vs-nuget-package-restore-wrong-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/VsNugetPackageRestore/vs-nuget-package-restore-wrong-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/VsNugetPackageRestore/vs-nuget-package-restore-wrong-stderr.txt b/Tests/RunCMake/VsNugetPackageRestore/vs-nuget-package-restore-wrong-stderr.txt new file mode 100644 index 0000000..4811bea --- /dev/null +++ b/Tests/RunCMake/VsNugetPackageRestore/vs-nuget-package-restore-wrong-stderr.txt @@ -0,0 +1 @@ +^Usage: cmake --build <dir> +\[options\] \[-- \[native-options\]\] diff --git a/Tests/RunCMake/string/Timestamp-stderr.txt b/Tests/RunCMake/string/Timestamp-stderr.txt index d54777b..f162f52 100644 --- a/Tests/RunCMake/string/Timestamp-stderr.txt +++ b/Tests/RunCMake/string/Timestamp-stderr.txt @@ -1 +1 @@ -RESULT=2005-08-07 23:19:49 Sunday=Sun August=Aug 05 day=219 wd=0 week=32 w_iso=31 %I=11 epoch=1123456789 +RESULT=2005-08-07 23:19:49.000000 Sunday=Sun August=Aug 05 day=219 wd=0 week=32 w_iso=31 %I=11 epoch=1123456789 diff --git a/Tests/RunCMake/string/Timestamp.cmake b/Tests/RunCMake/string/Timestamp.cmake index 7fd6d72..531a237 100644 --- a/Tests/RunCMake/string/Timestamp.cmake +++ b/Tests/RunCMake/string/Timestamp.cmake @@ -1,3 +1,3 @@ set(ENV{SOURCE_DATE_EPOCH} "1123456789") -string(TIMESTAMP RESULT "%Y-%m-%d %H:%M:%S %A=%a %B=%b %y day=%j wd=%w week=%U w_iso=%V %%I=%I epoch=%s" UTC) +string(TIMESTAMP RESULT "%Y-%m-%d %H:%M:%S.%f %A=%a %B=%b %y day=%j wd=%w week=%U w_iso=%V %%I=%I epoch=%s" UTC) message("RESULT=${RESULT}") diff --git a/Utilities/cmbzip2/CMakeLists.txt b/Utilities/cmbzip2/CMakeLists.txt index 0db470f..52efe14 100644 --- a/Utilities/cmbzip2/CMakeLists.txt +++ b/Utilities/cmbzip2/CMakeLists.txt @@ -2,7 +2,7 @@ project(bzip2) # Disable warnings to avoid changing 3rd party code. if(CMAKE_C_COMPILER_ID MATCHES - "^(GNU|LCC|Clang|AppleClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM|NVHPC)$") + "^(GNU|LCC|Clang|AppleClang|IBMClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM|NVHPC)$") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w") elseif(CMAKE_C_COMPILER_ID STREQUAL "PathScale") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -woffall") diff --git a/Utilities/cmcurl/CMakeLists.txt b/Utilities/cmcurl/CMakeLists.txt index 7cb497b..07f1d4f 100644 --- a/Utilities/cmcurl/CMakeLists.txt +++ b/Utilities/cmcurl/CMakeLists.txt @@ -113,7 +113,7 @@ endif(APPLE) # Disable warnings to avoid changing 3rd party code. if(CMAKE_C_COMPILER_ID MATCHES - "^(GNU|LCC|Clang|AppleClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM|NVHPC)$") + "^(GNU|LCC|Clang|AppleClang|IBMClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM|NVHPC)$") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w") elseif(CMAKE_C_COMPILER_ID STREQUAL "PathScale") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -woffall") diff --git a/Utilities/cmexpat/CMakeLists.txt b/Utilities/cmexpat/CMakeLists.txt index 6e49fe4..9a62b79 100644 --- a/Utilities/cmexpat/CMakeLists.txt +++ b/Utilities/cmexpat/CMakeLists.txt @@ -1,6 +1,6 @@ # Disable warnings to avoid changing 3rd party code. IF(CMAKE_C_COMPILER_ID MATCHES - "^(GNU|LCC|Clang|AppleClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM|NVHPC)$") + "^(GNU|LCC|Clang|AppleClang|IBMClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM|NVHPC)$") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w") ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "PathScale") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -woffall") diff --git a/Utilities/cmjsoncpp/CMakeLists.txt b/Utilities/cmjsoncpp/CMakeLists.txt index 16613d4..c384f4e 100644 --- a/Utilities/cmjsoncpp/CMakeLists.txt +++ b/Utilities/cmjsoncpp/CMakeLists.txt @@ -2,7 +2,7 @@ project(JsonCpp CXX) # Disable warnings to avoid changing 3rd party code. if(CMAKE_CXX_COMPILER_ID MATCHES - "^(GNU|LCC|Clang|AppleClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM|NVHPC)$") + "^(GNU|LCC|Clang|AppleClang|IBMClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM|NVHPC)$") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -w") elseif(CMAKE_CXX_COMPILER_ID STREQUAL "PathScale") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -woffall") diff --git a/Utilities/cmlibarchive/CMakeLists.txt b/Utilities/cmlibarchive/CMakeLists.txt index c1ac991..c2aa182 100644 --- a/Utilities/cmlibarchive/CMakeLists.txt +++ b/Utilities/cmlibarchive/CMakeLists.txt @@ -94,7 +94,7 @@ SET(CMAKE_REQUIRED_FLAGS) # Disable warnings to avoid changing 3rd party code. IF(CMAKE_C_COMPILER_ID MATCHES - "^(GNU|LCC|Clang|AppleClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM|NVHPC)$") + "^(GNU|LCC|Clang|AppleClang|IBMClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM|NVHPC)$") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w") ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "PathScale") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -woffall") diff --git a/Utilities/cmliblzma/CMakeLists.txt b/Utilities/cmliblzma/CMakeLists.txt index c779920..0de1e97 100644 --- a/Utilities/cmliblzma/CMakeLists.txt +++ b/Utilities/cmliblzma/CMakeLists.txt @@ -160,7 +160,7 @@ INCLUDE_DIRECTORIES( # Disable warnings to avoid changing 3rd party code. IF(CMAKE_C_COMPILER_ID MATCHES - "^(GNU|LCC|Clang|AppleClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM|NVHPC)$") + "^(GNU|LCC|Clang|AppleClang|IBMClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM|NVHPC)$") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w") ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "PathScale") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -woffall") diff --git a/Utilities/cmlibrhash/CMakeLists.txt b/Utilities/cmlibrhash/CMakeLists.txt index 99c76cc..9f532ad 100644 --- a/Utilities/cmlibrhash/CMakeLists.txt +++ b/Utilities/cmlibrhash/CMakeLists.txt @@ -2,7 +2,7 @@ project(librhash C) # Disable warnings to avoid changing 3rd party code. if(CMAKE_C_COMPILER_ID MATCHES - "^(GNU|LCC|Clang|AppleClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM|NVHPC)$") + "^(GNU|LCC|Clang|AppleClang|IBMClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM|NVHPC)$") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w") elseif(CMAKE_C_COMPILER_ID STREQUAL "PathScale") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -woffall") diff --git a/Utilities/cmlibuv/CMakeLists.txt b/Utilities/cmlibuv/CMakeLists.txt index fd68dd1..b815a5c 100644 --- a/Utilities/cmlibuv/CMakeLists.txt +++ b/Utilities/cmlibuv/CMakeLists.txt @@ -2,7 +2,7 @@ project(libuv C) # Disable warnings to avoid changing 3rd party code. if(CMAKE_C_COMPILER_ID MATCHES - "^(GNU|LCC|Clang|AppleClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM|NVHPC)$") + "^(GNU|LCC|Clang|AppleClang|IBMClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM|NVHPC)$") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w") elseif(CMAKE_C_COMPILER_ID STREQUAL "PathScale") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -woffall") diff --git a/Utilities/cmnghttp2/CMakeLists.txt b/Utilities/cmnghttp2/CMakeLists.txt index 7f58f1c..9002ab6 100644 --- a/Utilities/cmnghttp2/CMakeLists.txt +++ b/Utilities/cmnghttp2/CMakeLists.txt @@ -1,6 +1,6 @@ # Disable warnings to avoid changing 3rd party code. if(CMAKE_C_COMPILER_ID MATCHES - "^(GNU|LCC|Clang|AppleClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM|NVHPC)$") + "^(GNU|LCC|Clang|AppleClang|IBMClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM|NVHPC)$") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w") elseif(CMAKE_C_COMPILER_ID STREQUAL "PathScale") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -woffall") diff --git a/Utilities/cmpdcurses/CMakeLists.txt b/Utilities/cmpdcurses/CMakeLists.txt index cce4b71..94ca601 100644 --- a/Utilities/cmpdcurses/CMakeLists.txt +++ b/Utilities/cmpdcurses/CMakeLists.txt @@ -6,7 +6,7 @@ endif() # Disable warnings to avoid changing 3rd party code. if(CMAKE_C_COMPILER_ID MATCHES - "^(GNU|LCC|Clang|AppleClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM|NVHPC)$") + "^(GNU|LCC|Clang|AppleClang|IBMClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM|NVHPC)$") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w") elseif(CMAKE_C_COMPILER_ID STREQUAL "PathScale") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -woffall") diff --git a/Utilities/cmzlib/CMakeLists.txt b/Utilities/cmzlib/CMakeLists.txt index 9e10daf..42bf2c5 100644 --- a/Utilities/cmzlib/CMakeLists.txt +++ b/Utilities/cmzlib/CMakeLists.txt @@ -2,7 +2,7 @@ PROJECT(CMZLIB) # Disable warnings to avoid changing 3rd party code. if(CMAKE_C_COMPILER_ID MATCHES - "^(GNU|LCC|Clang|AppleClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM|NVHPC)$") + "^(GNU|LCC|Clang|AppleClang|IBMClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM|NVHPC)$") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w") elseif(CMAKE_C_COMPILER_ID STREQUAL "PathScale") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -woffall") diff --git a/Utilities/cmzstd/CMakeLists.txt b/Utilities/cmzstd/CMakeLists.txt index 1ba263a..981e3d5 100644 --- a/Utilities/cmzstd/CMakeLists.txt +++ b/Utilities/cmzstd/CMakeLists.txt @@ -2,7 +2,7 @@ project(zstd C) # Disable warnings to avoid changing 3rd party code. if(CMAKE_C_COMPILER_ID MATCHES - "^(GNU|LCC|Clang|AppleClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM|NVHPC)$") + "^(GNU|LCC|Clang|AppleClang|IBMClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM|NVHPC)$") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w") elseif(CMAKE_C_COMPILER_ID STREQUAL "PathScale") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -woffall") @@ -157,12 +157,19 @@ else cmake_system_hpux=false fi +# Determine whether this is AIX +if echo "${cmake_system}" | grep AIX >/dev/null 2>&1; then + cmake_system_aix=true +else + cmake_system_aix=false +fi + # Determine whether this is Linux if echo "${cmake_system}" | grep Linux >/dev/null 2>&1; then cmake_system_linux=true else cmake_system_linux=false - fi +fi # Determine whether this is a PA-RISC machine # This only works for Linux or HP-UX, not other PA-RISC OSs (BSD maybe?). Also @@ -1109,6 +1116,13 @@ if ${cmake_system_haiku}; then cmake_ld_flags="${LDFLAGS} -lroot -lbe" fi +# Add AIX arch-specific link flags. +if ${cmake_system_aix}; then + if uname -p | grep powerpc >/dev/null 2>&1; then + cmake_ld_flags="${LDFLAGS} -Wl,-bbigtoc" + fi +fi + #----------------------------------------------------------------------------- # Detect known toolchains on some platforms. cmake_toolchains='' |