OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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_create_bundle_target_writer.h" | 5 #include "tools/gn/ninja_create_bundle_target_writer.h" |
6 | 6 |
7 #include "base/macros.h" | 7 #include "base/macros.h" |
8 #include "base/strings/string_util.h" | 8 #include "base/strings/string_util.h" |
9 #include "tools/gn/filesystem_utils.h" | 9 #include "tools/gn/filesystem_utils.h" |
10 #include "tools/gn/ninja_utils.h" | 10 #include "tools/gn/ninja_utils.h" |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
50 : NinjaTargetWriter(target, out) {} | 50 : NinjaTargetWriter(target, out) {} |
51 | 51 |
52 NinjaCreateBundleTargetWriter::~NinjaCreateBundleTargetWriter() {} | 52 NinjaCreateBundleTargetWriter::~NinjaCreateBundleTargetWriter() {} |
53 | 53 |
54 void NinjaCreateBundleTargetWriter::Run() { | 54 void NinjaCreateBundleTargetWriter::Run() { |
55 if (!EnsureAllToolsAvailable(target_)) | 55 if (!EnsureAllToolsAvailable(target_)) |
56 return; | 56 return; |
57 | 57 |
58 std::string code_signing_rule_name = WriteCodeSigningRuleDefinition(); | 58 std::string code_signing_rule_name = WriteCodeSigningRuleDefinition(); |
59 | 59 |
60 OutputFile input_dep = | |
61 WriteInputDepsStampAndGetDep(std::vector<const Target*>()); | |
62 | |
63 std::vector<OutputFile> output_files; | 60 std::vector<OutputFile> output_files; |
64 WriteCopyBundleDataRules(input_dep, &output_files); | 61 WriteCopyBundleDataSteps(&output_files); |
65 WriteCompileAssetsCatalogRule(input_dep, &output_files); | 62 WriteCompileAssetsCatalogStep(&output_files); |
66 WriteCodeSigningRules(code_signing_rule_name, input_dep, &output_files); | 63 WriteCodeSigningStep(code_signing_rule_name, &output_files); |
67 | 64 |
68 std::vector<OutputFile> order_only_deps; | 65 std::vector<OutputFile> order_only_deps; |
69 for (const auto& pair : target_->data_deps()) | 66 for (const auto& pair : target_->data_deps()) |
70 order_only_deps.push_back(pair.ptr->dependency_output_file()); | 67 order_only_deps.push_back(pair.ptr->dependency_output_file()); |
71 WriteStampForTarget(output_files, order_only_deps); | 68 WriteStampForTarget(output_files, order_only_deps); |
72 | 69 |
73 // Write a phony target for the outer bundle directory. This allows other | 70 // Write a phony target for the outer bundle directory. This allows other |
74 // targets to treat the entire bundle as a single unit, even though it is | 71 // targets to treat the entire bundle as a single unit, even though it is |
75 // a directory, so that it can be depended upon as a discrete build edge. | 72 // a directory, so that it can be depended upon as a discrete build edge. |
76 out_ << "build "; | 73 out_ << "build "; |
(...skipping 29 matching lines...) Expand all Loading... |
106 SubstitutionWriter::WriteWithNinjaVariables(arg, args_escape_options, out_); | 103 SubstitutionWriter::WriteWithNinjaVariables(arg, args_escape_options, out_); |
107 } | 104 } |
108 out_ << std::endl; | 105 out_ << std::endl; |
109 out_ << " description = CODE SIGNING " << target_label << std::endl; | 106 out_ << " description = CODE SIGNING " << target_label << std::endl; |
110 out_ << " restat = 1" << std::endl; | 107 out_ << " restat = 1" << std::endl; |
111 out_ << std::endl; | 108 out_ << std::endl; |
112 | 109 |
113 return custom_rule_name; | 110 return custom_rule_name; |
114 } | 111 } |
115 | 112 |
116 void NinjaCreateBundleTargetWriter::WriteCopyBundleDataRules( | 113 void NinjaCreateBundleTargetWriter::WriteCopyBundleDataSteps( |
117 const OutputFile& input_dep, | |
118 std::vector<OutputFile>* output_files) { | 114 std::vector<OutputFile>* output_files) { |
119 for (const BundleFileRule& file_rule : target_->bundle_data().file_rules()) { | 115 for (const BundleFileRule& file_rule : target_->bundle_data().file_rules()) |
120 for (const SourceFile& source_file : file_rule.sources()) { | 116 WriteCopyBundleFileRuleSteps(file_rule, output_files); |
121 OutputFile output_file = file_rule.ApplyPatternToSourceAsOutputFile( | 117 } |
122 settings_, target_->bundle_data(), source_file); | |
123 output_files->push_back(output_file); | |
124 | 118 |
125 out_ << "build "; | 119 void NinjaCreateBundleTargetWriter::WriteCopyBundleFileRuleSteps( |
126 path_output_.WriteFile(out_, output_file); | 120 const BundleFileRule& file_rule, |
127 out_ << ": " | 121 std::vector<OutputFile>* output_files) { |
128 << GetNinjaRulePrefixForToolchain(settings_) | 122 // Note that we don't write implicit deps for copy steps. "copy_bundle_data" |
129 << Toolchain::ToolTypeToName(Toolchain::TYPE_COPY_BUNDLE_DATA) | 123 // steps as this is most likely implemented using hardlink in the common case. |
130 << " "; | 124 // See NinjaCopyTargetWriter::WriteCopyRules() for a detailed explanation. |
131 path_output_.WriteFile(out_, source_file); | 125 for (const SourceFile& source_file : file_rule.sources()) { |
132 if (!input_dep.value().empty()) { | 126 OutputFile output_file = file_rule.ApplyPatternToSourceAsOutputFile( |
133 out_ << " | "; | 127 settings_, target_->bundle_data(), source_file); |
134 path_output_.WriteFile(out_, input_dep); | 128 output_files->push_back(output_file); |
135 } | 129 |
136 out_ << std::endl; | 130 out_ << "build "; |
137 } | 131 path_output_.WriteFile(out_, output_file); |
| 132 out_ << ": " << GetNinjaRulePrefixForToolchain(settings_) |
| 133 << Toolchain::ToolTypeToName(Toolchain::TYPE_COPY_BUNDLE_DATA) << " "; |
| 134 path_output_.WriteFile(out_, source_file); |
| 135 out_ << std::endl; |
138 } | 136 } |
139 } | 137 } |
140 | 138 |
141 void NinjaCreateBundleTargetWriter::WriteCompileAssetsCatalogRule( | 139 void NinjaCreateBundleTargetWriter::WriteCompileAssetsCatalogStep( |
142 const OutputFile& input_dep, | |
143 std::vector<OutputFile>* output_files) { | 140 std::vector<OutputFile>* output_files) { |
144 if (target_->bundle_data().asset_catalog_sources().empty()) | 141 if (target_->bundle_data().assets_catalog_sources().empty()) |
145 return; | 142 return; |
146 | 143 |
| 144 OutputFile input_dep = WriteCompileAssetsCatalogInputDepsStamp( |
| 145 target_->bundle_data().assets_catalog_deps()); |
| 146 DCHECK(!input_dep.value().empty()); |
| 147 |
147 OutputFile output_file(settings_->build_settings(), | 148 OutputFile output_file(settings_->build_settings(), |
148 target_->bundle_data().GetCompiledAssetCatalogPath()); | 149 target_->bundle_data().GetCompiledAssetCatalogPath()); |
149 output_files->push_back(output_file); | 150 output_files->push_back(output_file); |
150 | 151 |
151 out_ << "build "; | 152 out_ << "build "; |
152 path_output_.WriteFile(out_, output_file); | 153 path_output_.WriteFile(out_, output_file); |
153 out_ << ": " << GetNinjaRulePrefixForToolchain(settings_) | 154 out_ << ": " << GetNinjaRulePrefixForToolchain(settings_) |
154 << Toolchain::ToolTypeToName(Toolchain::TYPE_COMPILE_XCASSETS); | 155 << Toolchain::ToolTypeToName(Toolchain::TYPE_COMPILE_XCASSETS); |
155 | 156 |
156 std::set<SourceFile> asset_catalog_bundles; | 157 std::set<SourceFile> asset_catalog_bundles; |
157 for (const auto& source : target_->bundle_data().asset_catalog_sources()) { | 158 for (const auto& source : target_->bundle_data().assets_catalog_sources()) { |
158 SourceFile asset_catalog_bundle; | |
159 CHECK(IsSourceFileFromAssetCatalog(source, &asset_catalog_bundle)); | |
160 if (asset_catalog_bundles.find(asset_catalog_bundle) != | |
161 asset_catalog_bundles.end()) | |
162 continue; | |
163 out_ << " "; | 159 out_ << " "; |
164 path_output_.WriteFile(out_, asset_catalog_bundle); | 160 path_output_.WriteFile(out_, source); |
165 asset_catalog_bundles.insert(asset_catalog_bundle); | 161 asset_catalog_bundles.insert(source); |
166 } | 162 } |
167 | 163 |
168 out_ << " |"; | 164 out_ << " | "; |
169 for (const auto& source : target_->bundle_data().asset_catalog_sources()) { | 165 path_output_.WriteFile(out_, input_dep); |
170 out_ << " "; | |
171 path_output_.WriteFile( | |
172 out_, OutputFile(settings_->build_settings(), source)); | |
173 } | |
174 | |
175 if (!input_dep.value().empty()) { | |
176 out_ << " "; | |
177 path_output_.WriteFile(out_, input_dep); | |
178 } | |
179 out_ << std::endl; | 166 out_ << std::endl; |
180 } | 167 } |
181 | 168 |
182 void NinjaCreateBundleTargetWriter::WriteCodeSigningRules( | 169 OutputFile |
| 170 NinjaCreateBundleTargetWriter::WriteCompileAssetsCatalogInputDepsStamp( |
| 171 const std::vector<const Target*>& dependencies) { |
| 172 DCHECK(!dependencies.empty()); |
| 173 if (dependencies.size() == 1) |
| 174 return dependencies[0]->dependency_output_file(); |
| 175 |
| 176 OutputFile xcassets_input_stamp_file = |
| 177 OutputFile(RebasePath(GetTargetOutputDir(target_).value(), |
| 178 settings_->build_settings()->build_dir(), |
| 179 settings_->build_settings()->root_path_utf8())); |
| 180 xcassets_input_stamp_file.value().append(target_->label().name()); |
| 181 xcassets_input_stamp_file.value().append(".xcassets.inputdeps.stamp"); |
| 182 |
| 183 out_ << "build "; |
| 184 path_output_.WriteFile(out_, xcassets_input_stamp_file); |
| 185 out_ << ": " << GetNinjaRulePrefixForToolchain(settings_) |
| 186 << Toolchain::ToolTypeToName(Toolchain::TYPE_STAMP); |
| 187 |
| 188 for (const Target* target : dependencies) { |
| 189 out_ << " "; |
| 190 path_output_.WriteFile(out_, target->dependency_output_file()); |
| 191 } |
| 192 out_ << std::endl; |
| 193 return xcassets_input_stamp_file; |
| 194 } |
| 195 |
| 196 void NinjaCreateBundleTargetWriter::WriteCodeSigningStep( |
183 const std::string& code_signing_rule_name, | 197 const std::string& code_signing_rule_name, |
184 const OutputFile& input_dep, | |
185 std::vector<OutputFile>* output_files) { | 198 std::vector<OutputFile>* output_files) { |
186 if (code_signing_rule_name.empty()) | 199 if (code_signing_rule_name.empty()) |
187 return; | 200 return; |
188 | 201 |
189 OutputFile code_signing_input_stamp_file = | 202 OutputFile code_signing_input_stamp_file = |
190 WriteCodeSigningInputDepsStamp(input_dep, output_files); | 203 WriteCodeSigningInputDepsStamp(output_files); |
| 204 DCHECK(!code_signing_input_stamp_file.value().empty()); |
191 | 205 |
192 out_ << "build"; | 206 out_ << "build"; |
193 std::vector<OutputFile> code_signing_output_files; | 207 std::vector<OutputFile> code_signing_output_files; |
194 SubstitutionWriter::GetListAsOutputFiles( | 208 SubstitutionWriter::GetListAsOutputFiles( |
195 settings_, target_->bundle_data().code_signing_outputs(), | 209 settings_, target_->bundle_data().code_signing_outputs(), |
196 &code_signing_output_files); | 210 &code_signing_output_files); |
197 path_output_.WriteFiles(out_, code_signing_output_files); | 211 path_output_.WriteFiles(out_, code_signing_output_files); |
198 | 212 |
199 // Since the code signature step depends on all the files from the bundle, | 213 // Since the code signature step depends on all the files from the bundle, |
200 // the create_bundle stamp can just depends on the output of the signature. | 214 // the create_bundle stamp can just depends on the output of the signature |
| 215 // script (dependencies are transitive). |
201 output_files->swap(code_signing_output_files); | 216 output_files->swap(code_signing_output_files); |
202 | 217 |
203 out_ << ": " << code_signing_rule_name; | 218 out_ << ": " << code_signing_rule_name; |
204 if (!code_signing_input_stamp_file.value().empty()) { | 219 out_ << " | "; |
205 out_ << " | "; | 220 path_output_.WriteFile(out_, code_signing_input_stamp_file); |
206 path_output_.WriteFile(out_, code_signing_input_stamp_file); | |
207 } | |
208 out_ << std::endl; | 221 out_ << std::endl; |
209 } | 222 } |
210 | 223 |
211 OutputFile NinjaCreateBundleTargetWriter::WriteCodeSigningInputDepsStamp( | 224 OutputFile NinjaCreateBundleTargetWriter::WriteCodeSigningInputDepsStamp( |
212 const OutputFile& input_dep, | |
213 std::vector<OutputFile>* output_files) { | 225 std::vector<OutputFile>* output_files) { |
214 std::vector<SourceFile> code_signing_input_files; | 226 std::vector<SourceFile> code_signing_input_files; |
215 code_signing_input_files.push_back( | 227 code_signing_input_files.push_back( |
216 target_->bundle_data().code_signing_script()); | 228 target_->bundle_data().code_signing_script()); |
217 code_signing_input_files.insert( | 229 code_signing_input_files.insert( |
218 code_signing_input_files.end(), | 230 code_signing_input_files.end(), |
219 target_->bundle_data().code_signing_sources().begin(), | 231 target_->bundle_data().code_signing_sources().begin(), |
220 target_->bundle_data().code_signing_sources().end()); | 232 target_->bundle_data().code_signing_sources().end()); |
221 for (const OutputFile& output_file : *output_files) { | 233 for (const OutputFile& output_file : *output_files) { |
222 code_signing_input_files.push_back( | 234 code_signing_input_files.push_back( |
223 output_file.AsSourceFile(settings_->build_settings())); | 235 output_file.AsSourceFile(settings_->build_settings())); |
224 } | 236 } |
225 if (!input_dep.value().empty()) { | 237 |
226 code_signing_input_files.push_back( | 238 std::vector<const Target*> dependencies; |
227 input_dep.AsSourceFile(settings_->build_settings())); | 239 for (const auto& label_target_pair : target_->private_deps()) { |
| 240 if (label_target_pair.ptr->output_type() == Target::BUNDLE_DATA) |
| 241 continue; |
| 242 dependencies.push_back(label_target_pair.ptr); |
| 243 } |
| 244 for (const auto& label_target_pair : target_->public_deps()) { |
| 245 if (label_target_pair.ptr->output_type() == Target::BUNDLE_DATA) |
| 246 continue; |
| 247 dependencies.push_back(label_target_pair.ptr); |
228 } | 248 } |
229 | 249 |
230 DCHECK(!code_signing_input_files.empty()); | 250 DCHECK(!code_signing_input_files.empty()); |
231 if (code_signing_input_files.size() == 1) | 251 if (code_signing_input_files.size() == 1 && dependencies.empty()) |
232 return OutputFile(settings_->build_settings(), code_signing_input_files[0]); | 252 return OutputFile(settings_->build_settings(), code_signing_input_files[0]); |
233 | 253 |
| 254 // Remove possible duplicates (if a target is listed in both deps and |
| 255 // public_deps. |
| 256 std::sort(dependencies.begin(), dependencies.end(), |
| 257 [](const Target* lhs, const Target* rhs) -> bool { |
| 258 return lhs->label() < rhs->label(); |
| 259 }); |
| 260 dependencies.erase(std::unique(dependencies.begin(), dependencies.end()), |
| 261 dependencies.end()); |
| 262 |
234 OutputFile code_signing_input_stamp_file = | 263 OutputFile code_signing_input_stamp_file = |
235 OutputFile(RebasePath(GetTargetOutputDir(target_).value(), | 264 OutputFile(RebasePath(GetTargetOutputDir(target_).value(), |
236 settings_->build_settings()->build_dir(), | 265 settings_->build_settings()->build_dir(), |
237 settings_->build_settings()->root_path_utf8())); | 266 settings_->build_settings()->root_path_utf8())); |
238 code_signing_input_stamp_file.value().append(target_->label().name()); | 267 code_signing_input_stamp_file.value().append(target_->label().name()); |
239 code_signing_input_stamp_file.value().append(".codesigning.inputdeps.stamp"); | 268 code_signing_input_stamp_file.value().append(".codesigning.inputdeps.stamp"); |
240 | 269 |
241 out_ << "build "; | 270 out_ << "build "; |
242 path_output_.WriteFile(out_, code_signing_input_stamp_file); | 271 path_output_.WriteFile(out_, code_signing_input_stamp_file); |
243 out_ << ": " << GetNinjaRulePrefixForToolchain(settings_) | 272 out_ << ": " << GetNinjaRulePrefixForToolchain(settings_) |
244 << Toolchain::ToolTypeToName(Toolchain::TYPE_STAMP); | 273 << Toolchain::ToolTypeToName(Toolchain::TYPE_STAMP); |
245 | 274 |
246 for (const SourceFile& source : code_signing_input_files) { | 275 for (const SourceFile& source : code_signing_input_files) { |
247 out_ << " "; | 276 out_ << " "; |
248 path_output_.WriteFile(out_, source); | 277 path_output_.WriteFile(out_, source); |
249 } | 278 } |
| 279 for (const Target* target : dependencies) { |
| 280 out_ << " "; |
| 281 path_output_.WriteFile(out_, target->dependency_output_file()); |
| 282 } |
250 out_ << std::endl; | 283 out_ << std::endl; |
251 return code_signing_input_stamp_file; | 284 return code_signing_input_stamp_file; |
252 } | 285 } |
OLD | NEW |