Merge topic 'doc-LINK_LIBRARY_genex' into release-3.24 d185f7c0a8 Help: Rework $<LINK_LIBRARY>, $<LINK_GROUP> and related docs Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !7413
diff --git a/Help/guide/using-dependencies/index.rst b/Help/guide/using-dependencies/index.rst index 03285b6..6cab7ef 100644 --- a/Help/guide/using-dependencies/index.rst +++ b/Help/guide/using-dependencies/index.rst
@@ -304,6 +304,8 @@ ``FetchContent`` And ``find_package()`` Integration =================================================== +.. versionadded:: 3.24 + Some dependencies support being added by either :command:`find_package` or :module:`FetchContent`. Such dependencies must ensure they define the same namespaced targets in both installed and built-from-source scenarios. @@ -375,6 +377,8 @@ Dependency Providers ==================== +.. versionadded:: 3.24 + The preceding section discussed techniques that projects can use to specify their dependencies. Ideally, the project shouldn't really care where a dependency comes from, as long as it provides the things it expects (often
diff --git a/Help/variable/CMAKE_OSX_VARIABLE.txt b/Help/variable/CMAKE_OSX_VARIABLE.txt index 16f3c1a..5670980 100644 --- a/Help/variable/CMAKE_OSX_VARIABLE.txt +++ b/Help/variable/CMAKE_OSX_VARIABLE.txt
@@ -3,7 +3,8 @@ because it may influence configuration of the toolchain and flags. It is intended to be set locally by the user creating a build tree. This variable should be set as a ``CACHE`` entry (or else CMake may -remove it while initializing a cache entry of the same name). +remove it while initializing a cache entry of the same name) unless +policy :policy:`CMP0126` is set to ``NEW``. Despite the ``OSX`` part in the variable name(s) they apply also to other SDKs than macOS like iOS, tvOS, or watchOS.
diff --git a/Modules/FetchContent.cmake b/Modules/FetchContent.cmake index c4c3a93..df40c85 100644 --- a/Modules/FetchContent.cmake +++ b/Modules/FetchContent.cmake
@@ -1178,7 +1178,11 @@ # Always check this even if we won't save these details. # This helps projects catch errors earlier. - if("OVERRIDE_FIND_PACKAGE" IN_LIST ARGN AND "FIND_PACKAGE_ARGS" IN_LIST ARGN) + # Avoid using if(... IN_LIST ...) so we don't have to alter policy settings + list(FIND ARGN OVERRIDE_FIND_PACKAGE index_OVERRIDE_FIND_PACKAGE) + list(FIND ARGN FIND_PACKAGE_ARGS index_FIND_PACKAGE_ARGS) + if(index_OVERRIDE_FIND_PACKAGE GREATER_EQUAL 0 AND + index_FIND_PACKAGE_ARGS GREATER_EQUAL 0) message(FATAL_ERROR "Cannot specify both OVERRIDE_FIND_PACKAGE and FIND_PACKAGE_ARGS " "when declaring details for ${contentName}" @@ -1750,7 +1754,9 @@ DEFINED ) - if(NOT wantFindPackage AND NOT OVERRIDE_FIND_PACKAGE IN_LIST contentDetails) + # Avoid using if(... IN_LIST ...) so we don't have to alter policy settings + list(FIND contentDetails OVERRIDE_FIND_PACKAGE indexResult) + if(NOT wantFindPackage AND indexResult EQUAL -1) # No find_package() redirection allowed return() endif()
diff --git a/Modules/FindHDF5.cmake b/Modules/FindHDF5.cmake index 46ad015..40ed9a9 100644 --- a/Modules/FindHDF5.cmake +++ b/Modules/FindHDF5.cmake
@@ -555,8 +555,8 @@ endif() if( _hdf5_lang_location ) set(HDF5_${_lang}_LIBRARY ${_hdf5_lang_location}) - list(APPEND HDF5_LIBRARIES ${HDF5_${_lang}_LIBRARY}) - set(HDF5_${_lang}_LIBRARIES ${HDF5_${_lang}_LIBRARY}) + list(APPEND HDF5_LIBRARIES ${HDF5_${_lang}_TARGET}${_suffix}) + set(HDF5_${_lang}_LIBRARIES ${HDF5_${_lang}_TARGET}${_suffix}) set(HDF5_${_lang}_FOUND TRUE) endif() if(HDF5_FIND_HL) @@ -569,8 +569,8 @@ endif() if( _hdf5_lang_hl_location ) set(HDF5_${_lang}_HL_LIBRARY ${_hdf5_lang_hl_location}) - list(APPEND HDF5_HL_LIBRARIES ${HDF5_${_lang}_HL_LIBRARY}) - set(HDF5_${_lang}_HL_LIBRARIES ${HDF5_${_lang}_HL_LIBRARY}) + list(APPEND HDF5_HL_LIBRARIES ${HDF5_${_lang}_HL_TARGET}${_suffix}) + set(HDF5_${_lang}_HL_LIBRARIES ${HDF5_${_lang}_HL_TARGET}${_suffix}) set(HDF5_HL_FOUND TRUE) endif() unset(_hdf5_lang_hl_location)
diff --git a/Modules/FindPython/Support.cmake b/Modules/FindPython/Support.cmake index 8e98500..c4fae6b 100644 --- a/Modules/FindPython/Support.cmake +++ b/Modules/FindPython/Support.cmake
@@ -2861,7 +2861,8 @@ endif() unset (_${_PYTHON_PREFIX}_INCLUDE_HINTS) - if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE) + if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS + AND _${_PYTHON_PREFIX}_LIBRARY_RELEASE) # Use the library's install prefix as a hint if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "^(.+/Frameworks/Python.framework/Versions/[0-9.]+)") list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}") @@ -2945,7 +2946,8 @@ if (_${_PYTHON_PREFIX}_INCLUDE_DIR) # retrieve version from header file _python_get_version (INCLUDE PREFIX _${_PYTHON_PREFIX}_INC_) - if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE) + if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS + AND _${_PYTHON_PREFIX}_LIBRARY_RELEASE) if ("${_${_PYTHON_PREFIX}_INC_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_INC_VERSION_MINOR}" VERSION_EQUAL _${_PYTHON_PREFIX}_VERSION) # update versioning
diff --git a/Modules/Platform/Linux-LCC-Fortran.cmake b/Modules/Platform/Linux-LCC-Fortran.cmake index d3a4cf4..bf2a1c2 100644 --- a/Modules/Platform/Linux-LCC-Fortran.cmake +++ b/Modules/Platform/Linux-LCC-Fortran.cmake
@@ -1,3 +1,7 @@ include(Platform/Linux-LCC) __linux_compiler_lcc(Fortran) -set(CMAKE_SHARED_LIBRARY_LINK_Fortran_FLAGS "-llfortran") +if (CMAKE_Fortran_COMPILER_VERSION VERSION_LESS "1.26.03") + set(CMAKE_SHARED_LIBRARY_LINK_Fortran_FLAGS "-llfortran") +else() + set(CMAKE_SHARED_LIBRARY_LINK_Fortran_FLAGS "-lgfortran") +endif()
diff --git a/Source/cmExportSet.cxx b/Source/cmExportSet.cxx index a20aa9a..3d4ef0a 100644 --- a/Source/cmExportSet.cxx +++ b/Source/cmExportSet.cxx
@@ -2,10 +2,15 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmExportSet.h" +#include <algorithm> #include <tuple> #include <utility> +#include "cmGeneratorTarget.h" #include "cmLocalGenerator.h" +#include "cmMessageType.h" +#include "cmStringAlgorithms.h" +#include "cmTarget.h" #include "cmTargetExport.h" cmExportSet::cmExportSet(std::string name) @@ -15,11 +20,35 @@ cmExportSet::~cmExportSet() = default; -void cmExportSet::Compute(cmLocalGenerator* lg) +bool cmExportSet::Compute(cmLocalGenerator* lg) { for (std::unique_ptr<cmTargetExport>& tgtExport : this->TargetExports) { tgtExport->Target = lg->FindGeneratorTargetToUse(tgtExport->TargetName); + + auto const interfaceFileSets = + tgtExport->Target->Target->GetAllInterfaceFileSets(); + auto const fileSetInTargetExport = + [&tgtExport, lg](const std::string& fileSetName) -> bool { + auto* fileSet = tgtExport->Target->Target->GetFileSet(fileSetName); + + if (!tgtExport->FileSetGenerators.count(fileSet)) { + lg->IssueMessage(MessageType::FATAL_ERROR, + cmStrCat("File set \"", fileSetName, + "\" is listed in interface file sets of ", + tgtExport->Target->GetName(), + " but has not been exported")); + return false; + } + return true; + }; + + if (!std::all_of(interfaceFileSets.begin(), interfaceFileSets.end(), + fileSetInTargetExport)) { + return false; + } } + + return true; } void cmExportSet::AddTargetExport(std::unique_ptr<cmTargetExport> te)
diff --git a/Source/cmExportSet.h b/Source/cmExportSet.h index 07deb11..b75a26d 100644 --- a/Source/cmExportSet.h +++ b/Source/cmExportSet.h
@@ -25,7 +25,7 @@ cmExportSet(const cmExportSet&) = delete; cmExportSet& operator=(const cmExportSet&) = delete; - void Compute(cmLocalGenerator* lg); + bool Compute(cmLocalGenerator* lg); void AddTargetExport(std::unique_ptr<cmTargetExport> tgt);
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx index b08cddb..d773fdf 100644 --- a/Source/cmGeneratorExpressionNode.cxx +++ b/Source/cmGeneratorExpressionNode.cxx
@@ -2763,8 +2763,18 @@ return std::string(); } - return target->GetAppBundleDirectory(context->Config, - cmGeneratorTarget::BundleDirLevel); + auto level = cmGeneratorTarget::BundleDirLevel; + auto config = context->Config; + if (target->IsAppBundleOnApple()) { + return target->GetAppBundleDirectory(config, level); + } + if (target->IsFrameworkOnApple()) { + return target->GetFrameworkDirectory(config, level); + } + if (target->IsCFBundleOnApple()) { + return target->GetCFBundleDirectory(config, level); + } + return std::string(); } };
diff --git a/Source/cmInstallExportGenerator.cxx b/Source/cmInstallExportGenerator.cxx index 8a48aa2..b80437d 100644 --- a/Source/cmInstallExportGenerator.cxx +++ b/Source/cmInstallExportGenerator.cxx
@@ -48,8 +48,7 @@ bool cmInstallExportGenerator::Compute(cmLocalGenerator* lg) { this->LocalGenerator = lg; - this->ExportSet->Compute(lg); - return true; + return this->ExportSet->Compute(lg); } std::string cmInstallExportGenerator::TempDirCalculate() const
diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx index 40f3ab5..1514a8a 100644 --- a/Source/cmQtAutoGenInitializer.cxx +++ b/Source/cmQtAutoGenInitializer.cxx
@@ -909,6 +909,7 @@ // The reason is that their file names might be discovered from source files // at generation time. if (this->MocOrUicEnabled()) { + std::unordered_set<std::string> addedFiles; for (const auto& sf : this->Makefile->GetSourceFiles()) { // sf->GetExtension() is only valid after sf->ResolveFullPath() ... // Since we're iterating over source files that might be not in the @@ -950,25 +951,28 @@ cmExpandedList(uicOpts)); } - auto uiHeaderRelativePath = cmSystemTools::RelativePath( - this->LocalGen->GetCurrentSourceDirectory(), - cmSystemTools::GetFilenamePath(fullPath)); + auto uiHeaderFileName = cmStrCat( + "ui_"_s, cmSystemTools::GetFilenameWithoutLastExtension(fullPath), + ".h"_s); - // Avoid creating a path containing adjacent slashes - if (!uiHeaderRelativePath.empty() && - uiHeaderRelativePath.back() != '/') { - uiHeaderRelativePath += '/'; + // .ui files with the same base name will conflict. Yield an error. + { + auto insertResult = addedFiles.insert(uiHeaderFileName); + if (!insertResult.second) { + this->Makefile->IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("More than one .ui file with the name "_s, + cmSystemTools::GetFilenameName(fullPath), + " was found in the sources for target "_s, + this->GenTarget->GetName(), ".")); + } } - auto uiHeaderFilePath = cmStrCat( - '/', uiHeaderRelativePath, "ui_"_s, - cmSystemTools::GetFilenameWithoutLastExtension(fullPath), ".h"_s); - ConfigString uiHeader; std::string uiHeaderGenex; this->ConfigFileNamesAndGenex( uiHeader, uiHeaderGenex, cmStrCat(this->Dir.Build, "/include"_s), - uiHeaderFilePath); + cmStrCat("/"_s, uiHeaderFileName)); this->Uic.UiHeaders.emplace_back( std::make_pair(uiHeader, uiHeaderGenex));
diff --git a/Tests/FindPython/CMakeLists.txt b/Tests/FindPython/CMakeLists.txt index 520ba9e..d4cf36b 100644 --- a/Tests/FindPython/CMakeLists.txt +++ b/Tests/FindPython/CMakeLists.txt
@@ -423,6 +423,19 @@ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION> ) + add_test(NAME FindPython.DifferentComponents COMMAND + ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> + --build-and-test + "${CMake_SOURCE_DIR}/Tests/FindPython/DifferentComponents" + "${CMake_BINARY_DIR}/Tests/FindPython/DifferentComponents" + ${build_generator_args} + --build-project DifferentComponents + --build-options ${build_options} "-Dbuild_generator_args=${build_generator_args}" + "-DCMake_SOURCE_DIR=${CMake_SOURCE_DIR}" + "-DCMake_BINARY_DIR=${CMake_BINARY_DIR}" + --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION> + ) + if (CMAKE_SYSTEM_NAME MATCHES "Linux|Darwin") add_test(NAME FindPython.Interpreter.SOABI COMMAND ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
diff --git a/Tests/FindPython/DifferentComponents/CMakeLists.txt b/Tests/FindPython/DifferentComponents/CMakeLists.txt new file mode 100644 index 0000000..7476632 --- /dev/null +++ b/Tests/FindPython/DifferentComponents/CMakeLists.txt
@@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 3.1) + +project(TestDifferentComponents LANGUAGES C) + +add_subdirectory(subdir) + +find_package(Python3 REQUIRED COMPONENTS Development.Module)
diff --git a/Tests/FindPython/DifferentComponents/subdir/CMakeLists.txt b/Tests/FindPython/DifferentComponents/subdir/CMakeLists.txt new file mode 100644 index 0000000..98fcd5f --- /dev/null +++ b/Tests/FindPython/DifferentComponents/subdir/CMakeLists.txt
@@ -0,0 +1,2 @@ + +find_package(Python3 REQUIRED COMPONENTS Development)
diff --git a/Tests/RunCMake/GenEx-TARGET_FILE/RunCMakeTest.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/RunCMakeTest.cmake index 148baac..a79fcaf 100644 --- a/Tests/RunCMake/GenEx-TARGET_FILE/RunCMakeTest.cmake +++ b/Tests/RunCMake/GenEx-TARGET_FILE/RunCMakeTest.cmake
@@ -2,6 +2,9 @@ run_cmake(TARGET_FILE-recursion) run_cmake(OUTPUT_NAME-recursion) +if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin") + run_cmake(TARGET_BUNDLE_DIR_NAME) +endif() run_cmake(TARGET_FILE_DIR-dependency) run_cmake(TARGET_FILE_DIR-no-dependency) run_cmake(TARGET_FILE_PREFIX-imported-target)
diff --git a/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_BUNDLE_DIR_NAME-check.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_BUNDLE_DIR_NAME-check.cmake new file mode 100644 index 0000000..6e62ce3 --- /dev/null +++ b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_BUNDLE_DIR_NAME-check.cmake
@@ -0,0 +1 @@ +include ("${RunCMake_TEST_BINARY_DIR}/TARGET_BUNDLE_DIR_NAME-generated.cmake")
diff --git a/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_BUNDLE_DIR_NAME.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_BUNDLE_DIR_NAME.cmake new file mode 100644 index 0000000..23db8fd --- /dev/null +++ b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_BUNDLE_DIR_NAME.cmake
@@ -0,0 +1,33 @@ +enable_language(C) + +set(GENERATE_CONTENT [[ +macro (check_value test_msg value expected) + if (NOT "${value}" STREQUAL "${expected}") + string (APPEND RunCMake_TEST_FAILED "${test_msg}: actual result:\n [${value}]\nbut expected:\n [${expected}]\n") + endif() +endmacro() +]]) + +add_library(test-lib MODULE empty.c) +set_target_properties(test-lib PROPERTIES BUNDLE TRUE) + +add_library(test-fw empty.c) +set_target_properties(test-fw PROPERTIES FRAMEWORK TRUE) + +add_executable(test-app MACOSX_BUNDLE empty.c) + +add_executable(test-app-custom MACOSX_BUNDLE empty.c) +set_target_properties(test-app-custom PROPERTIES BUNDLE_EXTENSION custom) + +string(APPEND GENERATE_CONTENT [[ +check_value("TARGET_BUNDLE_DIR_NAME library" "$<TARGET_BUNDLE_DIR_NAME:test-lib>" "test-lib.bundle") +check_value("TARGET_BUNDLE_DIR_NAME framework" "$<TARGET_BUNDLE_DIR_NAME:test-fw>" "test-fw.framework") +check_value("TARGET_BUNDLE_DIR_NAME app" "$<TARGET_BUNDLE_DIR_NAME:test-app>" "test-app.app") +check_value("TARGET_BUNDLE_DIR_NAME custom" "$<TARGET_BUNDLE_DIR_NAME:test-app-custom>" "test-app-custom.custom") +]]) + +file( + GENERATE + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/TARGET_BUNDLE_DIR_NAME-generated.cmake" + CONTENT "${GENERATE_CONTENT}" +)
diff --git a/Tests/RunCMake/target_sources/FileSetExportMissingSetsInterfacePostExport-result.txt b/Tests/RunCMake/target_sources/FileSetExportMissingSetsInterfacePostExport-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/target_sources/FileSetExportMissingSetsInterfacePostExport-result.txt
@@ -0,0 +1 @@ +1
diff --git a/Tests/RunCMake/target_sources/FileSetExportMissingSetsInterfacePostExport-stderr.txt b/Tests/RunCMake/target_sources/FileSetExportMissingSetsInterfacePostExport-stderr.txt new file mode 100644 index 0000000..b8d35af --- /dev/null +++ b/Tests/RunCMake/target_sources/FileSetExportMissingSetsInterfacePostExport-stderr.txt
@@ -0,0 +1,6 @@ +^CMake Error in CMakeLists\.txt: + File set "a" is listed in interface file sets of lib1 but has not been + exported + + +CMake Generate step failed\. Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/target_sources/FileSetExportMissingSetsInterfacePostExport.cmake b/Tests/RunCMake/target_sources/FileSetExportMissingSetsInterfacePostExport.cmake new file mode 100644 index 0000000..72fab47 --- /dev/null +++ b/Tests/RunCMake/target_sources/FileSetExportMissingSetsInterfacePostExport.cmake
@@ -0,0 +1,6 @@ +enable_language(C) + +add_library(lib1 STATIC empty.c) +install(TARGETS lib1 EXPORT a) +target_sources(lib1 INTERFACE FILE_SET a TYPE HEADERS BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} FILES h1.h) +export(EXPORT a)
diff --git a/Tests/RunCMake/target_sources/FileSetInstallMissingSetsInterfacePostInstall-result.txt b/Tests/RunCMake/target_sources/FileSetInstallMissingSetsInterfacePostInstall-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/target_sources/FileSetInstallMissingSetsInterfacePostInstall-result.txt
@@ -0,0 +1 @@ +1
diff --git a/Tests/RunCMake/target_sources/FileSetInstallMissingSetsInterfacePostInstall-stderr.txt b/Tests/RunCMake/target_sources/FileSetInstallMissingSetsInterfacePostInstall-stderr.txt new file mode 100644 index 0000000..b8d35af --- /dev/null +++ b/Tests/RunCMake/target_sources/FileSetInstallMissingSetsInterfacePostInstall-stderr.txt
@@ -0,0 +1,6 @@ +^CMake Error in CMakeLists\.txt: + File set "a" is listed in interface file sets of lib1 but has not been + exported + + +CMake Generate step failed\. Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/target_sources/FileSetInstallMissingSetsInterfacePostInstall.cmake b/Tests/RunCMake/target_sources/FileSetInstallMissingSetsInterfacePostInstall.cmake new file mode 100644 index 0000000..4e1edff --- /dev/null +++ b/Tests/RunCMake/target_sources/FileSetInstallMissingSetsInterfacePostInstall.cmake
@@ -0,0 +1,6 @@ +enable_language(C) + +add_library(lib1 STATIC empty.c) +install(TARGETS lib1 EXPORT a) +target_sources(lib1 INTERFACE FILE_SET a TYPE HEADERS BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} FILES h1.h) +install(EXPORT a DESTINATION lib/cmake/test)
diff --git a/Tests/RunCMake/target_sources/RunCMakeTest.cmake b/Tests/RunCMake/target_sources/RunCMakeTest.cmake index e78ee9d..6a3c7b9 100644 --- a/Tests/RunCMake/target_sources/RunCMakeTest.cmake +++ b/Tests/RunCMake/target_sources/RunCMakeTest.cmake
@@ -33,6 +33,8 @@ run_cmake(FileSetOverlappingBaseDirs) run_cmake(FileSetInstallMissingSetsPrivate) run_cmake(FileSetInstallMissingSetsInterface) +run_cmake(FileSetInstallMissingSetsInterfacePostInstall) +run_cmake(FileSetExportMissingSetsInterfacePostExport) run_cmake(FileSetReadOnlyPrivate) run_cmake(FileSetReadOnlyInterface) run_cmake(FileSetNoExistInstall)