123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453 |
- # Copyright 2014 The Chromium Authors. All rights reserved.
- # Use of this source code is governed by a BSD-style license that can be
- # found in the LICENSE file.
- # Instantiate grit. This will produce a script target to run grit (named
- # ${target_name}_grit), and a static library that compiles the .cc files.
- #
- # In general, code should depend on the static library. However, if the
- # generated files are only processed by other actions to generate other
- # files, it is possible to depend on the script target directly.
- #
- # Parameters
- #
- # source (required)
- # Path to .grd file.
- #
- # enable_input_discovery_for_gn_analyze (default=true)
- # Runs grit_info.py via exec_script() when compute_inputs_for_analyze=true
- # in order to discover all files that affect this target.
- # Turn this off when the .grd file is generated, or an <include> with
- # flattenhtml=true points to a generated file.
- # For "gn analyze" to be correct with this arg disabled, all inputs
- # must be listed via |inputs|.
- #
- # inputs (optional)
- # List of additional files, required for grit to process source file.
- #
- # outputs (required)
- # List of outputs from grit, relative to the target_gen_dir. Grit will
- # verify at build time that this list is correct and will fail if there
- # is a mismatch between the outputs specified by the .grd file and the
- # outputs list here.
- #
- # To get this list, you can look in the .grd file for
- # <output filename="..." and put those filename here. The base directory
- # of the list in Grit and the output list specified in the GN grit target
- # are the same (the target_gen_dir) so you can generally copy the names
- # exactly.
- #
- # To get the list of outputs programatically, run:
- # python tools/grit/grit_info.py --outputs . path/to/your.grd
- # And strip the leading "./" from the output files.
- #
- # defines (optional)
- # Extra defines to pass to grit (on top of the global defines in the
- # grit_args list).
- #
- # grit_flags (optional)
- # List of strings containing extra command-line flags to pass to Grit.
- #
- # resource_ids (optional)
- # Path to a grit "firstidsfile". Default is
- # //tools/gritsettings/resource_ids. Set to "" to use the value specified
- # in the <grit> nodes of the processed files.
- #
- # output_dir (optional)
- # Directory for generated files. If you specify this, you will often
- # want to specify output_name if the target name is not particularly
- # unique, since this can cause files from multiple grit targets to
- # overwrite each other.
- #
- # output_name (optional)
- # Provide an alternate base name for the generated files, like the .d
- # files. Normally these are based on the target name and go in the
- # output_dir, but if multiple targets with the same name end up in
- # the same output_dir, they can collide.
- #
- # configs (optional)
- # List of additional configs to be applied to the generated target.
- #
- # deps (optional)
- # testonly (optional)
- # visibility (optional)
- # Normal meaning.
- #
- #
- # Example
- #
- # grit("my_resources") {
- # # Source and outputs are required.
- # source = "myfile.grd"
- # outputs = [
- # "foo_strings.h",
- # "foo_strings.pak",
- # ]
- #
- # grit_flags = [ "-E", "foo=bar" ] # Optional extra flags.
- # # You can also put deps here if the grit source depends on generated
- # # files.
- # }
- import("//build/config/compiler/compiler.gni")
- import("//build/config/compute_inputs_for_analyze.gni")
- import("//build/config/sanitizers/sanitizers.gni")
- import("//build/toolchain/gcc_toolchain.gni")
- import("//tools/grit/grit_args.gni")
- _strip_resource_files = is_android && is_official_build
- _js_minifier = "//tools/grit/minify_with_uglify.py"
- _css_minifier = "//tools/grit/minimize_css.py"
- grit_resource_id_target = "//tools/gritsettings:default_resource_ids"
- grit_resource_id_file =
- get_label_info(grit_resource_id_target, "target_gen_dir") +
- "/default_resource_ids"
- grit_info_script = "//tools/grit/grit_info.py"
- # TODO(asvitkine): Add predetermined ids files for other platforms.
- grit_predetermined_resource_ids_file = ""
- if (is_mac) {
- grit_predetermined_resource_ids_file =
- "//tools/gritsettings/startup_resources_mac.txt"
- }
- if (is_win) {
- grit_predetermined_resource_ids_file =
- "//tools/gritsettings/startup_resources_win.txt"
- }
- template("grit") {
- if (defined(invoker.output_dir)) {
- _output_dir = invoker.output_dir
- } else {
- _output_dir = target_gen_dir
- }
- _grit_outputs =
- get_path_info(rebase_path(invoker.outputs, ".", _output_dir), "abspath")
- # Add .info output for all pak files
- _pak_info_outputs = []
- foreach(output, _grit_outputs) {
- if (get_path_info(output, "extension") == "pak") {
- _pak_info_outputs += [ output + ".info" ]
- }
- }
- if (defined(invoker.output_name)) {
- _grit_output_name = invoker.output_name
- } else {
- _grit_output_name = target_name
- }
- _grit_custom_target = target_name + "_grit"
- action(_grit_custom_target) {
- script = "//tools/grit/grit.py"
- inputs = [ invoker.source ]
- testonly = defined(invoker.testonly) && invoker.testonly
- depfile = "$target_gen_dir/$target_name.d"
- deps = [ "//tools/grit:grit_sources" ]
- outputs = [ "${depfile}.stamp" ] + _grit_outputs + _pak_info_outputs
- _grit_flags = grit_args
- # Add extra defines with -D flags.
- if (defined(invoker.defines)) {
- foreach(i, invoker.defines) {
- _grit_flags += [
- "-D",
- i,
- ]
- }
- }
- if (defined(invoker.grit_flags)) {
- _grit_flags += invoker.grit_flags
- }
- _rebased_source_path = rebase_path(invoker.source, root_build_dir)
- _enable_grit_info =
- !defined(invoker.enable_input_discovery_for_gn_analyze) ||
- invoker.enable_input_discovery_for_gn_analyze
- if (_enable_grit_info && compute_inputs_for_analyze) {
- # Only call exec_script when the user has explicitly opted into greater
- # precision at the expense of performance.
- _rel_inputs = exec_script("//tools/grit/grit_info.py",
- [
- "--inputs",
- _rebased_source_path,
- ] + _grit_flags,
- "list lines")
- inputs += rebase_path(_rel_inputs, ".", root_build_dir)
- }
- args = [
- "-i",
- _rebased_source_path,
- "build",
- "-o",
- rebase_path(_output_dir, root_build_dir),
- "--depdir",
- ".",
- "--depfile",
- rebase_path(depfile, root_build_dir),
- "--write-only-new=1",
- "--depend-on-stamp",
- ] + _grit_flags
- # Add brotli executable if using brotli.
- if (defined(invoker.use_brotli) && invoker.use_brotli) {
- _brotli_target = "//third_party/brotli:brotli($host_toolchain)"
- _brotli_executable = get_label_info(_brotli_target, "root_out_dir") +
- "/" + get_label_info(_brotli_target, "name")
- if (host_os == "win") {
- _brotli_executable += ".exe"
- }
- inputs += [ _brotli_executable ]
- args += [
- "--brotli",
- rebase_path(_brotli_executable, root_build_dir),
- ]
- }
- _resource_ids = grit_resource_id_file
- if (defined(invoker.resource_ids)) {
- _resource_ids = invoker.resource_ids
- }
- if (_resource_ids != "") {
- inputs += [ _resource_ids ]
- args += [
- "-f",
- rebase_path(_resource_ids, root_build_dir),
- ]
- if (_resource_ids == grit_resource_id_file) {
- deps += [ grit_resource_id_target ]
- }
- }
- if (grit_predetermined_resource_ids_file != "") {
- inputs += [ grit_predetermined_resource_ids_file ]
- args += [
- "-p",
- rebase_path(grit_predetermined_resource_ids_file, root_build_dir),
- ]
- }
- # We want to make sure the declared outputs actually match what Grit is
- # writing. We write the list to a file (some of the output lists are long
- # enough to not fit on a Windows command line) and ask Grit to verify those
- # are the actual outputs at runtime.
- _asserted_list_file =
- "$target_out_dir/${_grit_output_name}_expected_outputs.txt"
- write_file(_asserted_list_file,
- rebase_path(invoker.outputs, root_build_dir, _output_dir))
- inputs += [ _asserted_list_file ]
- args += [
- "--assert-file-list",
- rebase_path(_asserted_list_file, root_build_dir),
- ]
- if (enable_resource_allowlist_generation) {
- _rc_grit_outputs = []
- foreach(output, _grit_outputs) {
- if (get_path_info(output, "extension") == "rc") {
- _rc_grit_outputs += [ output ]
- }
- }
- if (_rc_grit_outputs != []) {
- # Resource allowlisting cannot be used with .rc files.
- # Make sure that there aren't any .pak outputs which would require
- # allowlist annotations.
- assert(_pak_info_outputs == [], "can't combine .pak and .rc outputs")
- } else {
- args += [ "--allowlist-support" ]
- }
- }
- if (_strip_resource_files) {
- _js_minifier_command = rebase_path(_js_minifier, root_build_dir)
- _css_minifier_command = rebase_path(_css_minifier, root_build_dir)
- args += [
- "--js-minifier",
- _js_minifier_command,
- "--css-minifier",
- _css_minifier_command,
- ]
- inputs += [
- _js_minifier,
- _css_minifier,
- ]
- }
- if (defined(invoker.visibility)) {
- # This needs to include both what the invoker specified (since they
- # probably include generated headers from this target), as well as the
- # generated source set (since there's no guarantee that the visibility
- # specified by the invoker includes our target).
- #
- # Only define visibility at all if the invoker specified it. Otherwise,
- # we want to keep the public "no visibility specified" default.
- visibility = [ ":${invoker.target_name}" ] + invoker.visibility
- }
- if (defined(invoker.use_brotli) && invoker.use_brotli) {
- if (is_mac && is_asan) {
- deps += [ "//tools/grit:brotli_mac_asan_workaround" ]
- } else {
- deps += [ "//third_party/brotli:brotli($host_toolchain)" ]
- }
- }
- if (defined(invoker.deps)) {
- deps += invoker.deps
- }
- if (defined(invoker.inputs)) {
- inputs += invoker.inputs
- }
- }
- # This is the thing that people actually link with, it must be named the
- # same as the argument the template was invoked with.
- source_set(target_name) {
- testonly = defined(invoker.testonly) && invoker.testonly
- # Since we generate a file, we need to be run before the targets that
- # depend on us.
- sources = []
- foreach(_output, _grit_outputs) {
- _extension = get_path_info(_output, "extension")
- if (_extension != "json" && _extension != "gz" && _extension != "pak" &&
- _extension != "xml") {
- sources += [ _output ]
- }
- }
- # Deps set on the template invocation will go on the action that runs
- # grit above rather than this library. This target needs to depend on the
- # action publicly so other scripts can take the outputs from the grit
- # script as inputs.
- public_deps = [ ":$_grit_custom_target" ]
- deps = [ "//base" ]
- if (defined(invoker.public_configs)) {
- public_configs += invoker.public_configs
- }
- if (defined(invoker.configs)) {
- configs += invoker.configs
- }
- if (defined(invoker.visibility)) {
- visibility = invoker.visibility
- }
- output_name = _grit_output_name
- }
- }
- if (is_android) {
- import("//build/config/android/rules.gni")
- # Declare a target that generates localized strings.xml from a .grd file.
- #
- # If this target is included in the deps of an android resources/library/apk,
- # the strings.xml will be included with that target.
- #
- # Variables
- # deps: Specifies the dependencies of this target.
- # grd_file: Path to the .grd file to generate strings.xml from.
- # outputs: Expected grit outputs (see grit rule).
- #
- # Example
- # java_strings_grd("foo_strings_grd") {
- # grd_file = "foo_strings.grd"
- # }
- template("java_strings_grd") {
- forward_variables_from(invoker, [ "testonly" ])
- _resources_zip = "$target_out_dir/$target_name.resources.zip"
- _grit_target_name = "${target_name}__grit"
- _grit_output_dir = "$target_gen_dir/${target_name}_grit_output"
- grit(_grit_target_name) {
- forward_variables_from(invoker,
- [
- "deps",
- "defines",
- ])
- grit_flags = [
- "-E",
- "ANDROID_JAVA_TAGGED_ONLY=false",
- ]
- output_dir = _grit_output_dir
- resource_ids = ""
- source = invoker.grd_file
- outputs = invoker.outputs
- }
- _zip_target_name = "${target_name}__zip"
- zip(_zip_target_name) {
- base_dir = _grit_output_dir
- # No need to depend on the source_set().
- _grit_dep = ":${_grit_target_name}_grit"
- deps = [ _grit_dep ]
- inputs = filter_exclude(get_target_outputs(_grit_dep), [ "*.stamp" ])
- output = _resources_zip
- }
- android_generated_resources(target_name) {
- forward_variables_from(invoker,
- [
- "resource_overlay",
- "visibility",
- ])
- generating_target = ":$_zip_target_name"
- generated_resources_zip = _resources_zip
- }
- }
- # Declare a target that packages strings.xml generated from a grd file.
- #
- # If this target is included in the deps of an android resources/library/apk,
- # the strings.xml will be included with that target.
- #
- # Variables
- # grit_output_dir: directory containing grit-generated files.
- # generated_files: list of android resource files to package.
- #
- # Example
- # java_strings_grd_prebuilt("foo_strings_grd") {
- # grit_output_dir = "$root_gen_dir/foo/grit"
- # generated_files = [
- # "values/strings.xml"
- # ]
- # }
- template("java_strings_grd_prebuilt") {
- forward_variables_from(invoker, [ "testonly" ])
- _resources_zip = "$target_out_dir/$target_name.resources.zip"
- _zip_target_name = "${target_name}__zip"
- zip(_zip_target_name) {
- base_dir = invoker.grit_output_dir
- inputs = rebase_path(invoker.generated_files, ".", base_dir)
- output = _resources_zip
- if (defined(invoker.deps)) {
- deps = invoker.deps
- }
- }
- android_generated_resources(target_name) {
- forward_variables_from(invoker,
- [
- "resource_overlay",
- "visibility",
- ])
- generating_target = ":$_zip_target_name"
- generated_resources_zip = _resources_zip
- }
- }
- }
|