diff options
126 files changed, 1713 insertions, 266 deletions
diff --git a/.clang-tidy b/.clang-tidy index dda86b0..7b8d200 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,6 +1,8 @@ --- Checks: "-*,\ bugprone-*,\ +-bugprone-easily-swappable-parameters,\ +-bugprone-implicit-widening-of-multiplication-result,\ -bugprone-macro-parentheses,\ -bugprone-misplaced-widening-cast,\ -bugprone-narrowing-conversions,\ @@ -12,6 +14,7 @@ misc-*,\ -misc-static-assert,\ modernize-*,\ -modernize-avoid-c-arrays,\ +-modernize-return-braced-init-list,\ -modernize-use-nodiscard,\ -modernize-use-noexcept,\ -modernize-use-trailing-return-type,\ @@ -27,6 +30,8 @@ readability-*,\ -readability-magic-numbers,\ -readability-named-parameter,\ -readability-redundant-declaration,\ +-readability-redundant-member-init,\ +-readability-suspicious-call-argument,\ -readability-uppercase-literal-suffix,\ " HeaderFilterRegex: 'Source/cm[^/]*\.(h|hxx|cxx)$' diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2cb4716..d8d3a36 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -53,7 +53,7 @@ p:source-package: p:doc-package: extends: - - .fedora34_sphinx_package + - .fedora35_sphinx_package - .cmake_prep_doc_linux - .linux_builder_tags_qt - .cmake_doc_artifacts @@ -119,16 +119,16 @@ l:iwyu-debian10: - .linux_builder_tags - .run_automatically -l:tidy-fedora34: +l:tidy-fedora35: extends: - - .fedora34_tidy + - .fedora35_tidy - .cmake_build_linux - .linux_builder_tags_qt - .run_automatically -l:sphinx-fedora34: +l:sphinx-fedora35: extends: - - .fedora34_sphinx + - .fedora35_sphinx - .cmake_build_linux - .linux_builder_tags_qt - .run_automatically @@ -136,9 +136,9 @@ l:sphinx-fedora34: CMAKE_CI_JOB_CONTINUOUS: "true" CMAKE_CI_JOB_HELP: "true" -l:clang-analyzer-fedora34: +l:clang-analyzer-fedora35: extends: - - .fedora34_clang_analyzer + - .fedora35_clang_analyzer - .cmake_build_linux - .linux_builder_tags_qt - .run_automatically @@ -207,17 +207,17 @@ t:debian10-makefiles-clang: variables: CMAKE_CI_JOB_NIGHTLY: "true" -t:fedora34-makefiles: +t:fedora35-makefiles: extends: - - .fedora34_makefiles + - .fedora35_makefiles - .cmake_test_linux_release - .linux_builder_tags_qt - .run_dependent - .needs_centos6_x86_64 -t:fedora34-makefiles-nospace: +t:fedora35-makefiles-nospace: extends: - - .fedora34_makefiles + - .fedora35_makefiles - .cmake_test_linux_release - .linux_builder_tags_qt - .cmake_junit_artifacts @@ -225,7 +225,7 @@ t:fedora34-makefiles-nospace: - .needs_centos6_x86_64 variables: GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake-ci" - CMAKE_CI_BUILD_NAME: fedora34_makefiles_nospace + CMAKE_CI_BUILD_NAME: fedora35_makefiles_nospace CMAKE_CI_JOB_NIGHTLY: "true" t:cuda9.2-nvidia: @@ -267,37 +267,37 @@ t:hip4.2-radeon: variables: CMAKE_CI_JOB_NIGHTLY: "true" -b:fedora34-ninja: +b:fedora35-ninja: extends: - - .fedora34_ninja + - .fedora35_ninja - .cmake_build_linux - .cmake_build_artifacts - .linux_builder_tags_qt - .run_manually -t:fedora34-ninja: +t:fedora35-ninja: extends: - - .fedora34_ninja + - .fedora35_ninja - .cmake_test_linux - .linux_builder_tags_x11 - .cmake_test_artifacts - .run_dependent dependencies: - - b:fedora34-ninja + - b:fedora35-ninja needs: - - b:fedora34-ninja + - b:fedora35-ninja -t:fedora34-ninja-multi: +t:fedora35-ninja-multi: extends: - - .fedora34_ninja_multi + - .fedora35_ninja_multi - .cmake_test_linux_external - .linux_builder_tags_qt - .cmake_junit_artifacts - .run_dependent dependencies: - - t:fedora34-ninja + - t:fedora35-ninja needs: - - t:fedora34-ninja + - t:fedora35-ninja t:intel2016-makefiles: extends: @@ -566,9 +566,9 @@ u:linux-aarch64-package: ## Sanitizer builds -b:fedora34-asan: +b:fedora35-asan: extends: - - .fedora34_asan + - .fedora35_asan - .cmake_build_linux - .cmake_build_artifacts - .linux_builder_tags_qt @@ -576,16 +576,16 @@ b:fedora34-asan: variables: CMAKE_CI_JOB_NIGHTLY: "true" -t:fedora34-asan: +t:fedora35-asan: extends: - - .fedora34_asan + - .fedora35_asan - .cmake_memcheck_linux - .linux_builder_tags_qt - .run_dependent dependencies: - - b:fedora34-asan + - b:fedora35-asan needs: - - b:fedora34-asan + - b:fedora35-asan variables: CMAKE_CI_JOB_NIGHTLY: "true" diff --git a/.gitlab/ci/configure_fedora34_clang_analyzer.cmake b/.gitlab/ci/configure_fedora34_clang_analyzer.cmake deleted file mode 100644 index e00f8a7..0000000 --- a/.gitlab/ci/configure_fedora34_clang_analyzer.cmake +++ /dev/null @@ -1 +0,0 @@ -include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora34_common.cmake") diff --git a/.gitlab/ci/configure_fedora34_ninja.cmake b/.gitlab/ci/configure_fedora34_ninja.cmake deleted file mode 100644 index 37bc189..0000000 --- a/.gitlab/ci/configure_fedora34_ninja.cmake +++ /dev/null @@ -1,7 +0,0 @@ -set(CMake_TEST_ISPC "ON" CACHE STRING "") -set(CMake_TEST_GUI "ON" CACHE BOOL "") - -# Cover compilation with C++11 only and not higher standards. -set(CMAKE_CXX_STANDARD "11" CACHE STRING "") - -include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora34_common.cmake") diff --git a/.gitlab/ci/configure_fedora34_tidy.cmake b/.gitlab/ci/configure_fedora34_tidy.cmake deleted file mode 100644 index 9c79303..0000000 --- a/.gitlab/ci/configure_fedora34_tidy.cmake +++ /dev/null @@ -1,3 +0,0 @@ -set(CMake_RUN_CLANG_TIDY ON CACHE BOOL "") - -include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora34_common.cmake") diff --git a/.gitlab/ci/configure_fedora34_asan.cmake b/.gitlab/ci/configure_fedora35_asan.cmake index c22cdb7..84fefad 100644 --- a/.gitlab/ci/configure_fedora34_asan.cmake +++ b/.gitlab/ci/configure_fedora35_asan.cmake @@ -1,4 +1,4 @@ set(CMAKE_C_FLAGS "-fsanitize=address" CACHE STRING "") set(CMAKE_CXX_FLAGS "-fsanitize=address" CACHE STRING "") -include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora34_common.cmake") +include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora35_common.cmake") diff --git a/.gitlab/ci/configure_fedora35_clang_analyzer.cmake b/.gitlab/ci/configure_fedora35_clang_analyzer.cmake new file mode 100644 index 0000000..761a323 --- /dev/null +++ b/.gitlab/ci/configure_fedora35_clang_analyzer.cmake @@ -0,0 +1 @@ +include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora35_common.cmake") diff --git a/.gitlab/ci/configure_fedora34_common.cmake b/.gitlab/ci/configure_fedora35_common.cmake index 4484e26..4484e26 100644 --- a/.gitlab/ci/configure_fedora34_common.cmake +++ b/.gitlab/ci/configure_fedora35_common.cmake diff --git a/.gitlab/ci/configure_fedora34_makefiles.cmake b/.gitlab/ci/configure_fedora35_makefiles.cmake index a482378..a482378 100644 --- a/.gitlab/ci/configure_fedora34_makefiles.cmake +++ b/.gitlab/ci/configure_fedora35_makefiles.cmake diff --git a/.gitlab/ci/configure_fedora35_ninja.cmake b/.gitlab/ci/configure_fedora35_ninja.cmake new file mode 100644 index 0000000..e6143b7 --- /dev/null +++ b/.gitlab/ci/configure_fedora35_ninja.cmake @@ -0,0 +1,11 @@ +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 "") + +include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora35_common.cmake") diff --git a/.gitlab/ci/configure_fedora34_ninja_multi.cmake b/.gitlab/ci/configure_fedora35_ninja_multi.cmake index efb4b84..efb4b84 100644 --- a/.gitlab/ci/configure_fedora34_ninja_multi.cmake +++ b/.gitlab/ci/configure_fedora35_ninja_multi.cmake diff --git a/.gitlab/ci/configure_fedora34_sphinx.cmake b/.gitlab/ci/configure_fedora35_sphinx.cmake index 90d159b..90d159b 100644 --- a/.gitlab/ci/configure_fedora34_sphinx.cmake +++ b/.gitlab/ci/configure_fedora35_sphinx.cmake diff --git a/.gitlab/ci/configure_fedora34_sphinx_package.cmake b/.gitlab/ci/configure_fedora35_sphinx_package.cmake index e839de8..e839de8 100644 --- a/.gitlab/ci/configure_fedora34_sphinx_package.cmake +++ b/.gitlab/ci/configure_fedora35_sphinx_package.cmake diff --git a/.gitlab/ci/configure_fedora35_tidy.cmake b/.gitlab/ci/configure_fedora35_tidy.cmake new file mode 100644 index 0000000..752d241 --- /dev/null +++ b/.gitlab/ci/configure_fedora35_tidy.cmake @@ -0,0 +1,3 @@ +set(CMake_RUN_CLANG_TIDY ON CACHE BOOL "") + +include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora35_common.cmake") diff --git a/.gitlab/ci/ctest_memcheck_fedora34_asan.lsan.supp b/.gitlab/ci/ctest_memcheck_fedora35_asan.lsan.supp index 8ec1a03..8ec1a03 100644 --- a/.gitlab/ci/ctest_memcheck_fedora34_asan.lsan.supp +++ b/.gitlab/ci/ctest_memcheck_fedora35_asan.lsan.supp diff --git a/.gitlab/ci/docker/fedora34/Dockerfile b/.gitlab/ci/docker/fedora35/Dockerfile index af2322d..d1614b4 100644 --- a/.gitlab/ci/docker/fedora34/Dockerfile +++ b/.gitlab/ci/docker/fedora35/Dockerfile @@ -1,10 +1,10 @@ -FROM fedora:34 as rvm-build +FROM fedora:35 as rvm-build MAINTAINER Ben Boeckel <ben.boeckel@kitware.com> COPY install_rvm.sh /root/install_rvm.sh RUN sh /root/install_rvm.sh -FROM fedora:34 +FROM fedora:35 MAINTAINER Ben Boeckel <ben.boeckel@kitware.com> COPY install_deps.sh /root/install_deps.sh diff --git a/.gitlab/ci/docker/fedora34/install_deps.sh b/.gitlab/ci/docker/fedora35/install_deps.sh index bef3a97..30214af 100755 --- a/.gitlab/ci/docker/fedora34/install_deps.sh +++ b/.gitlab/ci/docker/fedora35/install_deps.sh @@ -75,7 +75,7 @@ dnf install --setopt=install_weak_deps=False -y \ libinput-devel systemd-devel \ libjpeg-turbo-devel \ libpng-devel \ - libpq-devel postgresql-server-devel \ + postgresql-server-devel \ libtiff-devel \ libuv-devel \ libxml2-devel \ diff --git a/.gitlab/ci/docker/fedora34/install_ispc.sh b/.gitlab/ci/docker/fedora35/install_ispc.sh index fdc14b5..fdc14b5 100755 --- a/.gitlab/ci/docker/fedora34/install_ispc.sh +++ b/.gitlab/ci/docker/fedora35/install_ispc.sh diff --git a/.gitlab/ci/docker/fedora34/install_rvm.sh b/.gitlab/ci/docker/fedora35/install_rvm.sh index fca5104..fca5104 100755 --- a/.gitlab/ci/docker/fedora34/install_rvm.sh +++ b/.gitlab/ci/docker/fedora35/install_rvm.sh diff --git a/.gitlab/ci/env_fedora34_asan.sh b/.gitlab/ci/env_fedora35_asan.sh index e976486..e976486 100644 --- a/.gitlab/ci/env_fedora34_asan.sh +++ b/.gitlab/ci/env_fedora35_asan.sh diff --git a/.gitlab/ci/env_fedora34_clang_analyzer.sh b/.gitlab/ci/env_fedora35_clang_analyzer.sh index d732c0b..d732c0b 100644 --- a/.gitlab/ci/env_fedora34_clang_analyzer.sh +++ b/.gitlab/ci/env_fedora35_clang_analyzer.sh diff --git a/.gitlab/ci/env_fedora34_makefiles.cmake b/.gitlab/ci/env_fedora35_makefiles.cmake index aa84e23..aa84e23 100644 --- a/.gitlab/ci/env_fedora34_makefiles.cmake +++ b/.gitlab/ci/env_fedora35_makefiles.cmake diff --git a/.gitlab/os-linux.yml b/.gitlab/os-linux.yml index c831530..a2da7f9 100644 --- a/.gitlab/os-linux.yml +++ b/.gitlab/os-linux.yml @@ -5,7 +5,7 @@ ### Release .linux_prep_source: - image: "fedora:34" + image: "fedora:35" variables: GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci" @@ -68,8 +68,8 @@ ### Fedora -.fedora34: - image: "kitware/cmake:ci-fedora34-x86_64-2021-10-05" +.fedora35: + image: "kitware/cmake:ci-fedora35-x86_64-2022-02-01" variables: GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci/long file name for testing purposes" @@ -77,37 +77,37 @@ #### Lint builds -.fedora34_tidy: - extends: .fedora34 +.fedora35_tidy: + extends: .fedora35 variables: - CMAKE_CONFIGURATION: fedora34_tidy + CMAKE_CONFIGURATION: fedora35_tidy CTEST_NO_WARNINGS_ALLOWED: 1 CMake_SKIP_INSTALL: 1 -.fedora34_clang_analyzer: - extends: .fedora34 +.fedora35_clang_analyzer: + extends: .fedora35 variables: - CMAKE_CONFIGURATION: fedora34_clang_analyzer + CMAKE_CONFIGURATION: fedora35_clang_analyzer CMAKE_CI_BUILD_TYPE: Debug CTEST_NO_WARNINGS_ALLOWED: 1 CMake_SKIP_INSTALL: 1 -.fedora34_sphinx: - extends: .fedora34 +.fedora35_sphinx: + extends: .fedora35 variables: - CMAKE_CONFIGURATION: fedora34_sphinx + CMAKE_CONFIGURATION: fedora35_sphinx CTEST_NO_WARNINGS_ALLOWED: 1 CTEST_SOURCE_SUBDIRECTORY: "Utilities/Sphinx" CMake_SKIP_INSTALL: 1 -.fedora34_sphinx_package: - extends: .fedora34 +.fedora35_sphinx_package: + extends: .fedora35 variables: - CMAKE_CONFIGURATION: fedora34_sphinx_package + CMAKE_CONFIGURATION: fedora35_sphinx_package CTEST_SOURCE_SUBDIRECTORY: "Utilities/Sphinx" #### Build and test @@ -126,26 +126,27 @@ CMAKE_CONFIGURATION: debian10_aarch64_ninja CTEST_NO_WARNINGS_ALLOWED: 1 -.fedora34_ninja: - extends: .fedora34 +.fedora35_ninja: + extends: .fedora35 variables: - CMAKE_CONFIGURATION: fedora34_ninja + CMAKE_CONFIGURATION: fedora35_ninja + CMAKE_CI_BUILD_TYPE: Release CTEST_NO_WARNINGS_ALLOWED: 1 -.fedora34_ninja_multi: - extends: .fedora34 +.fedora35_ninja_multi: + extends: .fedora35 variables: - CMAKE_CONFIGURATION: fedora34_ninja_multi + CMAKE_CONFIGURATION: fedora35_ninja_multi CTEST_NO_WARNINGS_ALLOWED: 1 CMAKE_GENERATOR: "Ninja Multi-Config" -.fedora34_makefiles: - extends: .fedora34 +.fedora35_makefiles: + extends: .fedora35 variables: - CMAKE_CONFIGURATION: fedora34_makefiles + CMAKE_CONFIGURATION: fedora35_makefiles CTEST_NO_WARNINGS_ALLOWED: 1 CMAKE_GENERATOR: "Unix Makefiles" @@ -177,13 +178,13 @@ CTEST_MEMORYCHECK_TYPE: AddressSanitizer CTEST_MEMORYCHECK_SANITIZER_OPTIONS: "" -.fedora34_asan: +.fedora35_asan: extends: - - .fedora34 + - .fedora35 - .fedora_asan_addon variables: - CMAKE_CONFIGURATION: fedora34_asan + CMAKE_CONFIGURATION: fedora35_asan ### Intel Compiler @@ -352,7 +353,7 @@ .cmake_codespell_linux: stage: build - extends: .fedora34 + extends: .fedora35 script: - codespell interruptible: true @@ -482,7 +483,7 @@ .cmake_org_help: stage: build extends: - - .fedora34 + - .fedora35 - .linux_builder_tags - .cmake_org_help_artifacts script: diff --git a/.gitlab/upload.yml b/.gitlab/upload.yml index 693388d..dc7da7e 100644 --- a/.gitlab/upload.yml +++ b/.gitlab/upload.yml @@ -1,7 +1,7 @@ # Steps for uploading artifacts .rsync_upload_binary: - image: "fedora:34" + image: "fedora:35" stage: upload tags: - cmake @@ -20,7 +20,7 @@ .rsync_upload_help: stage: upload - image: "fedora:34" + image: "fedora:35" tags: - cmake - docker 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-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/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.21.rst b/Help/release/3.21.rst index e1c6172..ae954b2 100644 --- a/Help/release/3.21.rst +++ b/Help/release/3.21.rst @@ -334,3 +334,10 @@ Changes made since CMake 3.21.0 include the following. * The :generator:`Visual Studio 17 2022` generator is now based on the "Visual Studio 2022" release candidates. Previously it was based on preview versions. + +3.21.5 +------ + +This version made no changes to documented features or interfaces. +Some implementation updates were made to support ecosystem changes +and/or fix regressions. 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/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/FindHDF5.cmake b/Modules/FindHDF5.cmake index 6e07da5..9123d56 100644 --- a/Modules/FindHDF5.cmake +++ b/Modules/FindHDF5.cmake @@ -1050,8 +1050,12 @@ if (HDF5_FOUND) else() if (DEFINED "HDF5_${hdf5_target_name}_LIBRARY") set(_hdf5_location "${HDF5_${hdf5_target_name}_LIBRARY}") + set(_hdf5_location_release "${HDF5_${hdf5_target_name}_LIBRARY_RELEASE}") + set(_hdf5_location_debug "${HDF5_${hdf5_target_name}_LIBRARY_DEBUG}") elseif (DEFINED "HDF5_${hdf5_lang}_LIBRARY") set(_hdf5_location "${HDF5_${hdf5_lang}_LIBRARY}") + set(_hdf5_location_release "${HDF5_${hdf5_lang}_LIBRARY_RELEASE}") + set(_hdf5_location_debug "${HDF5_${hdf5_lang}_LIBRARY_DEBUG}") elseif (DEFINED "HDF5_${hdf5_lang}_LIBRARY_${hdf5_target_name}") set(_hdf5_location "${HDF5_${hdf5_lang}_LIBRARY_${hdf5_target_name}}") else () @@ -1066,10 +1070,24 @@ if (HDF5_FOUND) set(HDF5_${hdf5_lang}_INCLUDE_DIRS ${HDF5_INCLUDE_DIRS}) endif () set_target_properties("hdf5::${hdf5_target_name}" PROPERTIES - IMPORTED_LOCATION "${_hdf5_location}" - IMPORTED_IMPLIB "${_hdf5_location}" INTERFACE_INCLUDE_DIRECTORIES "${HDF5_${hdf5_lang}_INCLUDE_DIRS}" INTERFACE_COMPILE_DEFINITIONS "${_hdf5_definitions}") + if (_hdf5_location_release) + set_property(TARGET "hdf5::${hdf5_target_name}" APPEND PROPERTY + IMPORTED_CONFIGURATIONS RELEASE) + set_property(TARGET "hdf5::${hdf5_target_name}" PROPERTY + IMPORTED_LOCATION_RELEASE "${_hdf5_location_release}") + endif() + if (_hdf5_location_debug) + set_property(TARGET "hdf5::${hdf5_target_name}" APPEND PROPERTY + IMPORTED_CONFIGURATIONS DEBUG) + set_property(TARGET "hdf5::${hdf5_target_name}" PROPERTY + IMPORTED_LOCATION_DEBUG "${_hdf5_location_debug}") + endif() + if (NOT _hdf5_location_release AND NOT _hdf5_location_debug) + set_property(TARGET "hdf5::${hdf5_target_name}" PROPERTY + IMPORTED_LOCATION "${_hdf5_location}") + endif() if (_hdf5_libtype STREQUAL "SHARED") set_property(TARGET "hdf5::${hdf5_target_name}" APPEND PROPERTY @@ -1082,6 +1100,8 @@ if (HDF5_FOUND) unset(_hdf5_definitions) unset(_hdf5_libtype) unset(_hdf5_location) + unset(_hdf5_location_release) + unset(_hdf5_location_debug) endif () endif () @@ -1111,8 +1131,12 @@ if (HDF5_FOUND) else() if (DEFINED "HDF5_${hdf5_target_name}_LIBRARY") set(_hdf5_location "${HDF5_${hdf5_target_name}_LIBRARY}") + set(_hdf5_location_release "${HDF5_${hdf5_target_name}_LIBRARY_RELEASE}") + set(_hdf5_location_debug "${HDF5_${hdf5_target_name}_LIBRARY_DEBUG}") elseif (DEFINED "HDF5_${hdf5_lang}_HL_LIBRARY") set(_hdf5_location "${HDF5_${hdf5_lang}_HL_LIBRARY}") + set(_hdf5_location_release "${HDF5_${hdf5_lang}_HL_LIBRARY_RELEASE}") + set(_hdf5_location_debug "${HDF5_${hdf5_lang}_HL_LIBRARY_DEBUG}") elseif (DEFINED "HDF5_${hdf5_lang}_LIBRARY_${hdf5_target_name}") set(_hdf5_location "${HDF5_${hdf5_lang}_LIBRARY_${hdf5_target_name}}") elseif (hdf5_alt_target_name AND DEFINED "HDF5_${hdf5_lang}_LIBRARY_${hdf5_alt_target_name}") @@ -1126,10 +1150,24 @@ if (HDF5_FOUND) add_library("hdf5::${hdf5_target_name}" UNKNOWN IMPORTED) string(REPLACE "-D" "" _hdf5_definitions "${HDF5_${hdf5_lang}_HL_DEFINITIONS}") set_target_properties("hdf5::${hdf5_target_name}" PROPERTIES - IMPORTED_LOCATION "${_hdf5_location}" - IMPORTED_IMPLIB "${_hdf5_location}" INTERFACE_INCLUDE_DIRECTORIES "${HDF5_${hdf5_lang}_HL_INCLUDE_DIRS}" INTERFACE_COMPILE_DEFINITIONS "${_hdf5_definitions}") + if (_hdf5_location_release) + set_property(TARGET "hdf5::${hdf5_target_name}" APPEND PROPERTY + IMPORTED_CONFIGURATIONS RELEASE) + set_property(TARGET "hdf5::${hdf5_target_name}" PROPERTY + IMPORTED_LOCATION_RELEASE "${_hdf5_location_release}") + endif() + if (_hdf5_location_debug) + set_property(TARGET "hdf5::${hdf5_target_name}" APPEND PROPERTY + IMPORTED_CONFIGURATIONS DEBUG) + set_property(TARGET "hdf5::${hdf5_target_name}" PROPERTY + IMPORTED_LOCATION_DEBUG "${_hdf5_location_debug}") + endif() + if (NOT _hdf5_location_release AND NOT _hdf5_location_debug) + set_property(TARGET "hdf5::${hdf5_target_name}" PROPERTY + IMPORTED_LOCATION "${_hdf5_location}") + endif() if (_hdf5_libtype STREQUAL "SHARED") set_property(TARGET "hdf5::${hdf5_target_name}" APPEND PROPERTY 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/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/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 3e58230..a661c20 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 20220130) +set(CMake_VERSION_PATCH 20220202) #set(CMake_VERSION_RC 0) set(CMake_VERSION_IS_DIRTY 0) 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/cmFindBase.cxx b/Source/cmFindBase.cxx index a123e44..efc4e3a 100644 --- a/Source/cmFindBase.cxx +++ b/Source/cmFindBase.cxx @@ -168,7 +168,7 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn) } this->ExpandPaths(); - this->ComputeFinalPaths(); + this->ComputeFinalPaths(IgnorePaths::Yes); return true; } diff --git a/Source/cmFindCommon.cxx b/Source/cmFindCommon.cxx index 7631583..c58db1e 100644 --- a/Source/cmFindCommon.cxx +++ b/Source/cmFindCommon.cxx @@ -283,14 +283,15 @@ void cmFindCommon::RerootPaths(std::vector<std::string>& paths) void cmFindCommon::GetIgnoredPaths(std::vector<std::string>& ignore) { - // null-terminated list of paths. - static const char* paths[] = { "CMAKE_SYSTEM_IGNORE_PATH", - "CMAKE_IGNORE_PATH", nullptr }; + static constexpr const char* paths[] = { + "CMAKE_SYSTEM_IGNORE_PATH", + "CMAKE_IGNORE_PATH", + }; // Construct the list of path roots with no trailing slashes. - for (const char** pathName = paths; *pathName; ++pathName) { + for (const char* pathName : paths) { // Get the list of paths to ignore from the variable. - this->Makefile->GetDefExpandList(*pathName, ignore); + this->Makefile->GetDefExpandList(pathName, ignore); } for (std::string& i : ignore) { @@ -365,11 +366,13 @@ static void AddTrailingSlash(std::string& s) s += '/'; } } -void cmFindCommon::ComputeFinalPaths() +void cmFindCommon::ComputeFinalPaths(IgnorePaths ignorePaths) { // Filter out ignored paths from the prefix list std::set<std::string> ignored; - this->GetIgnoredPaths(ignored); + if (ignorePaths == IgnorePaths::Yes) { + this->GetIgnoredPaths(ignored); + } // Combine the separate path types, filtering out ignores this->SearchPaths.clear(); diff --git a/Source/cmFindCommon.h b/Source/cmFindCommon.h index 1a49aff..49d64e4 100644 --- a/Source/cmFindCommon.h +++ b/Source/cmFindCommon.h @@ -82,12 +82,17 @@ protected: /** Place a set of search paths under the search roots. */ void RerootPaths(std::vector<std::string>& paths); - /** Get ignored paths from CMAKE_[SYSTEM_]IGNORE_path variables. */ + /** Get ignored paths from CMAKE_[SYSTEM_]IGNORE_PATH variables. */ void GetIgnoredPaths(std::vector<std::string>& ignore); void GetIgnoredPaths(std::set<std::string>& ignore); /** Compute final search path list (reroot + trailing slash). */ - void ComputeFinalPaths(); + enum class IgnorePaths + { + No, + Yes, + }; + void ComputeFinalPaths(IgnorePaths ignorePaths); /** Compute the current default root path mode. */ void SelectDefaultRootPathMode(); diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index 6d788e4..c468a3c 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx @@ -1346,7 +1346,7 @@ void cmFindPackageCommand::ComputePrefixes() } this->FillPrefixesUserGuess(); - this->ComputeFinalPaths(); + this->ComputeFinalPaths(IgnorePaths::No); } void cmFindPackageCommand::FillPrefixesPackageRoot() @@ -2286,6 +2286,15 @@ bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in) return false; } + // Skip this if it's in ignored paths. + std::string prefixWithoutSlash = prefix_in; + if (prefixWithoutSlash != "/" && prefixWithoutSlash.back() == '/') { + prefixWithoutSlash.erase(prefixWithoutSlash.length() - 1); + } + if (this->IgnoredPaths.count(prefixWithoutSlash)) { + return false; + } + // PREFIX/ (useful on windows or in build trees) if (this->SearchDirectory(prefix_in)) { return true; 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 45e3b64..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(); diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index a58dc93..45639c0 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -667,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); @@ -1001,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; }; @@ -1063,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/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/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/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/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..487da8d 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,17 +326,17 @@ 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; } // While we're at it, check proper TestFileAccess functionality. bool do_write_test = true; #if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || \ - defined(__NetBSD__) || defined(__DragonFly__) + defined(__NetBSD__) || defined(__DragonFly__) || defined(__HOS_AIX__) // If we are running as root on POSIX-ish systems (Linux and the BSDs, // at least), ignore this check, as root can always write to files. do_write_test = (getuid() != 0); 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/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/FindBoost/TestPython/CMakeLists.txt b/Tests/FindBoost/TestPython/CMakeLists.txt index 6d292cd..8ef18e9 100644 --- a/Tests/FindBoost/TestPython/CMakeLists.txt +++ b/Tests/FindBoost/TestPython/CMakeLists.txt @@ -2,10 +2,10 @@ cmake_minimum_required(VERSION 3.14) project(TestFindBoostPython CXX) include(CTest) -find_package(Boost OPTIONAL_COMPONENTS python27 python34 python35 python36 python37 python38 python39) +find_package(Boost OPTIONAL_COMPONENTS python27 python34 python35 python36 python37 python38 python39 python310) set(FAILTEST TRUE) -foreach (v IN ITEMS 27 34 35 36 37 38 39) +foreach (v IN ITEMS 27 34 35 36 37 38 39 310) if (Boost_PYTHON${v}_FOUND) set(FAILTEST FALSE) break() 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/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/find_package/IgnorePath.cmake b/Tests/RunCMake/find_package/IgnorePath.cmake new file mode 100644 index 0000000..f40549b --- /dev/null +++ b/Tests/RunCMake/find_package/IgnorePath.cmake @@ -0,0 +1,12 @@ +set(CMAKE_PREFIX_PATH + ${CMAKE_SOURCE_DIR}/PackageRoot/foo/cmake_root + ${CMAKE_SOURCE_DIR}/PackageRoot/foo/env_root + ) +set(CMAKE_IGNORE_PATH + ${CMAKE_SOURCE_DIR}/PackageRoot//foo/cmake_root// # Test double slashes + ${CMAKE_SOURCE_DIR}/PackageRoot/foo/env_root/cmake + ) +find_package(Bar QUIET CONFIG) +if(Bar_FOUND) + message(FATAL_ERROR "Bar should not be found, was found in ${Bar_DIR}") +endif() diff --git a/Tests/RunCMake/find_package/RunCMakeTest.cmake b/Tests/RunCMake/find_package/RunCMakeTest.cmake index 2bace98..12701dc 100644 --- a/Tests/RunCMake/find_package/RunCMakeTest.cmake +++ b/Tests/RunCMake/find_package/RunCMakeTest.cmake @@ -44,6 +44,7 @@ run_cmake(VersionRangeConfig2) run_cmake(VersionRangeConfig02) run_cmake(VersionRangeConfigStd) run_cmake(VersionRangeConfigStd2) +run_cmake(IgnorePath) if(UNIX AND NOT MSYS # FIXME: This works on CYGWIN but not on MSYS ) diff --git a/Utilities/Sphinx/CMakeLists.txt b/Utilities/Sphinx/CMakeLists.txt index 165d557..073e5ff 100644 --- a/Utilities/Sphinx/CMakeLists.txt +++ b/Utilities/Sphinx/CMakeLists.txt @@ -9,6 +9,7 @@ if(NOT CMake_SOURCE_DIR) include(${CMake_SOURCE_DIR}/Modules/CTestUseLaunchers.cmake) include(${CMake_SOURCE_DIR}/Source/CMakeVersion.cmake) include(${CMake_SOURCE_DIR}/Source/CMakeInstallDestinations.cmake) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/CTestCustom.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/CTestCustom.cmake @ONLY) unset(CMAKE_DATA_DIR) unset(CMAKE_DATA_DIR CACHE) macro(CMake_OPTIONAL_COMPONENT) diff --git a/Utilities/Sphinx/CTestCustom.cmake.in b/Utilities/Sphinx/CTestCustom.cmake.in new file mode 100644 index 0000000..840121b --- /dev/null +++ b/Utilities/Sphinx/CTestCustom.cmake.in @@ -0,0 +1,3 @@ +list(APPEND CTEST_CUSTOM_WARNING_EXCEPTION + "cmake.texi:[0-9]+: warning: .definfoenclose is obsolete" + ) |