Disallow non-buildable sources in binary targets
When adding a file that's not a source, header, or object file to a source_set,
loadable_module, shared_library, executable, or static_library, gn will now
generate an error like the following:
ERROR at //third_party/protobuf/proto_library.gni:369:15: Only source, header,
and object files belong in the sources of a
source_set. //out/Test/pyproto/google_apis/gcm/protocol/mcs_pb2.py is not one of
the valid types.
sources = get_target_outputs(":$action_name")
^---------------------------------
See //google_apis/gcm/BUILD.gn:78:1: whence it was called.
proto_library("proto") {
^-----------------------
See //BUILD.gn:89:7: which caused the file to be included.
"//google_apis/gcm:gcm_unit_tests",
^---------------------------------
BUG=77
R=brettw
Change-Id: I4ed8da10c48e3e5d74f79e51d8222c998a7b883a
Reviewed-on: https://gn-review.googlesource.com/c/gn/+/4980
Commit-Queue: Brett Wilson <brettw@google.com>
Reviewed-by: Brett Wilson <brettw@google.com>
diff --git a/tools/gn/binary_target_generator.cc b/tools/gn/binary_target_generator.cc
index 60af242..6d8cec9 100644
--- a/tools/gn/binary_target_generator.cc
+++ b/tools/gn/binary_target_generator.cc
@@ -68,6 +68,38 @@
return;
}
+bool BinaryTargetGenerator::FillSources() {
+ bool ret = TargetGenerator::FillSources();
+ for (std::size_t i = 0; i < target_->sources().size(); ++i) {
+ const auto& source = target_->sources()[i];
+ switch (source.type()) {
+ case SourceFile::SOURCE_CPP:
+ case SourceFile::SOURCE_H:
+ case SourceFile::SOURCE_C:
+ case SourceFile::SOURCE_M:
+ case SourceFile::SOURCE_MM:
+ case SourceFile::SOURCE_S:
+ case SourceFile::SOURCE_ASM:
+ case SourceFile::SOURCE_O:
+ // These are allowed.
+ break;
+ case SourceFile::SOURCE_RC:
+ case SourceFile::SOURCE_DEF:
+ case SourceFile::SOURCE_RS:
+ case SourceFile::SOURCE_GO:
+ case SourceFile::SOURCE_UNKNOWN:
+ case SourceFile::SOURCE_NUMTYPES:
+ *err_ =
+ Err(scope_->GetValue(variables::kSources, true)->list_value()[i],
+ std::string("Only source, header, and object files belong in "
+ "the sources of a ") +
+ Target::GetStringForOutputType(target_->output_type()) +
+ ". " + source.value() + " is not one of the valid types.");
+ }
+ }
+ return ret;
+}
+
bool BinaryTargetGenerator::FillCompleteStaticLib() {
if (target_->output_type() == Target::STATIC_LIBRARY) {
const Value* value = scope_->GetValue(variables::kCompleteStaticLib, true);
diff --git a/tools/gn/binary_target_generator.h b/tools/gn/binary_target_generator.h
index 40fc314..6cbd11e 100644
--- a/tools/gn/binary_target_generator.h
+++ b/tools/gn/binary_target_generator.h
@@ -22,6 +22,7 @@
protected:
void DoRun() override;
+ bool FillSources() override;
private:
bool FillCompleteStaticLib();
diff --git a/tools/gn/source_dir.cc b/tools/gn/source_dir.cc
index 0fd5c75..50b4517 100644
--- a/tools/gn/source_dir.cc
+++ b/tools/gn/source_dir.cc
@@ -98,10 +98,10 @@
return ret;
const std::string& input_string = p.string_value();
- if (!ValidateResolveInput<std::string>(true, p, input_string, err)) {
+ if (!ValidateResolveInput<std::string>(true, p, input_string, err))
return ret;
- }
- ret.value_ = ResolveRelative(input_string, value_, true, source_root);
+
+ ret.SetValue(ResolveRelative(input_string, value_, true, source_root));
return ret;
}
diff --git a/tools/gn/source_file.cc b/tools/gn/source_file.cc
index 7c860d4..2923227 100644
--- a/tools/gn/source_file.cc
+++ b/tools/gn/source_file.cc
@@ -55,18 +55,19 @@
SourceFile::SourceFile() : type_(SOURCE_UNKNOWN) {}
SourceFile::SourceFile(const base::StringPiece& p)
- : value_(p.data(), p.size()), type_(GetSourceFileType(value_)) {
+ : value_(p.data(), p.size()) {
DCHECK(!value_.empty());
AssertValueSourceFileString(value_);
NormalizePath(&value_);
+ type_ = GetSourceFileType(value_);
}
-SourceFile::SourceFile(SwapIn, std::string* value)
- : type_(GetSourceFileType(*value)) {
+SourceFile::SourceFile(SwapIn, std::string* value) {
value_.swap(*value);
DCHECK(!value_.empty());
AssertValueSourceFileString(value_);
NormalizePath(&value_);
+ type_ = GetSourceFileType(value_);
}
SourceFile::~SourceFile() = default;
@@ -92,3 +93,8 @@
base::FilePath SourceFile::Resolve(const base::FilePath& source_root) const {
return ResolvePath(value_, true, source_root);
}
+
+void SourceFile::SetValue(const std::string& value) {
+ value_ = value;
+ type_ = GetSourceFileType(value_);
+}
diff --git a/tools/gn/source_file.h b/tools/gn/source_file.h
index bcf5f42..d42063d 100644
--- a/tools/gn/source_file.h
+++ b/tools/gn/source_file.h
@@ -97,11 +97,16 @@
return value_ < other.value_;
}
- void swap(SourceFile& other) { value_.swap(other.value_); }
+ void swap(SourceFile& other) {
+ value_.swap(other.value_);
+ std::swap(type_, other.type_);
+ }
private:
friend class SourceDir;
+ void SetValue(const std::string& value);
+
std::string value_;
Type type_;
diff --git a/tools/gn/target_generator.h b/tools/gn/target_generator.h
index 627505d..8795cbf 100644
--- a/tools/gn/target_generator.h
+++ b/tools/gn/target_generator.h
@@ -47,7 +47,7 @@
const BuildSettings* GetBuildSettings() const;
- bool FillSources();
+ virtual bool FillSources();
bool FillPublic();
bool FillConfigs();
bool FillOutputs(bool allow_substitutions);