1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "tools/gn/ninja_target_writer.h"
10 #include "base/file_util.h"
11 #include "tools/gn/err.h"
12 #include "tools/gn/file_template.h"
13 #include "tools/gn/ninja_action_target_writer.h"
14 #include "tools/gn/ninja_binary_target_writer.h"
15 #include "tools/gn/ninja_copy_target_writer.h"
16 #include "tools/gn/ninja_group_target_writer.h"
17 #include "tools/gn/scheduler.h"
18 #include "tools/gn/string_utils.h"
19 #include "tools/gn/target.h"
20 #include "tools/gn/trace.h"
22 NinjaTargetWriter::NinjaTargetWriter(const Target
* target
,
23 const Toolchain
* toolchain
,
25 : settings_(target
->settings()),
27 toolchain_(toolchain
),
29 path_output_(settings_
->build_settings()->build_dir(),
32 helper_(settings_
->build_settings()) {
35 NinjaTargetWriter::~NinjaTargetWriter() {
39 void NinjaTargetWriter::RunAndWriteFile(const Target
* target
,
40 const Toolchain
* toolchain
) {
41 const Settings
* settings
= target
->settings();
42 NinjaHelper
helper(settings
->build_settings());
44 ScopedTrace
trace(TraceItem::TRACE_FILE_WRITE
,
45 target
->label().GetUserVisibleName(false));
46 trace
.SetToolchain(settings
->toolchain_label());
48 base::FilePath
ninja_file(settings
->build_settings()->GetFullPath(
49 helper
.GetNinjaFileForTarget(target
).GetSourceFile(
50 settings
->build_settings())));
52 if (g_scheduler
->verbose_logging())
53 g_scheduler
->Log("Writing", FilePathToUTF8(ninja_file
));
55 base::CreateDirectory(ninja_file
.DirName());
57 // It's rediculously faster to write to a string and then write that to
58 // disk in one operation than to use an fstream here.
59 std::stringstream file
;
61 // Call out to the correct sub-type of writer.
62 if (target
->output_type() == Target::COPY_FILES
) {
63 NinjaCopyTargetWriter
writer(target
, toolchain
, file
);
65 } else if (target
->output_type() == Target::ACTION
||
66 target
->output_type() == Target::ACTION_FOREACH
) {
67 NinjaActionTargetWriter
writer(target
, toolchain
, file
);
69 } else if (target
->output_type() == Target::GROUP
) {
70 NinjaGroupTargetWriter
writer(target
, toolchain
, file
);
72 } else if (target
->output_type() == Target::EXECUTABLE
||
73 target
->output_type() == Target::STATIC_LIBRARY
||
74 target
->output_type() == Target::SHARED_LIBRARY
||
75 target
->output_type() == Target::SOURCE_SET
) {
76 NinjaBinaryTargetWriter
writer(target
, toolchain
, file
);
82 std::string contents
= file
.str();
83 base::WriteFile(ninja_file
, contents
.c_str(),
84 static_cast<int>(contents
.size()));
87 std::string
NinjaTargetWriter::GetSourcesImplicitDeps() const {
88 std::ostringstream ret
;
91 // Input files are order-only deps.
92 const Target::FileList
& prereqs
= target_
->source_prereqs();
93 bool has_files
= !prereqs
.empty();
94 for (size_t i
= 0; i
< prereqs
.size(); i
++) {
96 path_output_
.WriteFile(ret
, prereqs
[i
]);
99 // Add on any direct deps marked as "hard".
100 const LabelTargetVector
& deps
= target_
->deps();
101 for (size_t i
= 0; i
< deps
.size(); i
++) {
102 if (deps
[i
].ptr
->hard_dep()) {
105 path_output_
.WriteFile(ret
, helper_
.GetTargetOutputFile(deps
[i
].ptr
));
111 return std::string(); // No files added.
114 FileTemplate
NinjaTargetWriter::GetOutputTemplate() const {
115 const Target::FileList
& outputs
= target_
->action_values().outputs();
116 std::vector
<std::string
> output_template_args
;
117 for (size_t i
= 0; i
< outputs
.size(); i
++) {
118 // All outputs should be in the output dir.
119 output_template_args
.push_back(
120 RemovePrefix(outputs
[i
].value(),
121 settings_
->build_settings()->build_dir().value()));
123 return FileTemplate(output_template_args
);