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 |