Browse Source

Merge topic 'dyndep-module-info-objlib-dependency'

b665966933 cmComputeLinkInformation: track OBJECT library dependencies
a99b87a628 Tests/RunCMake/CXXModules: add a test for issue #25112
2870a67540 Tests/FortranOnly: add a test case for issue #25112

Acked-by: Kitware Robot <[email protected]>
Tested-by: buildbot <[email protected]>
Merge-request: !8645
Brad King 2 years ago
parent
commit
f8c3fd0c45

+ 9 - 3
Source/cmCommonTargetGenerator.cxx

@@ -170,9 +170,15 @@ std::vector<std::string> cmCommonTargetGenerator::GetLinkedTargetDirectories(
   cmGlobalCommonGenerator* const gg = this->GlobalCommonGenerator;
   if (cmComputeLinkInformation* cli =
         this->GeneratorTarget->GetLinkInformation(config)) {
-    cmComputeLinkInformation::ItemVector const& items = cli->GetItems();
-    for (auto const& item : items) {
-      cmGeneratorTarget const* linkee = item.Target;
+    std::vector<cmGeneratorTarget const*> targets;
+    for (auto const& item : cli->GetItems()) {
+      targets.push_back(item.Target);
+    }
+    for (auto const* target : cli->GetObjectLibrariesLinked()) {
+      targets.push_back(target);
+    }
+
+    for (auto const* linkee : targets) {
       if (linkee &&
           !linkee->IsImported()
           // Skip targets that build after this one in a static lib cycle.

+ 12 - 2
Source/cmComputeLinkInformation.cxx

@@ -525,6 +525,12 @@ cmComputeLinkInformation::GetSharedLibrariesLinked() const
   return this->SharedLibrariesLinked;
 }
 
+const std::vector<const cmGeneratorTarget*>&
+cmComputeLinkInformation::GetObjectLibrariesLinked() const
+{
+  return this->ObjectLibrariesLinked;
+}
+
 bool cmComputeLinkInformation::Compute()
 {
   // Skip targets that do not link.
@@ -1147,8 +1153,12 @@ void cmComputeLinkInformation::AddItem(LinkEntry const& entry)
         this->AddItem(BT<std::string>(libName, item.Backtrace));
       }
     } else if (tgt->GetType() == cmStateEnums::OBJECT_LIBRARY) {
-      // Ignore object library!
-      // Its object-files should already have been extracted for linking.
+      if (!tgt->HaveCxx20ModuleSources() && !tgt->HaveFortranSources(config)) {
+        // Ignore object library!
+        // Its object-files should already have been extracted for linking.
+      } else {
+        this->ObjectLibrariesLinked.push_back(entry.Target);
+      }
     } else {
       // Decide whether to use an import library.
       cmStateEnums::ArtifactType artifact = tgt->HasImportLibrary(config)

+ 3 - 0
Source/cmComputeLinkInformation.h

@@ -96,6 +96,8 @@ public:
   std::string GetRPathString(bool for_install) const;
   std::string GetChrpathString() const;
   std::set<cmGeneratorTarget const*> const& GetSharedLibrariesLinked() const;
+  std::vector<cmGeneratorTarget const*> const& GetObjectLibrariesLinked()
+    const;
   std::vector<cmGeneratorTarget const*> const& GetRuntimeDLLs() const
   {
     return this->RuntimeDLLs;
@@ -132,6 +134,7 @@ private:
   std::vector<std::string> FrameworkPaths;
   std::vector<std::string> RuntimeSearchPath;
   std::set<cmGeneratorTarget const*> SharedLibrariesLinked;
+  std::vector<cmGeneratorTarget const*> ObjectLibrariesLinked;
   std::vector<cmGeneratorTarget const*> RuntimeDLLs;
 
   // Context information.

+ 6 - 0
Tests/FortranOnly/CMakeLists.txt

@@ -184,3 +184,9 @@ if(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_OFF AND
   set_property(TARGET no_preprocess_target PROPERTY Fortran_PREPROCESS OFF)
   set_property(SOURCE no_preprocess_source_upper.F no_preprocess_source_fpp.fpp PROPERTY Fortran_PREPROCESS OFF)
 endif()
+
+# Issue 25112
+set(CMAKE_Fortran_MODULE_DIRECTORY "${PROJECT_BINARY_DIR}/include")
+add_library(objmod OBJECT objmod.f90)
+add_executable(objmain objmain.f90)
+target_link_libraries(objmain PRIVATE objmod)

+ 5 - 0
Tests/FortranOnly/objmain.f90

@@ -0,0 +1,5 @@
+program main
+    use objmod, only : hello
+    implicit none
+    call hello()
+end program

+ 7 - 0
Tests/FortranOnly/objmod.f90

@@ -0,0 +1,7 @@
+module objmod
+    implicit none
+contains
+    subroutine hello()
+        print '(a)', "hello world"
+    end subroutine hello
+end module objmod

+ 1 - 0
Tests/RunCMake/CXXModules/RunCMakeTest.cmake

@@ -142,6 +142,7 @@ string(REPLACE "," ";" CMake_TEST_MODULE_COMPILATION "${CMake_TEST_MODULE_COMPIL
 if ("named" IN_LIST CMake_TEST_MODULE_COMPILATION)
   run_cxx_module_test(simple)
   run_cxx_module_test(library library-static -DBUILD_SHARED_LIBS=OFF)
+  run_cxx_module_test(object-library)
   run_cxx_module_test(generated)
   run_cxx_module_test(deep-chain)
   run_cxx_module_test(duplicate)

+ 4 - 0
Tests/RunCMake/CXXModules/examples/object-library-stderr.txt

@@ -0,0 +1,4 @@
+CMake Warning \(dev\) at CMakeLists.txt:[0-9]* \(target_sources\):
+  CMake's C\+\+ module support is experimental.  It is meant only for
+  experimentation and feedback to CMake developers.
+This warning is for project developers.  Use -Wno-dev to suppress it.

+ 22 - 0
Tests/RunCMake/CXXModules/examples/object-library/CMakeLists.txt

@@ -0,0 +1,22 @@
+cmake_minimum_required(VERSION 3.24)
+project(cxx_modules_objlib CXX)
+
+include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
+
+add_library(objlib OBJECT)
+target_sources(objlib
+  PUBLIC
+    FILE_SET CXX_MODULES
+      BASE_DIRS
+        "${CMAKE_CURRENT_SOURCE_DIR}"
+      FILES
+        importable.cxx)
+target_compile_features(objlib PUBLIC cxx_std_20)
+
+add_executable(objmain)
+target_sources(objmain
+  PRIVATE
+    main.cxx)
+target_link_libraries(objmain PRIVATE objlib)
+
+add_test(NAME objmain COMMAND objmain)

+ 6 - 0
Tests/RunCMake/CXXModules/examples/object-library/importable.cxx

@@ -0,0 +1,6 @@
+export module importable;
+
+export int from_import()
+{
+  return 0;
+}

+ 6 - 0
Tests/RunCMake/CXXModules/examples/object-library/main.cxx

@@ -0,0 +1,6 @@
+import importable;
+
+int main(int argc, char* argv[])
+{
+  return from_import();
+}