OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "tools/gn/ninja_binary_target_writer.h" | 5 #include "tools/gn/ninja_binary_target_writer.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 #include <sstream> | 8 #include <sstream> |
9 | 9 |
10 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 WRITE_FLAGS(cflags_objc, SUBSTITUTION_CFLAGS_OBJC) | 126 WRITE_FLAGS(cflags_objc, SUBSTITUTION_CFLAGS_OBJC) |
127 WRITE_FLAGS(cflags_objcc, SUBSTITUTION_CFLAGS_OBJCC) | 127 WRITE_FLAGS(cflags_objcc, SUBSTITUTION_CFLAGS_OBJCC) |
128 | 128 |
129 #undef WRITE_FLAGS | 129 #undef WRITE_FLAGS |
130 | 130 |
131 WriteSharedVars(subst); | 131 WriteSharedVars(subst); |
132 } | 132 } |
133 | 133 |
134 void NinjaBinaryTargetWriter::WriteSources( | 134 void NinjaBinaryTargetWriter::WriteSources( |
135 std::vector<OutputFile>* object_files) { | 135 std::vector<OutputFile>* object_files) { |
136 const Target::FileList& sources = target_->sources(); | 136 object_files->reserve(target_->sources().size()); |
137 object_files->reserve(sources.size()); | |
138 | 137 |
139 OutputFile input_dep = | 138 OutputFile input_dep = |
140 WriteInputDepsStampAndGetDep(std::vector<const Target*>()); | 139 WriteInputDepsStampAndGetDep(std::vector<const Target*>()); |
141 | 140 |
142 std::string rule_prefix = GetNinjaRulePrefixForToolchain(settings_); | 141 std::string rule_prefix = GetNinjaRulePrefixForToolchain(settings_); |
143 | 142 |
144 std::vector<OutputFile> tool_outputs; // Prevent reallocation in loop. | 143 std::vector<OutputFile> tool_outputs; // Prevent reallocation in loop. |
145 for (size_t i = 0; i < sources.size(); i++) { | 144 for (const auto& source : target_->sources()) { |
146 Toolchain::ToolType tool_type = Toolchain::TYPE_NONE; | 145 Toolchain::ToolType tool_type = Toolchain::TYPE_NONE; |
147 if (!GetOutputFilesForSource(target_, sources[i], | 146 if (!GetOutputFilesForSource(target_, source, |
148 &tool_type, &tool_outputs)) | 147 &tool_type, &tool_outputs)) |
149 continue; // No output for this source. | 148 continue; // No output for this source. |
150 | 149 |
151 if (tool_type != Toolchain::TYPE_NONE) { | 150 if (tool_type != Toolchain::TYPE_NONE) { |
152 out_ << "build"; | 151 out_ << "build"; |
153 path_output_.WriteFiles(out_, tool_outputs); | 152 path_output_.WriteFiles(out_, tool_outputs); |
154 out_ << ": " << rule_prefix << Toolchain::ToolTypeToName(tool_type); | 153 out_ << ": " << rule_prefix << Toolchain::ToolTypeToName(tool_type); |
155 out_ << " "; | 154 out_ << " "; |
156 path_output_.WriteFile(out_, sources[i]); | 155 path_output_.WriteFile(out_, source); |
157 if (!input_dep.value().empty()) { | 156 if (!input_dep.value().empty()) { |
158 // Write out the input dependencies as an order-only dependency. This | 157 // Write out the input dependencies as an order-only dependency. This |
159 // will cause Ninja to make sure the inputs are up-to-date before | 158 // will cause Ninja to make sure the inputs are up-to-date before |
160 // compiling this source, but changes in the inputs deps won't cause | 159 // compiling this source, but changes in the inputs deps won't cause |
161 // the file to be recompiled. | 160 // the file to be recompiled. |
162 // | 161 // |
163 // This is important to prevent changes in unrelated actions that | 162 // This is important to prevent changes in unrelated actions that |
164 // are upstream of this target from causing everything to be recompiled. | 163 // are upstream of this target from causing everything to be recompiled. |
165 // | 164 // |
166 // Why can we get away with this rather than using implicit deps ("|", | 165 // Why can we get away with this rather than using implicit deps ("|", |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 << GetNinjaRulePrefixForToolchain(settings_) | 204 << GetNinjaRulePrefixForToolchain(settings_) |
206 << Toolchain::ToolTypeToName( | 205 << Toolchain::ToolTypeToName( |
207 target_->toolchain()->GetToolTypeForTargetFinalOutput(target_)); | 206 target_->toolchain()->GetToolTypeForTargetFinalOutput(target_)); |
208 | 207 |
209 UniqueVector<OutputFile> extra_object_files; | 208 UniqueVector<OutputFile> extra_object_files; |
210 UniqueVector<const Target*> linkable_deps; | 209 UniqueVector<const Target*> linkable_deps; |
211 UniqueVector<const Target*> non_linkable_deps; | 210 UniqueVector<const Target*> non_linkable_deps; |
212 GetDeps(&extra_object_files, &linkable_deps, &non_linkable_deps); | 211 GetDeps(&extra_object_files, &linkable_deps, &non_linkable_deps); |
213 | 212 |
214 // Object files. | 213 // Object files. |
215 for (size_t i = 0; i < object_files.size(); i++) { | 214 for (const auto& obj : object_files) { |
216 out_ << " "; | 215 out_ << " "; |
217 path_output_.WriteFile(out_, object_files[i]); | 216 path_output_.WriteFile(out_, obj); |
218 } | 217 } |
219 for (size_t i = 0; i < extra_object_files.size(); i++) { | 218 for (const auto& obj : extra_object_files) { |
220 out_ << " "; | 219 out_ << " "; |
221 path_output_.WriteFile(out_, extra_object_files[i]); | 220 path_output_.WriteFile(out_, obj); |
222 } | 221 } |
223 | 222 |
224 std::vector<OutputFile> implicit_deps; | 223 std::vector<OutputFile> implicit_deps; |
225 std::vector<OutputFile> solibs; | 224 std::vector<OutputFile> solibs; |
226 | 225 |
227 for (size_t i = 0; i < linkable_deps.size(); i++) { | 226 for (const Target* cur : linkable_deps) { |
228 const Target* cur = linkable_deps[i]; | |
229 | |
230 // All linkable deps should have a link output file. | 227 // All linkable deps should have a link output file. |
231 DCHECK(!cur->link_output_file().value().empty()) | 228 DCHECK(!cur->link_output_file().value().empty()) |
232 << "No link output file for " | 229 << "No link output file for " |
233 << target_->label().GetUserVisibleName(false); | 230 << target_->label().GetUserVisibleName(false); |
234 | 231 |
235 if (cur->dependency_output_file().value() != | 232 if (cur->dependency_output_file().value() != |
236 cur->link_output_file().value()) { | 233 cur->link_output_file().value()) { |
237 // This is a shared library with separate link and deps files. Save for | 234 // This is a shared library with separate link and deps files. Save for |
238 // later. | 235 // later. |
239 implicit_deps.push_back(cur->dependency_output_file()); | 236 implicit_deps.push_back(cur->dependency_output_file()); |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
358 UniqueVector<const Target*> linkable_deps; | 355 UniqueVector<const Target*> linkable_deps; |
359 UniqueVector<const Target*> non_linkable_deps; | 356 UniqueVector<const Target*> non_linkable_deps; |
360 GetDeps(&extra_object_files, &linkable_deps, &non_linkable_deps); | 357 GetDeps(&extra_object_files, &linkable_deps, &non_linkable_deps); |
361 | 358 |
362 // The classifier should never put extra object files in a source set: | 359 // The classifier should never put extra object files in a source set: |
363 // any source sets that we depend on should appear in our non-linkable | 360 // any source sets that we depend on should appear in our non-linkable |
364 // deps instead. | 361 // deps instead. |
365 DCHECK(extra_object_files.empty()); | 362 DCHECK(extra_object_files.empty()); |
366 | 363 |
367 std::vector<OutputFile> order_only_deps; | 364 std::vector<OutputFile> order_only_deps; |
368 for (size_t i = 0; i < non_linkable_deps.size(); i++) | 365 for (const auto& dep : non_linkable_deps) |
369 order_only_deps.push_back(non_linkable_deps[i]->dependency_output_file()); | 366 order_only_deps.push_back(dep->dependency_output_file()); |
370 | 367 |
371 WriteStampForTarget(object_files, order_only_deps); | 368 WriteStampForTarget(object_files, order_only_deps); |
372 } | 369 } |
373 | 370 |
374 void NinjaBinaryTargetWriter::GetDeps( | 371 void NinjaBinaryTargetWriter::GetDeps( |
375 UniqueVector<OutputFile>* extra_object_files, | 372 UniqueVector<OutputFile>* extra_object_files, |
376 UniqueVector<const Target*>* linkable_deps, | 373 UniqueVector<const Target*>* linkable_deps, |
377 UniqueVector<const Target*>* non_linkable_deps) const { | 374 UniqueVector<const Target*>* non_linkable_deps) const { |
378 // Normal public/private deps. | 375 // Normal public/private deps. |
379 for (const auto& pair : target_->GetDeps(Target::DEPS_LINKED)) { | 376 for (const auto& pair : target_->GetDeps(Target::DEPS_LINKED)) { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
411 // Source sets have their object files linked into final targets | 408 // Source sets have their object files linked into final targets |
412 // (shared libraries, executables, and complete static | 409 // (shared libraries, executables, and complete static |
413 // libraries). Intermediate static libraries and other source sets | 410 // libraries). Intermediate static libraries and other source sets |
414 // just forward the dependency, otherwise the files in the source | 411 // just forward the dependency, otherwise the files in the source |
415 // set can easily get linked more than once which will cause | 412 // set can easily get linked more than once which will cause |
416 // multiple definition errors. | 413 // multiple definition errors. |
417 if (can_link_libs) { | 414 if (can_link_libs) { |
418 // Linking in a source set to an executable, shared library, or | 415 // Linking in a source set to an executable, shared library, or |
419 // complete static library, so copy its object files. | 416 // complete static library, so copy its object files. |
420 std::vector<OutputFile> tool_outputs; // Prevent allocation in loop. | 417 std::vector<OutputFile> tool_outputs; // Prevent allocation in loop. |
421 for (size_t i = 0; i < dep->sources().size(); i++) { | 418 for (const auto& source : dep->sources()) { |
422 Toolchain::ToolType tool_type = Toolchain::TYPE_NONE; | 419 Toolchain::ToolType tool_type = Toolchain::TYPE_NONE; |
423 if (GetOutputFilesForSource(dep, dep->sources()[i], &tool_type, | 420 if (GetOutputFilesForSource(dep, source, &tool_type, &tool_outputs)) { |
424 &tool_outputs)) { | |
425 // Only link the first output if there are more than one. | 421 // Only link the first output if there are more than one. |
426 extra_object_files->push_back(tool_outputs[0]); | 422 extra_object_files->push_back(tool_outputs[0]); |
427 } | 423 } |
428 } | 424 } |
429 } | 425 } |
430 } else if (can_link_libs && dep->IsLinkable()) { | 426 } else if (can_link_libs && dep->IsLinkable()) { |
431 linkable_deps->push_back(dep); | 427 linkable_deps->push_back(dep); |
432 } else { | 428 } else { |
433 non_linkable_deps->push_back(dep); | 429 non_linkable_deps->push_back(dep); |
434 } | 430 } |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
472 return false; // No tool for this file (it's a header file or something). | 468 return false; // No tool for this file (it's a header file or something). |
473 const Tool* tool = target->toolchain()->GetTool(*computed_tool_type); | 469 const Tool* tool = target->toolchain()->GetTool(*computed_tool_type); |
474 if (!tool) | 470 if (!tool) |
475 return false; // Tool does not apply for this toolchain.file. | 471 return false; // Tool does not apply for this toolchain.file. |
476 | 472 |
477 // Figure out what output(s) this compiler produces. | 473 // Figure out what output(s) this compiler produces. |
478 SubstitutionWriter::ApplyListToCompilerAsOutputFile( | 474 SubstitutionWriter::ApplyListToCompilerAsOutputFile( |
479 target, source, tool->outputs(), outputs); | 475 target, source, tool->outputs(), outputs); |
480 return !outputs->empty(); | 476 return !outputs->empty(); |
481 } | 477 } |
OLD | NEW |