| 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) {
|
|
|