Commit 7d886382 authored by phosek's avatar phosek Committed by Commit bot

Support for source_target_relative expansion in GN

This can be used to get a path to the source file relative to the target's
directory.

Review-Url: https://codereview.chromium.org/2387763002
Cr-Commit-Position: refs/heads/master@{#439541}
parent 7f1c6c95
...@@ -22,7 +22,7 @@ void ActionValues::GetOutputsAsSourceFiles( ...@@ -22,7 +22,7 @@ void ActionValues::GetOutputsAsSourceFiles(
target->output_type() == Target::ACTION_FOREACH) { target->output_type() == Target::ACTION_FOREACH) {
// Copy and foreach applies the outputs to the sources. // Copy and foreach applies the outputs to the sources.
SubstitutionWriter::ApplyListToSources( SubstitutionWriter::ApplyListToSources(
target->settings(), outputs_, target->sources(), result); target, target->settings(), outputs_, target->sources(), result);
} else { } else {
// Actions (and anything else that happens to specify an output) just use // Actions (and anything else that happens to specify an output) just use
// the output list with no substitution. // the output list with no substitution.
......
...@@ -46,7 +46,7 @@ SourceFile BundleFileRule::ApplyPatternToSource( ...@@ -46,7 +46,7 @@ SourceFile BundleFileRule::ApplyPatternToSource(
break; break;
default: default:
output_path.append(SubstitutionWriter::GetSourceSubstitution( output_path.append(SubstitutionWriter::GetSourceSubstitution(
settings, source_file, subrange.type, target_, target_->settings(), source_file, subrange.type,
SubstitutionWriter::OUTPUT_ABSOLUTE, SourceDir())); SubstitutionWriter::OUTPUT_ABSOLUTE, SourceDir()));
break; break;
} }
......
...@@ -616,8 +616,9 @@ class TargetDescBuilder : public BaseDescBuilder { ...@@ -616,8 +616,9 @@ class TargetDescBuilder : public BaseDescBuilder {
res->SetWithoutPathExpansion("output_patterns", std::move(patterns)); res->SetWithoutPathExpansion("output_patterns", std::move(patterns));
} }
std::vector<SourceFile> output_files; std::vector<SourceFile> output_files;
SubstitutionWriter::ApplyListToSources(target_->settings(), outputs, SubstitutionWriter::ApplyListToSources(target_, target_->settings(),
target_->sources(), &output_files); outputs, target_->sources(),
&output_files);
res->SetWithoutPathExpansion(variables::kOutputs, res->SetWithoutPathExpansion(variables::kOutputs,
RenderValue(output_files)); RenderValue(output_files));
} else { } else {
......
...@@ -6584,6 +6584,13 @@ ...@@ -6584,6 +6584,13 @@
build.gn file. build.gn file.
"//foo/bar/baz.txt" => "obj/foo/bar" "//foo/bar/baz.txt" => "obj/foo/bar"
{{source_target_relative}}\n"
The path to the source file relative to the target's directory. This will
generally be used for replicating the source directory layout in the
output directory. This can only be used in actions and it is an error to
use in process_file_template where there is no "target".
"//foo/bar/baz.txt" => "baz.txt"
``` ```
### **(*) Note on directories** ### **(*) Note on directories**
......
...@@ -93,8 +93,15 @@ Value RunProcessFileTemplate(Scope* scope, ...@@ -93,8 +93,15 @@ Value RunProcessFileTemplate(Scope* scope,
return Value(); return Value();
} }
auto& types = subst.required_types();
if (std::find(types.begin(), types.end(),
SUBSTITUTION_SOURCE_TARGET_RELATIVE) != types.end()) {
*err = Err(template_arg, "Not a valid substitution type for the function.");
return Value();
}
SubstitutionWriter::ApplyListToSourcesAsString( SubstitutionWriter::ApplyListToSourcesAsString(
scope->settings(), subst, input_files, &result_files); nullptr, scope->settings(), subst, input_files, &result_files);
// Convert the list of strings to the return Value. // Convert the list of strings to the return Value.
Value ret(function, Value::LIST); Value ret(function, Value::LIST);
......
...@@ -184,11 +184,11 @@ void NinjaActionTargetWriter::WriteSourceRules( ...@@ -184,11 +184,11 @@ void NinjaActionTargetWriter::WriteSourceRules(
// very unusual (normally the substitutions will go in one place or the // very unusual (normally the substitutions will go in one place or the
// other) and the redundant assignment won't bother Ninja. // other) and the redundant assignment won't bother Ninja.
SubstitutionWriter::WriteNinjaVariablesForSource( SubstitutionWriter::WriteNinjaVariablesForSource(
settings_, sources[i], target_, settings_, sources[i],
target_->action_values().args().required_types(), target_->action_values().args().required_types(),
args_escape_options, out_); args_escape_options, out_);
SubstitutionWriter::WriteNinjaVariablesForSource( SubstitutionWriter::WriteNinjaVariablesForSource(
settings_, sources[i], target_, settings_, sources[i],
target_->action_values().rsp_file_contents().required_types(), target_->action_values().rsp_file_contents().required_types(),
args_escape_options, out_); args_escape_options, out_);
...@@ -206,7 +206,8 @@ void NinjaActionTargetWriter::WriteOutputFilesForBuildLine( ...@@ -206,7 +206,8 @@ void NinjaActionTargetWriter::WriteOutputFilesForBuildLine(
size_t first_output_index = output_files->size(); size_t first_output_index = output_files->size();
SubstitutionWriter::ApplyListToSourceAsOutputFile( SubstitutionWriter::ApplyListToSourceAsOutputFile(
settings_, target_->action_values().outputs(), source, output_files); target_, settings_, target_->action_values().outputs(), source,
output_files);
for (size_t i = first_output_index; i < output_files->size(); i++) { for (size_t i = first_output_index; i < output_files->size(); i++) {
out_ << " "; out_ << " ";
...@@ -217,5 +218,5 @@ void NinjaActionTargetWriter::WriteOutputFilesForBuildLine( ...@@ -217,5 +218,5 @@ void NinjaActionTargetWriter::WriteOutputFilesForBuildLine(
void NinjaActionTargetWriter::WriteDepfile(const SourceFile& source) { void NinjaActionTargetWriter::WriteDepfile(const SourceFile& source) {
path_output_.WriteFile(out_, path_output_.WriteFile(out_,
SubstitutionWriter::ApplyPatternToSourceAsOutputFile( SubstitutionWriter::ApplyPatternToSourceAsOutputFile(
settings_, target_->action_values().depfile(), source)); target_, settings_, target_->action_values().depfile(), source));
} }
...@@ -103,7 +103,7 @@ void NinjaCopyTargetWriter::WriteCopyRules( ...@@ -103,7 +103,7 @@ void NinjaCopyTargetWriter::WriteCopyRules(
for (const auto& input_file : target_->sources()) { for (const auto& input_file : target_->sources()) {
OutputFile output_file = OutputFile output_file =
SubstitutionWriter::ApplyPatternToSourceAsOutputFile( SubstitutionWriter::ApplyPatternToSourceAsOutputFile(
target_->settings(), output_subst, input_file); target_, target_->settings(), output_subst, input_file);
output_files->push_back(output_file); output_files->push_back(output_file);
out_ << "build "; out_ << "build ";
......
...@@ -21,6 +21,7 @@ const char* kSubstitutionNames[SUBSTITUTION_NUM_TYPES] = { ...@@ -21,6 +21,7 @@ const char* kSubstitutionNames[SUBSTITUTION_NUM_TYPES] = {
"{{source_root_relative_dir}}", // SUBSTITUTION_SOURCE_ROOT_RELATIVE_DIR "{{source_root_relative_dir}}", // SUBSTITUTION_SOURCE_ROOT_RELATIVE_DIR
"{{source_gen_dir}}", // SUBSTITUTION_SOURCE_GEN_DIR "{{source_gen_dir}}", // SUBSTITUTION_SOURCE_GEN_DIR
"{{source_out_dir}}", // SUBSTITUTION_SOURCE_OUT_DIR "{{source_out_dir}}", // SUBSTITUTION_SOURCE_OUT_DIR
"{{source_target_relative}}", // SUBSTITUTION_SOURCE_TARGET_RELATIVE
"{{label}}", // SUBSTITUTION_LABEL "{{label}}", // SUBSTITUTION_LABEL
"{{label_name}}", // SUBSTITUTION_LABEL_NAME "{{label_name}}", // SUBSTITUTION_LABEL_NAME
...@@ -70,6 +71,7 @@ const char* kSubstitutionNinjaNames[SUBSTITUTION_NUM_TYPES] = { ...@@ -70,6 +71,7 @@ const char* kSubstitutionNinjaNames[SUBSTITUTION_NUM_TYPES] = {
"source_root_relative_dir", // SUBSTITUTION_SOURCE_ROOT_RELATIVE_DIR "source_root_relative_dir", // SUBSTITUTION_SOURCE_ROOT_RELATIVE_DIR
"source_gen_dir", // SUBSTITUTION_SOURCE_GEN_DIR "source_gen_dir", // SUBSTITUTION_SOURCE_GEN_DIR
"source_out_dir", // SUBSTITUTION_SOURCE_OUT_DIR "source_out_dir", // SUBSTITUTION_SOURCE_OUT_DIR
"source_target_relative", // SUBSTITUTION_SOURCE_TARGET_RELATIVE
"label", // SUBSTITUTION_LABEL "label", // SUBSTITUTION_LABEL
"label_name", // SUBSTITUTION_LABEL_NAME "label_name", // SUBSTITUTION_LABEL_NAME
...@@ -160,7 +162,8 @@ bool IsValidSourceSubstitution(SubstitutionType type) { ...@@ -160,7 +162,8 @@ bool IsValidSourceSubstitution(SubstitutionType type) {
type == SUBSTITUTION_SOURCE_DIR || type == SUBSTITUTION_SOURCE_DIR ||
type == SUBSTITUTION_SOURCE_ROOT_RELATIVE_DIR || type == SUBSTITUTION_SOURCE_ROOT_RELATIVE_DIR ||
type == SUBSTITUTION_SOURCE_GEN_DIR || type == SUBSTITUTION_SOURCE_GEN_DIR ||
type == SUBSTITUTION_SOURCE_OUT_DIR; type == SUBSTITUTION_SOURCE_OUT_DIR ||
type == SUBSTITUTION_SOURCE_TARGET_RELATIVE;
} }
bool IsValidToolSubstitution(SubstitutionType type) { bool IsValidToolSubstitution(SubstitutionType type) {
......
...@@ -30,6 +30,7 @@ enum SubstitutionType { ...@@ -30,6 +30,7 @@ enum SubstitutionType {
SUBSTITUTION_SOURCE_ROOT_RELATIVE_DIR, // {{root_relative_dir}} SUBSTITUTION_SOURCE_ROOT_RELATIVE_DIR, // {{root_relative_dir}}
SUBSTITUTION_SOURCE_GEN_DIR, // {{source_gen_dir}} SUBSTITUTION_SOURCE_GEN_DIR, // {{source_gen_dir}}
SUBSTITUTION_SOURCE_OUT_DIR, // {{source_out_dir}} SUBSTITUTION_SOURCE_OUT_DIR, // {{source_out_dir}}
SUBSTITUTION_SOURCE_TARGET_RELATIVE, // {{source_target_relative}}
// Valid for all compiler and linker tools. These depend on the target and // Valid for all compiler and linker tools. These depend on the target and
// do not vary on a per-file basis. // do not vary on a per-file basis.
......
...@@ -98,6 +98,13 @@ Placeholders ...@@ -98,6 +98,13 @@ Placeholders
build.gn file. build.gn file.
"//foo/bar/baz.txt" => "obj/foo/bar" "//foo/bar/baz.txt" => "obj/foo/bar"
{{source_target_relative}}\n"
The path to the source file relative to the target's directory. This will
generally be used for replicating the source directory layout in the
output directory. This can only be used in actions and it is an error to
use in process_file_template where there is no "target".
"//foo/bar/baz.txt" => "baz.txt"
(*) Note on directories (*) Note on directories
Paths containing directories (except the source_root_relative_dir) will be Paths containing directories (except the source_root_relative_dir) will be
...@@ -196,11 +203,12 @@ void SubstitutionWriter::GetListAsOutputFiles( ...@@ -196,11 +203,12 @@ void SubstitutionWriter::GetListAsOutputFiles(
// static // static
SourceFile SubstitutionWriter::ApplyPatternToSource( SourceFile SubstitutionWriter::ApplyPatternToSource(
const Target* target,
const Settings* settings, const Settings* settings,
const SubstitutionPattern& pattern, const SubstitutionPattern& pattern,
const SourceFile& source) { const SourceFile& source) {
std::string result_value = ApplyPatternToSourceAsString( std::string result_value = ApplyPatternToSourceAsString(
settings, pattern, source); target, settings, pattern, source);
CHECK(!result_value.empty() && result_value[0] == '/') CHECK(!result_value.empty() && result_value[0] == '/')
<< "The result of the pattern \"" << "The result of the pattern \""
<< pattern.AsString() << pattern.AsString()
...@@ -210,6 +218,7 @@ SourceFile SubstitutionWriter::ApplyPatternToSource( ...@@ -210,6 +218,7 @@ SourceFile SubstitutionWriter::ApplyPatternToSource(
// static // static
std::string SubstitutionWriter::ApplyPatternToSourceAsString( std::string SubstitutionWriter::ApplyPatternToSourceAsString(
const Target* target,
const Settings* settings, const Settings* settings,
const SubstitutionPattern& pattern, const SubstitutionPattern& pattern,
const SourceFile& source) { const SourceFile& source) {
...@@ -219,7 +228,7 @@ std::string SubstitutionWriter::ApplyPatternToSourceAsString( ...@@ -219,7 +228,7 @@ std::string SubstitutionWriter::ApplyPatternToSourceAsString(
result_value.append(subrange.literal); result_value.append(subrange.literal);
} else { } else {
result_value.append( result_value.append(
GetSourceSubstitution(settings, source, subrange.type, GetSourceSubstitution(target, settings, source, subrange.type,
OUTPUT_ABSOLUTE, SourceDir())); OUTPUT_ABSOLUTE, SourceDir()));
} }
} }
...@@ -228,78 +237,89 @@ std::string SubstitutionWriter::ApplyPatternToSourceAsString( ...@@ -228,78 +237,89 @@ std::string SubstitutionWriter::ApplyPatternToSourceAsString(
// static // static
OutputFile SubstitutionWriter::ApplyPatternToSourceAsOutputFile( OutputFile SubstitutionWriter::ApplyPatternToSourceAsOutputFile(
const Target* target,
const Settings* settings, const Settings* settings,
const SubstitutionPattern& pattern, const SubstitutionPattern& pattern,
const SourceFile& source) { const SourceFile& source) {
SourceFile result_as_source = ApplyPatternToSource(settings, pattern, source); SourceFile result_as_source = ApplyPatternToSource(
target, settings, pattern, source);
return OutputFile(settings->build_settings(), result_as_source); return OutputFile(settings->build_settings(), result_as_source);
} }
// static // static
void SubstitutionWriter::ApplyListToSource( void SubstitutionWriter::ApplyListToSource(
const Target* target,
const Settings* settings, const Settings* settings,
const SubstitutionList& list, const SubstitutionList& list,
const SourceFile& source, const SourceFile& source,
std::vector<SourceFile>* output) { std::vector<SourceFile>* output) {
for (const auto& item : list.list()) for (const auto& item : list.list())
output->push_back(ApplyPatternToSource(settings, item, source)); output->push_back(ApplyPatternToSource(target, settings, item, source));
} }
// static // static
void SubstitutionWriter::ApplyListToSourceAsString( void SubstitutionWriter::ApplyListToSourceAsString(
const Target* target,
const Settings* settings, const Settings* settings,
const SubstitutionList& list, const SubstitutionList& list,
const SourceFile& source, const SourceFile& source,
std::vector<std::string>* output) { std::vector<std::string>* output) {
for (const auto& item : list.list()) for (const auto& item : list.list())
output->push_back(ApplyPatternToSourceAsString(settings, item, source)); output->push_back(ApplyPatternToSourceAsString(
target, settings, item, source));
} }
// static // static
void SubstitutionWriter::ApplyListToSourceAsOutputFile( void SubstitutionWriter::ApplyListToSourceAsOutputFile(
const Target* target,
const Settings* settings, const Settings* settings,
const SubstitutionList& list, const SubstitutionList& list,
const SourceFile& source, const SourceFile& source,
std::vector<OutputFile>* output) { std::vector<OutputFile>* output) {
for (const auto& item : list.list()) for (const auto& item : list.list())
output->push_back(ApplyPatternToSourceAsOutputFile(settings, item, source)); output->push_back(ApplyPatternToSourceAsOutputFile(
target, settings, item, source));
} }
// static // static
void SubstitutionWriter::ApplyListToSources( void SubstitutionWriter::ApplyListToSources(
const Target* target,
const Settings* settings, const Settings* settings,
const SubstitutionList& list, const SubstitutionList& list,
const std::vector<SourceFile>& sources, const std::vector<SourceFile>& sources,
std::vector<SourceFile>* output) { std::vector<SourceFile>* output) {
output->clear(); output->clear();
for (const auto& source : sources) for (const auto& source : sources)
ApplyListToSource(settings, list, source, output); ApplyListToSource(target, settings, list, source, output);
} }
// static // static
void SubstitutionWriter::ApplyListToSourcesAsString( void SubstitutionWriter::ApplyListToSourcesAsString(
const Target* target,
const Settings* settings, const Settings* settings,
const SubstitutionList& list, const SubstitutionList& list,
const std::vector<SourceFile>& sources, const std::vector<SourceFile>& sources,
std::vector<std::string>* output) { std::vector<std::string>* output) {
output->clear(); output->clear();
for (const auto& source : sources) for (const auto& source : sources)
ApplyListToSourceAsString(settings, list, source, output); ApplyListToSourceAsString(target, settings, list, source, output);
} }
// static // static
void SubstitutionWriter::ApplyListToSourcesAsOutputFile( void SubstitutionWriter::ApplyListToSourcesAsOutputFile(
const Target* target,
const Settings* settings, const Settings* settings,
const SubstitutionList& list, const SubstitutionList& list,
const std::vector<SourceFile>& sources, const std::vector<SourceFile>& sources,
std::vector<OutputFile>* output) { std::vector<OutputFile>* output) {
output->clear(); output->clear();
for (const auto& source : sources) for (const auto& source : sources)
ApplyListToSourceAsOutputFile(settings, list, source, output); ApplyListToSourceAsOutputFile(target, settings, list, source, output);
} }
// static // static
void SubstitutionWriter::WriteNinjaVariablesForSource( void SubstitutionWriter::WriteNinjaVariablesForSource(
const Target* target,
const Settings* settings, const Settings* settings,
const SourceFile& source, const SourceFile& source,
const std::vector<SubstitutionType>& types, const std::vector<SubstitutionType>& types,
...@@ -314,7 +334,8 @@ void SubstitutionWriter::WriteNinjaVariablesForSource( ...@@ -314,7 +334,8 @@ void SubstitutionWriter::WriteNinjaVariablesForSource(
out << " " << kSubstitutionNinjaNames[type] << " = "; out << " " << kSubstitutionNinjaNames[type] << " = ";
EscapeStringToStream( EscapeStringToStream(
out, out,
GetSourceSubstitution(settings, source, type, OUTPUT_RELATIVE, GetSourceSubstitution(target, settings, source, type,
OUTPUT_RELATIVE,
settings->build_settings()->build_dir()), settings->build_settings()->build_dir()),
escape_options); escape_options);
out << std::endl; out << std::endl;
...@@ -324,6 +345,7 @@ void SubstitutionWriter::WriteNinjaVariablesForSource( ...@@ -324,6 +345,7 @@ void SubstitutionWriter::WriteNinjaVariablesForSource(
// static // static
std::string SubstitutionWriter::GetSourceSubstitution( std::string SubstitutionWriter::GetSourceSubstitution(
const Target* target,
const Settings* settings, const Settings* settings,
const SourceFile& source, const SourceFile& source,
SubstitutionType type, SubstitutionType type,
...@@ -366,6 +388,16 @@ std::string SubstitutionWriter::GetSourceSubstitution( ...@@ -366,6 +388,16 @@ std::string SubstitutionWriter::GetSourceSubstitution(
BuildDirContext(settings), source.GetDir(), BuildDirType::OBJ)); BuildDirContext(settings), source.GetDir(), BuildDirType::OBJ));
break; break;
case SUBSTITUTION_SOURCE_TARGET_RELATIVE:
if (target) {
return RebasePath(source.value(), target->label().dir(),
settings->build_settings()->root_path_utf8());
}
NOTREACHED()
<< "Cannot use substitution " << kSubstitutionNames[type]
<< " without target";
return std::string();
default: default:
NOTREACHED() NOTREACHED()
<< "Unsupported substitution for this function: " << "Unsupported substitution for this function: "
...@@ -502,7 +534,7 @@ std::string SubstitutionWriter::GetCompilerSubstitution( ...@@ -502,7 +534,7 @@ std::string SubstitutionWriter::GetCompilerSubstitution(
// Fall-through to the source ones. // Fall-through to the source ones.
return GetSourceSubstitution( return GetSourceSubstitution(
target->settings(), source, type, OUTPUT_RELATIVE, target, target->settings(), source, type, OUTPUT_RELATIVE,
target->settings()->build_settings()->build_dir()); target->settings()->build_settings()->build_dir());
} }
......
...@@ -46,6 +46,10 @@ extern const char kSourceExpansion_Help[]; ...@@ -46,6 +46,10 @@ extern const char kSourceExpansion_Help[];
// The compiler and linker specific substitutions do NOT include the various // The compiler and linker specific substitutions do NOT include the various
// cflags, ldflags, libraries, etc. These are written by the ninja target // cflags, ldflags, libraries, etc. These are written by the ninja target
// writer since they depend on traversing the dependency tree. // writer since they depend on traversing the dependency tree.
//
// The methods which take a target as an argument can accept null target
// pointer if there is no target context, in which case the substitutions
// requiring target context will not work.
class SubstitutionWriter { class SubstitutionWriter {
public: public:
enum OutputStyle { enum OutputStyle {
...@@ -81,15 +85,20 @@ class SubstitutionWriter { ...@@ -81,15 +85,20 @@ class SubstitutionWriter {
// expected to be a SourceFile or an OutputFile, this will CHECK if the // expected to be a SourceFile or an OutputFile, this will CHECK if the
// result isn't in the correct directory. The caller should validate this // result isn't in the correct directory. The caller should validate this
// first (see for example IsFileInOuputDir). // first (see for example IsFileInOuputDir).
//
// The target can be null (see class comment above).
static SourceFile ApplyPatternToSource( static SourceFile ApplyPatternToSource(
const Target* target,
const Settings* settings, const Settings* settings,
const SubstitutionPattern& pattern, const SubstitutionPattern& pattern,
const SourceFile& source); const SourceFile& source);
static std::string ApplyPatternToSourceAsString( static std::string ApplyPatternToSourceAsString(
const Target* target,
const Settings* settings, const Settings* settings,
const SubstitutionPattern& pattern, const SubstitutionPattern& pattern,
const SourceFile& source); const SourceFile& source);
static OutputFile ApplyPatternToSourceAsOutputFile( static OutputFile ApplyPatternToSourceAsOutputFile(
const Target* target,
const Settings* settings, const Settings* settings,
const SubstitutionPattern& pattern, const SubstitutionPattern& pattern,
const SourceFile& source); const SourceFile& source);
...@@ -98,17 +107,22 @@ class SubstitutionWriter { ...@@ -98,17 +107,22 @@ class SubstitutionWriter {
// given output vector. It works this way so one can call multiple times to // given output vector. It works this way so one can call multiple times to
// apply to multiple files and create a list. The result can either be // apply to multiple files and create a list. The result can either be
// SourceFiles or OutputFiles. // SourceFiles or OutputFiles.
//
// The target can be null (see class comment above).
static void ApplyListToSource( static void ApplyListToSource(
const Target* target,
const Settings* settings, const Settings* settings,
const SubstitutionList& list, const SubstitutionList& list,
const SourceFile& source, const SourceFile& source,
std::vector<SourceFile>* output); std::vector<SourceFile>* output);
static void ApplyListToSourceAsString( static void ApplyListToSourceAsString(
const Target* target,
const Settings* settings, const Settings* settings,
const SubstitutionList& list, const SubstitutionList& list,
const SourceFile& source, const SourceFile& source,
std::vector<std::string>* output); std::vector<std::string>* output);
static void ApplyListToSourceAsOutputFile( static void ApplyListToSourceAsOutputFile(
const Target* target,
const Settings* settings, const Settings* settings,
const SubstitutionList& list, const SubstitutionList& list,
const SourceFile& source, const SourceFile& source,
...@@ -116,17 +130,22 @@ class SubstitutionWriter { ...@@ -116,17 +130,22 @@ class SubstitutionWriter {
// Like ApplyListToSource but applies the list to all sources and replaces // Like ApplyListToSource but applies the list to all sources and replaces
// rather than appends the output (this produces the complete output). // rather than appends the output (this produces the complete output).
//
// The target can be null (see class comment above).
static void ApplyListToSources( static void ApplyListToSources(
const Target* target,
const Settings* settings, const Settings* settings,
const SubstitutionList& list, const SubstitutionList& list,
const std::vector<SourceFile>& sources, const std::vector<SourceFile>& sources,
std::vector<SourceFile>* output); std::vector<SourceFile>* output);
static void ApplyListToSourcesAsString( static void ApplyListToSourcesAsString(
const Target* target,
const Settings* settings, const Settings* settings,
const SubstitutionList& list, const SubstitutionList& list,
const std::vector<SourceFile>& sources, const std::vector<SourceFile>& sources,
std::vector<std::string>* output); std::vector<std::string>* output);
static void ApplyListToSourcesAsOutputFile( static void ApplyListToSourcesAsOutputFile(
const Target* target,
const Settings* settings, const Settings* settings,
const SubstitutionList& list, const SubstitutionList& list,
const std::vector<SourceFile>& sources, const std::vector<SourceFile>& sources,
...@@ -138,7 +157,10 @@ class SubstitutionWriter { ...@@ -138,7 +157,10 @@ class SubstitutionWriter {
// Ninja files, paths will be relative to the build dir, and no definition // Ninja files, paths will be relative to the build dir, and no definition
// for {{source}} will be written since that maps to Ninja's implicit $in // for {{source}} will be written since that maps to Ninja's implicit $in
// variable. // variable.
//
// The target can be null (see class comment above).
static void WriteNinjaVariablesForSource( static void WriteNinjaVariablesForSource(
const Target* target,
const Settings* settings, const Settings* settings,
const SourceFile& source, const SourceFile& source,
const std::vector<SubstitutionType>& types, const std::vector<SubstitutionType>& types,
...@@ -149,7 +171,10 @@ class SubstitutionWriter { ...@@ -149,7 +171,10 @@ class SubstitutionWriter {
// given source file. If output_style is OUTPUT_RELATIVE, relative_to // given source file. If output_style is OUTPUT_RELATIVE, relative_to
// indicates the directory that the relative directories should be relative // indicates the directory that the relative directories should be relative
// to, otherwise it is ignored. // to, otherwise it is ignored.
//
// The target can be null (see class comment above).
static std::string GetSourceSubstitution( static std::string GetSourceSubstitution(
const Target* target,
const Settings* settings, const Settings* settings,
const SourceFile& source, const SourceFile& source,
SubstitutionType type, SubstitutionType type,
......
...@@ -43,7 +43,7 @@ TEST(SubstitutionWriter, ApplyPatternToSource) { ...@@ -43,7 +43,7 @@ TEST(SubstitutionWriter, ApplyPatternToSource) {
nullptr, &err)); nullptr, &err));
SourceFile result = SubstitutionWriter::ApplyPatternToSource( SourceFile result = SubstitutionWriter::ApplyPatternToSource(
setup.settings(), pattern, SourceFile("//foo/bar/myfile.txt")); nullptr, setup.settings(), pattern, SourceFile("//foo/bar/myfile.txt"));
ASSERT_EQ("//out/Debug/gen/foo/bar/myfile.tmp", result.value()); ASSERT_EQ("//out/Debug/gen/foo/bar/myfile.tmp", result.value());
} }
...@@ -56,7 +56,7 @@ TEST(SubstitutionWriter, ApplyPatternToSourceAsOutputFile) { ...@@ -56,7 +56,7 @@ TEST(SubstitutionWriter, ApplyPatternToSourceAsOutputFile) {
nullptr, &err)); nullptr, &err));
OutputFile result = SubstitutionWriter::ApplyPatternToSourceAsOutputFile( OutputFile result = SubstitutionWriter::ApplyPatternToSourceAsOutputFile(
setup.settings(), pattern, SourceFile("//foo/bar/myfile.txt")); nullptr, setup.settings(), pattern, SourceFile("//foo/bar/myfile.txt"));
ASSERT_EQ("gen/foo/bar/myfile.tmp", result.value()); ASSERT_EQ("gen/foo/bar/myfile.tmp", result.value());
} }
...@@ -73,7 +73,8 @@ TEST(SubstitutionWriter, WriteNinjaVariablesForSource) { ...@@ -73,7 +73,8 @@ TEST(SubstitutionWriter, WriteNinjaVariablesForSource) {
std::ostringstream out; std::ostringstream out;
SubstitutionWriter::WriteNinjaVariablesForSource( SubstitutionWriter::WriteNinjaVariablesForSource(
setup.settings(), SourceFile("//foo/bar/baz.txt"), types, options, out); nullptr, setup.settings(), SourceFile("//foo/bar/baz.txt"), types,
options, out);
// The "source" should be skipped since that will expand to $in which is // The "source" should be skipped since that will expand to $in which is
// implicit. // implicit.
...@@ -103,10 +104,17 @@ TEST(SubstitutionWriter, WriteWithNinjaVariables) { ...@@ -103,10 +104,17 @@ TEST(SubstitutionWriter, WriteWithNinjaVariables) {
TEST(SubstitutionWriter, SourceSubstitutions) { TEST(SubstitutionWriter, SourceSubstitutions) {
TestWithScope setup; TestWithScope setup;
Err err;
Target target(setup.settings(), Label(SourceDir("//foo/bar/"), "baz"));
target.set_output_type(Target::STATIC_LIBRARY);
target.SetToolchain(setup.toolchain());
ASSERT_TRUE(target.OnResolved(&err));
// Call to get substitutions relative to the build dir. // Call to get substitutions relative to the build dir.
#define GetRelSubst(str, what) \ #define GetRelSubst(str, what) \
SubstitutionWriter::GetSourceSubstitution( \ SubstitutionWriter::GetSourceSubstitution( \
&target, \
setup.settings(), \ setup.settings(), \
SourceFile(str), \ SourceFile(str), \
what, \ what, \
...@@ -116,6 +124,7 @@ TEST(SubstitutionWriter, SourceSubstitutions) { ...@@ -116,6 +124,7 @@ TEST(SubstitutionWriter, SourceSubstitutions) {
// Call to get absolute directory substitutions. // Call to get absolute directory substitutions.
#define GetAbsSubst(str, what) \ #define GetAbsSubst(str, what) \
SubstitutionWriter::GetSourceSubstitution( \ SubstitutionWriter::GetSourceSubstitution( \
&target, \
setup.settings(), \ setup.settings(), \
SourceFile(str), \ SourceFile(str), \
what, \ what, \
...@@ -175,6 +184,11 @@ TEST(SubstitutionWriter, SourceSubstitutions) { ...@@ -175,6 +184,11 @@ TEST(SubstitutionWriter, SourceSubstitutions) {
EXPECT_EQ(".", EXPECT_EQ(".",
GetRelSubst("//baz.txt", SUBSTITUTION_SOURCE_ROOT_RELATIVE_DIR)); GetRelSubst("//baz.txt", SUBSTITUTION_SOURCE_ROOT_RELATIVE_DIR));
EXPECT_EQ("baz.txt",
GetRelSubst("//foo/bar/baz.txt", SUBSTITUTION_SOURCE_TARGET_RELATIVE));
EXPECT_EQ("baz.txt",
GetAbsSubst("//foo/bar/baz.txt", SUBSTITUTION_SOURCE_TARGET_RELATIVE));
#undef GetAbsSubst #undef GetAbsSubst
#undef GetRelSubst #undef GetRelSubst
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment