cmLocalGenerator: Migrate custom command output lookup from cmMakefile
Since commit 777ceaea94
(cmMakefile: Delay custom command creation,
2019-10-17, v3.17.0-rc1~352^2) we process custom command declarations at
generate time. Therefore we do not need to look up what source file
holds the custom command producing a given output until generate time.
This commit is contained in:
parent
26464da5d3
commit
0090a11a42
@ -2986,7 +2986,8 @@ void cmTargetTraceDependencies::FollowName(std::string const& name)
|
||||
auto i = this->NameMap.lower_bound(name);
|
||||
if (i == this->NameMap.end() || i->first != name) {
|
||||
// Check if we know how to generate this file.
|
||||
cmSourcesWithOutput sources = this->Makefile->GetSourcesWithOutput(name);
|
||||
cmSourcesWithOutput sources =
|
||||
this->LocalGenerator->GetSourcesWithOutput(name);
|
||||
// If we failed to find a target or source and we have a relative path, it
|
||||
// might be a valid source if made relative to the current binary
|
||||
// directory.
|
||||
@ -2996,7 +2997,7 @@ void cmTargetTraceDependencies::FollowName(std::string const& name)
|
||||
cmStrCat(this->Makefile->GetCurrentBinaryDirectory(), '/', name);
|
||||
fullname = cmSystemTools::CollapseFullPath(
|
||||
fullname, this->Makefile->GetHomeOutputDirectory());
|
||||
sources = this->Makefile->GetSourcesWithOutput(fullname);
|
||||
sources = this->LocalGenerator->GetSourcesWithOutput(fullname);
|
||||
}
|
||||
i = this->NameMap.emplace_hint(i, name, sources);
|
||||
}
|
||||
|
@ -763,9 +763,9 @@ bool cmGhsMultiTargetGenerator::VisitCustomCommand(
|
||||
/* set temporary mark; check if revisit*/
|
||||
if (temp.insert(si).second) {
|
||||
for (auto& di : si->GetCustomCommand()->GetDepends()) {
|
||||
cmSourceFile const* sf = this->GeneratorTarget->GetLocalGenerator()
|
||||
->GetMakefile()
|
||||
->GetSourceFileWithOutput(di);
|
||||
cmSourceFile const* sf =
|
||||
this->GeneratorTarget->GetLocalGenerator()->GetSourceFileWithOutput(
|
||||
di);
|
||||
/* if sf exists then visit */
|
||||
if (sf && this->VisitCustomCommand(temp, perm, order, sf)) {
|
||||
return true;
|
||||
|
@ -3918,10 +3918,35 @@ cmSourceFile* AddCustomCommand(
|
||||
cc->SetJobPool(job_pool);
|
||||
file->SetCustomCommand(std::move(cc));
|
||||
|
||||
mf->AddSourceOutputs(file, outputs, byproducts);
|
||||
lg.AddSourceOutputs(file, outputs, byproducts);
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
bool AnyOutputMatches(const std::string& name,
|
||||
const std::vector<std::string>& outputs)
|
||||
{
|
||||
for (std::string const& output : outputs) {
|
||||
std::string::size_type pos = output.rfind(name);
|
||||
// If the output matches exactly
|
||||
if (pos != std::string::npos && pos == output.size() - name.size() &&
|
||||
(pos == 0 || output[pos - 1] == '/')) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AnyTargetCommandOutputMatches(
|
||||
const std::string& name, const std::vector<cmCustomCommand>& commands)
|
||||
{
|
||||
for (cmCustomCommand const& command : commands) {
|
||||
if (AnyOutputMatches(name, command.GetByproducts())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
@ -3937,8 +3962,6 @@ void AddCustomCommandToTarget(cmLocalGenerator& lg,
|
||||
const std::string& job_pool,
|
||||
bool command_expand_lists, bool stdPipesUTF8)
|
||||
{
|
||||
cmMakefile* mf = lg.GetMakefile();
|
||||
|
||||
// Always create the byproduct sources and mark them generated.
|
||||
CreateGeneratedSources(lg, byproducts, origin, lfbt);
|
||||
|
||||
@ -3964,7 +3987,7 @@ void AddCustomCommandToTarget(cmLocalGenerator& lg,
|
||||
break;
|
||||
}
|
||||
|
||||
mf->AddTargetByproducts(target, byproducts);
|
||||
lg.AddTargetByproducts(target, byproducts);
|
||||
}
|
||||
|
||||
cmSourceFile* AddCustomCommandToOutput(
|
||||
@ -3996,7 +4019,7 @@ void AppendCustomCommandToOutput(cmLocalGenerator& lg,
|
||||
const cmCustomCommandLines& commandLines)
|
||||
{
|
||||
// Lookup an existing command.
|
||||
if (cmSourceFile* sf = lg.GetMakefile()->GetSourceFileWithOutput(output)) {
|
||||
if (cmSourceFile* sf = lg.GetSourceFileWithOutput(output)) {
|
||||
if (cmCustomCommand* cc = sf->GetCustomCommand()) {
|
||||
cc->AppendCommands(commandLines);
|
||||
cc->AppendDepends(depends);
|
||||
@ -4040,7 +4063,7 @@ void AddUtilityCommand(cmLocalGenerator& lg, const cmListFileBacktrace& lfbt,
|
||||
/*replace=*/false, escapeOldStyle, uses_terminal, command_expand_lists,
|
||||
/*depfile=*/"", job_pool, stdPipesUTF8);
|
||||
if (rule) {
|
||||
lg.GetMakefile()->AddTargetByproducts(target, byproducts);
|
||||
lg.AddTargetByproducts(target, byproducts);
|
||||
}
|
||||
|
||||
if (!force.NameCMP0049.empty()) {
|
||||
@ -4088,3 +4111,166 @@ std::vector<std::string> ComputeISPCExtraObjects(
|
||||
return computedObjects;
|
||||
}
|
||||
}
|
||||
|
||||
cmSourcesWithOutput cmLocalGenerator::GetSourcesWithOutput(
|
||||
const std::string& name) const
|
||||
{
|
||||
// Linear search? Also see GetSourceFileWithOutput for detail.
|
||||
if (!cmSystemTools::FileIsFullPath(name)) {
|
||||
cmSourcesWithOutput sources;
|
||||
sources.Target = this->LinearGetTargetWithOutput(name);
|
||||
sources.Source = this->LinearGetSourceFileWithOutput(
|
||||
name, cmSourceOutputKind::OutputOrByproduct, sources.SourceIsByproduct);
|
||||
return sources;
|
||||
}
|
||||
// Otherwise we use an efficient lookup map.
|
||||
auto o = this->OutputToSource.find(name);
|
||||
if (o != this->OutputToSource.end()) {
|
||||
return o->second.Sources;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
cmSourceFile* cmLocalGenerator::GetSourceFileWithOutput(
|
||||
const std::string& name, cmSourceOutputKind kind) const
|
||||
{
|
||||
// If the queried path is not absolute we use the backward compatible
|
||||
// linear-time search for an output with a matching suffix.
|
||||
if (!cmSystemTools::FileIsFullPath(name)) {
|
||||
bool byproduct = false;
|
||||
return this->LinearGetSourceFileWithOutput(name, kind, byproduct);
|
||||
}
|
||||
// Otherwise we use an efficient lookup map.
|
||||
auto o = this->OutputToSource.find(name);
|
||||
if (o != this->OutputToSource.end() &&
|
||||
(!o->second.Sources.SourceIsByproduct ||
|
||||
kind == cmSourceOutputKind::OutputOrByproduct)) {
|
||||
// Source file could also be null pointer for example if we found the
|
||||
// byproduct of a utility target, a PRE_BUILD, PRE_LINK, or POST_BUILD
|
||||
// command of a target, or a not yet created custom command.
|
||||
return o->second.Sources.Source;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void cmLocalGenerator::AddTargetByproducts(
|
||||
cmTarget* target, const std::vector<std::string>& byproducts)
|
||||
{
|
||||
for (std::string const& o : byproducts) {
|
||||
this->UpdateOutputToSourceMap(o, target);
|
||||
}
|
||||
}
|
||||
|
||||
void cmLocalGenerator::AddSourceOutputs(
|
||||
cmSourceFile* source, const std::vector<std::string>& outputs,
|
||||
const std::vector<std::string>& byproducts)
|
||||
{
|
||||
for (std::string const& o : outputs) {
|
||||
this->UpdateOutputToSourceMap(o, source, false);
|
||||
}
|
||||
for (std::string const& o : byproducts) {
|
||||
this->UpdateOutputToSourceMap(o, source, true);
|
||||
}
|
||||
}
|
||||
|
||||
void cmLocalGenerator::UpdateOutputToSourceMap(std::string const& byproduct,
|
||||
cmTarget* target)
|
||||
{
|
||||
SourceEntry entry;
|
||||
entry.Sources.Target = target;
|
||||
|
||||
auto pr = this->OutputToSource.emplace(byproduct, entry);
|
||||
if (!pr.second) {
|
||||
SourceEntry& current = pr.first->second;
|
||||
// Has the target already been set?
|
||||
if (!current.Sources.Target) {
|
||||
current.Sources.Target = target;
|
||||
} else {
|
||||
// Multiple custom commands/targets produce the same output (source file
|
||||
// or target). See also comment in other UpdateOutputToSourceMap
|
||||
// overload.
|
||||
//
|
||||
// TODO: Warn the user about this case.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cmLocalGenerator::UpdateOutputToSourceMap(std::string const& output,
|
||||
cmSourceFile* source,
|
||||
bool byproduct)
|
||||
{
|
||||
SourceEntry entry;
|
||||
entry.Sources.Source = source;
|
||||
entry.Sources.SourceIsByproduct = byproduct;
|
||||
|
||||
auto pr = this->OutputToSource.emplace(output, entry);
|
||||
if (!pr.second) {
|
||||
SourceEntry& current = pr.first->second;
|
||||
// Outputs take precedence over byproducts
|
||||
if (!current.Sources.Source ||
|
||||
(current.Sources.SourceIsByproduct && !byproduct)) {
|
||||
current.Sources.Source = source;
|
||||
current.Sources.SourceIsByproduct = false;
|
||||
} else {
|
||||
// Multiple custom commands produce the same output but may
|
||||
// be attached to a different source file (MAIN_DEPENDENCY).
|
||||
// LinearGetSourceFileWithOutput would return the first one,
|
||||
// so keep the mapping for the first one.
|
||||
//
|
||||
// TODO: Warn the user about this case. However, the VS 8 generator
|
||||
// triggers it for separate generate.stamp rules in ZERO_CHECK and
|
||||
// individual targets.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cmTarget* cmLocalGenerator::LinearGetTargetWithOutput(
|
||||
const std::string& name) const
|
||||
{
|
||||
// We go through the ordered vector of targets to get reproducible results
|
||||
// should multiple names match.
|
||||
for (cmTarget* t : this->Makefile->GetOrderedTargets()) {
|
||||
// Does the output of any command match the source file name?
|
||||
if (AnyTargetCommandOutputMatches(name, t->GetPreBuildCommands())) {
|
||||
return t;
|
||||
}
|
||||
if (AnyTargetCommandOutputMatches(name, t->GetPreLinkCommands())) {
|
||||
return t;
|
||||
}
|
||||
if (AnyTargetCommandOutputMatches(name, t->GetPostBuildCommands())) {
|
||||
return t;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
cmSourceFile* cmLocalGenerator::LinearGetSourceFileWithOutput(
|
||||
const std::string& name, cmSourceOutputKind kind, bool& byproduct) const
|
||||
{
|
||||
// Outputs take precedence over byproducts.
|
||||
byproduct = false;
|
||||
cmSourceFile* fallback = nullptr;
|
||||
|
||||
// Look through all the source files that have custom commands and see if the
|
||||
// custom command has the passed source file as an output.
|
||||
for (const auto& src : this->Makefile->GetSourceFiles()) {
|
||||
// Does this source file have a custom command?
|
||||
if (src->GetCustomCommand()) {
|
||||
// Does the output of the custom command match the source file name?
|
||||
if (AnyOutputMatches(name, src->GetCustomCommand()->GetOutputs())) {
|
||||
// Return the first matching output.
|
||||
return src.get();
|
||||
}
|
||||
if (kind == cmSourceOutputKind::OutputOrByproduct) {
|
||||
if (AnyOutputMatches(name, src->GetCustomCommand()->GetByproducts())) {
|
||||
// Do not return the source yet as there might be a matching output.
|
||||
fallback = src.get();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Did we find a byproduct?
|
||||
byproduct = fallback != nullptr;
|
||||
return fallback;
|
||||
}
|
||||
|
@ -36,6 +36,24 @@ class cmState;
|
||||
class cmTarget;
|
||||
class cmake;
|
||||
|
||||
/** Flag if byproducts shall also be considered. */
|
||||
enum class cmSourceOutputKind
|
||||
{
|
||||
OutputOnly,
|
||||
OutputOrByproduct
|
||||
};
|
||||
|
||||
/** Target and source file which have a specific output. */
|
||||
struct cmSourcesWithOutput
|
||||
{
|
||||
/** Target with byproduct. */
|
||||
cmTarget* Target = nullptr;
|
||||
|
||||
/** Source file with output or byproduct. */
|
||||
cmSourceFile* Source = nullptr;
|
||||
bool SourceIsByproduct = false;
|
||||
};
|
||||
|
||||
/** \class cmLocalGenerator
|
||||
* \brief Create required build files for a directory.
|
||||
*
|
||||
@ -337,6 +355,34 @@ public:
|
||||
bool command_expand_lists = false, const std::string& job_pool = "",
|
||||
bool stdPipesUTF8 = false);
|
||||
|
||||
/**
|
||||
* Add target byproducts.
|
||||
*/
|
||||
void AddTargetByproducts(cmTarget* target,
|
||||
const std::vector<std::string>& byproducts);
|
||||
|
||||
/**
|
||||
* Add source file outputs.
|
||||
*/
|
||||
void AddSourceOutputs(cmSourceFile* source,
|
||||
const std::vector<std::string>& outputs,
|
||||
const std::vector<std::string>& byproducts);
|
||||
|
||||
/**
|
||||
* Return the target if the provided source name is a byproduct of a utility
|
||||
* target or a PRE_BUILD, PRE_LINK, or POST_BUILD command.
|
||||
* Return the source file which has the provided source name as output.
|
||||
*/
|
||||
cmSourcesWithOutput GetSourcesWithOutput(const std::string& name) const;
|
||||
|
||||
/**
|
||||
* Is there a source file that has the provided source name as an output?
|
||||
* If so then return it.
|
||||
*/
|
||||
cmSourceFile* GetSourceFileWithOutput(
|
||||
const std::string& name,
|
||||
cmSourceOutputKind kind = cmSourceOutputKind::OutputOnly) const;
|
||||
|
||||
std::string GetProjectName() const;
|
||||
|
||||
/** Compute the language used to compile the given source file. */
|
||||
@ -532,6 +578,33 @@ protected:
|
||||
bool BackwardsCompatibilityFinal;
|
||||
|
||||
private:
|
||||
/**
|
||||
* See LinearGetSourceFileWithOutput for background information
|
||||
*/
|
||||
cmTarget* LinearGetTargetWithOutput(const std::string& name) const;
|
||||
|
||||
/**
|
||||
* Generalized old version of GetSourceFileWithOutput kept for
|
||||
* backward-compatibility. It implements a linear search and supports
|
||||
* relative file paths. It is used as a fall back by GetSourceFileWithOutput
|
||||
* and GetSourcesWithOutput.
|
||||
*/
|
||||
cmSourceFile* LinearGetSourceFileWithOutput(const std::string& name,
|
||||
cmSourceOutputKind kind,
|
||||
bool& byproduct) const;
|
||||
struct SourceEntry
|
||||
{
|
||||
cmSourcesWithOutput Sources;
|
||||
};
|
||||
|
||||
// A map for fast output to input look up.
|
||||
using OutputToSourceMap = std::unordered_map<std::string, SourceEntry>;
|
||||
OutputToSourceMap OutputToSource;
|
||||
|
||||
void UpdateOutputToSourceMap(std::string const& byproduct, cmTarget* target);
|
||||
void UpdateOutputToSourceMap(std::string const& output, cmSourceFile* source,
|
||||
bool byproduct);
|
||||
|
||||
void AddSharedFlags(std::string& flags, const std::string& lang,
|
||||
bool shared);
|
||||
bool GetShouldUseOldFlags(bool shared, const std::string& lang) const;
|
||||
|
@ -2145,191 +2145,6 @@ cmTarget* cmMakefile::AddNewUtilityTarget(const std::string& utilityName,
|
||||
}
|
||||
|
||||
namespace {
|
||||
bool AnyOutputMatches(const std::string& name,
|
||||
const std::vector<std::string>& outputs)
|
||||
{
|
||||
for (std::string const& output : outputs) {
|
||||
std::string::size_type pos = output.rfind(name);
|
||||
// If the output matches exactly
|
||||
if (pos != std::string::npos && pos == output.size() - name.size() &&
|
||||
(pos == 0 || output[pos - 1] == '/')) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AnyTargetCommandOutputMatches(
|
||||
const std::string& name, const std::vector<cmCustomCommand>& commands)
|
||||
{
|
||||
for (cmCustomCommand const& command : commands) {
|
||||
if (AnyOutputMatches(name, command.GetByproducts())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
cmTarget* cmMakefile::LinearGetTargetWithOutput(const std::string& name) const
|
||||
{
|
||||
// We go through the ordered vector of targets to get reproducible results
|
||||
// should multiple names match.
|
||||
for (cmTarget* t : this->OrderedTargets) {
|
||||
// Does the output of any command match the source file name?
|
||||
if (AnyTargetCommandOutputMatches(name, t->GetPreBuildCommands())) {
|
||||
return t;
|
||||
}
|
||||
if (AnyTargetCommandOutputMatches(name, t->GetPreLinkCommands())) {
|
||||
return t;
|
||||
}
|
||||
if (AnyTargetCommandOutputMatches(name, t->GetPostBuildCommands())) {
|
||||
return t;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
cmSourceFile* cmMakefile::LinearGetSourceFileWithOutput(
|
||||
const std::string& name, cmSourceOutputKind kind, bool& byproduct) const
|
||||
{
|
||||
// Outputs take precedence over byproducts.
|
||||
byproduct = false;
|
||||
cmSourceFile* fallback = nullptr;
|
||||
|
||||
// Look through all the source files that have custom commands and see if the
|
||||
// custom command has the passed source file as an output.
|
||||
for (const auto& src : this->SourceFiles) {
|
||||
// Does this source file have a custom command?
|
||||
if (src->GetCustomCommand()) {
|
||||
// Does the output of the custom command match the source file name?
|
||||
if (AnyOutputMatches(name, src->GetCustomCommand()->GetOutputs())) {
|
||||
// Return the first matching output.
|
||||
return src.get();
|
||||
}
|
||||
if (kind == cmSourceOutputKind::OutputOrByproduct) {
|
||||
if (AnyOutputMatches(name, src->GetCustomCommand()->GetByproducts())) {
|
||||
// Do not return the source yet as there might be a matching output.
|
||||
fallback = src.get();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Did we find a byproduct?
|
||||
byproduct = fallback != nullptr;
|
||||
return fallback;
|
||||
}
|
||||
|
||||
cmSourcesWithOutput cmMakefile::GetSourcesWithOutput(
|
||||
const std::string& name) const
|
||||
{
|
||||
// Linear search? Also see GetSourceFileWithOutput for detail.
|
||||
if (!cmSystemTools::FileIsFullPath(name)) {
|
||||
cmSourcesWithOutput sources;
|
||||
sources.Target = this->LinearGetTargetWithOutput(name);
|
||||
sources.Source = this->LinearGetSourceFileWithOutput(
|
||||
name, cmSourceOutputKind::OutputOrByproduct, sources.SourceIsByproduct);
|
||||
return sources;
|
||||
}
|
||||
// Otherwise we use an efficient lookup map.
|
||||
auto o = this->OutputToSource.find(name);
|
||||
if (o != this->OutputToSource.end()) {
|
||||
return o->second.Sources;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
cmSourceFile* cmMakefile::GetSourceFileWithOutput(
|
||||
const std::string& name, cmSourceOutputKind kind) const
|
||||
{
|
||||
// If the queried path is not absolute we use the backward compatible
|
||||
// linear-time search for an output with a matching suffix.
|
||||
if (!cmSystemTools::FileIsFullPath(name)) {
|
||||
bool byproduct = false;
|
||||
return this->LinearGetSourceFileWithOutput(name, kind, byproduct);
|
||||
}
|
||||
// Otherwise we use an efficient lookup map.
|
||||
auto o = this->OutputToSource.find(name);
|
||||
if (o != this->OutputToSource.end() &&
|
||||
(!o->second.Sources.SourceIsByproduct ||
|
||||
kind == cmSourceOutputKind::OutputOrByproduct)) {
|
||||
// Source file could also be null pointer for example if we found the
|
||||
// byproduct of a utility target, a PRE_BUILD, PRE_LINK, or POST_BUILD
|
||||
// command of a target, or a not yet created custom command.
|
||||
return o->second.Sources.Source;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void cmMakefile::AddTargetByproducts(
|
||||
cmTarget* target, const std::vector<std::string>& byproducts)
|
||||
{
|
||||
for (std::string const& o : byproducts) {
|
||||
this->UpdateOutputToSourceMap(o, target);
|
||||
}
|
||||
}
|
||||
|
||||
void cmMakefile::AddSourceOutputs(cmSourceFile* source,
|
||||
const std::vector<std::string>& outputs,
|
||||
const std::vector<std::string>& byproducts)
|
||||
{
|
||||
for (std::string const& o : outputs) {
|
||||
this->UpdateOutputToSourceMap(o, source, false);
|
||||
}
|
||||
for (std::string const& o : byproducts) {
|
||||
this->UpdateOutputToSourceMap(o, source, true);
|
||||
}
|
||||
}
|
||||
|
||||
void cmMakefile::UpdateOutputToSourceMap(std::string const& byproduct,
|
||||
cmTarget* target)
|
||||
{
|
||||
SourceEntry entry;
|
||||
entry.Sources.Target = target;
|
||||
|
||||
auto pr = this->OutputToSource.emplace(byproduct, entry);
|
||||
if (!pr.second) {
|
||||
SourceEntry& current = pr.first->second;
|
||||
// Has the target already been set?
|
||||
if (!current.Sources.Target) {
|
||||
current.Sources.Target = target;
|
||||
} else {
|
||||
// Multiple custom commands/targets produce the same output (source file
|
||||
// or target). See also comment in other UpdateOutputToSourceMap
|
||||
// overload.
|
||||
//
|
||||
// TODO: Warn the user about this case.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cmMakefile::UpdateOutputToSourceMap(std::string const& output,
|
||||
cmSourceFile* source, bool byproduct)
|
||||
{
|
||||
SourceEntry entry;
|
||||
entry.Sources.Source = source;
|
||||
entry.Sources.SourceIsByproduct = byproduct;
|
||||
|
||||
auto pr = this->OutputToSource.emplace(output, entry);
|
||||
if (!pr.second) {
|
||||
SourceEntry& current = pr.first->second;
|
||||
// Outputs take precedence over byproducts
|
||||
if (!current.Sources.Source ||
|
||||
(current.Sources.SourceIsByproduct && !byproduct)) {
|
||||
current.Sources.Source = source;
|
||||
current.Sources.SourceIsByproduct = false;
|
||||
} else {
|
||||
// Multiple custom commands produce the same output but may
|
||||
// be attached to a different source file (MAIN_DEPENDENCY).
|
||||
// LinearGetSourceFileWithOutput would return the first one,
|
||||
// so keep the mapping for the first one.
|
||||
//
|
||||
// TODO: Warn the user about this case. However, the VS 8 generator
|
||||
// triggers it for separate generate.stamp rules in ZERO_CHECK and
|
||||
// individual targets.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(CMAKE_BOOTSTRAP)
|
||||
|
@ -59,24 +59,6 @@ class cmTestGenerator;
|
||||
class cmVariableWatch;
|
||||
class cmake;
|
||||
|
||||
/** Flag if byproducts shall also be considered. */
|
||||
enum class cmSourceOutputKind
|
||||
{
|
||||
OutputOnly,
|
||||
OutputOrByproduct
|
||||
};
|
||||
|
||||
/** Target and source file which have a specific output. */
|
||||
struct cmSourcesWithOutput
|
||||
{
|
||||
/** Target with byproduct. */
|
||||
cmTarget* Target = nullptr;
|
||||
|
||||
/** Source file with output or byproduct. */
|
||||
cmSourceFile* Source = nullptr;
|
||||
bool SourceIsByproduct = false;
|
||||
};
|
||||
|
||||
/** A type-safe wrapper for a string representing a directory id. */
|
||||
class cmDirectoryId
|
||||
{
|
||||
@ -230,19 +212,6 @@ public:
|
||||
const cmImplicitDependsList& implicit_depends,
|
||||
const cmCustomCommandLines& commandLines);
|
||||
|
||||
/**
|
||||
* Add target byproducts.
|
||||
*/
|
||||
void AddTargetByproducts(cmTarget* target,
|
||||
const std::vector<std::string>& byproducts);
|
||||
|
||||
/**
|
||||
* Add source file outputs.
|
||||
*/
|
||||
void AddSourceOutputs(cmSourceFile* source,
|
||||
const std::vector<std::string>& outputs,
|
||||
const std::vector<std::string>& byproducts);
|
||||
|
||||
/**
|
||||
* Add a define flag to the build.
|
||||
*/
|
||||
@ -753,20 +722,10 @@ public:
|
||||
return this->SourceFiles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the target if the provided source name is a byproduct of a utility
|
||||
* target or a PRE_BUILD, PRE_LINK, or POST_BUILD command.
|
||||
* Return the source file which has the provided source name as output.
|
||||
*/
|
||||
cmSourcesWithOutput GetSourcesWithOutput(const std::string& name) const;
|
||||
|
||||
/**
|
||||
* Is there a source file that has the provided source name as an output?
|
||||
* If so then return it.
|
||||
*/
|
||||
cmSourceFile* GetSourceFileWithOutput(
|
||||
const std::string& name,
|
||||
cmSourceOutputKind kind = cmSourceOutputKind::OutputOnly) const;
|
||||
std::vector<cmTarget*> const& GetOrderedTargets() const
|
||||
{
|
||||
return this->OrderedTargets;
|
||||
}
|
||||
|
||||
//! Add a new cmTest to the list of tests for this makefile.
|
||||
cmTest* CreateTest(const std::string& testName);
|
||||
@ -983,8 +942,7 @@ protected:
|
||||
mutable cmTargetMap Targets;
|
||||
std::map<std::string, std::string> AliasTargets;
|
||||
|
||||
using TargetsVec = std::vector<cmTarget*>;
|
||||
TargetsVec OrderedTargets;
|
||||
std::vector<cmTarget*> OrderedTargets;
|
||||
|
||||
std::vector<std::unique_ptr<cmSourceFile>> SourceFiles;
|
||||
|
||||
@ -1134,34 +1092,6 @@ private:
|
||||
std::vector<BT<GeneratorAction>> GeneratorActions;
|
||||
bool GeneratorActionsInvoked = false;
|
||||
|
||||
/**
|
||||
* See LinearGetSourceFileWithOutput for background information
|
||||
*/
|
||||
cmTarget* LinearGetTargetWithOutput(const std::string& name) const;
|
||||
|
||||
/**
|
||||
* Generalized old version of GetSourceFileWithOutput kept for
|
||||
* backward-compatibility. It implements a linear search and supports
|
||||
* relative file paths. It is used as a fall back by GetSourceFileWithOutput
|
||||
* and GetSourcesWithOutput.
|
||||
*/
|
||||
cmSourceFile* LinearGetSourceFileWithOutput(const std::string& name,
|
||||
cmSourceOutputKind kind,
|
||||
bool& byproduct) const;
|
||||
|
||||
struct SourceEntry
|
||||
{
|
||||
cmSourcesWithOutput Sources;
|
||||
};
|
||||
|
||||
// A map for fast output to input look up.
|
||||
using OutputToSourceMap = std::unordered_map<std::string, SourceEntry>;
|
||||
OutputToSourceMap OutputToSource;
|
||||
|
||||
void UpdateOutputToSourceMap(std::string const& byproduct, cmTarget* target);
|
||||
void UpdateOutputToSourceMap(std::string const& output, cmSourceFile* source,
|
||||
bool byproduct);
|
||||
|
||||
bool CheckSystemVars;
|
||||
bool CheckCMP0000;
|
||||
std::set<std::string> WarnedCMP0074;
|
||||
|
Loading…
Reference in New Issue
Block a user