Browse Source

Merge topic 'fix-cxx-module-transitive-requirements' into release-3.28

e9b0dcbbfa cmCxxModuleMapper: Fix transitive requirements computation

Acked-by: Kitware Robot <[email protected]>
Acked-by: buildbot <[email protected]>
Merge-request: !9030
Brad King 2 years ago
parent
commit
ef9cba9f42
36 changed files with 392 additions and 6 deletions
  1. 8 5
      Source/cmCxxModuleMapper.cxx
  2. 2 0
      Tests/RunCMake/CXXModules/RunCMakeTest.cmake
  3. 1 1
      Tests/RunCMake/CXXModules/examples/circular-build-stdout.txt
  4. 9 0
      Tests/RunCMake/CXXModules/examples/non-trivial-collation-order-randomized/CMakeLists.txt
  5. 132 0
      Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/CMakeLists.txt
  6. 6 0
      Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/main.cxx
  7. 7 0
      Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/module_level/mod1.cxx
  8. 7 0
      Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/module_level/mod2.cxx
  9. 7 0
      Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/module_level/mod3.cxx
  10. 7 0
      Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/module_level/mod4.cxx
  11. 7 0
      Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/module_level/mod5.cxx
  12. 7 0
      Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/module_level/mod6.cxx
  13. 7 0
      Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/module_level/mod7.cxx
  14. 10 0
      Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/impl-non-partition.cxx
  15. 7 0
      Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/impl1.cxx
  16. 8 0
      Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/impl2.cxx
  17. 8 0
      Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/impl3.cxx
  18. 8 0
      Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/impl4.cxx
  19. 8 0
      Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/impl5.cxx
  20. 8 0
      Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/impl6.cxx
  21. 8 0
      Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/impl7.cxx
  22. 8 0
      Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/intf1.cxx
  23. 8 0
      Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/intf2.cxx
  24. 8 0
      Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/intf3.cxx
  25. 8 0
      Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/intf4.cxx
  26. 8 0
      Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/intf5.cxx
  27. 8 0
      Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/intf6.cxx
  28. 8 0
      Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/intf7.cxx
  29. 15 0
      Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/partition_level.cxx
  30. 7 0
      Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/target_level/target1.cxx
  31. 7 0
      Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/target_level/target2.cxx
  32. 7 0
      Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/target_level/target3.cxx
  33. 7 0
      Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/target_level/target4.cxx
  34. 7 0
      Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/target_level/target5.cxx
  35. 7 0
      Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/target_level/target6.cxx
  36. 7 0
      Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/target_level/target7.cxx

+ 8 - 5
Source/cmCxxModuleMapper.cxx

@@ -346,13 +346,16 @@ std::set<std::string> CxxModuleUsageSeed(
         // Add the direct usage.
         this_usages.insert(r.LogicalName);
 
-        // Add the transitive usage.
-        if (transitive_usages != usages.Usage.end()) {
+        if (transitive_usages == usages.Usage.end() ||
+            internal_usages.find(r.LogicalName) != internal_usages.end()) {
+          // Mark that we need to update transitive usages later.
+          if (bmi_loc.IsKnown()) {
+            internal_usages[p.LogicalName].insert(r.LogicalName);
+          }
+        } else {
+          // Add the transitive usage.
           this_usages.insert(transitive_usages->second.begin(),
                              transitive_usages->second.end());
-        } else if (bmi_loc.IsKnown()) {
-          // Mark that we need to update transitive usages later.
-          internal_usages[p.LogicalName].insert(r.LogicalName);
         }
       }
 

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

@@ -174,6 +174,8 @@ if ("named" IN_LIST CMake_TEST_MODULE_COMPILATION)
   run_cxx_module_test(object-library)
   run_cxx_module_test(generated)
   run_cxx_module_test(deep-chain)
+  run_cxx_module_test(non-trivial-collation-order)
+  run_cxx_module_test(non-trivial-collation-order-randomized)
   run_cxx_module_test(duplicate)
   set(RunCMake_CXXModules_NO_TEST 1)
   run_cxx_module_test(circular)

+ 1 - 1
Tests/RunCMake/CXXModules/examples/circular-build-stdout.txt

@@ -1 +1 @@
-((Ninja generators)?(build stopped: dependency cycle:)|(Visual Studio generators)?(error : Cannot build the following source files because there is a cyclic dependency between them))
+((Ninja generators)?(CMake Error: Circular dependency detected in the C\+\+ module import graph. See modules named: "a", "b")|(Visual Studio generators)?(error : Cannot build the following source files because there is a cyclic dependency between them))

+ 9 - 0
Tests/RunCMake/CXXModules/examples/non-trivial-collation-order-randomized/CMakeLists.txt

@@ -0,0 +1,9 @@
+cmake_minimum_required(VERSION 3.24...3.28)
+project(cxx_modules_non_trivial_collation_order_randomized CXX)
+
+include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
+
+set(non_trivial_collation_order_randomized TRUE)
+
+add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/../non-trivial-collation-order/"
+                 "${CMAKE_CURRENT_BINARY_DIR}/non-trivial-collation-order")

