From 5cfb8ae79065b900c23c0dafb9b7a90b66bdeca7 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Thu, 9 Jan 2025 16:23:16 +0100 Subject: Tests/CXXModules: add a test with duplicate sources See: #26549 --- Tests/RunCMake/CXXModules/RunCMakeTest.cmake | 1 + .../examples/duplicate-sources/CMakeLists.txt | 19 +++++++++++++++++++ .../examples/duplicate-sources/duplicate.cxx | 8 ++++++++ .../CXXModules/examples/duplicate-sources/main.cxx | 6 ++++++ 4 files changed, 34 insertions(+) create mode 100644 Tests/RunCMake/CXXModules/examples/duplicate-sources/CMakeLists.txt create mode 100644 Tests/RunCMake/CXXModules/examples/duplicate-sources/duplicate.cxx create mode 100644 Tests/RunCMake/CXXModules/examples/duplicate-sources/main.cxx diff --git a/Tests/RunCMake/CXXModules/RunCMakeTest.cmake b/Tests/RunCMake/CXXModules/RunCMakeTest.cmake index ceb990a..47475d3 100644 --- a/Tests/RunCMake/CXXModules/RunCMakeTest.cmake +++ b/Tests/RunCMake/CXXModules/RunCMakeTest.cmake @@ -321,6 +321,7 @@ endif () # Tests which require collation work. if ("collation" IN_LIST CMake_TEST_MODULE_COMPILATION) + run_cxx_module_test(duplicate-sources) run_cxx_module_test(public-req-private) set(RunCMake_CXXModules_NO_TEST 1) run_cxx_module_test(req-private-other-target) diff --git a/Tests/RunCMake/CXXModules/examples/duplicate-sources/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/duplicate-sources/CMakeLists.txt new file mode 100644 index 0000000..b46adaa --- /dev/null +++ b/Tests/RunCMake/CXXModules/examples/duplicate-sources/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 3.31) +project(cxx_modules_duplicate_sources CXX) + +include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake") + +add_executable(duplicate_sources) +target_sources(duplicate_sources + PRIVATE + main.cxx + PRIVATE + FILE_SET CXX_MODULES + BASE_DIRS + "${CMAKE_CURRENT_SOURCE_DIR}" + FILES + duplicate.cxx + duplicate.cxx) +target_compile_features(duplicate_sources PRIVATE cxx_std_20) + +add_test(NAME duplicate_sources COMMAND duplicate_sources) diff --git a/Tests/RunCMake/CXXModules/examples/duplicate-sources/duplicate.cxx b/Tests/RunCMake/CXXModules/examples/duplicate-sources/duplicate.cxx new file mode 100644 index 0000000..39d2178 --- /dev/null +++ b/Tests/RunCMake/CXXModules/examples/duplicate-sources/duplicate.cxx @@ -0,0 +1,8 @@ +module; + +export module duplicate; + +export int from_import() +{ + return 0; +} diff --git a/Tests/RunCMake/CXXModules/examples/duplicate-sources/main.cxx b/Tests/RunCMake/CXXModules/examples/duplicate-sources/main.cxx new file mode 100644 index 0000000..bce0322 --- /dev/null +++ b/Tests/RunCMake/CXXModules/examples/duplicate-sources/main.cxx @@ -0,0 +1,6 @@ +import duplicate; + +int main() +{ + return from_import(); +} -- cgit v0.12 From 3e15419bd459a4bdca5195fd3868f1dae2bef680 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Thu, 9 Jan 2025 16:23:46 +0100 Subject: target_sources: Restore toleration of duplicate CXX_MODULES sources In commit 9c0491a3e4 (cmDyndepCollation: write out scanned source information too, 2024-03-25) via !9708, the `sf_map` gained a new job of also being used to track non-file set sources which could import modules. This was implemented by removing processed `FILE_SET TYPE CXX_MODULES` sources from the map and working with the sources remaining. When a `FILE_SET TYPE CXX_MODULES` source appeared multiple times, this would then erroneously complain that it "was not scheduled for compilation". Use a set of source paths to track sources that have already been processed. If duplicates are found, trigger an author warning and skip the duplicate file. Fixes: #26549 --- Source/cmDyndepCollation.cxx | 13 +++++++++++++ .../CXXModules/examples/duplicate-sources-stderr.txt | 8 ++++++++ 2 files changed, 21 insertions(+) create mode 100644 Tests/RunCMake/CXXModules/examples/duplicate-sources-stderr.txt diff --git a/Source/cmDyndepCollation.cxx b/Source/cmDyndepCollation.cxx index 1c05f25..f42136f 100644 --- a/Source/cmDyndepCollation.cxx +++ b/Source/cmDyndepCollation.cxx @@ -127,11 +127,23 @@ TdiSourceInfo CollationInformationSources(cmGeneratorTarget const* gt, } } + // Detect duplicate sources. + std::set visited_sources; + for (auto const& files_per_dir : files_per_dirs) { for (auto const& file : files_per_dir.second) { auto const full_file = cmSystemTools::CollapseFullPath(file); auto lookup = sf_map.find(full_file); if (lookup == sf_map.end()) { + if (visited_sources.count(full_file)) { + // Duplicate source; raise an author warning. + gt->Makefile->IssueMessage( + MessageType::AUTHOR_WARNING, + cmStrCat( + "Target \"", tgt->GetName(), "\" has source file\n ", file, + "\nin a \"FILE_SET TYPE CXX_MODULES\" multiple times.")); + continue; + } gt->Makefile->IssueMessage( MessageType::FATAL_ERROR, cmStrCat("Target \"", tgt->GetName(), "\" has source file\n ", @@ -140,6 +152,7 @@ TdiSourceInfo CollationInformationSources(cmGeneratorTarget const* gt, "scheduled for compilation.")); continue; } + visited_sources.insert(full_file); auto const* sf = lookup->second.first; CompileType const ct = lookup->second.second; diff --git a/Tests/RunCMake/CXXModules/examples/duplicate-sources-stderr.txt b/Tests/RunCMake/CXXModules/examples/duplicate-sources-stderr.txt new file mode 100644 index 0000000..bf964dd --- /dev/null +++ b/Tests/RunCMake/CXXModules/examples/duplicate-sources-stderr.txt @@ -0,0 +1,8 @@ +CMake Warning \(dev\) in CMakeLists.txt: + Target "duplicate_sources" has source file + + [^ +]*/Tests/RunCMake/CXXModules/examples/duplicate-sources/duplicate.cxx + + in a "FILE_SET TYPE CXX_MODULES" multiple times. +This warning is for project developers. Use -Wno-dev to suppress it. -- cgit v0.12