summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Boeckel <ben.boeckel@kitware.com>2023-07-19 23:00:05 (GMT)
committerBen Boeckel <ben.boeckel@kitware.com>2023-07-31 15:59:47 (GMT)
commitb768d293c5c358dd734234cacab7c34e61c88c54 (patch)
treec509fe68fab1661f978acd7a07b0aa3132c0d20c
parent93993c7ad4f634451fb1c8f67f00d4d959d199ac (diff)
downloadCMake-b768d293c5c358dd734234cacab7c34e61c88c54.zip
CMake-b768d293c5c358dd734234cacab7c34e61c88c54.tar.gz
CMake-b768d293c5c358dd734234cacab7c34e61c88c54.tar.bz2
cmCoreTryCompile: use the source type context for source files
Also add a test to `RunCMake/CXXModules` to test `try_compile` with C++ modules. Fixes: #25097
-rw-r--r--Source/cmCoreTryCompile.cxx68
-rw-r--r--Source/cmCoreTryCompile.h14
-rw-r--r--Tests/RunCMake/CXXModules/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/CXXModules/examples/try-compile-stderr.txt4
-rw-r--r--Tests/RunCMake/CXXModules/examples/try-compile/CMakeLists.txt19
-rw-r--r--Tests/RunCMake/CXXModules/examples/try-compile/importable.cxx6
-rw-r--r--Tests/RunCMake/CXXModules/examples/try-compile/use_importable.cxx6
-rw-r--r--Tests/RunCMake/CXXModules/examples/try-run-stderr.txt4
-rw-r--r--Tests/RunCMake/CXXModules/examples/try-run/CMakeLists.txt23
-rw-r--r--Tests/RunCMake/CXXModules/examples/try-run/importable.cxx6
-rw-r--r--Tests/RunCMake/CXXModules/examples/try-run/main.cxx6
11 files changed, 137 insertions, 21 deletions
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index 57a9180..03c71bf 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -168,7 +168,8 @@ auto const TryCompileBaseArgParser =
auto const TryCompileBaseSourcesArgParser =
cmArgumentParser<Arguments>{ TryCompileBaseArgParser }
.Bind("SOURCES_TYPE"_s, &Arguments::SetSourceType)
- .Bind("SOURCES"_s, &Arguments::Sources)
+ .BindWithContext("SOURCES"_s, &Arguments::Sources,
+ &Arguments::SourceTypeContext)
.Bind("COMPILE_DEFINITIONS"_s, TryCompileCompileDefs,
ArgumentParser::ExpectAtLeast{ 0 })
.Bind("LINK_LIBRARIES"_s, &Arguments::LinkLibraries)
@@ -185,9 +186,12 @@ auto const TryCompileBaseSourcesArgParser =
auto const TryCompileBaseNewSourcesArgParser =
cmArgumentParser<Arguments>{ TryCompileBaseSourcesArgParser }
- .Bind("SOURCE_FROM_CONTENT"_s, &Arguments::SourceFromContent)
- .Bind("SOURCE_FROM_VAR"_s, &Arguments::SourceFromVar)
- .Bind("SOURCE_FROM_FILE"_s, &Arguments::SourceFromFile)
+ .BindWithContext("SOURCE_FROM_CONTENT"_s, &Arguments::SourceFromContent,
+ &Arguments::SourceTypeContext)
+ .BindWithContext("SOURCE_FROM_VAR"_s, &Arguments::SourceFromVar,
+ &Arguments::SourceTypeContext)
+ .BindWithContext("SOURCE_FROM_FILE"_s, &Arguments::SourceFromFile,
+ &Arguments::SourceTypeContext)
/* keep semicolon on own line */;
auto const TryCompileBaseProjectArgParser =
@@ -524,42 +528,45 @@ cm::optional<cmTryCompileResult> cmCoreTryCompile::TryCompileCode(
cmSystemTools::RemoveFile(ccFile);
// Choose sources.
- std::vector<std::string> sources;
+ std::vector<std::pair<std::string, Arguments::SourceType>> sources;
if (arguments.Sources) {
sources = std::move(*arguments.Sources);
} else if (arguments.SourceDirectoryOrFile) {
- sources.emplace_back(*arguments.SourceDirectoryOrFile);
+ sources.emplace_back(*arguments.SourceDirectoryOrFile,
+ Arguments::SourceType::Directory);
}
if (arguments.SourceFromContent) {
auto const k = arguments.SourceFromContent->size();
for (auto i = decltype(k){ 0 }; i < k; i += 2) {
- const auto& name = (*arguments.SourceFromContent)[i + 0];
- const auto& content = (*arguments.SourceFromContent)[i + 1];
+ const auto& name = (*arguments.SourceFromContent)[i + 0].first;
+ const auto& content = (*arguments.SourceFromContent)[i + 1].first;
auto out = this->WriteSource(name, content, "SOURCE_FROM_CONTENT");
if (out.empty()) {
return cm::nullopt;
}
- sources.emplace_back(std::move(out));
+ sources.emplace_back(std::move(out),
+ (*arguments.SourceFromContent)[i + 0].second);
}
}
if (arguments.SourceFromVar) {
auto const k = arguments.SourceFromVar->size();
for (auto i = decltype(k){ 0 }; i < k; i += 2) {
- const auto& name = (*arguments.SourceFromVar)[i + 0];
- const auto& var = (*arguments.SourceFromVar)[i + 1];
+ const auto& name = (*arguments.SourceFromVar)[i + 0].first;
+ const auto& var = (*arguments.SourceFromVar)[i + 1].first;
const auto& content = this->Makefile->GetDefinition(var);
auto out = this->WriteSource(name, content, "SOURCE_FROM_VAR");
if (out.empty()) {
return cm::nullopt;
}
- sources.emplace_back(std::move(out));
+ sources.emplace_back(std::move(out),
+ (*arguments.SourceFromVar)[i + 0].second);
}
}
if (arguments.SourceFromFile) {
auto const k = arguments.SourceFromFile->size();
for (auto i = decltype(k){ 0 }; i < k; i += 2) {
- const auto& dst = (*arguments.SourceFromFile)[i + 0];
- const auto& src = (*arguments.SourceFromFile)[i + 1];
+ const auto& dst = (*arguments.SourceFromFile)[i + 0].first;
+ const auto& src = (*arguments.SourceFromFile)[i + 1].first;
if (!cmSystemTools::GetFilenamePath(dst).empty()) {
const auto& msg =
@@ -577,7 +584,8 @@ cm::optional<cmTryCompileResult> cmCoreTryCompile::TryCompileCode(
return cm::nullopt;
}
- sources.emplace_back(std::move(dstPath));
+ sources.emplace_back(std::move(dstPath),
+ (*arguments.SourceFromFile)[i + 0].second);
}
}
// TODO: ensure sources is not empty
@@ -585,7 +593,8 @@ cm::optional<cmTryCompileResult> cmCoreTryCompile::TryCompileCode(
// Detect languages to enable.
cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator();
std::set<std::string> testLangs;
- for (std::string const& si : sources) {
+ for (auto const& source : sources) {
+ auto const& si = source.first;
std::string ext = cmSystemTools::GetFilenameLastExtension(si);
std::string lang = gg->GetLanguageFromExtension(ext.c_str());
if (!lang.empty()) {
@@ -885,7 +894,32 @@ cm::optional<cmTryCompileResult> cmCoreTryCompile::TryCompileCode(
fprintf(fout, "add_library(%s STATIC)\n", targetName.c_str());
}
fprintf(fout, "target_sources(%s PRIVATE\n", targetName.c_str());
- for (std::string const& si : sources) {
+ std::string file_set_name;
+ bool in_file_set = false;
+ for (auto const& source : sources) {
+ auto const& si = source.first;
+ switch (source.second) {
+ case Arguments::SourceType::Normal: {
+ if (in_file_set) {
+ fprintf(fout, " PRIVATE\n");
+ in_file_set = false;
+ }
+ } break;
+ case Arguments::SourceType::CxxModule: {
+ if (!in_file_set) {
+ file_set_name += 'a';
+ fprintf(fout,
+ " PRIVATE FILE_SET %s TYPE CXX_MODULES BASE_DIRS \"%s\" "
+ "FILES\n",
+ file_set_name.c_str(),
+ this->Makefile->GetCurrentSourceDirectory().c_str());
+ in_file_set = true;
+ }
+ } break;
+ case Arguments::SourceType::Directory:
+ /* Handled elsewhere. */
+ break;
+ }
fprintf(fout, " \"%s\"\n", si.c_str());
// Add dependencies on any non-temporary sources.
diff --git a/Source/cmCoreTryCompile.h b/Source/cmCoreTryCompile.h
index 7d5a4f8..3217a1b 100644
--- a/Source/cmCoreTryCompile.h
+++ b/Source/cmCoreTryCompile.h
@@ -6,6 +6,7 @@
#include <map>
#include <string>
+#include <utility>
#include <vector>
#include <cm/optional>
@@ -71,12 +72,17 @@ public:
cm::optional<std::string> SourceDirectoryOrFile;
cm::optional<std::string> ProjectName;
cm::optional<std::string> TargetName;
- cm::optional<ArgumentParser::NonEmpty<std::vector<std::string>>> Sources;
- cm::optional<ArgumentParser::NonEmpty<std::vector<std::string>>>
+ cm::optional<ArgumentParser::NonEmpty<
+ std::vector<std::pair<std::string, SourceType>>>>
+ Sources;
+ cm::optional<ArgumentParser::NonEmpty<
+ std::vector<std::pair<std::string, SourceType>>>>
SourceFromContent;
- cm::optional<ArgumentParser::NonEmpty<std::vector<std::string>>>
+ cm::optional<ArgumentParser::NonEmpty<
+ std::vector<std::pair<std::string, SourceType>>>>
SourceFromVar;
- cm::optional<ArgumentParser::NonEmpty<std::vector<std::string>>>
+ cm::optional<ArgumentParser::NonEmpty<
+ std::vector<std::pair<std::string, SourceType>>>>
SourceFromFile;
ArgumentParser::MaybeEmpty<std::vector<std::string>> CMakeFlags{
1, "CMAKE_FLAGS"
diff --git a/Tests/RunCMake/CXXModules/RunCMakeTest.cmake b/Tests/RunCMake/CXXModules/RunCMakeTest.cmake
index d324ec9..25670bd 100644
--- a/Tests/RunCMake/CXXModules/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CXXModules/RunCMakeTest.cmake
@@ -148,6 +148,8 @@ if ("named" IN_LIST CMake_TEST_MODULE_COMPILATION)
run_cxx_module_test(duplicate)
set(RunCMake_CXXModules_NO_TEST 1)
run_cxx_module_test(circular)
+ run_cxx_module_test(try-compile)
+ run_cxx_module_test(try-run)
unset(RunCMake_CXXModules_NO_TEST)
run_cxx_module_test(same-src-name)
run_cxx_module_test(scan_properties)
diff --git a/Tests/RunCMake/CXXModules/examples/try-compile-stderr.txt b/Tests/RunCMake/CXXModules/examples/try-compile-stderr.txt
new file mode 100644
index 0000000..571bb9c
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/try-compile-stderr.txt
@@ -0,0 +1,4 @@
+CMake Warning \(dev\) at CMakeLists.txt:[0-9]* \(try_compile\):
+ 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.
diff --git a/Tests/RunCMake/CXXModules/examples/try-compile/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/try-compile/CMakeLists.txt
new file mode 100644
index 0000000..dee61f1
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/try-compile/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 3.24)
+project(cxx_modules_try_compile CXX)
+
+include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
+
+set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")
+try_compile(can_use_modules
+ SOURCES_TYPE CXX_MODULE
+ SOURCES
+ "${CMAKE_CURRENT_LIST_DIR}/importable.cxx"
+ SOURCES_TYPE NORMAL
+ SOURCE_FROM_FILE
+ use_importable.cxx "${CMAKE_CURRENT_LIST_DIR}/use_importable.cxx"
+ CXX_STANDARD 20)
+
+if (NOT can_use_modules)
+ message(FATAL_ERROR
+ "`try_compile` could not compile sources using modules.")
+endif ()
diff --git a/Tests/RunCMake/CXXModules/examples/try-compile/importable.cxx b/Tests/RunCMake/CXXModules/examples/try-compile/importable.cxx
new file mode 100644
index 0000000..607680a
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/try-compile/importable.cxx
@@ -0,0 +1,6 @@
+export module importable;
+
+export int from_import()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/CXXModules/examples/try-compile/use_importable.cxx b/Tests/RunCMake/CXXModules/examples/try-compile/use_importable.cxx
new file mode 100644
index 0000000..8d6bab2
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/try-compile/use_importable.cxx
@@ -0,0 +1,6 @@
+import importable;
+
+int foo()
+{
+ return from_import();
+}
diff --git a/Tests/RunCMake/CXXModules/examples/try-run-stderr.txt b/Tests/RunCMake/CXXModules/examples/try-run-stderr.txt
new file mode 100644
index 0000000..508db55
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/try-run-stderr.txt
@@ -0,0 +1,4 @@
+CMake Warning \(dev\) at CMakeLists.txt:[0-9]* \(try_run\):
+ 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.
diff --git a/Tests/RunCMake/CXXModules/examples/try-run/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/try-run/CMakeLists.txt
new file mode 100644
index 0000000..fb03571
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/try-run/CMakeLists.txt
@@ -0,0 +1,23 @@
+cmake_minimum_required(VERSION 3.24)
+project(cxx_modules_try_run CXX)
+
+include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
+
+try_run(can_run_modules_result can_compile_modules
+ SOURCES_TYPE CXX_MODULE
+ SOURCES
+ "${CMAKE_CURRENT_LIST_DIR}/importable.cxx"
+ SOURCES_TYPE NORMAL
+ SOURCE_FROM_FILE
+ main.cxx "${CMAKE_CURRENT_LIST_DIR}/main.cxx"
+ CXX_STANDARD 20)
+
+if (NOT can_compile_modules)
+ message(FATAL_ERROR
+ "`try_run` could not compile sources using modules.")
+endif ()
+
+if (can_run_modules_result)
+ message(FATAL_ERROR
+ "`try_run` could not run sources using modules.")
+endif ()
diff --git a/Tests/RunCMake/CXXModules/examples/try-run/importable.cxx b/Tests/RunCMake/CXXModules/examples/try-run/importable.cxx
new file mode 100644
index 0000000..607680a
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/try-run/importable.cxx
@@ -0,0 +1,6 @@
+export module importable;
+
+export int from_import()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/CXXModules/examples/try-run/main.cxx b/Tests/RunCMake/CXXModules/examples/try-run/main.cxx
new file mode 100644
index 0000000..5c1bb42
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/try-run/main.cxx
@@ -0,0 +1,6 @@
+import importable;
+
+int main(int argc, char* argv[])
+{
+ return from_import() == 1;
+}