+ 132 - 0
Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/CMakeLists.txt

@@ -0,0 +1,132 @@
+cmake_minimum_required(VERSION 3.24...3.28)
+project(cxx_modules_non_trivial_collation_order CXX)
+
+include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
+
+if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+  include(CheckCompilerFlag)
+  check_compiler_flag(CXX "-Wread-modules-implicitly" have_implicit_module_warning)
+  if (have_implicit_module_warning)
+    add_compile_options(-Werror=read-modules-implicitly)
+  endif ()
+endif ()
+
+# Returns an random integer from range [0,length)
+function(get_random_index result length)
+  # math(EXPR) parses and evaluates as 64-bit signed integer.
+  string(RANDOM LENGTH 18 ALPHABET "0123456789" value)
+  # Modulo is not uniformly distributed, but we doesn't need that here.
+  math(EXPR ${result} "${value} % ${length}")
+  return(PROPAGATE ${result})
+endfunction()
+
+# Shuffle list_var randomly
+function(shuffle_list list_var)
+  set(result)
+  set(length 0)
+  foreach(item IN LISTS "${list_var}")
+    math(EXPR length "${length} + 1")
+    get_random_index(index ${length})
+    list(INSERT result ${index} "${item}")
+  endforeach()
+  set("${list_var}" "${result}" PARENT_SCOPE)
+endfunction()
+
+# The import chain is:
+# impl-non-partition  --(implicitly)-->  partition_level(primary interface unit)
+# --> :intf7 --> :intf6 --> :intf5 --> :intf4 --> :intf3 --> :intf2 --> :intf1
+# --> :impl7 --> :impl6 --> :impl5 --> :impl4 --> :impl3 --> :impl2 --> :impl1
+set(partition_level_srcs
+  partition_level/partition_level.cxx
+  partition_level/intf1.cxx
+  partition_level/intf3.cxx
+  partition_level/intf4.cxx
+  partition_level/intf2.cxx   # intentional order
+  partition_level/intf5.cxx
+  partition_level/intf6.cxx
+  partition_level/intf7.cxx
+  partition_level/impl1.cxx
+  partition_level/impl3.cxx
+  partition_level/impl4.cxx
+  partition_level/impl2.cxx   # intentional order
+  partition_level/impl5.cxx
+  partition_level/impl6.cxx
+  partition_level/impl7.cxx
+)
+
+# The import chain is:
+# mod7 --> mod6 --> mod5 --> mod4 --> mod3 --> mod2 --> mod1 --> partition_level
+set(module_level_srcs
+  ${partition_level_srcs}
+  module_level/mod1.cxx
+  module_level/mod3.cxx
+  module_level/mod4.cxx
+  module_level/mod2.cxx   # intentional order
+  module_level/mod5.cxx
+  module_level/mod6.cxx
+  module_level/mod7.cxx
+)
+
+# The import chain is:
+# target7 --> target6 --> target5 --> target4 -->
+# target3 --> target2 --> target1 --> target_module_level
+set(targets
+  target_module_level
+  target1
+  target3
+  target4
+  target2 # intentional order
+  target5
+  target6
+  target7
+)
+
+if(non_trivial_collation_order_randomized)
+  shuffle_list(module_level_srcs)
+  shuffle_list(targets)
+endif()
+
+message(STATUS "module_level_srcs: ${module_level_srcs}")
+message(STATUS "targets: ${targets}")
+
+foreach(tgt IN LISTS targets)
+  if (tgt STREQUAL "target_module_level")
+
+    add_library(target_module_level STATIC)
+    target_sources(target_module_level
+      PUBLIC
+        FILE_SET CXX_MODULES
+          BASE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}"
+          FILES ${module_level_srcs}
+      PRIVATE
+        partition_level/impl-non-partition.cxx
+    )
+    target_compile_features(target_module_level PUBLIC cxx_std_20)
+
+  else()
+
+    add_library(${tgt} STATIC)
+    target_sources(${tgt}
+      PUBLIC
+        FILE_SET CXX_MODULES
+          BASE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}"
+          FILES target_level/${tgt}.cxx
+    )
+    target_compile_features(${tgt} PUBLIC cxx_std_20)
+    if (tgt MATCHES "^target([2-9])$")
+      math(EXPR dep_number "${CMAKE_MATCH_1} - 1")
+      target_link_libraries(${tgt} PRIVATE "target${dep_number}")
+    else()
+      target_link_libraries(${tgt} PRIVATE target_module_level)
+    endif()
+
+  endif()
+endforeach()
+
+add_executable(exe)
+target_link_libraries(exe PRIVATE target7)
+target_sources(exe
+  PRIVATE
+    main.cxx)
+
+add_test(NAME exe COMMAND exe)

