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 |