| 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 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 402 // Only the following types of outputs have libraries linked into them: | 402 // Only the following types of outputs have libraries linked into them: |
| 403 // EXECUTABLE | 403 // EXECUTABLE |
| 404 // SHARED_LIBRARY | 404 // SHARED_LIBRARY |
| 405 // _complete_ STATIC_LIBRARY | 405 // _complete_ STATIC_LIBRARY |
| 406 // | 406 // |
| 407 // Child deps of intermediate static libraries get pushed up the | 407 // Child deps of intermediate static libraries get pushed up the |
| 408 // dependency tree until one of these is reached, and source sets | 408 // dependency tree until one of these is reached, and source sets |
| 409 // don't link at all. | 409 // don't link at all. |
| 410 bool can_link_libs = target_->IsFinal(); | 410 bool can_link_libs = target_->IsFinal(); |
| 411 | 411 |
| 412 if (dep->output_type() == Target::SOURCE_SET) { | 412 if (dep->output_type() == Target::SOURCE_SET || |
| 413 // If a complete static library depends on an incomplete static library, |
| 414 // manually link in the object files of the dependent library as if it |
| 415 // were a source set. This avoids problems with braindead tools such as |
| 416 // ar which don't properly link dependent static libraries. |
| 417 (target_->complete_static_lib() && |
| 418 dep->output_type() == Target::STATIC_LIBRARY && |
| 419 !dep->complete_static_lib())) { |
| 413 // Source sets have their object files linked into final targets | 420 // Source sets have their object files linked into final targets |
| 414 // (shared libraries, executables, and complete static | 421 // (shared libraries, executables, and complete static |
| 415 // libraries). Intermediate static libraries and other source sets | 422 // libraries). Intermediate static libraries and other source sets |
| 416 // just forward the dependency, otherwise the files in the source | 423 // just forward the dependency, otherwise the files in the source |
| 417 // set can easily get linked more than once which will cause | 424 // set can easily get linked more than once which will cause |
| 418 // multiple definition errors. | 425 // multiple definition errors. |
| 419 if (can_link_libs) { | 426 if (can_link_libs) { |
| 420 // Linking in a source set to an executable, shared library, or | 427 // Linking in a source set to an executable, shared library, or |
| 421 // complete static library, so copy its object files. | 428 // complete static library, so copy its object files. |
| 422 std::vector<OutputFile> tool_outputs; // Prevent allocation in loop. | 429 std::vector<OutputFile> tool_outputs; // Prevent allocation in loop. |
| 423 for (const auto& source : dep->sources()) { | 430 for (const auto& source : dep->sources()) { |
| 424 Toolchain::ToolType tool_type = Toolchain::TYPE_NONE; | 431 Toolchain::ToolType tool_type = Toolchain::TYPE_NONE; |
| 425 if (GetOutputFilesForSource(dep, source, &tool_type, &tool_outputs)) { | 432 if (GetOutputFilesForSource(dep, source, &tool_type, &tool_outputs)) { |
| 426 // Only link the first output if there are more than one. | 433 // Only link the first output if there are more than one. |
| 427 extra_object_files->push_back(tool_outputs[0]); | 434 extra_object_files->push_back(tool_outputs[0]); |
| 428 } | 435 } |
| 429 } | 436 } |
| 430 } | 437 } |
| 431 | |
| 432 // Add the source set itself as a non-linkable dependency on the current | 438 // Add the source set itself as a non-linkable dependency on the current |
| 433 // target. This will make sure that anything the source set's stamp file | 439 // target. This will make sure that anything the source set's stamp file |
| 434 // depends on (like data deps) are also built before the current target | 440 // depends on (like data deps) are also built before the current target |
| 435 // can be complete. Otherwise, these will be skipped since this target | 441 // can be complete. Otherwise, these will be skipped since this target |
| 436 // will depend only on the source set's object files. | 442 // will depend only on the source set's object files. |
| 437 non_linkable_deps->push_back(dep); | 443 non_linkable_deps->push_back(dep); |
| 444 } else if (target_->complete_static_lib() && dep->IsFinal()) { |
| 445 non_linkable_deps->push_back(dep); |
| 438 } else if (can_link_libs && dep->IsLinkable()) { | 446 } else if (can_link_libs && dep->IsLinkable()) { |
| 439 linkable_deps->push_back(dep); | 447 linkable_deps->push_back(dep); |
| 440 } else { | 448 } else { |
| 441 non_linkable_deps->push_back(dep); | 449 non_linkable_deps->push_back(dep); |
| 442 } | 450 } |
| 443 } | 451 } |
| 444 | 452 |
| 445 void NinjaBinaryTargetWriter::WriteOrderOnlyDependencies( | 453 void NinjaBinaryTargetWriter::WriteOrderOnlyDependencies( |
| 446 const UniqueVector<const Target*>& non_linkable_deps) { | 454 const UniqueVector<const Target*>& non_linkable_deps) { |
| 447 if (!non_linkable_deps.empty()) { | 455 if (!non_linkable_deps.empty()) { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 478 return false; // No tool for this file (it's a header file or something). | 486 return false; // No tool for this file (it's a header file or something). |
| 479 const Tool* tool = target->toolchain()->GetTool(*computed_tool_type); | 487 const Tool* tool = target->toolchain()->GetTool(*computed_tool_type); |
| 480 if (!tool) | 488 if (!tool) |
| 481 return false; // Tool does not apply for this toolchain.file. | 489 return false; // Tool does not apply for this toolchain.file. |
| 482 | 490 |
| 483 // Figure out what output(s) this compiler produces. | 491 // Figure out what output(s) this compiler produces. |
| 484 SubstitutionWriter::ApplyListToCompilerAsOutputFile( | 492 SubstitutionWriter::ApplyListToCompilerAsOutputFile( |
| 485 target, source, tool->outputs(), outputs); | 493 target, source, tool->outputs(), outputs); |
| 486 return !outputs->empty(); | 494 return !outputs->empty(); |
| 487 } | 495 } |
| OLD | NEW |