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 3 // found in the LICENSE file. 4 5 #ifndef TOOLS_GN_BUNDLE_DATA_H_ 6 #define TOOLS_GN_BUNDLE_DATA_H_ 7 8 #include <map> 9 #include <string> 10 #include <vector> 11 12 #include "gn/action_values.h" 13 #include "gn/bundle_file_rule.h" 14 #include "gn/source_dir.h" 15 #include "gn/source_file.h" 16 #include "gn/substitution_list.h" 17 #include "gn/unique_vector.h" 18 19 class LabelPattern; 20 class OutputFile; 21 class Settings; 22 class Target; 23 24 // BundleData holds the information required by "create_bundle" target. 25 class BundleData { 26 public: 27 using UniqueTargets = UniqueVector<const Target*>; 28 using SourceFiles = std::vector<SourceFile>; 29 using OutputFiles = std::vector<OutputFile>; 30 using BundleFileRules = std::vector<BundleFileRule>; 31 32 BundleData(); 33 ~BundleData(); 34 35 // Return the assets catalog directory path from `source` as a SourceFile, 36 // if present, or a null instance (in case assets catalog are nested, this 37 // returns the outer most path). 38 // 39 // Example: 40 // "//my/bundle/foo.xcassets/my/file" 41 // -> "//my/bundle/foo.xcassets" 42 // "//my/bundle/foo.xcassets/nested/bar.xcassets/my/file" 43 // -> "//my/bundle/foo.xcassets" 44 // "//my/bundle/my/file" 45 // -> "" 46 // 47 static SourceFile GetAssetsCatalogDirectory(const SourceFile& source); 48 49 // Adds a bundle_data target to the recursive collection of all bundle_data 50 // that the target depends on. 51 void AddBundleData(const Target* target, bool is_create_bundle); 52 53 // Called upon resolution of the target owning this instance of BundleData. 54 // |owning_target| is the owning target. 55 void OnTargetResolved(Target* owning_target); 56 57 // Returns the list of inputs. 58 void GetSourceFiles(SourceFiles* sources) const; 59 60 // Returns the list of outputs. 61 bool GetOutputFiles(const Settings* settings, 62 const Target* target, 63 OutputFiles* outputs, 64 Err* err) const; 65 66 // Returns the list of outputs as SourceFile. 67 bool GetOutputsAsSourceFiles(const Settings* settings, 68 const Target* target, 69 SourceFiles* outputs_as_source, 70 Err* err) const; 71 72 // Returns the path to the compiled asset catalog. Only valid if 73 // assets_catalog_sources() is not empty. 74 SourceFile GetCompiledAssetCatalogPath() const; 75 76 // Returns the path to the top-level directory of the bundle. This is 77 // based on root_dir(), but since that can be Bundle.app/Contents/ or 78 // any other subpath, this is just the most top-level directory (e.g., 79 // just Bundle.app/). 80 // 81 // Note that this is a SourceFile instead of a SourceDir. This is because 82 // the output of a create_bundle rule is a single logical unit, even though 83 // it is really a directory containing many outputs. This allows other 84 // targets to treat the bundle as a single unit, rather than a collection 85 // of its contents. 86 SourceFile GetBundleRootDirOutput(const Settings* settings) const; 87 88 // Performs GetBundleRootDirOutput but returns the result as a directory. 89 SourceDir GetBundleRootDirOutputAsDir(const Settings* settings) const; 90 91 // Returns directory where bundle is 92 SourceDir GetBundleDir(const Settings* settings) const; 93 94 // Returns the list of inputs for the compilation of the asset catalog. assets_catalog_sources()95 SourceFiles& assets_catalog_sources() { return assets_catalog_sources_; } assets_catalog_sources()96 const SourceFiles& assets_catalog_sources() const { 97 return assets_catalog_sources_; 98 } 99 100 // Returns the list of dependencies for the compilation of the asset catalog. assets_catalog_deps()101 std::vector<const Target*> assets_catalog_deps() const { 102 return assets_catalog_deps_; 103 } 104 file_rules()105 BundleFileRules& file_rules() { return file_rules_; } file_rules()106 const BundleFileRules& file_rules() const { return file_rules_; } 107 root_dir()108 SourceDir& root_dir() { return root_dir_; } root_dir()109 const SourceDir& root_dir() const { return root_dir_; } 110 contents_dir()111 SourceDir& contents_dir() { return contents_dir_; } contents_dir()112 const SourceDir& contents_dir() const { return contents_dir_; } 113 resources_dir()114 SourceDir& resources_dir() { return resources_dir_; } resources_dir()115 const SourceDir& resources_dir() const { return resources_dir_; } 116 executable_dir()117 SourceDir& executable_dir() { return executable_dir_; } executable_dir()118 const SourceDir& executable_dir() const { return executable_dir_; } 119 xcode_extra_attributes()120 std::map<std::string, std::string>& xcode_extra_attributes() { 121 return xcode_extra_attributes_; 122 } xcode_extra_attributes()123 const std::map<std::string, std::string>& xcode_extra_attributes() const { 124 return xcode_extra_attributes_; 125 } 126 transparent()127 bool transparent() const { return transparent_; } set_transparent(bool value)128 void set_transparent(bool value) { transparent_ = value; } 129 product_type()130 std::string& product_type() { return product_type_; } product_type()131 const std::string& product_type() const { return product_type_; } 132 xcode_test_application_name()133 std::string& xcode_test_application_name() { 134 return xcode_test_application_name_; 135 } xcode_test_application_name()136 const std::string& xcode_test_application_name() const { 137 return xcode_test_application_name_; 138 } 139 set_partial_info_plist(const SourceFile & partial_info_plist)140 void set_partial_info_plist(const SourceFile& partial_info_plist) { 141 partial_info_plist_ = partial_info_plist; 142 } partial_info_plist()143 const SourceFile& partial_info_plist() const { return partial_info_plist_; } 144 set_post_processing_script(const SourceFile & script_file)145 void set_post_processing_script(const SourceFile& script_file) { 146 post_processing_script_ = script_file; 147 } post_processing_script()148 const SourceFile& post_processing_script() const { 149 return post_processing_script_; 150 } 151 post_processing_sources()152 std::vector<SourceFile>& post_processing_sources() { 153 return post_processing_sources_; 154 } post_processing_sources()155 const std::vector<SourceFile>& post_processing_sources() const { 156 return post_processing_sources_; 157 } 158 post_processing_outputs()159 SubstitutionList& post_processing_outputs() { 160 return post_processing_outputs_; 161 } post_processing_outputs()162 const SubstitutionList& post_processing_outputs() const { 163 return post_processing_outputs_; 164 } 165 post_processing_args()166 SubstitutionList& post_processing_args() { return post_processing_args_; } post_processing_args()167 const SubstitutionList& post_processing_args() const { 168 return post_processing_args_; 169 } 170 bundle_deps_filter()171 std::vector<LabelPattern>& bundle_deps_filter() { 172 return bundle_deps_filter_; 173 } bundle_deps_filter()174 const std::vector<LabelPattern>& bundle_deps_filter() const { 175 return bundle_deps_filter_; 176 } 177 xcasset_compiler_flags()178 SubstitutionList& xcasset_compiler_flags() { return xcasset_compiler_flags_; } xcasset_compiler_flags()179 const SubstitutionList& xcasset_compiler_flags() const { 180 return xcasset_compiler_flags_; 181 } 182 183 // Recursive collection of all bundle_data that the target depends on. bundle_deps()184 const UniqueTargets& bundle_deps() const { return bundle_deps_; } 185 186 // Recursive collection of all forwarded bundle_data that the target 187 // depends on (but does not use, see `transparent` in `create_bundle`). forwarded_bundle_deps()188 const UniqueTargets& forwarded_bundle_deps() const { 189 return forwarded_bundle_deps_; 190 } 191 192 // Returns whether the bundle is an application bundle. is_application()193 bool is_application() const { 194 return product_type_ == "com.apple.product-type.application"; 195 } 196 197 // Returns whether the bundle is a framework bundle. is_framework()198 bool is_framework() const { 199 return product_type_ == "com.apple.product-type.framework"; 200 } 201 202 private: 203 SourceFiles assets_catalog_sources_; 204 std::vector<const Target*> assets_catalog_deps_; 205 BundleFileRules file_rules_; 206 UniqueTargets bundle_deps_; 207 UniqueTargets forwarded_bundle_deps_; 208 std::vector<LabelPattern> bundle_deps_filter_; 209 210 // All those values are subdirectories relative to root_build_dir, and apart 211 // from root_dir_, they are either equal to root_dir_ or subdirectories of it. 212 SourceDir root_dir_; 213 SourceDir contents_dir_; 214 SourceDir resources_dir_; 215 SourceDir executable_dir_; 216 217 // The specified attributes will append to the build settings of the generated 218 // Xcode target. 219 std::map<std::string, std::string> xcode_extra_attributes_; 220 221 // This is the target type as known to Xcode. This is only used to generate 222 // the Xcode project file when using --ide=xcode. 223 std::string product_type_; 224 225 // Whether the bundle should be considered "transparent". A transparent 226 // `create_bundle` target includes only the `bundle_data` with the same 227 // `product_type` as itself. 228 bool transparent_ = false; 229 230 // Each Xcode unit test or ui test target must have a test application target, 231 // and this value corresponds to the target name. This is only used to 232 // generate the Xcode project when using --ide=xcode. 233 std::string xcode_test_application_name_; 234 235 // Path to the partial Info.plist generated by the asset catalog compiler 236 // (corresponds to {{bundle_partial_info_plist}} expansion). 237 SourceFile partial_info_plist_; 238 239 // Holds the values (script name, sources, outputs, script arguments) for the 240 // post-processing step if defined. 241 SourceFile post_processing_script_; 242 std::vector<SourceFile> post_processing_sources_; 243 SubstitutionList post_processing_outputs_; 244 SubstitutionList post_processing_args_; 245 SubstitutionList xcasset_compiler_flags_; 246 247 BundleData(const BundleData&) = delete; 248 BundleData& operator=(const BundleData&) = delete; 249 }; 250 251 #endif // TOOLS_GN_BUNDLE_DATA_H_ 252