OLD | NEW |
(Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "tools/gn/ninja_helper.h" |
| 6 |
| 7 #include "base/logging.h" |
| 8 #include "tools/gn/filesystem_utils.h" |
| 9 #include "tools/gn/string_utils.h" |
| 10 #include "tools/gn/target.h" |
| 11 |
| 12 namespace { |
| 13 |
| 14 const char kLibDirWithSlash[] = "lib"; |
| 15 const char kObjectDirNoSlash[] = "obj"; |
| 16 |
| 17 } // namespace |
| 18 |
| 19 NinjaHelper::NinjaHelper(const BuildSettings* build_settings) |
| 20 : build_settings_(build_settings) { |
| 21 build_to_src_no_last_slash_ = build_settings->build_to_source_dir_string(); |
| 22 if (!build_to_src_no_last_slash_.empty() && |
| 23 build_to_src_no_last_slash_[build_to_src_no_last_slash_.size() - 1] == |
| 24 '/') |
| 25 build_to_src_no_last_slash_.resize(build_to_src_no_last_slash_.size() - 1); |
| 26 |
| 27 build_to_src_system_no_last_slash_ = build_to_src_no_last_slash_; |
| 28 ConvertPathToSystem(&build_to_src_system_no_last_slash_); |
| 29 } |
| 30 |
| 31 NinjaHelper::~NinjaHelper() { |
| 32 } |
| 33 |
| 34 std::string NinjaHelper::GetTopleveOutputDir() const { |
| 35 return kObjectDirNoSlash; |
| 36 } |
| 37 |
| 38 std::string NinjaHelper::GetTargetOutputDir(const Target* target) const { |
| 39 return kObjectDirNoSlash + target->label().dir().SourceAbsoluteWithOneSlash(); |
| 40 } |
| 41 |
| 42 OutputFile NinjaHelper::GetNinjaFileForTarget(const Target* target) const { |
| 43 OutputFile ret(target->settings()->toolchain_output_subdir()); |
| 44 ret.value().append(kObjectDirNoSlash); |
| 45 AppendStringPiece(&ret.value(), |
| 46 target->label().dir().SourceAbsoluteWithOneSlash()); |
| 47 ret.value().append(target->label().name()); |
| 48 ret.value().append(".ninja"); |
| 49 return ret; |
| 50 } |
| 51 |
| 52 OutputFile NinjaHelper::GetNinjaFileForToolchain( |
| 53 const Settings* settings) const { |
| 54 OutputFile ret; |
| 55 ret.value().append(settings->toolchain_output_subdir().value()); |
| 56 ret.value().append("toolchain.ninja"); |
| 57 return ret; |
| 58 } |
| 59 |
| 60 // In Python, GypPathToUniqueOutput does the qualification. The only case where |
| 61 // the Python version doesn't qualify the name is for target outputs, which we |
| 62 // handle in a separate function. |
| 63 OutputFile NinjaHelper::GetOutputFileForSource( |
| 64 const Target* target, |
| 65 const SourceFile& source, |
| 66 SourceFileType type) const { |
| 67 // Extract the filename and remove the extension (keep the dot). |
| 68 base::StringPiece filename = FindFilename(&source.value()); |
| 69 std::string name(filename.data(), filename.size()); |
| 70 size_t extension_offset = FindExtensionOffset(name); |
| 71 CHECK(extension_offset != std::string::npos); |
| 72 name.resize(extension_offset); |
| 73 |
| 74 // Append the new extension. |
| 75 switch (type) { |
| 76 case SOURCE_ASM: |
| 77 case SOURCE_C: |
| 78 case SOURCE_CC: |
| 79 case SOURCE_M: |
| 80 case SOURCE_MM: |
| 81 name.append(target->settings()->IsWin() ? "obj" : "o"); |
| 82 break; |
| 83 |
| 84 case SOURCE_RC: |
| 85 name.append("res"); |
| 86 break; |
| 87 |
| 88 case SOURCE_H: |
| 89 case SOURCE_UNKNOWN: |
| 90 NOTREACHED(); |
| 91 return OutputFile(); |
| 92 } |
| 93 |
| 94 // Use the scheme <path>/<target>.<name>.<extension> so that all output |
| 95 // names are unique to different targets. |
| 96 OutputFile ret(kObjectDirNoSlash); |
| 97 |
| 98 // Find the directory, assume it starts with two slashes, and trim to one. |
| 99 base::StringPiece dir = FindDir(&source.value()); |
| 100 CHECK(dir.size() >= 2 && dir[0] == '/' && dir[1] == '/') |
| 101 << "Source file isn't in the source repo: " << dir; |
| 102 AppendStringPiece(&ret.value(), dir.substr(1)); |
| 103 |
| 104 ret.value().append(target->label().name()); |
| 105 ret.value().append("."); |
| 106 ret.value().append(name); |
| 107 return ret; |
| 108 } |
| 109 |
| 110 OutputFile NinjaHelper::GetTargetOutputFile(const Target* target) const { |
| 111 OutputFile ret; |
| 112 if (target->output_type() == Target::NONE) { |
| 113 NOTREACHED(); |
| 114 return ret; |
| 115 } |
| 116 |
| 117 const char* extension; |
| 118 if (target->output_type() == Target::NONE || |
| 119 target->output_type() == Target::COPY_FILES || |
| 120 target->output_type() == Target::CUSTOM) { |
| 121 extension = "stamp"; |
| 122 } else { |
| 123 extension = GetExtensionForOutputType(target->output_type(), |
| 124 target->settings()->target_os()); |
| 125 } |
| 126 |
| 127 // Everything goes into the toolchain directory (which will be empty for the |
| 128 // default toolchain, and will end in a slash otherwise). |
| 129 ret.value().append(target->settings()->toolchain_output_subdir().value()); |
| 130 |
| 131 // Binaries and loadable libraries go into the toolchain root. |
| 132 if (target->output_type() == Target::EXECUTABLE || |
| 133 target->output_type() == Target::LOADABLE_MODULE || |
| 134 (target->settings()->IsMac() && |
| 135 (target->output_type() == Target::SHARED_LIBRARY || |
| 136 target->output_type() == Target::STATIC_LIBRARY)) || |
| 137 (target->settings()->IsWin() && |
| 138 target->output_type() == Target::SHARED_LIBRARY)) { |
| 139 // Generate a name like "<toolchain>/<name>.<extension>". |
| 140 ret.value().append(target->label().name()); |
| 141 ret.value().push_back('.'); |
| 142 ret.value().append(extension); |
| 143 return ret; |
| 144 } |
| 145 |
| 146 // Libraries go into the library subdirectory like |
| 147 // "<toolchain>/lib/<name>.<extension>". |
| 148 if (target->output_type() == Target::SHARED_LIBRARY) { |
| 149 ret.value().append(kLibDirWithSlash); |
| 150 ret.value().append(target->label().name()); |
| 151 ret.value().push_back('.'); |
| 152 ret.value().append(extension); |
| 153 return ret; |
| 154 } |
| 155 |
| 156 // Everything else goes next to the target's .ninja file like |
| 157 // "<toolchain>/obj/<path>/<name>.<extension>". |
| 158 ret.value().append(kObjectDirNoSlash); |
| 159 AppendStringPiece(&ret.value(), |
| 160 target->label().dir().SourceAbsoluteWithOneSlash()); |
| 161 ret.value().append(target->label().name()); |
| 162 ret.value().push_back('.'); |
| 163 ret.value().append(extension); |
| 164 return ret; |
| 165 } |
OLD | NEW |