| Index: tools/gn/scope.cc
|
| diff --git a/tools/gn/scope.cc b/tools/gn/scope.cc
|
| index 93ce966e4f3e8abfcb0bc20ce9e7a374ed56f9a5..821b940b435be53843fe91f1d58f88a6a4d0b280 100644
|
| --- a/tools/gn/scope.cc
|
| +++ b/tools/gn/scope.cc
|
| @@ -298,18 +298,27 @@ bool Scope::NonRecursiveMergeTo(Scope* dest,
|
| }
|
|
|
| if (!options.clobber_existing) {
|
| - if (dest->GetTargetDefaults(current_name)) {
|
| - // TODO(brettw) it would be nice to know the origin of a
|
| - // set_target_defaults so we can give locations for the colliding target
|
| - // defaults.
|
| - std::string desc_string(desc_for_err);
|
| - *err = Err(node_for_err, "Target defaults collision.",
|
| - "This " + desc_string + " contains target defaults for\n"
|
| - "\"" + current_name + "\" which would clobber one for the\n"
|
| - "same target type in your current scope. It's unfortunate that I'm "
|
| - "too stupid\nto tell you the location of where the target defaults "
|
| - "were set. Usually\nthis happens in the BUILDCONFIG.gn file.");
|
| - return false;
|
| + const Scope* dest_defaults = dest->GetTargetDefaults(current_name);
|
| + if (dest_defaults) {
|
| + if (RecordMapValuesEqual(pair.second->values_,
|
| + dest_defaults->values_)) {
|
| + // Values of the two defaults are equivalent, just ignore the
|
| + // collision.
|
| + continue;
|
| + } else {
|
| + // TODO(brettw) it would be nice to know the origin of a
|
| + // set_target_defaults so we can give locations for the colliding
|
| + // target defaults.
|
| + std::string desc_string(desc_for_err);
|
| + *err = Err(node_for_err, "Target defaults collision.",
|
| + "This " + desc_string + " contains target defaults for\n"
|
| + "\"" + current_name + "\" which would clobber one for the\n"
|
| + "same target type in your current scope. It's unfortunate that "
|
| + "I'm too stupid\nto tell you the location of where the target "
|
| + "defaults were set. Usually\nthis happens in the BUILDCONFIG.gn "
|
| + "file or in a related .gni file.\n");
|
| + return false;
|
| + }
|
| }
|
| }
|
|
|
| @@ -404,14 +413,7 @@ std::unique_ptr<Scope> Scope::MakeClosure() const {
|
| }
|
|
|
| Scope* Scope::MakeTargetDefaults(const std::string& target_type) {
|
| - if (GetTargetDefaults(target_type))
|
| - return nullptr;
|
| -
|
| std::unique_ptr<Scope>& dest = target_defaults_[target_type];
|
| - if (dest) {
|
| - NOTREACHED(); // Already set.
|
| - return dest.get();
|
| - }
|
| dest = base::WrapUnique(new Scope(settings_));
|
| return dest.get();
|
| }
|
| @@ -514,3 +516,17 @@ void Scope::RemoveProvider(ProgrammaticProvider* p) {
|
| DCHECK(programmatic_providers_.find(p) != programmatic_providers_.end());
|
| programmatic_providers_.erase(p);
|
| }
|
| +
|
| +// static
|
| +bool Scope::RecordMapValuesEqual(const RecordMap& a, const RecordMap& b) {
|
| + if (a.size() != b.size())
|
| + return false;
|
| + for (const auto& pair : a) {
|
| + const auto& found_b = b.find(pair.first);
|
| + if (found_b == b.end())
|
| + return false; // Item in 'a' but not 'b'.
|
| + if (pair.second.value != found_b->second.value)
|
| + return false; // Values for variable in 'a' and 'b' are different.
|
| + }
|
| + return true;
|
| +}
|
|
|