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.
5 # Instantiate grit. This will produce a script target to run grit, and a
6 # static library that compiles the .cc files.
13 # source_is_generated (optional, defaults to false)
14 # Declares that the input (or one of its dependencies) is generated so
15 # that grit_info is not run on the file when
16 # compute_grit_inputs_for_analyze is set (because the file will not
17 # exist at analyze time). For "analyze" to be correct in this case, the
18 # inputs to the grit file must either be listed in the inputs variable
19 # or are listed as inputs to dependencies of this target.
22 # List of additional files, required for grit to process source file.
25 # List of outputs from grit, relative to the target_gen_dir. Grit will
26 # verify at build time that this list is correct and will fail if there
27 # is a mismatch between the outputs specified by the .grd file and the
30 # To get this list, you can look in the .grd file for
31 # <output filename="..." and put those filename here. The base directory
32 # of the list in Grit and the output list specified in the GN grit target
33 # are the same (the target_gen_dir) so you can generally copy the names
36 # To get the list of outputs programatically, run:
37 # python tools/grit/grit_info.py --outputs . path/to/your.grd
38 # And strip the leading "./" from the output files.
41 # Extra defines to pass to grit (on top of the global grit_defines list).
43 # grit_flags (optional)
44 # List of strings containing extra command-line flags to pass to Grit.
46 # resource_ids (optional)
47 # Path to a grit "firstidsfile". Default is
48 # //tools/gritsettings/resource_ids. Set to "" to use the value specified
49 # in the <grit> nodes of the processed files.
51 # output_dir (optional)
52 # Directory for generated files. If you specify this, you will often
53 # want to specify output_name if the target name is not particularly
54 # unique, since this can cause files from multiple grit targets to
55 # overwrite each other.
57 # output_name (optional)
58 # Provide an alternate base name for the generated files, like the .d
59 # files. Normally these are based on the target name and go in the
60 # output_dir, but if multiple targets with the same name end up in
61 # the same output_dir, they can collide.
63 # depfile_dir (optional)
64 # If set, used to store the depfile and corresponding stamp file.
65 # Defaults to output_dir
68 # List of additional configs to be applied to the generated target.
70 # visibility (optional)
75 # grit("my_resources") {
76 # # Source and outputs are required.
77 # source = "myfile.grd"
83 # grit_flags = [ "-E", "foo=bar" ] # Optional extra flags.
84 # # You can also put deps here if the grit source depends on generated
87 import("//build/config/android/config.gni")
88 import("//build/config/chrome_build.gni")
89 import("//build/config/crypto.gni")
90 import("//build/config/features.gni")
91 import("//build/config/ui.gni")
92 import("//third_party/closure_compiler/closure_args.gni")
94 assert(!enable_resource_whitelist_generation || is_android,
95 "resource whitelist generation only works on android")
98 # When set, this will fork out to grit at GN-time to get all inputs
99 # referenced by the .grd file.
101 # Normal builds don't need this since proper incremental builds are handled
102 # by grit writing out the inputs in .d files at build-time. But for analyze
103 # to work on the bots, it needs to know about all input files at GN-time so
104 # it knows which tests to trigger when something changes. This option will
105 # slow down the GN run.
106 compute_grit_inputs_for_analyze = false
111 # Mac and iOS want Title Case strings.
112 use_titlecase_in_grd_files = is_mac || is_ios
113 if (use_titlecase_in_grd_files) {
120 if (is_chrome_branded) {
125 "CHROMIUM_BUILD=google_chrome",
132 "CHROMIUM_BUILD=chromium",
145 if (is_desktop_linux) {
183 "ANDROID_JAVA_TAGGED_ONLY=true",
187 if (is_mac || is_ios) {
194 # When cross-compiling, explicitly pass the target system to grit.
195 if (current_toolchain != host_toolchain) {
208 if (is_linux || is_bsd) {
228 # TODO(aberent): Enable for other platforms once the build machines have
229 # Java on them (and hence can run the closure compiler).
230 _strip_resource_files = is_android
231 _js_minifier = "//third_party/closure_compiler/js_minify.py"
233 grit_resource_id_file = "//tools/gritsettings/resource_ids"
234 grit_info_script = "//tools/grit/grit_info.py"
236 # TODO(asvitkine): Add predetermined ids files for other platforms.
237 grit_predetermined_resource_ids_file = ""
239 grit_predetermined_resource_ids_file =
240 "//tools/gritsettings/startup_resources_mac.txt"
243 grit_predetermined_resource_ids_file =
244 "//tools/gritsettings/startup_resources_win.txt"
248 assert(defined(invoker.source),
249 "\"source\" must be defined for the grit template $target_name")
251 if (defined(invoker.resource_ids)) {
252 resource_ids = invoker.resource_ids
254 resource_ids = grit_resource_id_file
257 if (defined(invoker.output_dir)) {
258 output_dir = invoker.output_dir
260 output_dir = target_gen_dir
263 if (defined(invoker.output_name)) {
264 grit_output_name = invoker.output_name
266 grit_output_name = target_name
269 if (defined(invoker.depfile_dir)) {
270 depfile_dir = invoker.depfile_dir
272 depfile_dir = output_dir
275 # These are all passed as arguments to the script so have to be relative to
276 # the build directory.
277 rebased_output_dir = rebase_path(output_dir, root_build_dir)
278 source_path = rebase_path(invoker.source, root_build_dir)
282 if (enable_resource_whitelist_generation) {
283 grit_flags += [ "-h" ]
285 grit_flags += [ "#define {textual_id} __pragma(message(\"whitelisted_resource_{numeric_id}\")) {numeric_id}" ]
287 grit_flags += [ "#define {textual_id} _Pragma(\"whitelisted_resource_{numeric_id}\") {numeric_id}" ]
290 if (defined(invoker.grit_flags)) {
291 grit_flags += invoker.grit_flags
293 if (resource_ids != "") {
296 rebase_path(resource_ids, root_build_dir),
299 if (grit_predetermined_resource_ids_file != "") {
302 rebase_path(grit_predetermined_resource_ids_file, root_build_dir),
306 if (defined(invoker.source_is_generated)) {
307 source_is_generated = invoker.source_is_generated
309 source_is_generated = false
312 assert_files_flags = []
314 # We want to make sure the declared outputs actually match what Grit is
315 # writing. We write the list to a file (some of the output lists are long
316 # enough to not fit on a Windows command line) and ask Grit to verify those
317 # are the actual outputs at runtime.
319 "$target_out_dir/${grit_output_name}_expected_outputs.txt"
320 write_file(asserted_list_file,
321 rebase_path(invoker.outputs, root_build_dir, output_dir))
322 assert_files_flags += [ "--assert-file-list=" +
323 rebase_path(asserted_list_file, root_build_dir) ]
325 get_path_info(rebase_path(invoker.outputs, ".", output_dir), "abspath")
327 # Add .info output for all pak files
328 set_sources_assignment_filter([ "*.pak" ])
329 sources = grit_outputs
330 pak_grit_outputs = grit_outputs - sources
332 pak_info_outputs = []
333 foreach(output, pak_grit_outputs) {
334 pak_info_outputs += [ "${output}.info" ]
337 # The config and the action below get this visibility son only the generated
338 # source set can depend on them. The variable "target_name" will get
339 # overwritten inside the inner classes so we need to compute it here.
340 target_visibility = [ ":$target_name" ]
342 # This config sets up flags needed for enable_resource_whitelist_generation.
343 grit_config = target_name + "_grit_config"
344 config(grit_config) {
345 if ((is_linux || is_android || is_bsd) &&
346 enable_resource_whitelist_generation) {
349 "-Wno-error=unknown-pragmas",
352 visibility = target_visibility
355 grit_custom_target = target_name + "_grit"
356 action(grit_custom_target) {
357 script = "//tools/grit/grit.py"
362 if (resource_ids != "") {
363 # The script depends on the ID file. Only add this dependency if the ID
365 inputs += [ resource_ids ]
368 depfile = "$depfile_dir/${grit_output_name}_stamp.d"
369 outputs = [ "${depfile}.stamp" ] + grit_outputs + pak_info_outputs
380 rebase_path(depfile, root_build_dir),
381 "--write-only-new=1",
385 # Add extra defines with -D flags.
387 if (defined(invoker.defines)) {
388 foreach(i, invoker.defines) {
396 args += define_args + grit_flags + assert_files_flags
398 if (_strip_resource_files) {
399 js_minifier_command = rebase_path(_js_minifier)
400 js_minifier_command = "$js_minifier_command --closure_args"
402 common_closure_args + minifying_closure_args +
403 default_disabled_closure_args) {
404 js_minifier_command = "$js_minifier_command $closure_arg"
412 "//third_party/closure_compiler/compiler/compiler.jar",
416 # Must be after the args are computed since they are re-used.
417 # See the comments for the two variables used in this condition for
418 # why this works this way.
419 if (compute_grit_inputs_for_analyze && !source_is_generated) {
420 grit_info_script = "//tools/grit/grit_info.py"
424 ] + grit_flags + grit_defines
426 # Only call exec_script when the user has explicitly opted into greater
427 # precision at the expense of performance.
428 rel_inputs = exec_script(grit_info_script,
431 [ grit_info_script ])
432 inputs += rebase_path(rel_inputs, ".", root_build_dir)
434 assert(source_is_generated || !source_is_generated) # Prevent error.
437 if (defined(invoker.visibility)) {
438 # This needs to include both what the invoker specified (since they
439 # probably include generated headers from this target), as well as the
440 # generated source set (since there's no guarantee that the visibility
441 # specified by the invoker includes our target).
443 # Only define visibility at all if the invoker specified it. Otherwise,
444 # we want to keep the public "no visibility specified" default.
445 visibility = target_visibility + invoker.visibility
449 "//tools/grit:grit_sources",
451 if (defined(invoker.deps)) {
454 if (defined(invoker.inputs)) {
455 inputs += invoker.inputs
459 # This is the thing that people actually link with, it must be named the
460 # same as the argument the template was invoked with.
461 source_set(target_name) {
462 # Since we generate a file, we need to be run before the targets that
464 sources = grit_outputs
466 # Deps set on the template invocation will go on the action that runs
467 # grit above rather than this library. This target needs to depend on the
468 # action publicly so other scripts can take the outputs from the grit
471 ":$grit_custom_target",
473 public_configs = [ ":$grit_config" ]
475 if (defined(invoker.public_configs)) {
476 public_configs += invoker.public_configs
479 if (defined(invoker.configs)) {
480 configs += invoker.configs
483 if (defined(invoker.visibility)) {
484 visibility = invoker.visibility
486 output_name = grit_output_name