blob: d1207ad63e5f0eb641a95686d8681779834d7bb9 [file] [log] [blame]
# 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, and a
# static library that compiles the .cc files.
#
# Parameters
#
# source (required)
# Path to .grd 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 grit_defines 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 (optiona)
# 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.
#
# depfile_dir (optional)
# If set, used to store the depfile and corresponding stamp file.
# Defaults to output_dir
#
# use_qualified_include (optional)
# If set, output_dir is not added to include_dirs.
#
# configs (optional)
# List of additional configs to be applied to the generated target.
# deps (optional)
# inputs (optional)
# List of additional files, required for grit to process source file.
# 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/chrome_build.gni")
import("//build/config/crypto.gni")
import("//build/config/features.gni")
import("//build/config/ui.gni")
import("//third_party/closure_compiler/closure_args.gni")
declare_args() {
# Enables used resource whitelist generation. Set for official builds only
# as a large amount of build output is generated.
enable_resource_whitelist_generation = is_android && is_official_build
}
assert(!enable_resource_whitelist_generation || is_android,
"resource whitelist generation only works on android")
grit_defines = []
# Mac and iOS want Title Case strings.
use_titlecase_in_grd_files = is_mac || is_ios
if (use_titlecase_in_grd_files) {
grit_defines += [
"-D",
"use_titlecase",
]
}
if (is_chrome_branded) {
grit_defines += [
"-D",
"_google_chrome",
"-E",
"CHROMIUM_BUILD=google_chrome",
]
} else {
grit_defines += [
"-D",
"_chromium",
"-E",
"CHROMIUM_BUILD=chromium",
]
}
if (is_chromeos) {
grit_defines += [
"-D",
"chromeos",
"-D",
"scale_factors=2x",
]
}
if (is_desktop_linux) {
grit_defines += [
"-D",
"desktop_linux",
]
}
if (toolkit_views) {
grit_defines += [
"-D",
"toolkit_views",
]
}
if (use_aura) {
grit_defines += [
"-D",
"use_aura",
]
}
if (use_ash) {
grit_defines += [
"-D",
"use_ash",
]
}
if (use_nss_certs) {
grit_defines += [
"-D",
"use_nss_certs",
]
}
if (use_ozone) {
grit_defines += [
"-D",
"use_ozone",
]
}
if (enable_image_loader_extension) {
grit_defines += [
"-D",
"image_loader_extension",
]
}
if (is_android) {
grit_defines += [
"-E",
"ANDROID_JAVA_TAGGED_ONLY=true",
]
}
if (is_mac || is_ios) {
grit_defines += [
"-D",
"scale_factors=2x",
]
}
# When cross-compiling, explicitly pass the target system to grit.
if (current_toolchain != host_toolchain) {
if (is_android) {
grit_defines += [
"-t",
"android",
]
}
if (is_ios) {
grit_defines += [
"-t",
"ios",
]
}
if (is_linux) {
grit_defines += [
"-t",
"linux2",
]
}
if (is_mac) {
grit_defines += [
"-t",
"darwin",
]
}
if (is_win) {
grit_defines += [
"-t",
"win32",
]
}
}
if (enable_extensions) {
grit_defines += [
"-D",
"enable_extensions",
]
}
if (enable_media_router) {
grit_defines += [
"-D",
"enable_media_router",
]
}
if (enable_plugins) {
grit_defines += [
"-D",
"enable_plugins",
]
}
if (enable_basic_printing || enable_print_preview) {
grit_defines += [
"-D",
"enable_printing",
]
if (enable_print_preview) {
grit_defines += [
"-D",
"enable_print_preview",
]
}
}
if (enable_themes) {
grit_defines += [
"-D",
"enable_themes",
]
}
if (enable_app_list) {
grit_defines += [
"-D",
"enable_app_list",
]
}
if (enable_webrtc) {
grit_defines += [
"-D",
"enable_webrtc",
]
}
if (enable_hangout_services_extension) {
grit_defines += [
"-D",
"enable_hangout_services_extension",
]
}
if (enable_task_manager) {
grit_defines += [
"-D",
"enable_task_manager",
]
}
if (enable_notifications) {
grit_defines += [
"-D",
"enable_notifications",
]
}
if (enable_service_discovery) {
grit_defines += [
"-D",
"enable_service_discovery",
]
}
if (mac_views_browser) {
grit_defines += [
"-D",
"mac_views_browser",
]
}
# TODO(aberent): Enable for other platforms once the build machines have
# Java on them (and hence can run the closure compiler).
_strip_resource_files = is_android
_js_minifier = "//third_party/closure_compiler/js_minify.py"
grit_resource_id_file = "//tools/gritsettings/resource_ids"
grit_info_script = "//tools/grit/grit_info.py"
template("grit") {
assert(defined(invoker.source),
"\"source\" must be defined for the grit template $target_name")
grit_inputs = [ invoker.source ]
if (defined(invoker.resource_ids)) {
resource_ids = invoker.resource_ids
} else {
resource_ids = grit_resource_id_file
}
if (resource_ids != "") {
# The script depends on the ID file. Only add this dependency if the ID
# file is specified.
grit_inputs += [ resource_ids ]
}
if (defined(invoker.output_dir)) {
output_dir = invoker.output_dir
} else {
output_dir = target_gen_dir
}
if (defined(invoker.output_name)) {
grit_output_name = invoker.output_name
} else {
grit_output_name = target_name
}
if (defined(invoker.depfile_dir)) {
depfile_dir = invoker.depfile_dir
} else {
depfile_dir = output_dir
}
# These are all passed as arguments to the script so have to be relative to
# the build directory.
if (resource_ids != "") {
resource_ids = rebase_path(resource_ids, root_build_dir)
}
rebased_output_dir = rebase_path(output_dir, root_build_dir)
source_path = rebase_path(invoker.source, root_build_dir)
grit_flags = []
if (enable_resource_whitelist_generation) {
grit_flags += [ "-h" ]
if (is_win) {
grit_flags += [ "#define {textual_id} __pragma(message(\"whitelisted_resource_{numeric_id}\")) {numeric_id}" ]
} else {
grit_flags += [ "#define {textual_id} _Pragma(\"whitelisted_resource_{numeric_id}\") {numeric_id}" ]
}
}
if (defined(invoker.grit_flags)) {
grit_flags += invoker.grit_flags
}
assert_files_flags = []
# 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))
assert_files_flags += [ "--assert-file-list=" +
rebase_path(asserted_list_file, root_build_dir) ]
grit_outputs =
get_path_info(rebase_path(invoker.outputs, ".", output_dir), "abspath")
# The config and the action below get this visibility son only the generated
# source set can depend on them. The variable "target_name" will get
# overwritten inside the inner classes so we need to compute it here.
target_visibility = [ ":$target_name" ]
# The current grit setup makes an file in $output_dir/grit/foo.h that
# the source code expects to include via "grit/foo.h". It would be nice to
# change this to including absolute paths relative to the root gen directory
# (like "mycomponent/foo.h"). This config sets up the include path.
grit_config = target_name + "_grit_config"
config(grit_config) {
if (!defined(invoker.use_qualified_include) ||
!invoker.use_qualified_include) {
include_dirs = [ output_dir ]
}
if ((is_linux || is_android) && enable_resource_whitelist_generation) {
cflags = [
"-Wunknown-pragmas",
"-Wno-error=unknown-pragmas",
]
}
visibility = target_visibility
}
grit_custom_target = target_name + "_grit"
action(grit_custom_target) {
script = "//tools/grit/grit.py"
inputs = grit_inputs
depfile = "$depfile_dir/${grit_output_name}_stamp.d"
outputs = [ "${depfile}.stamp" ] + grit_outputs
args = [
"-i",
source_path,
"build",
]
if (resource_ids != "") {
args += [
"-f",
resource_ids,
]
}
args += [
"-o",
rebased_output_dir,
"--depdir",
".",
"--depfile",
rebase_path(depfile, root_build_dir),
"--write-only-new=1",
"--depend-on-stamp",
] + grit_defines
# Add extra defines with -D flags.
if (defined(invoker.defines)) {
foreach(i, invoker.defines) {
args += [
"-D",
i,
]
}
}
args += grit_flags + assert_files_flags
if (_strip_resource_files) {
js_minifier_command = rebase_path(_js_minifier)
js_minifier_command = "$js_minifier_command --closure_args"
foreach(closure_arg,
common_closure_args + minifying_closure_args +
default_disabled_closure_args) {
js_minifier_command = "$js_minifier_command $closure_arg"
}
args += [
"--js-minifier",
js_minifier_command,
]
inputs += [ _js_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 = target_visibility + invoker.visibility
}
deps = [
"//tools/grit:grit_sources",
]
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) {
# Since we generate a file, we need to be run before the targets that
# depend on us.
sources = grit_outputs
# 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",
]
public_configs = [ ":$grit_config" ]
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
}
}