| 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 |