Home | History | Annotate | Download | only in grit
      1 # Copyright 2014 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 # Instantiate grit. This will produce a script target to run grit, and a
      6 # static library that compiles the .cc files.
      7 #
      8 # Parameters
      9 #
     10 #   source (required)
     11 #       Path to .grd file.
     12 #
     13 #   outputs (required)
     14 #       List of outputs from grit, relative to the target_gen_dir. If supplied,
     15 #       a call to Grit to compute the outputs can be skipped which will make
     16 #       GN run faster. Grit will verify at build time that this list is correct
     17 #       and will fail if there is a mismatch between the outputs specified by
     18 #       the .grd file and the outputs list here.
     19 #
     20 #       To get this list, you can look in the .grd file for
     21 #       <output filename="..." and put those filename here. The base directory
     22 #       of the list in Grit and the output list specified in the GN grit target
     23 #       are the same (the target_gen_dir) so you can generally copy the names
     24 #       exactly.
     25 #
     26 #       To get the list of outputs programatically, run:
     27 #           python tools/grit/grit_info.py --outputs . path/to/your.grd
     28 #       And strip the leading "./" from the output files.
     29 #
     30 #   defines (optional)
     31 #       Extra defines to pass to grit (on top of the global grit_defines list).
     32 #
     33 #   grit_flags (optional)
     34 #       List of strings containing extra command-line flags to pass to Grit.
     35 #
     36 #   resource_ids (optional)
     37 #       Path to a grit "firstidsfile". Default is
     38 #       //tools/gritsettings/resource_ids. Set to "" to use the value specified
     39 #       in the <grit> nodes of the processed files.
     40 #
     41 #   output_dir (optional)
     42 #       Directory for generated files. If you specify this, you will often
     43 #       want to specify output_name if the target name is not particularly
     44 #       unique, since this can cause files from multiple grit targets to
     45 #       overwrite each other.
     46 #
     47 #   output_name (optiona)
     48 #       Provide an alternate base name for the generated files, like the .d
     49 #       files. Normally these are based on the target name and go in the
     50 #       output_dir, but if multiple targets with the same name end up in
     51 #       the same output_dir, they can collide.
     52 #
     53 #   use_qualified_include (optional)
     54 #       If set, output_dir is not added to include_dirs.
     55 #
     56 #   deps  (optional)
     57 #   visibility  (optional)
     58 #       Normal meaning.
     59 #
     60 # Example
     61 #
     62 #   grit("my_resources") {
     63 #     # Source and outputs are required.
     64 #     source = "myfile.grd"
     65 #     outputs = [
     66 #       "foo_strings.h",
     67 #       "foo_strings.pak",
     68 #     ]
     69 #
     70 #     grit_flags = [ "-E", "foo=bar" ]  # Optional extra flags.
     71 #     # You can also put deps here if the grit source depends on generated
     72 #     # files.
     73 #   }
     74 import ("//build/config/crypto.gni")
     75 import ("//build/config/features.gni")
     76 import ("//build/config/ui.gni")
     77 
     78 grit_defines = []
     79 
     80 # Mac and iOS want Title Case strings.
     81 use_titlecase_in_grd_files = is_mac || is_ios
     82 if (use_titlecase_in_grd_files) {
     83   grit_defines += [ "-D", "use_titlecase" ]
     84 }
     85 
     86 if (is_chrome_branded) {
     87   grit_defines += [
     88     "-D", "_google_chrome",
     89     "-E", "CHROMIUM_BUILD=google_chrome",
     90   ]
     91 } else {
     92   grit_defines += [
     93     "-D", "_chromium",
     94     "-E", "CHROMIUM_BUILD=chromium",
     95   ]
     96 }
     97 
     98 if (is_chromeos) {
     99   grit_defines += [
    100     "-D", "chromeos",
    101     "-D", "scale_factors=2x"
    102   ]
    103 }
    104 
    105 if (is_desktop_linux) {
    106   grit_defines += [ "-D", "desktop_linux" ]
    107 }
    108 
    109 if (toolkit_views) {
    110   grit_defines += [ "-D", "toolkit_views" ]
    111 }
    112 
    113 if (use_aura) {
    114   grit_defines += [ "-D", "use_aura" ]
    115 }
    116 
    117 if (use_ash) {
    118   grit_defines += [ "-D", "use_ash" ]
    119 }
    120 
    121 if (use_nss_certs) {
    122   grit_defines += [ "-D", "use_nss" ]
    123 }
    124 
    125 if (use_ozone) {
    126   grit_defines += [ "-D", "use_ozone" ]
    127 }
    128 
    129 if (enable_image_loader_extension) {
    130   grit_defines += [ "-D", "image_loader_extension" ]
    131 }
    132 
    133 if (enable_remoting) {
    134   grit_defines += [ "-D", "remoting" ]
    135 }
    136 
    137 if (is_android) {
    138   grit_defines += [
    139     "-t", "android",
    140     "-E", "ANDROID_JAVA_TAGGED_ONLY=true",
    141   ]
    142 }
    143 
    144 if (is_mac || is_ios) {
    145   grit_defines += [ "-D", "scale_factors=2x" ]
    146 }
    147 
    148 if (is_ios) {
    149   grit_defines += [
    150     "-t", "ios",
    151     # iOS uses a whitelist to filter resources.
    152     "-w", rebase_path("//build/ios/grit_whitelist.txt", root_build_dir),
    153   ]
    154 }
    155 
    156 if (enable_extensions) {
    157   grit_defines += [ "-D", "enable_extensions" ]
    158 }
    159 if (enable_plugins) {
    160   grit_defines += [ "-D", "enable_plugins" ]
    161 }
    162 if (printing_mode != 0) {
    163   grit_defines += [ "-D", "enable_printing" ]
    164   if (printing_mode == 1) {
    165     grit_defines += [ "-D", "enable_full_printing" ]
    166   }
    167 }
    168 if (enable_themes) {
    169   grit_defines += [ "-D", "enable_themes" ]
    170 }
    171 if (enable_app_list) {
    172   grit_defines += [ "-D", "enable_app_list" ]
    173 }
    174 if (enable_settings_app) {
    175   grit_defines += [ "-D", "enable_settings_app" ]
    176 }
    177 if (enable_google_now) {
    178   grit_defines += [ "-D", "enable_google_now" ]
    179 }
    180 # Note: use_concatenated_impulse_responses is omitted. It is never used and
    181 # should probably be removed from GYP build.
    182 if (enable_webrtc) {
    183   grit_defines += [ "-D", "enable_webrtc" ]
    184 }
    185 # Note: enable_hangout_services_extension is omitted. It is never set in the
    186 # GYP build. Need to figure out what it's for.
    187 if (enable_task_manager) {
    188   grit_defines += [ "-D", "enable_task_manager" ]
    189 }
    190 if (enable_notifications) {
    191   grit_defines += [ "-D", "enable_notifications" ]
    192 }
    193 if (enable_wifi_bootstrapping) {
    194   grit_defines += [ "-D", "enable_wifi_bootstrapping" ]
    195 }
    196 if (enable_service_discovery) {
    197   grit_defines += [ "-D", "enable_service_discovery" ]
    198 }
    199 
    200 grit_resource_id_file = "//tools/gritsettings/resource_ids"
    201 grit_info_script = "//tools/grit/grit_info.py"
    202 
    203 template("grit") {
    204   assert(defined(invoker.source),
    205          "\"source\" must be defined for the grit template $target_name")
    206 
    207   if (defined(invoker.resource_ids)) {
    208     resource_ids = invoker.resource_ids
    209   } else {
    210     resource_ids = grit_resource_id_file
    211   }
    212 
    213   if (defined(invoker.output_dir)) {
    214     output_dir = invoker.output_dir
    215   } else {
    216     output_dir = target_gen_dir
    217   }
    218 
    219   if (defined(invoker.output_name)) {
    220     grit_output_name = invoker.output_name
    221   } else {
    222     grit_output_name = target_name
    223   }
    224 
    225   # These are all passed as arguments to the script so have to be relative to
    226   # the build directory.
    227   if (resource_ids != "") {
    228     resource_ids = rebase_path(resource_ids, root_build_dir)
    229   }
    230   rebased_output_dir = rebase_path(output_dir, root_build_dir)
    231   source_path = rebase_path(invoker.source, root_build_dir)
    232 
    233   if (defined(invoker.grit_flags)) {
    234     grit_flags = invoker.grit_flags
    235   } else {
    236     grit_flags = []  # These are optional so default to empty list.
    237   }
    238 
    239   grit_inputs = [ invoker.source ]
    240 
    241   assert_files_flags = []
    242 
    243   # We want to make sure the declared outputs actually match what Grit is
    244   # writing. We write the list to a file (some of the output lists are long
    245   # enough to not fit on a Windows command line) and ask Grit to verify those
    246   # are the actual outputs at runtime.
    247   asserted_list_file =
    248       "$target_out_dir/${grit_output_name}_expected_outputs.txt"
    249   write_file(asserted_list_file,
    250              rebase_path(invoker.outputs, root_build_dir, output_dir))
    251   assert_files_flags += [
    252     "--assert-file-list=" + rebase_path(asserted_list_file, root_build_dir),
    253   ]
    254   grit_outputs = get_path_info(
    255       rebase_path(invoker.outputs, ".", output_dir),
    256       "abspath")
    257 
    258   # The config and the action below get this visibility son only the generated
    259   # source set can depend on them. The variable "target_name" will get
    260   # overwritten inside the inner classes so we need to compute it here.
    261   target_visibility = [ ":$target_name" ]
    262 
    263   # The current grit setup makes an file in $output_dir/grit/foo.h that
    264   # the source code expects to include via "grit/foo.h". It would be nice to
    265   # change this to including absolute paths relative to the root gen directory
    266   # (like "mycomponent/foo.h"). This config sets up the include path.
    267   grit_config = target_name + "_grit_config"
    268   config(grit_config) {
    269     if (!defined(invoker.use_qualified_include) ||
    270         !invoker.use_qualified_include) {
    271       include_dirs = [ output_dir ]
    272     }
    273     visibility = target_visibility
    274   }
    275 
    276   grit_custom_target = target_name + "_grit"
    277   action(grit_custom_target) {
    278     script = "//tools/grit/grit.py"
    279     inputs = grit_inputs
    280     outputs = grit_outputs
    281     depfile = "$output_dir/${grit_output_name}.d"
    282 
    283     args = [
    284       "-i", source_path, "build",
    285     ]
    286     if (resource_ids != "") {
    287       args += [ "-f", resource_ids ]
    288     }
    289     args += [
    290       "-o", rebased_output_dir,
    291       "--depdir", ".",
    292       "--depfile", rebase_path(depfile, root_build_dir),
    293     ] + grit_defines
    294 
    295     # Add extra defines with -D flags.
    296     if (defined(invoker.defines)) {
    297       foreach (i, invoker.defines) {
    298         args += [ "-D", i ]
    299       }
    300     }
    301 
    302     args += grit_flags + assert_files_flags
    303 
    304     if (defined(invoker.visibility)) {
    305       # This needs to include both what the invoker specified (since they
    306       # probably include generated headers from this target), as well as the
    307       # generated source set (since there's no guarantee that the visibility
    308       # specified by the invoker includes our target).
    309       #
    310       # Only define visibility at all if the invoker specified it. Otherwise,
    311       # we want to keep the public "no visibility specified" default.
    312       visibility = target_visibility + invoker.visibility
    313     }
    314 
    315     deps = [ "//tools/grit:grit_sources" ]
    316     if (defined(invoker.deps)) {
    317       deps += invoker.deps
    318     }
    319   }
    320 
    321   # This is the thing that people actually link with, it must be named the
    322   # same as the argument the template was invoked with.
    323   source_set(target_name) {
    324     # Since we generate a file, we need to be run before the targets that
    325     # depend on us.
    326     sources = grit_outputs
    327 
    328     # Deps set on the template invocation will go on the grit script running
    329     # target rather than this library.
    330     deps = [ ":$grit_custom_target" ]
    331     public_configs = [ ":$grit_config" ]
    332 
    333     if (defined(invoker.visibility)) {
    334       visibility = invoker.visibility
    335     }
    336     output_name = grit_output_name
    337   }
    338 }
    339