| 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_target_writer.h" | 5 #include "tools/gn/ninja_target_writer.h" |
| 6 | 6 |
| 7 #include <fstream> | 7 #include <fstream> |
| 8 #include <sstream> | 8 #include <sstream> |
| 9 | 9 |
| 10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 222 for (size_t i = 0; i < target_->script_args().size(); i++) { | 222 for (size_t i = 0; i < target_->script_args().size(); i++) { |
| 223 const std::string& arg = target_->script_args()[i]; | 223 const std::string& arg = target_->script_args()[i]; |
| 224 out_ << " "; | 224 out_ << " "; |
| 225 WriteCustomArg(arg); | 225 WriteCustomArg(arg); |
| 226 } | 226 } |
| 227 out_ << std::endl << std::endl; | 227 out_ << std::endl << std::endl; |
| 228 | 228 |
| 229 // Precompute the common dependencies for each step. This includes the | 229 // Precompute the common dependencies for each step. This includes the |
| 230 // script itself (changing the script should force a rebuild) and any data | 230 // script itself (changing the script should force a rebuild) and any data |
| 231 // files. | 231 // files. |
| 232 // |
| 233 // TODO(brettW) this needs to be re-thought. "data" is supposed to be runtime |
| 234 // data (i.e. for tests and such) rather than compile-time dependencies for |
| 235 // each target. If we really need this, we need to have a different way to |
| 236 // express it. |
| 237 // |
| 238 // One idea: add an "inputs" variable to specify this kind of thing. We |
| 239 // should probably make it an error to specify data but no inputs for a |
| 240 // script as a way to catch people doing the wrong way. |
| 232 std::ostringstream common_deps_stream; | 241 std::ostringstream common_deps_stream; |
| 233 path_output_.WriteFile(common_deps_stream, target_->script()); | 242 path_output_.WriteFile(common_deps_stream, target_->script()); |
| 234 const Target::FileList& datas = target_->data(); | 243 const Target::FileList& datas = target_->data(); |
| 235 for (size_t i = 0; i < datas.size(); i++) { | 244 for (size_t i = 0; i < datas.size(); i++) { |
| 236 common_deps_stream << " "; | 245 common_deps_stream << " "; |
| 237 path_output_.WriteFile(common_deps_stream, datas[i]); | 246 path_output_.WriteFile(common_deps_stream, datas[i]); |
| 238 } | 247 } |
| 239 const std::string& common_deps = common_deps_stream.str(); | 248 const std::string& common_deps = common_deps_stream.str(); |
| 240 | 249 |
| 241 // Collects all output files for writing below. | 250 // Collects all output files for writing below. |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 450 if (target_->output_type() == Target::SHARED_LIBRARY) { | 459 if (target_->output_type() == Target::SHARED_LIBRARY) { |
| 451 if (settings_->IsWin()) { | 460 if (settings_->IsWin()) { |
| 452 internal_output_file = OutputFile(target_->label().name() + ".dll"); | 461 internal_output_file = OutputFile(target_->label().name() + ".dll"); |
| 453 } else { | 462 } else { |
| 454 internal_output_file = external_output_file; | 463 internal_output_file = external_output_file; |
| 455 } | 464 } |
| 456 } else { | 465 } else { |
| 457 internal_output_file = external_output_file; | 466 internal_output_file = external_output_file; |
| 458 } | 467 } |
| 459 | 468 |
| 460 // TODO(brettw) should we append data files to this? | |
| 461 | |
| 462 // In Python see "self.ninja.build(output, command, input," | 469 // In Python see "self.ninja.build(output, command, input," |
| 463 out_ << "build "; | 470 WriteLinkCommand(external_output_file, internal_output_file, object_files); |
| 464 path_output_.WriteFile(out_, internal_output_file); | |
| 465 if (external_output_file != internal_output_file) { | |
| 466 out_ << " "; | |
| 467 path_output_.WriteFile(out_, external_output_file); | |
| 468 } | |
| 469 out_ << ": " << GetCommandForTargetType(); | |
| 470 for (size_t i = 0; i < object_files.size(); i++) { | |
| 471 out_ << " "; | |
| 472 path_output_.WriteFile(out_, object_files[i]); | |
| 473 } | |
| 474 | |
| 475 if (target_->output_type() == Target::EXECUTABLE || | |
| 476 target_->output_type() == Target::SHARED_LIBRARY || | |
| 477 target_->output_type() == Target::LOADABLE_MODULE) { | |
| 478 const std::vector<const Target*>& deps = target_->deps(); | |
| 479 const std::set<const Target*>& inherited = target_->inherited_libraries(); | |
| 480 | |
| 481 // Now append linkable libraries to the linker command. | |
| 482 for (size_t i = 0; i < deps.size(); i++) { | |
| 483 if (deps[i]->IsLinkable() && | |
| 484 inherited.find(deps[i]) == inherited.end()) { | |
| 485 out_ << " "; | |
| 486 path_output_.WriteFile(out_, | |
| 487 helper_.GetTargetOutputFile(target_->deps()[i])); | |
| 488 } | |
| 489 } | |
| 490 for (std::set<const Target*>::const_iterator i = inherited.begin(); | |
| 491 i != inherited.end(); ++i) { | |
| 492 out_ << " "; | |
| 493 path_output_.WriteFile(out_, helper_.GetTargetOutputFile(*i)); | |
| 494 } | |
| 495 } | |
| 496 out_ << std::endl; | |
| 497 | 471 |
| 498 if (target_->output_type() == Target::SHARED_LIBRARY) { | 472 if (target_->output_type() == Target::SHARED_LIBRARY) { |
| 499 out_ << " soname = "; | 473 out_ << " soname = "; |
| 500 path_output_.WriteFile(out_, internal_output_file); | 474 path_output_.WriteFile(out_, internal_output_file); |
| 501 out_ << std::endl; | 475 out_ << std::endl; |
| 502 | 476 |
| 503 out_ << " lib = "; | 477 out_ << " lib = "; |
| 504 path_output_.WriteFile(out_, internal_output_file); | 478 path_output_.WriteFile(out_, internal_output_file); |
| 505 out_ << std::endl; | 479 out_ << std::endl; |
| 506 | 480 |
| 507 out_ << " dll = "; | 481 out_ << " dll = "; |
| 508 path_output_.WriteFile(out_, internal_output_file); | 482 path_output_.WriteFile(out_, internal_output_file); |
| 509 out_ << std::endl; | 483 out_ << std::endl; |
| 510 | 484 |
| 511 if (settings_->IsWin()) { | 485 if (settings_->IsWin()) { |
| 512 out_ << " implibflag = /IMPLIB:"; | 486 out_ << " implibflag = /IMPLIB:"; |
| 513 path_output_.WriteFile(out_, external_output_file); | 487 path_output_.WriteFile(out_, external_output_file); |
| 514 out_ << std::endl; | 488 out_ << std::endl; |
| 515 } | 489 } |
| 516 | 490 |
| 517 // TODO(brettw) postbuild steps. | 491 // TODO(brettw) postbuild steps. |
| 518 if (settings_->IsMac()) | 492 if (settings_->IsMac()) |
| 519 out_ << " postbuilds = $ && (export BUILT_PRODUCTS_DIR=/Users/brettw/prj/
src/out/gn; export CONFIGURATION=Debug; export DYLIB_INSTALL_NAME_BASE=@rpath; e
xport EXECUTABLE_NAME=libbase.dylib; export EXECUTABLE_PATH=libbase.dylib; expor
t FULL_PRODUCT_NAME=libbase.dylib; export LD_DYLIB_INSTALL_NAME=@rpath/libbase.d
ylib; export MACH_O_TYPE=mh_dylib; export PRODUCT_NAME=base; export PRODUCT_TYPE
=com.apple.product-type.library.dynamic; export SDKROOT=/Applications/Xcode.app/
Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk; expo
rt SRCROOT=/Users/brettw/prj/src/out/gn/../../base; export SOURCE_ROOT=\"$${SRCR
OOT}\"; export TARGET_BUILD_DIR=/Users/brettw/prj/src/out/gn; export TEMP_DIR=\"
$${TMPDIR}\"; (cd ../../base && ../build/mac/strip_from_xcode); G=$$?; ((exit $$
G) || rm -rf libbase.dylib) && exit $$G)"; | 493 out_ << " postbuilds = $ && (export BUILT_PRODUCTS_DIR=/Users/brettw/prj/
src/out/gn; export CONFIGURATION=Debug; export DYLIB_INSTALL_NAME_BASE=@rpath; e
xport EXECUTABLE_NAME=libbase.dylib; export EXECUTABLE_PATH=libbase.dylib; expor
t FULL_PRODUCT_NAME=libbase.dylib; export LD_DYLIB_INSTALL_NAME=@rpath/libbase.d
ylib; export MACH_O_TYPE=mh_dylib; export PRODUCT_NAME=base; export PRODUCT_TYPE
=com.apple.product-type.library.dynamic; export SDKROOT=/Applications/Xcode.app/
Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk; expo
rt SRCROOT=/Users/brettw/prj/src/out/gn/../../base; export SOURCE_ROOT=\"$${SRCR
OOT}\"; export TARGET_BUILD_DIR=/Users/brettw/prj/src/out/gn; export TEMP_DIR=\"
$${TMPDIR}\"; (cd ../../base && ../build/mac/strip_from_xcode); G=$$?; ((exit $$
G) || rm -rf libbase.dylib) && exit $$G)"; |
| 520 } | 494 } |
| 521 | 495 |
| 496 out_ << std::endl; |
| 497 } |
| 498 |
| 499 void NinjaTargetWriter::WriteLinkCommand( |
| 500 const OutputFile& external_output_file, |
| 501 const OutputFile& internal_output_file, |
| 502 const std::vector<OutputFile>& object_files) { |
| 503 out_ << "build "; |
| 504 path_output_.WriteFile(out_, internal_output_file); |
| 505 if (external_output_file != internal_output_file) { |
| 506 out_ << " "; |
| 507 path_output_.WriteFile(out_, external_output_file); |
| 508 } |
| 509 out_ << ": " << GetCommandForTargetType(); |
| 510 |
| 511 // Object files. |
| 512 for (size_t i = 0; i < object_files.size(); i++) { |
| 513 out_ << " "; |
| 514 path_output_.WriteFile(out_, object_files[i]); |
| 515 } |
| 516 |
| 517 // Library inputs (deps and inherited static libraries). |
| 518 // |
| 519 // Static libraries since they're just a collection of the object files so |
| 520 // don't need libraries linked with them, but we still need to go through |
| 521 // the list and find non-linkable data deps in the "deps" section. We'll |
| 522 // collect all non-linkable deps and put it in the order-only deps below. |
| 523 std::vector<const Target*> extra_data_deps; |
| 524 const std::vector<const Target*>& deps = target_->deps(); |
| 525 const std::set<const Target*>& inherited = target_->inherited_libraries(); |
| 526 for (size_t i = 0; i < deps.size(); i++) { |
| 527 if (inherited.find(deps[i]) != inherited.end()) |
| 528 continue; |
| 529 if (target_->output_type() != Target::STATIC_LIBRARY && |
| 530 deps[i]->IsLinkable()) { |
| 531 out_ << " "; |
| 532 path_output_.WriteFile(out_, helper_.GetTargetOutputFile(deps[i])); |
| 533 } else { |
| 534 extra_data_deps.push_back(deps[i]); |
| 535 } |
| 536 } |
| 537 for (std::set<const Target*>::const_iterator i = inherited.begin(); |
| 538 i != inherited.end(); ++i) { |
| 539 if (target_->output_type() == Target::STATIC_LIBRARY) { |
| 540 extra_data_deps.push_back(*i); |
| 541 } else { |
| 542 out_ << " "; |
| 543 path_output_.WriteFile(out_, helper_.GetTargetOutputFile(*i)); |
| 544 } |
| 545 } |
| 546 |
| 547 // Append data dependencies as order-only dependencies. |
| 548 const std::vector<const Target*>& datadeps = target_->datadeps(); |
| 549 const std::vector<SourceFile>& data = target_->data(); |
| 550 if (!extra_data_deps.empty() || !datadeps.empty() || !data.empty()) { |
| 551 out_ << " ||"; |
| 552 |
| 553 // Non-linkable deps in the deps section above. |
| 554 for (size_t i = 0; i < extra_data_deps.size(); i++) { |
| 555 out_ << " "; |
| 556 path_output_.WriteFile(out_, |
| 557 helper_.GetTargetOutputFile(extra_data_deps[i])); |
| 558 } |
| 559 |
| 560 // Data deps. |
| 561 for (size_t i = 0; i < datadeps.size(); i++) { |
| 562 out_ << " "; |
| 563 path_output_.WriteFile(out_, helper_.GetTargetOutputFile(datadeps[i])); |
| 564 } |
| 565 |
| 566 // Data files. |
| 567 const std::vector<SourceFile>& data = target_->data(); |
| 568 for (size_t i = 0; i < data.size(); i++) { |
| 569 out_ << " "; |
| 570 path_output_.WriteFile(out_, data[i]); |
| 571 } |
| 572 } |
| 522 | 573 |
| 523 out_ << std::endl; | 574 out_ << std::endl; |
| 524 } | 575 } |
| 525 | 576 |
| 526 const char* NinjaTargetWriter::GetCommandForSourceType( | 577 const char* NinjaTargetWriter::GetCommandForSourceType( |
| 527 SourceFileType type) const { | 578 SourceFileType type) const { |
| 528 if (type == SOURCE_C) | 579 if (type == SOURCE_C) |
| 529 return "cc"; | 580 return "cc"; |
| 530 if (type == SOURCE_CC) | 581 if (type == SOURCE_CC) |
| 531 return "cxx"; | 582 return "cxx"; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 558 // TODO(brettw) stuff about standalong static libraryes on Unix in | 609 // TODO(brettw) stuff about standalong static libraryes on Unix in |
| 559 // WriteTarget in the Python one, and lots of postbuild steps. | 610 // WriteTarget in the Python one, and lots of postbuild steps. |
| 560 return "alink"; | 611 return "alink"; |
| 561 } | 612 } |
| 562 | 613 |
| 563 if (target_->output_type() == Target::SHARED_LIBRARY) | 614 if (target_->output_type() == Target::SHARED_LIBRARY) |
| 564 return "solink"; | 615 return "solink"; |
| 565 | 616 |
| 566 return "link"; | 617 return "link"; |
| 567 } | 618 } |
| OLD | NEW |