Home | History | Annotate | Download | only in mac
      1 # Copyright 2015 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 import("//build/config/mac/base_rules.gni")
      6 
      7 # Generates Info.plist files for Mac apps and frameworks.
      8 #
      9 # Arguments
     10 #
     11 #     info_plist:
     12 #         string, the path to an plist file that will be included in the final
     13 #         Info.plist generated.
     14 #
     15 #     executable_name:
     16 #         string, name of the generated target used for the product
     17 #         and executable name as specified in the output Info.plist.
     18 #
     19 #     extra_substitutions:
     20 #         (optional) string array, 'key=value' pairs for extra fields which are
     21 #         specified in a source Info.plist template.
     22 template("mac_info_plist") {
     23   assert(defined(invoker.info_plist) != defined(invoker.info_plist_target),
     24          "Only one of info_plist or info_plist_target may be specified in " +
     25              target_name)
     26 
     27   if (defined(invoker.info_plist)) {
     28     _info_plist = invoker.info_plist
     29   } else {
     30     _info_plist_target_output = get_target_outputs(invoker.info_plist_target)
     31     _info_plist = _info_plist_target_output[0]
     32   }
     33 
     34   info_plist(target_name) {
     35     format = "xml1"
     36     extra_substitutions = []
     37     if (defined(invoker.extra_substitutions)) {
     38       extra_substitutions = invoker.extra_substitutions
     39     }
     40     extra_substitutions += [
     41       "MAC_SDK_BUILD=$mac_sdk_build",
     42       "MAC_SDK_NAME=$mac_sdk_name$mac_sdk_version",
     43     ]
     44     plist_templates = [
     45       "//build/config/mac/BuildInfo.plist",
     46       _info_plist,
     47     ]
     48     if (defined(invoker.info_plist_target)) {
     49       deps = [
     50         invoker.info_plist_target,
     51       ]
     52     }
     53     forward_variables_from(invoker,
     54                            [
     55                              "testonly",
     56                              "executable_name",
     57                            ])
     58   }
     59 }
     60 
     61 # Template to compile and package Mac XIB files as bundle data.
     62 #
     63 # Arguments
     64 #
     65 #     sources:
     66 #         list of string, sources to comiple
     67 #
     68 #     output_path:
     69 #         (optional) string, the path to use for the outputs list in the
     70 #         bundle_data step. If unspecified, defaults to bundle_resources_dir.
     71 template("mac_xib_bundle_data") {
     72   _target_name = target_name
     73   _compile_target_name = _target_name + "_compile_ibtool"
     74 
     75   compile_xibs(_compile_target_name) {
     76     forward_variables_from(invoker, [ "testonly" ])
     77     visibility = [ ":$_target_name" ]
     78     sources = invoker.sources
     79     ibtool_flags = [
     80       "--minimum-deployment-target",
     81       mac_deployment_target,
     82 
     83       # TODO(rsesek): Enable this once all the bots are on Xcode 7+.
     84       # "--target-device",
     85       # "mac",
     86     ]
     87   }
     88 
     89   bundle_data(_target_name) {
     90     forward_variables_from(invoker,
     91                            [
     92                              "testonly",
     93                              "visibility",
     94                            ])
     95 
     96     public_deps = [
     97       ":$_compile_target_name",
     98     ]
     99     sources = get_target_outputs(":$_compile_target_name")
    100 
    101     _output_path = "{{bundle_resources_dir}}"
    102     if (defined(invoker.output_path)) {
    103       _output_path = invoker.output_path
    104     }
    105 
    106     outputs = [
    107       "$_output_path/{{source_file_part}}",
    108     ]
    109   }
    110 }
    111 
    112 # Template to package a shared library into a Mac framework bundle.
    113 #
    114 # This template provides two targets to control whether the framework is
    115 # merely built when targets depend on it, or whether it is linked as well:
    116 # "$target_name" and "$target_name+link".
    117 #
    118 # See the //build/config/mac/base_rules.gni:framework_bundle for a discussion
    119 # and examples.
    120 #
    121 # Arguments
    122 #
    123 #     info_plist:
    124 #         (optional) string, path to the Info.plist file that will be used for
    125 #         the bundle.
    126 #
    127 #     info_plist_target:
    128 #         (optional) string, if the info_plist is generated from an action,
    129 #         rather than a regular source file, specify the target name in lieu
    130 #         of info_plist. The two arguments are mutually exclusive.
    131 #
    132 #     output_name:
    133 #         (optional) string, name of the generated framework without the
    134 #         .framework suffix. If omitted, defaults to target_name.
    135 #
    136 #     framework_version:
    137 #         (optional) string, version of the framework. Typically this is a
    138 #         single letter, like "A". If omitted, the Versions/ subdirectory
    139 #         structure will not be created, and build output will go directly
    140 #         into the framework subdirectory.
    141 #
    142 #     extra_substitutions:
    143 #         (optional) string array, 'key=value' pairs for extra fields which are
    144 #         specified in a source Info.plist template.
    145 #
    146 # See "gn help shared_library" for more information on arguments supported
    147 # by shared library target.
    148 template("mac_framework_bundle") {
    149   assert(defined(invoker.deps),
    150          "Dependencies must be specified for $target_name")
    151 
    152   _info_plist_target = target_name + "_info_plist"
    153 
    154   mac_info_plist(_info_plist_target) {
    155     executable_name = target_name
    156     if (defined(invoker.output_name)) {
    157       executable_name = invoker.output_name
    158     }
    159     forward_variables_from(invoker,
    160                            [
    161                              "extra_substitutions",
    162                              "info_plist",
    163                              "info_plist_target",
    164                              "testonly",
    165                            ])
    166   }
    167 
    168   _info_plist_bundle_data = _info_plist_target + "_bundle_data"
    169 
    170   bundle_data(_info_plist_bundle_data) {
    171     forward_variables_from(invoker, [ "testonly" ])
    172     sources = get_target_outputs(":$_info_plist_target")
    173     outputs = [
    174       "{{bundle_resources_dir}}/Info.plist",
    175     ]
    176     public_deps = [
    177       ":$_info_plist_target",
    178     ]
    179   }
    180 
    181   framework_bundle(target_name) {
    182     forward_variables_from(invoker, "*", [ "info_plist" ])
    183 
    184     if (!defined(deps)) {
    185       deps = []
    186     }
    187     deps += [ ":$_info_plist_bundle_data" ]
    188   }
    189 }
    190 
    191 # Template to create a Mac executable application bundle.
    192 #
    193 # Arguments
    194 #
    195 #     info_plist:
    196 #         (optional) string, path to the Info.plist file that will be used for
    197 #         the bundle.
    198 #
    199 #     info_plist_target:
    200 #         (optional) string, if the info_plist is generated from an action,
    201 #         rather than a regular source file, specify the target name in lieu
    202 #         of info_plist. The two arguments are mutually exclusive.
    203 #
    204 #     output_name:
    205 #         (optional) string, name of the generated app without the
    206 #         .app suffix. If omitted, defaults to target_name.
    207 #
    208 #     extra_configs:
    209 #         (optional) list of label, additional configs to apply to the
    210 #         executable target.
    211 #
    212 #     extra_substitutions:
    213 #         (optional) string array, 'key=value' pairs for extra fields which are
    214 #         specified in a source Info.plist template.
    215 template("mac_app_bundle") {
    216   _target_name = target_name
    217   _output_name = target_name
    218   if (defined(invoker.output_name)) {
    219     _output_name = invoker.output_name
    220   }
    221 
    222   _executable_target = target_name + "_executable"
    223   _executable_bundle_data = _executable_target + "_bundle_data"
    224 
    225   _info_plist_target = target_name + "_info_plist"
    226 
    227   mac_info_plist(_info_plist_target) {
    228     executable_name = _output_name
    229     forward_variables_from(invoker,
    230                            [
    231                              "extra_substitutions",
    232                              "info_plist",
    233                              "info_plist_target",
    234                              "testonly",
    235                            ])
    236   }
    237 
    238   executable(_executable_target) {
    239     visibility = [ ":$_executable_bundle_data" ]
    240     forward_variables_from(invoker,
    241                            "*",
    242                            [
    243                              "assert_no_deps",
    244                              "data_deps",
    245                              "info_plist",
    246                              "output_name",
    247                              "visibility",
    248                            ])
    249     if (defined(extra_configs)) {
    250       configs += extra_configs
    251     }
    252     output_name = _output_name
    253     output_dir = "$target_out_dir/$_executable_target"
    254   }
    255 
    256   bundle_data(_executable_bundle_data) {
    257     visibility = [ ":$_target_name" ]
    258     forward_variables_from(invoker, [ "testonly" ])
    259     sources = [
    260       "$target_out_dir/$_executable_target/$_output_name",
    261     ]
    262     outputs = [
    263       "{{bundle_executable_dir}}/$_output_name",
    264     ]
    265     public_deps = [
    266       ":$_executable_target",
    267     ]
    268   }
    269 
    270   _info_plist_bundle_data = _info_plist_target + "_bundle_data"
    271 
    272   bundle_data(_info_plist_bundle_data) {
    273     forward_variables_from(invoker, [ "testonly" ])
    274     visibility = [ ":$_target_name" ]
    275     sources = get_target_outputs(":$_info_plist_target")
    276     outputs = [
    277       "{{bundle_root_dir}}/Info.plist",
    278     ]
    279     public_deps = [
    280       ":$_info_plist_target",
    281     ]
    282   }
    283 
    284   create_bundle(_target_name) {
    285     forward_variables_from(invoker,
    286                            [
    287                              "data_deps",
    288                              "deps",
    289                              "public_deps",
    290                              "testonly",
    291                            ])
    292     if (!defined(deps)) {
    293       deps = []
    294     }
    295     deps += [
    296       ":$_executable_bundle_data",
    297       ":$_info_plist_bundle_data",
    298     ]
    299 
    300     bundle_root_dir = "$root_out_dir/${_output_name}.app/Contents"
    301     bundle_resources_dir = "$bundle_root_dir/Resources"
    302     bundle_executable_dir = "$bundle_root_dir/MacOS"
    303   }
    304 }
    305 
    306 # Template to package a loadable_module into a .plugin bundle.
    307 #
    308 # This takes no extra arguments that differ from a loadable_module.
    309 template("mac_plugin_bundle") {
    310   assert(defined(invoker.deps),
    311          "Dependencies must be specified for $target_name")
    312 
    313   _target_name = target_name
    314   _loadable_module_target = _target_name + "_loadable_module"
    315   _loadable_module_bundle_data = _loadable_module_target + "_bundle_data"
    316 
    317   _output_name = _target_name
    318   if (defined(invoker.output_name)) {
    319     _output_name = invoker.output_name
    320   }
    321 
    322   loadable_module(_loadable_module_target) {
    323     visibility = [ ":$_loadable_module_bundle_data" ]
    324     forward_variables_from(invoker,
    325                            "*",
    326                            [
    327                              "assert_no_deps",
    328                              "data_deps",
    329                              "output_name",
    330                              "visibility",
    331                            ])
    332     output_dir = "$target_out_dir"
    333     output_name = _output_name
    334   }
    335 
    336   bundle_data(_loadable_module_bundle_data) {
    337     forward_variables_from(invoker, [ "testonly" ])
    338     visibility = [ ":$_target_name" ]
    339     sources = [
    340       "$target_out_dir/${_output_name}.so",
    341     ]
    342     outputs = [
    343       "{{bundle_executable_dir}}/$_output_name",
    344     ]
    345     public_deps = [
    346       ":$_loadable_module_target",
    347     ]
    348   }
    349 
    350   create_bundle(_target_name) {
    351     forward_variables_from(invoker,
    352                            [
    353                              "data_deps",
    354                              "deps",
    355                              "public_deps",
    356                              "testonly",
    357                              "visibility",
    358                            ])
    359     if (!defined(deps)) {
    360       deps = []
    361     }
    362     deps += [ ":$_loadable_module_bundle_data" ]
    363 
    364     bundle_root_dir = "$root_out_dir/$_output_name.plugin/Contents"
    365     bundle_executable_dir = "$bundle_root_dir/MacOS"
    366   }
    367 }
    368