+ 6 - 0
Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/main.cxx

@@ -0,0 +1,6 @@
+import target7;
+
+int main()
+{
+  return target7();
+}

+ 7 - 0
Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/module_level/mod1.cxx

@@ -0,0 +1,7 @@
+export module mod1;
+import partition_level;
+
+export int mod1()
+{
+  return partition_level::get();
+}

+ 7 - 0
Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/module_level/mod2.cxx

@@ -0,0 +1,7 @@
+export module mod2;
+import mod1;
+
+export int mod2()
+{
+  return mod1();
+}

+ 7 - 0
Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/module_level/mod3.cxx

@@ -0,0 +1,7 @@
+export module mod3;
+import mod2;
+
+export int mod3()
+{
+  return mod2();
+}

+ 7 - 0
Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/module_level/mod4.cxx

@@ -0,0 +1,7 @@
+export module mod4;
+import mod3;
+
+export int mod4()
+{
+  return mod3();
+}

+ 7 - 0
Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/module_level/mod5.cxx

@@ -0,0 +1,7 @@
+export module mod5;
+import mod4;
+
+export int mod5()
+{
+  return mod4();
+}

+ 7 - 0
Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/module_level/mod6.cxx

@@ -0,0 +1,7 @@
+export module mod6;
+import mod5;
+
+export int mod6()
+{
+  return mod5();
+}

+ 7 - 0
Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/module_level/mod7.cxx

@@ -0,0 +1,7 @@
+export module mod7;
+import mod6;
+
+export int mod7()
+{
+  return mod6();
+}

+ 10 - 0
Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/impl-non-partition.cxx

@@ -0,0 +1,10 @@
+module partition_level;
+
+namespace partition_level {
+int non_partition()
+{
+  return primary() + intf1() + intf2() + intf3() + intf4() + intf5() +
+    intf6() + intf7() + impl1() + impl2() + impl3() + impl4() + impl5() +
+    impl6() + impl7();
+}
+}

+ 7 - 0
Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/impl1.cxx

@@ -0,0 +1,7 @@
+module partition_level:impl1;
+namespace partition_level {
+int impl1()
+{
+  return 0;
+}
+}

+ 8 - 0
Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/impl2.cxx

@@ -0,0 +1,8 @@
+module partition_level:impl2;
+import :impl1;
+namespace partition_level {
+int impl2()
+{
+  return impl1();
+}
+}

+ 8 - 0
Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/impl3.cxx

@@ -0,0 +1,8 @@
+module partition_level:impl3;
+import :impl2;
+namespace partition_level {
+int impl3()
+{
+  return impl2();
+}
+}

