summaryrefslogtreecommitdiffstats
path: root/Source/cmMakefileTargetGenerator.cxx
diff options
context:
space:
mode:
authorBen Boeckel <ben.boeckel@kitware.com>2022-04-08 17:56:33 (GMT)
committerBen Boeckel <ben.boeckel@kitware.com>2022-06-16 14:28:34 (GMT)
commit386465bf8396dca8d00448b23734bc5edafb17c8 (patch)
tree08fe81417c136cfb716a53fa3db2fb91bdc83b4c /Source/cmMakefileTargetGenerator.cxx
parentff30a5397d804b9de564d54868bd5fdf504361c2 (diff)
downloadCMake-386465bf8396dca8d00448b23734bc5edafb17c8.zip
CMake-386465bf8396dca8d00448b23734bc5edafb17c8.tar.gz
CMake-386465bf8396dca8d00448b23734bc5edafb17c8.tar.bz2
cmTarget: add support for C++ module fileset types
C++ modules have two variants which are of importance to CMake: - `CXX_MODULES`: interface modules (those using `export module M;`, `export module M:part;`, or `module M:internal_part;`) - `CXX_MODULE_HEADER_UNITS`: importable header units Creating C++ modules or partitions are *not* supported in any other source listing. This is because the source files must be installed (so their scope matters), but not part of usage requirements (what it means for a module source to be injected into a consumer is not clear at this moment). Due to the way `FILE_SET` works with scopes, they are a perfect fit as long as `INTERFACE` is not allowed (which it is not).
Diffstat (limited to 'Source/cmMakefileTargetGenerator.cxx')
-rw-r--r--Source/cmMakefileTargetGenerator.cxx65
1 files changed, 65 insertions, 0 deletions
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index aec6577..b066c34 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -21,6 +21,7 @@
#include "cmComputeLinkInformation.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandGenerator.h"
+#include "cmFileSet.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
@@ -46,6 +47,7 @@
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+#include "cmTarget.h"
#include "cmValue.h"
#include "cmake.h"
@@ -190,6 +192,16 @@ void cmMakefileTargetGenerator::CreateRuleFile()
void cmMakefileTargetGenerator::WriteTargetBuildRules()
{
+ this->GeneratorTarget->CheckCxxModuleStatus(this->GetConfigName());
+
+ if (this->GeneratorTarget->HaveCxx20ModuleSources()) {
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("The \"", this->GeneratorTarget->GetName(),
+ "\" target contains C++ module sources which are not supported "
+ "by the generator"));
+ }
+
// -- Write the custom commands for this target
// Evaluates generator expressions and expands prop_value
@@ -302,6 +314,40 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
}
}
+ std::map<std::string, std::string> file_set_map;
+
+ auto const* tgt = this->GeneratorTarget->Target;
+ for (auto const& name : tgt->GetAllFileSetNames()) {
+ auto const* file_set = tgt->GetFileSet(name);
+ if (!file_set) {
+ this->Makefile->IssueMessage(
+ MessageType::INTERNAL_ERROR,
+ cmStrCat("Target \"", tgt->GetName(),
+ "\" is tracked to have file set \"", name,
+ "\", but it was not found."));
+ continue;
+ }
+
+ auto fileEntries = file_set->CompileFileEntries();
+ auto directoryEntries = file_set->CompileDirectoryEntries();
+ auto directories = file_set->EvaluateDirectoryEntries(
+ directoryEntries, this->LocalGenerator, this->GetConfigName(),
+ this->GeneratorTarget);
+
+ std::map<std::string, std::vector<std::string>> files;
+ for (auto const& entry : fileEntries) {
+ file_set->EvaluateFileEntry(directories, files, entry,
+ this->LocalGenerator, this->GetConfigName(),
+ this->GeneratorTarget);
+ }
+
+ for (auto const& it : files) {
+ for (auto const& filename : it.second) {
+ file_set_map[filename] = file_set->GetType();
+ }
+ }
+ }
+
std::vector<cmSourceFile const*> objectSources;
this->GeneratorTarget->GetObjectSources(objectSources,
this->GetConfigName());
@@ -314,6 +360,25 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
this->WriteObjectRuleFiles(*sf);
}
}
+
+ for (cmSourceFile const* sf : objectSources) {
+ auto const& path = sf->GetFullPath();
+ auto const it = file_set_map.find(path);
+ if (it != file_set_map.end()) {
+ auto const& file_set_type = it->second;
+ if (file_set_type == "CXX_MODULES"_s ||
+ file_set_type == "CXX_MODULE_HEADER_UNITS"_s) {
+ if (sf->GetLanguage() != "CXX"_s) {
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat(
+ "Target \"", tgt->GetName(), "\" contains the source\n ", path,
+ "\nin a file set of type \"", file_set_type,
+ R"(" but the source is not classified as a "CXX" source.)"));
+ }
+ }
+ }
+ }
}
void cmMakefileTargetGenerator::WriteCommonCodeRules()