Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(47)

Unified Diff: tools/gn/file_template.cc

Issue 387663003: Improve GN handling of directory templates. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: tools/gn/file_template.cc
diff --git a/tools/gn/file_template.cc b/tools/gn/file_template.cc
index 2809920ea2be8076ac38a9b1d0c3b932f52a3986..6ad37e5be9c7f296dac56306d23df40d1177ea2d 100644
--- a/tools/gn/file_template.cc
+++ b/tools/gn/file_template.cc
@@ -44,10 +44,9 @@ const char kSourceExpansion_Help[] =
"Placeholders\n"
"\n"
" {{source}}\n"
- " The name of the source file relative to the root build output\n"
- " directory (which is the current directory when running compilers\n"
- " and scripts). This will generally be used for specifying inputs\n"
- " to a script in the \"args\" variable.\n"
+ " The name of the source file including directory (*). This will\n"
+ " generally be used for specifying inputs to a script in the\n"
+ " \"args\" variable.\n"
" \"//foo/bar/baz.txt\" => \"../../foo/bar/baz.txt\"\n"
"\n"
" {{source_file_part}}\n"
@@ -62,34 +61,48 @@ const char kSourceExpansion_Help[] =
" \"//foo/bar/baz.txt\" => \"baz\"\n"
"\n"
" {{source_dir}}\n"
- " The directory containing the source file, relative to the build\n"
- " directory, with no trailing slash.\n"
+ " The directory (*) containing the source file with no\n"
+ " trailing slash.\n"
" \"//foo/bar/baz.txt\" => \"../../foo/bar\"\n"
"\n"
" {{source_root_relative_dir}}\n"
" The path to the source file's directory relative to the source\n"
" root, with no leading \"//\" or trailing slashes. If the path is\n"
" system-absolute, (beginning in a single slash) this will just\n"
- " return the path with no trailing slash.\n"
+ " return the path with no trailing slash. This value will always\n"
+ " be the same, regardless of whether it appears in the \"outputs\"\n"
+ " or \"args\" section.\n"
" \"//foo/bar/baz.txt\" => \"foo/bar\"\n"
"\n"
" {{source_gen_dir}}\n"
- " The generated file directory corresponding to the source file's\n"
- " path, relative to the build directory. This will be different than\n"
- " the target's generated file directory if the source file is in a\n"
- " different directory than the build.gn file. If the input path is\n"
- " system absolute, this will return the root generated file\n"
- " directory."
+ " The generated file directory (*) corresponding to the source\n"
+ " file's path. This will be different than the target's generated\n"
+ " file directory if the source file is in a different directory\n"
+ " than the BUILD.gn file.\n"
" \"//foo/bar/baz.txt\" => \"gen/foo/bar\"\n"
"\n"
" {{source_out_dir}}\n"
- " The object file directory corresponding to the source file's\n"
+ " The object file directory (*) corresponding to the source file's\n"
" path, relative to the build directory. this us be different than\n"
" the target's out directory if the source file is in a different\n"
- " directory than the build.gn file. if the input path is system\n"
- " absolute, this will return the root generated file directory.\n"
+ " directory than the build.gn file.\n"
" \"//foo/bar/baz.txt\" => \"obj/foo/bar\"\n"
"\n"
+ "(*) Note on directories\n"
+ "\n"
+ " Paths containing directories (except the source_root_relative_dir)\n"
+ " will be different depending on what context the expansion is evaluated\n"
+ " in. Generally it should \"just work\" but it means you can't\n"
+ " concatenate strings containing these values with reasonable results.\n"
+ "\n"
+ " Details: source expansions can be used in the \"outputs\" variable,\n"
+ " the \"args\" variable, and in calls to \"process_file_template\". The\n"
+ " \"args\" are passed to a script which is run from the build directory,\n"
+ " so these directories will relative to the build directory for the\n"
+ " script to find. In the other cases, the directories will be source-\n"
+ " absolute (begin with a \"//\") because the results of those expansions\n"
+ " will be handled by GN internally.\n"
+ "\n"
"Examples\n"
"\n"
" Non-varying outputs:\n"
@@ -103,8 +116,8 @@ const char kSourceExpansion_Help[] =
" Varying outputs:\n"
" action_foreach(\"varying_outputs\") {\n"
" sources = [ \"input1.idl\", \"input2.idl\" ]\n"
- " outputs = [ \"$target_out_dir/{{source_name_part}}.h\",\n"
- " \"$target_out_dir/{{source_name_part}}.cc\" ]\n"
+ " outputs = [ \"{{source_gen_dir}}/{{source_name_part}}.h\",\n"
+ " \"{{source_gen_dir}}/{{source_name_part}}.cc\" ]\n"
" }\n"
" Performing source expansion will result in the following output names:\n"
" //out/Debug/obj/mydirectory/input1.h\n"
@@ -112,16 +125,26 @@ const char kSourceExpansion_Help[] =
" //out/Debug/obj/mydirectory/input2.h\n"
" //out/Debug/obj/mydirectory/input2.cc\n";
-FileTemplate::FileTemplate(const Settings* settings, const Value& t, Err* err)
+FileTemplate::FileTemplate(const Settings* settings,
+ const Value& t,
+ OutputStyle output_style,
+ const SourceDir& relative_to,
+ Err* err)
: settings_(settings),
+ output_style_(output_style),
+ relative_to_(relative_to),
has_substitutions_(false) {
std::fill(types_required_, &types_required_[Subrange::NUM_TYPES], false);
ParseInput(t, err);
}
FileTemplate::FileTemplate(const Settings* settings,
- const std::vector<std::string>& t)
+ const std::vector<std::string>& t,
+ OutputStyle output_style,
+ const SourceDir& relative_to)
: settings_(settings),
+ output_style_(output_style),
+ relative_to_(relative_to),
has_substitutions_(false) {
std::fill(types_required_, &types_required_[Subrange::NUM_TYPES], false);
for (size_t i = 0; i < t.size(); i++)
@@ -129,8 +152,12 @@ FileTemplate::FileTemplate(const Settings* settings,
}
FileTemplate::FileTemplate(const Settings* settings,
- const std::vector<SourceFile>& t)
+ const std::vector<SourceFile>& t,
+ OutputStyle output_style,
+ const SourceDir& relative_to)
: settings_(settings),
+ output_style_(output_style),
+ relative_to_(relative_to),
has_substitutions_(false) {
std::fill(types_required_, &types_required_[Subrange::NUM_TYPES], false);
for (size_t i = 0; i < t.size(); i++)
@@ -142,11 +169,12 @@ FileTemplate::~FileTemplate() {
// static
FileTemplate FileTemplate::GetForTargetOutputs(const Target* target) {
- const Target::FileList& outputs = target->action_values().outputs();
+ const std::vector<std::string>& outputs = target->action_values().outputs();
std::vector<std::string> output_template_args;
for (size_t i = 0; i < outputs.size(); i++)
- output_template_args.push_back(outputs[i].value());
- return FileTemplate(target->settings(), output_template_args);
+ output_template_args.push_back(outputs[i]);
+ return FileTemplate(target->settings(), output_template_args,
+ OUTPUT_ABSOLUTE, SourceDir());
}
bool FileTemplate::IsTypeUsed(Subrange::Type type) const {
@@ -161,8 +189,9 @@ void FileTemplate::Apply(const SourceFile& source,
std::string subst[Subrange::NUM_TYPES];
for (int i = 1; i < Subrange::NUM_TYPES; i++) {
if (types_required_[i]) {
- subst[i] =
- GetSubstitution(settings_, source, static_cast<Subrange::Type>(i));
+ subst[i] = GetSubstitution(settings_, source,
+ static_cast<Subrange::Type>(i),
+ output_style_, relative_to_);
}
}
@@ -227,15 +256,16 @@ void FileTemplate::WriteWithNinjaExpansions(std::ostream& out) const {
void FileTemplate::WriteNinjaVariablesForSubstitution(
std::ostream& out,
- const Settings* settings,
const SourceFile& source,
const EscapeOptions& escape_options) const {
for (int i = 1; i < Subrange::NUM_TYPES; i++) {
if (types_required_[i]) {
Subrange::Type type = static_cast<Subrange::Type>(i);
out << " " << GetNinjaVariableNameForType(type) << " = ";
- EscapeStringToStream(out, GetSubstitution(settings, source, type),
- escape_options);
+ EscapeStringToStream(
+ out,
+ GetSubstitution(settings_, source, type, output_style_, relative_to_),
+ escape_options);
out << std::endl;
}
}
@@ -268,13 +298,16 @@ const char* FileTemplate::GetNinjaVariableNameForType(Subrange::Type type) {
// static
std::string FileTemplate::GetSubstitution(const Settings* settings,
const SourceFile& source,
- Subrange::Type type) {
+ Subrange::Type type,
+ OutputStyle output_style,
+ const SourceDir& relative_to) {
+ std::string to_rebase;
switch (type) {
case Subrange::SOURCE:
if (source.is_system_absolute())
return source.value();
- return RebaseSourceAbsolutePath(source.value(),
- settings->build_settings()->build_dir());
+ to_rebase = source.value();
+ break;
case Subrange::NAME_PART:
return FindFilenameNoExtension(&source.value()).as_string();
@@ -285,9 +318,8 @@ std::string FileTemplate::GetSubstitution(const Settings* settings,
case Subrange::SOURCE_DIR:
if (source.is_system_absolute())
return DirectoryWithNoLastSlash(source.GetDir());
- return RebaseSourceAbsolutePath(
- DirectoryWithNoLastSlash(source.GetDir()),
- settings->build_settings()->build_dir());
+ to_rebase = DirectoryWithNoLastSlash(source.GetDir());
+ break;
case Subrange::ROOT_RELATIVE_DIR:
if (source.is_system_absolute())
@@ -296,21 +328,26 @@ std::string FileTemplate::GetSubstitution(const Settings* settings,
DirectoryWithNoLastSlash(source.GetDir()), SourceDir("//"));
case Subrange::SOURCE_GEN_DIR:
- return RebaseSourceAbsolutePath(
- DirectoryWithNoLastSlash(
- GetGenDirForSourceDir(settings, source.GetDir())),
- settings->build_settings()->build_dir());
+ to_rebase = DirectoryWithNoLastSlash(
+ GetGenDirForSourceDir(settings, source.GetDir()));
+ break;
case Subrange::SOURCE_OUT_DIR:
- return RebaseSourceAbsolutePath(
- DirectoryWithNoLastSlash(
- GetOutputDirForSourceDir(settings, source.GetDir())),
- settings->build_settings()->build_dir());
+ to_rebase = DirectoryWithNoLastSlash(
+ GetOutputDirForSourceDir(settings, source.GetDir()));
+ break;
default:
NOTREACHED();
+ return std::string();
}
- return std::string();
+
+ // If we get here, the result is a path that should be made relative or
+ // absolute according to the output_style. Other cases (just file name or
+ // extension extraction) will have been handled via early return above.
+ if (output_style == OUTPUT_ABSOLUTE)
+ return to_rebase;
+ return RebaseSourceAbsolutePath(to_rebase, relative_to);
}
void FileTemplate::ParseInput(const Value& value, Err* err) {

Powered by Google App Engine
This is Rietveld 408576698