+ 8 - 0
Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/impl4.cxx

@@ -0,0 +1,8 @@
+module partition_level:impl4;
+import :impl3;
+namespace partition_level {
+int impl4()
+{
+  return impl3();
+}
+}

+ 8 - 0
Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/impl5.cxx

@@ -0,0 +1,8 @@
+module partition_level:impl5;
+import :impl4;
+namespace partition_level {
+int impl5()
+{
+  return impl4();
+}
+}

+ 8 - 0
Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/impl6.cxx

@@ -0,0 +1,8 @@
+module partition_level:impl6;
+import :impl5;
+namespace partition_level {
+int impl6()
+{
+  return impl5();
+}
+}

+ 8 - 0
Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/impl7.cxx

@@ -0,0 +1,8 @@
+module partition_level:impl7;
+import :impl6;
+namespace partition_level {
+int impl7()
+{
+  return impl6();
+}
+}

+ 8 - 0
Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/intf1.cxx

@@ -0,0 +1,8 @@
+export module partition_level:intf1;
+import :impl7;
+namespace partition_level {
+int intf1()
+{
+  return impl7();
+}
+}

+ 8 - 0
Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/intf2.cxx

@@ -0,0 +1,8 @@
+export module partition_level:intf2;
+export import :intf1;
+namespace partition_level {
+int intf2()
+{
+  return intf1();
+}
+}

+ 8 - 0
Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/intf3.cxx

@@ -0,0 +1,8 @@
+export module partition_level:intf3;
+export import :intf2;
+namespace partition_level {
+int intf3()
+{
+  return intf2();
+}
+}

+ 8 - 0
Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/intf4.cxx

@@ -0,0 +1,8 @@
+export module partition_level:intf4;
+export import :intf3;
+namespace partition_level {
+int intf4()
+{
+  return intf3();
+}
+}

+ 8 - 0
Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/intf5.cxx

@@ -0,0 +1,8 @@
+export module partition_level:intf5;
+export import :intf4;
+namespace partition_level {
+int intf5()
+{
+  return intf4();
+}
+}

+ 8 - 0
Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/intf6.cxx

@@ -0,0 +1,8 @@
+export module partition_level:intf6;
+export import :intf5;
+namespace partition_level {
+int intf6()
+{
+  return intf5();
+}
+}

+ 8 - 0
Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/intf7.cxx

@@ -0,0 +1,8 @@
+export module partition_level:intf7;
+export import :intf6;
+namespace partition_level {
+int intf7()
+{
+  return intf6();
+}
+}

+ 15 - 0
Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/partition_level.cxx

@@ -0,0 +1,15 @@
+export module partition_level;
+export import :intf7;
+namespace partition_level {
+int primary()
+{
+  return intf7();
+}
+
+int non_partition();
+
+export int get()
+{
+  return non_partition();
+}
+}

+ 7 - 0
Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/target_level/target1.cxx

@@ -0,0 +1,7 @@
+export module target1;
+import mod7;
+
+export int target1()
+{
+  return mod7();
+}

+ 7 - 0
Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/target_level/target2.cxx

@@ -0,0 +1,7 @@
+export module target2;
+import target1;
+
+export int target2()
+{
+  return target1();
+}

+ 7 - 0
Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/target_level/target3.cxx

@@ -0,0 +1,7 @@
+export module target3;
+import target2;
+
+export int target3()
+{
+  return target2();
+}

+ 7 - 0
Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/target_level/target4.cxx

@@ -0,0 +1,7 @@
+export module target4;
+import target3;
+
+export int target4()
+{
+  return target3();
+}

+ 7 - 0
Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/target_level/target5.cxx

@@ -0,0 +1,7 @@
+export module target5;
+import target4;
+
+export int target5()
+{
+  return target4();
+}

+ 7 - 0
Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/target_level/target6.cxx

@@ -0,0 +1,7 @@
+export module target6;
+import target5;
+
+export int target6()
+{
+  return target5();
+}

+ 7 - 0
Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/target_level/target7.cxx

@@ -0,0 +1,7 @@
+export module target7;
+import target6;
+
+export int target7()
+{
+  return target6();
+}