28 lines
1.4 KiB
Diff
28 lines
1.4 KiB
Diff
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
|
|
index abc1234..def5678 100644
|
|
--- a/Source/cmTarget.cxx
|
|
+++ b/Source/cmTarget.cxx
|
|
@@ -1428,11 +1428,19 @@ cmSourceFile* cmTarget::AddSource(std::string const& src, bool before)
|
|
{
|
|
cmSourceFileLocation sfl(this->impl->Makefile, src,
|
|
cmSourceFileLocationKind::Known);
|
|
+ // Fast path: check a parallel unordered_set of source-path strings.
|
|
+ // The full TargetPropertyEntryFinder scan is O(n) and is called from loops
|
|
+ // (e.g. Unity build file iteration), producing O(n^2) overall.
|
|
+ // An exact-string set lookup is O(1) amortized and covers the common case
|
|
+ // where src is a canonical resolved path.
|
|
+ if (!this->impl->SourcePathsSet.insert(src).second) {
|
|
+ // Already present — skip the expensive find_if and WriteDirect.
|
|
+ if (cmGeneratorExpression::Find(src) != std::string::npos)
|
|
+ return nullptr;
|
|
+ return this->impl->Makefile->GetOrCreateSource(
|
|
+ src, false, cmSourceFileLocationKind::Known);
|
|
+ }
|
|
auto const& sources = this->impl->Sources.Entries;
|
|
if (std::find_if(sources.begin(), sources.end(),
|
|
TargetPropertyEntryFinder(sfl)) == sources.end()) {
|
|
this->impl->Sources.WriteDirect(
|
|
this->impl.get(), {}, cmValue(src),
|
|
before ? UsageRequirementProperty::Action::Prepend
|
|
: UsageRequirementProperty::Action::Append);
|
|
}
|