Chromium Code Reviews| 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 <cstring> | 7 #include <cstring> |
| 8 #include <set> | 8 #include <set> |
| 9 #include <sstream> | 9 #include <sstream> |
| 10 | 10 |
| (...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 344 // added as explicit dependencies below. The .gch output files are placed in | 344 // added as explicit dependencies below. The .gch output files are placed in |
| 345 // |pch_other_files|. This is to prevent linking against them. | 345 // |pch_other_files|. This is to prevent linking against them. |
| 346 std::vector<OutputFile> pch_obj_files; | 346 std::vector<OutputFile> pch_obj_files; |
| 347 std::vector<OutputFile> pch_other_files; | 347 std::vector<OutputFile> pch_other_files; |
| 348 WritePCHCommands(used_types, order_only_dep, | 348 WritePCHCommands(used_types, order_only_dep, |
| 349 &pch_obj_files, &pch_other_files); | 349 &pch_obj_files, &pch_other_files); |
| 350 std::vector<OutputFile>* pch_files = !pch_obj_files.empty() ? | 350 std::vector<OutputFile>* pch_files = !pch_obj_files.empty() ? |
| 351 &pch_obj_files : &pch_other_files; | 351 &pch_obj_files : &pch_other_files; |
| 352 | 352 |
| 353 // Treat all pch output files as explicit dependencies of all | 353 // Treat all pch output files as explicit dependencies of all |
| 354 // compiles. Some notes: | 354 // compiles that support them. Some notes: |
| 355 // | |
| 356 // - Only the language-specific one is required for any specific compile, but | |
| 357 // that's more difficult to express and the additional logic doesn't buy | |
| 358 // much reduced parallelism. Just list them all (there's usually only one | |
| 359 // anyway). | |
| 360 // | 355 // |
| 361 // - On Windows, the .pch file is the input to the compile, not the | 356 // - On Windows, the .pch file is the input to the compile, not the |
| 362 // precompiled header's corresponding object file that we're using here. | 357 // precompiled header's corresponding object file that we're using here. |
| 363 // But Ninja's depslog doesn't support multiple outputs from the | 358 // But Ninja's depslog doesn't support multiple outputs from the |
| 364 // precompiled header compile step (it outputs both the .pch file and a | 359 // precompiled header compile step (it outputs both the .pch file and a |
| 365 // corresponding .obj file). So we consistently list the .obj file and the | 360 // corresponding .obj file). So we consistently list the .obj file and the |
| 366 // .pch file we really need comes along with it. | 361 // .pch file we really need comes along with it. |
| 367 // | 362 // |
| 368 // - GCC .gch files are not object files, therefore they are not added to the | 363 // - GCC .gch files are not object files, therefore they are not added to the |
| 369 // object file list. | 364 // object file list. |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 413 ESCAPE_NINJA_COMMAND); | 408 ESCAPE_NINJA_COMMAND); |
| 414 RecursiveTargetConfigToStream<SourceDir>( | 409 RecursiveTargetConfigToStream<SourceDir>( |
| 415 target_, &ConfigValues::include_dirs, | 410 target_, &ConfigValues::include_dirs, |
| 416 IncludeWriter(include_path_output), out_); | 411 IncludeWriter(include_path_output), out_); |
| 417 out_ << std::endl; | 412 out_ << std::endl; |
| 418 } | 413 } |
| 419 | 414 |
| 420 bool has_precompiled_headers = | 415 bool has_precompiled_headers = |
| 421 target_->config_values().has_precompiled_headers(); | 416 target_->config_values().has_precompiled_headers(); |
| 422 | 417 |
| 423 // Some toolchains pass cflags to the assembler since it's the same command. | |
| 424 EscapeOptions opts = GetFlagOptions(); | 418 EscapeOptions opts = GetFlagOptions(); |
| 419 if (used_types.Get(SOURCE_S) || used_types.Get(SOURCE_ASM)) { | |
| 420 WriteOneFlag(SUBSTITUTION_ASMFLAGS, false, Toolchain::TYPE_NONE, | |
| 421 &ConfigValues::asmflags, opts); | |
| 422 } | |
| 425 if (used_types.Get(SOURCE_C) || used_types.Get(SOURCE_CPP) || | 423 if (used_types.Get(SOURCE_C) || used_types.Get(SOURCE_CPP) || |
| 426 used_types.Get(SOURCE_M) || used_types.Get(SOURCE_MM) || | 424 used_types.Get(SOURCE_M) || used_types.Get(SOURCE_MM)) { |
| 427 used_types.Get(SOURCE_S) || used_types.Get(SOURCE_ASM)) { | |
|
brettw
2015/09/24 18:30:09
Can you leave the S/ASM check in here and below wi
Bons
2015/09/24 19:41:54
Done.
| |
| 428 WriteOneFlag(SUBSTITUTION_CFLAGS, false, Toolchain::TYPE_NONE, | 425 WriteOneFlag(SUBSTITUTION_CFLAGS, false, Toolchain::TYPE_NONE, |
| 429 &ConfigValues::cflags, opts); | 426 &ConfigValues::cflags, opts); |
| 430 } | 427 } |
| 431 if (used_types.Get(SOURCE_C) || used_types.Get(SOURCE_S) || | 428 if (used_types.Get(SOURCE_C)) { |
| 432 used_types.Get(SOURCE_ASM)) { | |
| 433 WriteOneFlag(SUBSTITUTION_CFLAGS_C, has_precompiled_headers, | 429 WriteOneFlag(SUBSTITUTION_CFLAGS_C, has_precompiled_headers, |
| 434 Toolchain::TYPE_CC, &ConfigValues::cflags_c, opts); | 430 Toolchain::TYPE_CC, &ConfigValues::cflags_c, opts); |
| 435 } | 431 } |
| 436 if (used_types.Get(SOURCE_CPP)) { | 432 if (used_types.Get(SOURCE_CPP)) { |
| 437 WriteOneFlag(SUBSTITUTION_CFLAGS_CC, has_precompiled_headers, | 433 WriteOneFlag(SUBSTITUTION_CFLAGS_CC, has_precompiled_headers, |
| 438 Toolchain::TYPE_CXX, &ConfigValues::cflags_cc, opts); | 434 Toolchain::TYPE_CXX, &ConfigValues::cflags_cc, opts); |
| 439 } | 435 } |
| 440 if (used_types.Get(SOURCE_M)) { | 436 if (used_types.Get(SOURCE_M)) { |
| 441 WriteOneFlag(SUBSTITUTION_CFLAGS_OBJC, has_precompiled_headers, | 437 WriteOneFlag(SUBSTITUTION_CFLAGS_OBJC, has_precompiled_headers, |
| 442 Toolchain::TYPE_OBJC, &ConfigValues::cflags_objc, opts); | 438 Toolchain::TYPE_OBJC, &ConfigValues::cflags_objc, opts); |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 671 | 667 |
| 672 if (tool_type != Toolchain::TYPE_NONE) { | 668 if (tool_type != Toolchain::TYPE_NONE) { |
| 673 // Only include PCH deps that correspond to the tool type, for instance, | 669 // Only include PCH deps that correspond to the tool type, for instance, |
| 674 // do not specify target_name.precompile.cc.o (a CXX PCH file) as a dep | 670 // do not specify target_name.precompile.cc.o (a CXX PCH file) as a dep |
| 675 // for the output of a C tool type. | 671 // for the output of a C tool type. |
| 676 // | 672 // |
| 677 // This makes the assumption that pch_deps only contains pch output files | 673 // This makes the assumption that pch_deps only contains pch output files |
| 678 // with the naming scheme specified in GetWindowsPCHObjectExtension or | 674 // with the naming scheme specified in GetWindowsPCHObjectExtension or |
| 679 // GetGCCPCHOutputExtension. | 675 // GetGCCPCHOutputExtension. |
| 680 const Tool* tool = target_->toolchain()->GetTool(tool_type); | 676 const Tool* tool = target_->toolchain()->GetTool(tool_type); |
| 681 for (const auto& dep : pch_deps) { | 677 if (tool->precompiled_header_type() != Tool::PCH_NONE) { |
| 682 const std::string& output_value = dep.value(); | 678 for (const auto& dep : pch_deps) { |
| 683 std::string output_extension; | 679 const std::string& output_value = dep.value(); |
| 684 if (tool->precompiled_header_type() == Tool::PCH_MSVC) { | 680 std::string output_extension; |
| 685 output_extension = GetWindowsPCHObjectExtension(tool_type); | 681 if (tool->precompiled_header_type() == Tool::PCH_MSVC) { |
| 686 } else if (tool->precompiled_header_type() == Tool::PCH_GCC) { | 682 output_extension = GetWindowsPCHObjectExtension(tool_type); |
| 687 output_extension = GetGCCPCHOutputExtension(tool_type); | 683 } else if (tool->precompiled_header_type() == Tool::PCH_GCC) { |
| 688 } | 684 output_extension = GetGCCPCHOutputExtension(tool_type); |
| 689 if (output_value.compare(output_value.size() - output_extension.size(), | 685 } |
| 690 output_extension.size(), output_extension) == 0) { | 686 if (output_value.compare(output_value.size() - |
| 691 deps.push_back(dep); | 687 output_extension.size(), output_extension.size(), |
| 688 output_extension) == 0) { | |
| 689 deps.push_back(dep); | |
| 690 } | |
| 692 } | 691 } |
| 693 } | 692 } |
| 694 WriteCompilerBuildLine(source, deps, order_only_dep, tool_type, | 693 WriteCompilerBuildLine(source, deps, order_only_dep, tool_type, |
| 695 tool_outputs); | 694 tool_outputs); |
| 696 } | 695 } |
| 697 | 696 |
| 698 // It's theoretically possible for a compiler to produce more than one | 697 // It's theoretically possible for a compiler to produce more than one |
| 699 // output, but we'll only link to the first output. | 698 // output, but we'll only link to the first output. |
| 700 object_files->push_back(tool_outputs[0]); | 699 object_files->push_back(tool_outputs[0]); |
| 701 } | 700 } |
| (...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1029 "\n" | 1028 "\n" |
| 1030 "In the latter case, either rename one of the files or move one of\n" | 1029 "In the latter case, either rename one of the files or move one of\n" |
| 1031 "the sources to a separate source_set to avoid them both being in\n" | 1030 "the sources to a separate source_set to avoid them both being in\n" |
| 1032 "the same target."); | 1031 "the same target."); |
| 1033 g_scheduler->FailWithError(err); | 1032 g_scheduler->FailWithError(err); |
| 1034 return false; | 1033 return false; |
| 1035 } | 1034 } |
| 1036 } | 1035 } |
| 1037 return true; | 1036 return true; |
| 1038 } | 1037 } |
| OLD | NEW |