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
This commit is contained in:
parent
93993c7ad4
commit
b768d293c5
@ -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.
|
||||
|
@ -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"
|
||||
|
@ -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)
|
||||
|
@ -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.
|
@ -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 ()
|
@ -0,0 +1,6 @@
|
||||
export module importable;
|
||||
|
||||
export int from_import()
|
||||
{
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
import importable;
|
||||
|
||||
int foo()
|
||||
{
|
||||
return from_import();
|
||||
}
|
4
Tests/RunCMake/CXXModules/examples/try-run-stderr.txt
Normal file
4
Tests/RunCMake/CXXModules/examples/try-run-stderr.txt
Normal file
@ -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.
|
23
Tests/RunCMake/CXXModules/examples/try-run/CMakeLists.txt
Normal file
23
Tests/RunCMake/CXXModules/examples/try-run/CMakeLists.txt
Normal file
@ -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 ()
|
@ -0,0 +1,6 @@
|
||||
export module importable;
|
||||
|
||||
export int from_import()
|
||||
{
|
||||
return 0;
|
||||
}
|
6
Tests/RunCMake/CXXModules/examples/try-run/main.cxx
Normal file
6
Tests/RunCMake/CXXModules/examples/try-run/main.cxx
Normal file
@ -0,0 +1,6 @@
|
||||
import importable;
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
return from_import() == 1;
|
||||
}
|
Loading…
Reference in New Issue
Block a user