cmGeneratorTarget: Integrate file sets into calculated sources

This commit is contained in:
Kyle Edwards
2021-07-13 12:02:58 -04:00
parent 2a78d47b16
commit 8a09723bff

View File

@@ -25,6 +25,7 @@
#include "cmAlgorithms.h"
#include "cmComputeLinkInformation.h"
#include "cmCustomCommandGenerator.h"
#include "cmFileSet.h"
#include "cmFileTimes.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
@@ -41,6 +42,7 @@
#include "cmSourceFile.h"
#include "cmSourceFileLocation.h"
#include "cmSourceFileLocationKind.h"
#include "cmSourceGroup.h"
#include "cmStandardLevelResolver.h"
#include "cmState.h"
#include "cmStringAlgorithms.h"
@@ -173,6 +175,65 @@ private:
BT<std::string> PropertyValue;
};
class TargetPropertyEntryFileSet
: public cmGeneratorTarget::TargetPropertyEntry
{
public:
TargetPropertyEntryFileSet(
std::vector<std::string> dirs, bool contextSensitiveDirs,
std::unique_ptr<cmCompiledGeneratorExpression> entryCge,
const cmFileSet* fileSet, cmLinkImplItem const& item = NoLinkImplItem)
: cmGeneratorTarget::TargetPropertyEntry(item)
, BaseDirs(std::move(dirs))
, ContextSensitiveDirs(contextSensitiveDirs)
, EntryCge(std::move(entryCge))
, FileSet(fileSet)
{
}
const std::string& Evaluate(cmLocalGenerator* lg, const std::string& config,
cmGeneratorTarget const* headTarget,
cmGeneratorExpressionDAGChecker* dagChecker,
std::string const& /*lang*/) const override
{
std::map<std::string, std::vector<std::string>> filesPerDir;
this->FileSet->EvaluateFileEntry(this->BaseDirs, filesPerDir,
this->EntryCge, lg, config, headTarget,
dagChecker);
std::vector<std::string> files;
for (auto const& it : filesPerDir) {
files.insert(files.end(), it.second.begin(), it.second.end());
}
static std::string filesStr;
filesStr = cmJoin(files, ";");
return filesStr;
}
cmListFileBacktrace GetBacktrace() const override
{
return this->EntryCge->GetBacktrace();
}
std::string const& GetInput() const override
{
return this->EntryCge->GetInput();
}
bool GetHadContextSensitiveCondition() const override
{
return this->ContextSensitiveDirs ||
this->EntryCge->GetHadContextSensitiveCondition();
}
private:
const std::vector<std::string> BaseDirs;
const bool ContextSensitiveDirs;
const std::unique_ptr<cmCompiledGeneratorExpression> EntryCge;
const cmFileSet* FileSet;
};
std::unique_ptr<
cmGeneratorTarget::
TargetPropertyEntry> static CreateTargetPropertyEntry(const BT<std::
@@ -1594,6 +1655,80 @@ void AddObjectEntries(cmGeneratorTarget const* headTarget,
}
}
void addFileSetEntry(cmGeneratorTarget const* headTarget,
std::string const& config,
cmGeneratorExpressionDAGChecker* dagChecker,
cmFileSet const* fileSet,
EvaluatedTargetPropertyEntries& entries)
{
auto dirCges = fileSet->CompileDirectoryEntries();
auto dirs = fileSet->EvaluateDirectoryEntries(
dirCges, headTarget->GetLocalGenerator(), config, headTarget, dagChecker);
bool contextSensitiveDirs = false;
for (auto const& dirCge : dirCges) {
if (dirCge->GetHadContextSensitiveCondition()) {
contextSensitiveDirs = true;
break;
}
}
cmake* cm = headTarget->GetLocalGenerator()->GetCMakeInstance();
for (auto& entryCge : fileSet->CompileFileEntries()) {
TargetPropertyEntryFileSet tpe(dirs, contextSensitiveDirs,
std::move(entryCge), fileSet);
entries.Entries.emplace_back(
EvaluateTargetPropertyEntry(headTarget, config, "", dagChecker, tpe));
for (auto const& file : entries.Entries.back().Values) {
auto* sf = headTarget->Makefile->GetOrCreateSource(file);
if (fileSet->GetType() == "HEADERS"_s) {
sf->SetProperty("HEADER_FILE_ONLY", "TRUE");
}
#ifndef CMAKE_BOOTSTRAP
std::string e;
std::string w;
auto path = sf->ResolveFullPath(&e, &w);
if (!w.empty()) {
cm->IssueMessage(MessageType::AUTHOR_WARNING, w,
headTarget->GetBacktrace());
}
if (path.empty()) {
if (!e.empty()) {
cm->IssueMessage(MessageType::FATAL_ERROR, e,
headTarget->GetBacktrace());
}
return;
}
bool found = false;
for (auto const& sg : headTarget->Makefile->GetSourceGroups()) {
if (sg.MatchesFiles(path)) {
found = true;
break;
}
}
if (!found) {
if (fileSet->GetType() == "HEADERS"_s) {
headTarget->Makefile->GetOrCreateSourceGroup("Header Files")
->AddGroupFile(path);
}
}
#endif
}
}
}
void AddFileSetEntries(cmGeneratorTarget const* headTarget,
std::string const& config,
cmGeneratorExpressionDAGChecker* dagChecker,
EvaluatedTargetPropertyEntries& entries)
{
for (auto const& entry : headTarget->Target->GetHeaderSetsEntries()) {
for (auto const& name : cmExpandedList(entry.Value)) {
auto const* headerSet = headTarget->Target->GetFileSet(name);
addFileSetEntry(headTarget, config, dagChecker, headerSet, entries);
}
}
}
bool processSources(cmGeneratorTarget const* tgt,
EvaluatedTargetPropertyEntries& entries,
std::vector<BT<std::string>>& srcs,
@@ -1731,10 +1866,18 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetSourceFilePaths(
uniqueSrcs, debugSources);
}
// Collect this target's file sets.
std::vector<std::string>::size_type numFilesBefore3 = files.size();
EvaluatedTargetPropertyEntries fileSetEntries;
AddFileSetEntries(this, config, &dagChecker, fileSetEntries);
bool contextDependentFileSets =
processSources(this, fileSetEntries, files, uniqueSrcs, debugSources);
// Determine if sources are context-dependent or not.
if (!contextDependentDirectSources &&
!(contextDependentInterfaceSources && numFilesBefore < files.size()) &&
!(contextDependentObjects && numFilesBefore2 < files.size())) {
!(contextDependentObjects && numFilesBefore2 < files.size()) &&
!(contextDependentFileSets && numFilesBefore3 < files.size())) {
this->SourcesAreContextDependent = Tribool::False;
} else {
this->SourcesAreContextDependent = Tribool::True;