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