author | Dan Minor <dminor@mozilla.com> |
Thu, 27 Jul 2017 12:42:30 -0400 | |
changeset 400726 | 0585c9c9e9f4a35b91510ea71c8143d01e219341 |
parent 400725 | 36537db2ecf5d87e5a1d95eb268154341355ba90 |
child 400727 | 726ef3a889d4f41d631683817701eb671c818e58 |
push id | 33313 |
push user | ncsoregi@mozilla.com |
push date | Thu, 25 Jan 2018 10:14:49 +0000 |
treeherder | mozilla-central@040afea6562f [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jesup |
bugs | 1393119 |
milestone | 60.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
new file mode 100644 --- /dev/null +++ b/media/webrtc/trunk/.gn @@ -0,0 +1,54 @@ +# Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. +# +# Use of this source code is governed by a BSD-style license +# that can be found in the LICENSE file in the root of the source +# tree. An additional intellectual property rights grant can be found +# in the file PATENTS. All contributing project authors may +# be found in the AUTHORS file in the root of the source tree. + +import("//build/dotfile_settings.gni") + +# The location of the build configuration file. +buildconfig = "//build/config/BUILDCONFIG.gn" + +# The secondary source root is a parallel directory tree where +# GN build files are placed when they can not be placed directly +# in the source tree, e.g. for third party source trees. +secondary_source = "//build/secondary/" + +# These are the targets to check headers for by default. The files in targets +# matching these patterns (see "gn help label_pattern" for format) will have +# their includes checked for proper dependencies when you run either +# "gn check" or "gn gen --check". +# TODO(kjellander): Keep adding paths to this list as work in webrtc:5589 is done. +check_targets = [ + "//webrtc/api/*", + "//webrtc/audio/*", + "//webrtc/modules/audio_coding/*", + "//webrtc/modules/audio_conference_mixer/*", + "//webrtc/modules/audio_device/*", + "//webrtc/modules/audio_mixer/*", + "//webrtc/modules/audio_processing/*", + "//webrtc/modules/bitrate_controller/*", + "//webrtc/modules/congestion_controller/*", + "//webrtc/modules/desktop_capture/*", + "//webrtc/modules/media_file/*", + "//webrtc/modules/pacing/*", + "//webrtc/modules/rtp_rtcp/*", + "//webrtc/modules/utility/*", + "//webrtc/modules/video_capture/*", + "//webrtc/modules/video_coding/*", + "//webrtc/modules/video_processing/*", + "//webrtc/modules/remote_bitrate_estimator/*", + "//webrtc/stats:rtc_stats", + "//webrtc/voice_engine", + "//webrtc/voice_engine:audio_coder", + "//webrtc/voice_engine:file_player", + "//webrtc/voice_engine:file_recorder", + "//webrtc/voice_engine:level_indicator", +] + +# These are the list of GN files that run exec_script. This whitelist exists +# to force additional review for new uses of exec_script, which is strongly +# discouraged except for gypi_to_gn calls. +exec_script_whitelist = build_dotfile_settings.exec_script_whitelist
new file mode 100644 --- /dev/null +++ b/media/webrtc/trunk/BUILD.gn @@ -0,0 +1,21 @@ +# Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. +# +# Use of this source code is governed by a BSD-style license +# that can be found in the LICENSE file in the root of the source +# tree. An additional intellectual property rights grant can be found +# in the file PATENTS. All contributing project authors may +# be found in the AUTHORS file in the root of the source tree. + +import("webrtc/build/webrtc.gni") + +group("default") { + testonly = true + deps = [ + "//webrtc", + "//webrtc/examples", + "//webrtc/tools", + ] + if (rtc_include_tests) { + deps += [ "//webrtc:webrtc_tests" ] + } +}
--- a/media/webrtc/trunk/build/OWNERS +++ b/media/webrtc/trunk/build/OWNERS @@ -1,1 +1,22 @@ -* +agrieve@chromium.org +dpranke@chromium.org +jbudorick@chromium.org +jochen@chromium.org +scottmg@chromium.org +thakis@chromium.org +brucedawson@chromium.org + +per-file .gitignore=* +per-file mac_toolchain.py=erikchen@chromium.org +per-file mac_toolchain.py=justincohen@chromium.org +per-file package_mac_toolchain.py=erikchen@chromium.org +per-file package_mac_toolchain.py=justincohen@chromium.org +per-file whitespace_file.txt=* +per-file OWNERS.status=* + +# gn-dev is probably a better team here, but the tooling won't let us +# have more than one team per component, and infra-dev is a catch-all +# for other build-related lists. +# +# TEAM: infra-dev@chromium.org +# COMPONENT: Build
new file mode 100644 --- /dev/null +++ b/media/webrtc/trunk/build/OWNERS.status @@ -0,0 +1,12 @@ +# Use this file to set a global status message that should be shown whenever +# git cl owners proposes to add you as a reviewer. +# +# The status messages should be somewhat stable, so please don't use this for +# short term, or frequently changing updates. +# +# The format of the file is +# +# you@chromium.org: Single line status message. +# + +jochen@chromium.org: EMEA based reviewer.
new file mode 100644 --- /dev/null +++ b/media/webrtc/trunk/build/args/OWNERS @@ -0,0 +1,1 @@ +per-file headless.gn=file://headless/OWNERS
new file mode 100644 --- /dev/null +++ b/media/webrtc/trunk/build/args/README.txt @@ -0,0 +1,31 @@ +This directory is here to hold .gni files that contain sets of GN build +arguments for given configurations. + +(Currently this directory is empty because we removed the only thing here, but +this has come up several times so I'm confident we'll need this again. If this +directory is still empty by 2017, feel free to delete it. --Brett) + +Some projects or bots may have build configurations with specific combinations +of flags. Rather than making a new global flag for your specific project and +adding it all over the build to each arg it should affect, you can add a .gni +file here with the variables. + +For example, for project foo you may put in build/args/foo.gni: + + target_os = "android" + use_pulseaudio = false + use_ozone = true + system_libdir = "foo" + +Users wanting to build this configuration would run: + + $ gn args out/mybuild + +And add the following line to their args for that build directory: + + import("//build/args/foo.gni") + # You can set any other args here like normal. + is_component_build = false + +This way everybody can agree on a set of flags for a project, and their builds +stay in sync as the flags in foo.gni are modified.
new file mode 100644 --- /dev/null +++ b/media/webrtc/trunk/build/args/headless.gn @@ -0,0 +1,44 @@ +# GN args template for the Headless Chrome library +# +# Add import to arg.gn in out directory and run gn gen on the directory to use. +# E.g. for out directory out/foo: +# echo 'import("//build/args/headless.gn")' > out/foo/args.gn +# gn gen out/foo +# +# Use gn args to add your own build preference args. + +use_ozone = true +ozone_auto_platforms = false +ozone_platform = "headless" +ozone_platform_headless = true + +# Embed resource.pak into binary to simplify deployment. +headless_use_embedded_resources = true + +# Expose headless bindings for freetype library bundled with Chromium. +headless_fontconfig_utils = true + +# Remove a dependency on a system fontconfig library. +use_bundled_fontconfig = true + +# In order to simplify deployment we build ICU data file +# into binary. +icu_use_data_file = false + +# Use embedded data instead external files for headless in order +# to simplify deployment. +v8_use_external_startup_data = false + +enable_nacl = false +enable_print_preview = false +enable_remoting = false +use_alsa = false +use_ash = false +use_cups = false +use_dbus = false +use_gconf = false +use_gio = false +use_kerberos = false +use_libpci = false +use_pulseaudio = false +use_udev = false
new file mode 100644 --- /dev/null +++ b/media/webrtc/trunk/build/build-ctags.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +# Copyright 2013 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. + +if [[ a"`ctags --version | head -1 | grep \"^Exuberant Ctags\"`" == "a" ]]; then + cat <<EOF + You must be using Exuberant Ctags, not just standard GNU ctags. If you are on + Debian or a related flavor of Linux, you may want to try running + apt-get install exuberant-ctags. +EOF + exit +fi + +CHROME_SRC_DIR="$PWD" + +fail() { + echo "Failed to create ctags for $1" + exit 1 +} + +ctags_cmd() { + echo "ctags --languages=C++ $1 --exclude=.git -R -f .tmp_tags" +} + +build_dir() { + local extraexcludes="" + if [[ a"$1" == "a--extra-excludes" ]]; then + extraexcludes="--exclude=third_party --exclude=build --exclude=out" + shift + fi + + cd "$CHROME_SRC_DIR/$1" || fail $1 + # Redirect error messages so they aren't seen because they are almost always + # errors about components that you just happen to have not built (NaCl, for + # example). + $(ctags_cmd "$extraexcludes") 2> /dev/null || fail $1 + mv -f .tmp_tags tags +} + +# We always build the top level but leave all submodules as optional. +build_dir --extra-excludes "" "top level" + +# Build any other directies that are listed on the command line. +for dir in $@; do + build_dir "$1" + shift +done
new file mode 100644 --- /dev/null +++ b/media/webrtc/trunk/build/buildflag.h @@ -0,0 +1,47 @@ +// Copyright 2015 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. + +#ifndef BUILD_BUILDFLAG_H_ +#define BUILD_BUILDFLAG_H_ + +// These macros un-mangle the names of the build flags in a way that looks +// natural, and gives errors if the flag is not defined. Normally in the +// preprocessor it's easy to make mistakes that interpret "you haven't done +// the setup to know what the flag is" as "flag is off". Normally you would +// include the generated header rather than include this file directly. +// +// This is for use with generated headers. See build/buildflag_header.gni. + +// This dance of two macros does a concatenation of two preprocessor args using +// ## doubly indirectly because using ## directly prevents macros in that +// parameter from being expanded. +#define BUILDFLAG_CAT_INDIRECT(a, b) a ## b +#define BUILDFLAG_CAT(a, b) BUILDFLAG_CAT_INDIRECT(a, b) + +// Accessor for build flags. +// +// To test for a value, if the build file specifies: +// +// ENABLE_FOO=true +// +// Then you would check at build-time in source code with: +// +// #include "foo_flags.h" // The header the build file specified. +// +// #if BUILDFLAG(ENABLE_FOO) +// ... +// #endif +// +// There will no #define called ENABLE_FOO so if you accidentally test for +// whether that is defined, it will always be negative. You can also use +// the value in expressions: +// +// const char kSpamServerName[] = BUILDFLAG(SPAM_SERVER_NAME); +// +// Because the flag is accessed as a preprocessor macro with (), an error +// will be thrown if the proper header defining the internal flag value has +// not been included. +#define BUILDFLAG(flag) (BUILDFLAG_CAT(BUILDFLAG_INTERNAL_, flag)()) + +#endif // BUILD_BUILDFLAG_H_
new file mode 100644 --- /dev/null +++ b/media/webrtc/trunk/build/buildflag_header.gni @@ -0,0 +1,137 @@ +# Copyright 2015 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. + +# Generates a header with preprocessor defines specified by the build file. +# +# The flags are converted to function-style defines with mangled names and +# code uses an accessor macro to access the values. This is to try to +# minimize bugs where code checks whether something is defined or not, and +# the proper header isn't included, meaning the answer will always be silently +# false or might vary across the code base. +# +# In the GN template, specify build flags in the template as a list +# of strings that encode key/value pairs like this: +# +# flags = [ "ENABLE_FOO=1", "ENABLE_BAR=$enable_bar" ] +# +# The GN values "true" and "false" will be mapped to 0 and 1 for boolean +# #if flags to be expressed naturally. This means you can't directly make a +# define that generates C++ value of true or false for use in code. If you +# REALLY need this, you can also use the string "(true)" and "(false)" to +# prevent the rewriting. + +# To check the value of the flag in C code: +# +# #include "path/to/here/header_file.h" +# +# #if BUILDFLAG(ENABLE_FOO) +# ... +# #endif +# +# const char kSpamServerUrl[] = BUILDFLAG(SPAM_SERVER_URL); +# +# There will no #define called ENABLE_FOO so if you accidentally test for that +# in an ifdef it will always be negative. +# +# +# Template parameters +# +# flags [required, list of strings] +# Flag values as described above. +# +# header [required, string] +# File name for generated header. By default, this will go in the +# generated file directory for this target, and you would include it +# with: +# #include "<path_to_this_BUILD_file>/<header>" +# +# header_dir [optional, string] +# Override the default location of the generated header. The string will +# be treated as a subdirectory of the root_gen_dir. For example: +# header_dir = "foo/bar" +# Then you can include the header as: +# #include "foo/bar/baz.h" +# +# deps, public_deps, testonly, visibility +# Normal meaning. +# +# +# Grit defines +# +# If one .grd file uses a flag, just add to the grit target: +# +# defines = [ +# "enable_doom_melon=$enable_doom_melon", +# ] +# +# If multiple .grd files use it, you'll want to put the defines in a .gni file +# so it can be shared. Generally this .gni file should include all grit defines +# for a given module (for some definition of "module"). Then do: +# +# defines = ui_grit_defines +# +# If you forget to do this, the flag will be implicitly false in the .grd file +# and those resources won't be compiled. You'll know because the resource +# #define won't be generated and any code that uses it won't compile. If you +# see a missing IDS_* string, this is probably the reason. +# +# +# Example +# +# buildflag_header("foo_features") { +# header = "foo_features.h" +# +# flags = [ +# # This uses the GN build flag enable_doom_melon as the definition. +# "ENABLE_DOOM_MELON=$enable_doom_melon", +# +# # This force-enables the flag. +# "ENABLE_SPACE_LASER=true", +# +# # This will expand to the quoted C string when used in source code. +# "SPAM_SERVER_URL=\"http://www.example.com/\"", +# ] +# } +template("buildflag_header") { + action(target_name) { + script = "//build/write_buildflag_header.py" + + if (defined(invoker.header_dir)) { + header_file = "${invoker.header_dir}/${invoker.header}" + } else { + # Compute the path from the root to this file. + header_file = rebase_path(".", "//") + "/${invoker.header}" + } + + outputs = [ + "$root_gen_dir/$header_file", + ] + + # Always write --flags to the file so it's not empty. Empty will confuse GN + # into thinking the response file isn't used. + response_file_contents = [ "--flags" ] + if (defined(invoker.flags)) { + response_file_contents += invoker.flags + } + + args = [ + "--output", + header_file, # Not rebased, Python script puts it inside gen-dir. + "--rulename", + get_label_info(":$target_name", "label_no_toolchain"), + "--gen-dir", + rebase_path(root_gen_dir, root_build_dir), + "--definitions", + "{{response_file_name}}", + ] + + forward_variables_from(invoker, + [ + "deps", + "public_deps", + "testonly", + "visibility", + ]) + } +}
new file mode 100644 --- /dev/null +++ b/media/webrtc/trunk/build/check_gn_headers.py @@ -0,0 +1,234 @@ +#!/usr/bin/env python +# Copyright 2017 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. + +"""Find header files missing in GN. + +This script gets all the header files from ninja_deps, which is from the true +dependency generated by the compiler, and report if they don't exist in GN. +""" + +import argparse +import json +import os +import re +import shutil +import subprocess +import sys +import tempfile +from multiprocessing import Process, Queue + + +def GetHeadersFromNinja(out_dir, q): + """Return all the header files from ninja_deps""" + + def NinjaSource(): + cmd = ['ninja', '-C', out_dir, '-t', 'deps'] + # A negative bufsize means to use the system default, which usually + # means fully buffered. + popen = subprocess.Popen(cmd, stdout=subprocess.PIPE, bufsize=-1) + for line in iter(popen.stdout.readline, ''): + yield line.rstrip() + + popen.stdout.close() + return_code = popen.wait() + if return_code: + raise subprocess.CalledProcessError(return_code, cmd) + + ans, err = set(), None + try: + ans = ParseNinjaDepsOutput(NinjaSource()) + except Exception as e: + err = str(e) + q.put((ans, err)) + + +def ParseNinjaDepsOutput(ninja_out): + """Parse ninja output and get the header files""" + all_headers = set() + + prefix = '..' + os.sep + '..' + os.sep + + is_valid = False + for line in ninja_out: + if line.startswith(' '): + if not is_valid: + continue + if line.endswith('.h') or line.endswith('.hh'): + f = line.strip() + if f.startswith(prefix): + f = f[6:] # Remove the '../../' prefix + # build/ only contains build-specific files like build_config.h + # and buildflag.h, and system header files, so they should be + # skipped. + if not f.startswith('build'): + all_headers.add(f) + else: + is_valid = line.endswith('(VALID)') + + return all_headers + + +def GetHeadersFromGN(out_dir, q): + """Return all the header files from GN""" + + tmp = None + ans, err = set(), None + try: + tmp = tempfile.mkdtemp() + shutil.copy2(os.path.join(out_dir, 'args.gn'), + os.path.join(tmp, 'args.gn')) + # Do "gn gen" in a temp dir to prevent dirtying |out_dir|. + subprocess.check_call(['gn', 'gen', tmp, '--ide=json', '-q']) + gn_json = json.load(open(os.path.join(tmp, 'project.json'))) + ans = ParseGNProjectJSON(gn_json, out_dir, tmp) + except Exception as e: + err = str(e) + finally: + if tmp: + shutil.rmtree(tmp) + q.put((ans, err)) + + +def ParseGNProjectJSON(gn, out_dir, tmp_out): + """Parse GN output and get the header files""" + all_headers = set() + + for _target, properties in gn['targets'].iteritems(): + sources = properties.get('sources', []) + public = properties.get('public', []) + # Exclude '"public": "*"'. + if type(public) is list: + sources += public + for f in sources: + if f.endswith('.h') or f.endswith('.hh'): + if f.startswith('//'): + f = f[2:] # Strip the '//' prefix. + if f.startswith(tmp_out): + f = out_dir + f[len(tmp_out):] + all_headers.add(f) + + return all_headers + + +def GetDepsPrefixes(q): + """Return all the folders controlled by DEPS file""" + prefixes, err = set(), None + try: + gclient_out = subprocess.check_output( + ['gclient', 'recurse', '--no-progress', '-j1', + 'python', '-c', 'import os;print os.environ["GCLIENT_DEP_PATH"]']) + for i in gclient_out.split('\n'): + if i.startswith('src/'): + i = i[4:] + prefixes.add(i) + except Exception as e: + err = str(e) + q.put((prefixes, err)) + + +def ParseWhiteList(whitelist): + out = set() + for line in whitelist.split('\n'): + line = re.sub(r'#.*', '', line).strip() + if line: + out.add(line) + return out + + +def FilterOutDepsedRepo(files, deps): + return {f for f in files if not any(f.startswith(d) for d in deps)} + + +def GetNonExistingFiles(lst): + out = set() + for f in lst: + if not os.path.isfile(f): + out.add(f) + return out + + +def main(): + parser = argparse.ArgumentParser(description=''' + NOTE: Use ninja to build all targets in OUT_DIR before running + this script.''') + parser.add_argument('--out-dir', metavar='OUT_DIR', default='out/Release', + help='output directory of the build') + parser.add_argument('--json', + help='JSON output filename for missing headers') + parser.add_argument('--whitelist', help='file containing whitelist') + + args, _extras = parser.parse_known_args() + + if not os.path.isdir(args.out_dir): + parser.error('OUT_DIR "%s" does not exist.' % args.out_dir) + + d_q = Queue() + d_p = Process(target=GetHeadersFromNinja, args=(args.out_dir, d_q,)) + d_p.start() + + gn_q = Queue() + gn_p = Process(target=GetHeadersFromGN, args=(args.out_dir, gn_q,)) + gn_p.start() + + deps_q = Queue() + deps_p = Process(target=GetDepsPrefixes, args=(deps_q,)) + deps_p.start() + + d, d_err = d_q.get() + gn, gn_err = gn_q.get() + missing = d - gn + nonexisting = GetNonExistingFiles(gn) + + deps, deps_err = deps_q.get() + missing = FilterOutDepsedRepo(missing, deps) + nonexisting = FilterOutDepsedRepo(nonexisting, deps) + + d_p.join() + gn_p.join() + deps_p.join() + + if d_err: + parser.error(d_err) + if gn_err: + parser.error(gn_err) + if deps_err: + parser.error(deps_err) + if len(GetNonExistingFiles(d)) > 0: + parser.error('''Found non-existing files in ninja deps. You should + build all in OUT_DIR.''') + if len(d) == 0: + parser.error('OUT_DIR looks empty. You should build all there.') + if any((('/gen/' in i) for i in nonexisting)): + parser.error('OUT_DIR looks wrong. You should build all there.') + + if args.whitelist: + whitelist = ParseWhiteList(open(args.whitelist).read()) + missing -= whitelist + + missing = sorted(missing) + nonexisting = sorted(nonexisting) + + if args.json: + with open(args.json, 'w') as f: + json.dump(missing, f) + + if len(missing) == 0 and len(nonexisting) == 0: + return 0 + + if len(missing) > 0: + print '\nThe following files should be included in gn files:' + for i in missing: + print i + + if len(nonexisting) > 0: + print '\nThe following non-existing files should be removed from gn files:' + for i in nonexisting: + print i + + return 1 + + +if __name__ == '__main__': + sys.exit(main())
new file mode 100644 --- /dev/null +++ b/media/webrtc/trunk/build/check_gn_headers_unittest.py @@ -0,0 +1,117 @@ +#!/usr/bin/env python +# Copyright 2017 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. + +import logging +import json +import os +import unittest +import check_gn_headers + + +ninja_input = r''' +obj/a.o: #deps 1, deps mtime 123 (VALID) + ../../a.cc + ../../dir/path/b.h + ../../c.hh + +obj/b.o: #deps 1, deps mtime 123 (STALE) + ../../b.cc + ../../dir2/path/b.h + ../../c2.hh + +obj/c.o: #deps 1, deps mtime 123 (VALID) + ../../c.cc + ../../build/a.h + gen/b.h + ../../dir3/path/b.h + ../../c3.hh +''' +ninja_input_win = ninja_input.replace('/', '\\') + + +gn_input = json.loads(r''' +{ + "others": [], + "targets": { + "//:All": { + }, + "//:base": { + "public": [ "//base/p.h" ], + "sources": [ "//base/a.cc", "//base/a.h", "//base/b.hh" ], + "visibility": [ "*" ] + }, + "//:star_public": { + "public": "*", + "sources": [ "//base/c.h", "//tmp/gen/a.h" ], + "visibility": [ "*" ] + } + } +} +''') + + +whitelist = r''' + white-front.c +a/b/c/white-end.c # comment + dir/white-both.c #more comment + +# empty line above +a/b/c +''' + + +class CheckGnHeadersTest(unittest.TestCase): + def testNinja(self): + headers = check_gn_headers.ParseNinjaDepsOutput(ninja_input.split('\n')) + expected = set([ + 'dir/path/b.h', + 'c.hh', + 'dir3/path/b.h', + 'c3.hh', + ]) + self.assertEquals(headers, expected) + + def testNinjaWin(self): + old_sep = os.sep + os.sep = '\\' + + headers = check_gn_headers.ParseNinjaDepsOutput( + ninja_input_win.split('\n')) + expected = set([ + 'dir\\path\\b.h', + 'c.hh', + 'dir3\\path\\b.h', + 'c3.hh', + ]) + self.assertEquals(headers, expected) + + os.sep = old_sep + + def testGn(self): + headers = check_gn_headers.ParseGNProjectJSON(gn_input, + 'out/Release', 'tmp') + expected = set([ + 'base/a.h', + 'base/b.hh', + 'base/c.h', + 'base/p.h', + 'out/Release/gen/a.h', + ]) + self.assertEquals(headers, expected) + + def testWhitelist(self): + output = check_gn_headers.ParseWhiteList(whitelist) + expected = set([ + 'white-front.c', + 'a/b/c/white-end.c', + 'dir/white-both.c', + 'a/b/c', + ]) + self.assertEquals(output, expected) + + +if __name__ == '__main__': + logging.getLogger().setLevel(logging.DEBUG) + unittest.main(verbosity=2)
new file mode 100644 --- /dev/null +++ b/media/webrtc/trunk/build/check_return_value.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python +# 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. + +"""This program wraps an arbitrary command and prints "1" if the command ran +successfully.""" + +import os +import subprocess +import sys + +devnull = open(os.devnull, 'wb') +if not subprocess.call(sys.argv[1:], stdout=devnull, stderr=devnull): + print 1 +else: + print 0
new file mode 100644 --- /dev/null +++ b/media/webrtc/trunk/build/clobber.py @@ -0,0 +1,132 @@ +#!/usr/bin/env python +# Copyright 2015 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. + +"""This script provides methods for clobbering build directories.""" + +import argparse +import os +import shutil +import subprocess +import sys + + +def extract_gn_build_commands(build_ninja_file): + """Extracts from a build.ninja the commands to run GN. + + The commands to run GN are the gn rule and build.ninja build step at the + top of the build.ninja file. We want to keep these when deleting GN builds + since we want to preserve the command-line flags to GN. + + On error, returns the empty string.""" + result = "" + with open(build_ninja_file, 'r') as f: + # Read until the second blank line. The first thing GN writes to the file + # is the "rule gn" and the second is the section for "build build.ninja", + # separated by blank lines. + num_blank_lines = 0 + while num_blank_lines < 2: + line = f.readline() + if len(line) == 0: + return '' # Unexpected EOF. + result += line + if line[0] == '\n': + num_blank_lines = num_blank_lines + 1 + return result + + +def delete_dir(build_dir): + if os.path.islink(build_dir): + return + # For unknown reasons (anti-virus?) rmtree of Chromium build directories + # often fails on Windows. + if sys.platform.startswith('win'): + subprocess.check_call(['rmdir', '/s', '/q', build_dir], shell=True) + else: + shutil.rmtree(build_dir) + + +def delete_build_dir(build_dir): + # GN writes a build.ninja.d file. Note that not all GN builds have args.gn. + build_ninja_d_file = os.path.join(build_dir, 'build.ninja.d') + if not os.path.exists(build_ninja_d_file): + delete_dir(build_dir) + return + + # GN builds aren't automatically regenerated when you sync. To avoid + # messing with the GN workflow, erase everything but the args file, and + # write a dummy build.ninja file that will automatically rerun GN the next + # time Ninja is run. + build_ninja_file = os.path.join(build_dir, 'build.ninja') + build_commands = extract_gn_build_commands(build_ninja_file) + + try: + gn_args_file = os.path.join(build_dir, 'args.gn') + with open(gn_args_file, 'r') as f: + args_contents = f.read() + except IOError: + args_contents = '' + + e = None + try: + # delete_dir and os.mkdir() may fail, such as when chrome.exe is running, + # and we still want to restore args.gn/build.ninja/build.ninja.d, so catch + # the exception and rethrow it later. + delete_dir(build_dir) + os.mkdir(build_dir) + except Exception as e: + pass + + # Put back the args file (if any). + if args_contents != '': + with open(gn_args_file, 'w') as f: + f.write(args_contents) + + # Write the build.ninja file sufficiently to regenerate itself. + with open(os.path.join(build_dir, 'build.ninja'), 'w') as f: + if build_commands != '': + f.write(build_commands) + else: + # Couldn't parse the build.ninja file, write a default thing. + f.write('''rule gn +command = gn -q gen //out/%s/ +description = Regenerating ninja files + +build build.ninja: gn +generator = 1 +depfile = build.ninja.d +''' % (os.path.split(build_dir)[1])) + + # Write a .d file for the build which references a nonexistant file. This + # will make Ninja always mark the build as dirty. + with open(build_ninja_d_file, 'w') as f: + f.write('build.ninja: nonexistant_file.gn\n') + + if e: + # Rethrow the exception we caught earlier. + raise e + +def clobber(out_dir): + """Clobber contents of build directory. + + Don't delete the directory itself: some checkouts have the build directory + mounted.""" + for f in os.listdir(out_dir): + path = os.path.join(out_dir, f) + if os.path.isfile(path): + os.unlink(path) + elif os.path.isdir(path): + delete_build_dir(path) + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('out_dir', help='The output directory to clobber') + args = parser.parse_args() + clobber(args.out_dir) + return 0 + + +if __name__ == '__main__': + sys.exit(main())
--- a/media/webrtc/trunk/build/common.croc +++ b/media/webrtc/trunk/build/common.croc @@ -52,17 +52,17 @@ }, # Don't include subversion or mercurial SCM dirs { 'regexp' : '.*/(\\.svn|\\.hg)/', 'include' : 0, }, # Don't include output dirs { - 'regexp' : '.*/(Debug|Release|sconsbuild|out|xcodebuild)/', + 'regexp' : '.*/(Debug|Release|out|xcodebuild)/', 'include' : 0, }, # Don't include third-party source { 'regexp' : '.*/third_party/', 'include' : 0, }, # We don't run the V8 test suite, so we don't care about V8 coverage. @@ -84,17 +84,17 @@ 'format' : '*RESULT FilesKnown: files_executable= %d files', }, { 'stat' : 'files_instrumented', 'format' : '*RESULT FilesInstrumented: files_instrumented= %d files', }, { 'stat' : '100.0 * files_instrumented / files_executable', - 'format' : '*RESULT FilesInstrumentedPercent: files_instrumented_percent= %g', + 'format' : '*RESULT FilesInstrumentedPercent: files_instrumented_percent= %g percent', }, { 'stat' : 'lines_executable', 'format' : '*RESULT LinesKnown: lines_known= %d lines', }, { 'stat' : 'lines_instrumented', 'format' : '*RESULT LinesInstrumented: lines_instrumented= %d lines', @@ -106,22 +106,22 @@ }, { 'stat' : 'lines_covered', 'format' : '*RESULT LinesCoveredTest: lines_covered_test= %d lines', 'group' : 'test', }, { 'stat' : '100.0 * lines_covered / lines_executable', - 'format' : '*RESULT PercentCovered: percent_covered= %g', + 'format' : '*RESULT PercentCovered: percent_covered= %g percent', }, { 'stat' : '100.0 * lines_covered / lines_executable', - 'format' : '*RESULT PercentCoveredSource: percent_covered_source= %g', + 'format' : '*RESULT PercentCoveredSource: percent_covered_source= %g percent', 'group' : 'source', }, { 'stat' : '100.0 * lines_covered / lines_executable', - 'format' : '*RESULT PercentCoveredTest: percent_covered_test= %g', + 'format' : '*RESULT PercentCoveredTest: percent_covered_test= %g percent', 'group' : 'test', }, ], }
new file mode 100644 --- /dev/null +++ b/media/webrtc/trunk/build/compiled_action.gni @@ -0,0 +1,170 @@ +# 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. + +# This file introduces two related templates that act like action and +# action_foreach but instead of running a Python script, it will compile a +# given tool in the host toolchain and run that (either once or over the list +# of inputs, depending on the variant). +# +# Parameters +# +# tool (required) +# [label] Label of the tool to run. This should be an executable, and +# this label should not include a toolchain (anything in parens). The +# host compile of this tool will be used. +# +# outputs (required) +# [list of files] Like the outputs of action (if using "compiled_action", +# this would be just the list of outputs), or action_foreach (if using +# "compiled_action_foreach", this would contain source expansions mapping +# input to output files). +# +# args (required) +# [list of strings] Same meaning as action/action_foreach. +# +# inputs (optional) +# Files the binary takes as input. The step will be re-run whenever any +# of these change. If inputs is empty, the step will run only when the +# binary itself changes. +# +# visibility +# deps +# args (all optional) +# Same meaning as action/action_foreach. +# +# +# Example of usage: +# +# compiled_action("run_my_tool") { +# tool = "//tools/something:mytool" +# outputs = [ +# "$target_gen_dir/mysource.cc", +# "$target_gen_dir/mysource.h", +# ] +# +# # The tool takes this input. +# inputs = [ "my_input_file.idl" ] +# +# # In this case, the tool takes as arguments the input file and the output +# # build dir (both relative to the "cd" that the script will be run in) +# # and will produce the output files listed above. +# args = [ +# rebase_path("my_input_file.idl", root_build_dir), +# "--output-dir", rebase_path(target_gen_dir, root_build_dir), +# ] +# } +# +# You would typically declare your tool like this: +# if (host_toolchain == current_toolchain) { +# executable("mytool") { +# ... +# } +# } +# The if statement around the executable is optional. That says "I only care +# about this target in the host toolchain". Usually this is what you want, and +# saves unnecessarily compiling your tool for the target platform. But if you +# need a target build of your tool as well, just leave off the if statement. + +if (host_os == "win") { + _host_executable_suffix = ".exe" +} else { + _host_executable_suffix = "" +} + +template("compiled_action") { + assert(defined(invoker.tool), "tool must be defined for $target_name") + assert(defined(invoker.outputs), "outputs must be defined for $target_name") + assert(defined(invoker.args), "args must be defined for $target_name") + + assert(!defined(invoker.sources), + "compiled_action doesn't take a sources arg. Use inputs instead.") + + action(target_name) { + forward_variables_from(invoker, + [ + "deps", + "inputs", + "outputs", + "testonly", + "visibility", + ]) + if (!defined(deps)) { + deps = [] + } + if (!defined(inputs)) { + inputs = [] + } + + script = "//build/gn_run_binary.py" + + # Constuct the host toolchain version of the tool. + host_tool = invoker.tool + "($host_toolchain)" + + # Get the path to the executable. Currently, this assumes that the tool + # does not specify output_name so that the target name is the name to use. + # If that's not the case, we'll need another argument to the script to + # specify this, since we can't know what the output name is (it might be in + # another file not processed yet). + host_executable = + get_label_info(host_tool, "root_out_dir") + "/" + + get_label_info(host_tool, "name") + _host_executable_suffix + + # Add the executable itself as an input. + inputs += [ host_executable ] + + deps += [ host_tool ] + + # The script takes as arguments the binary to run, and then the arguments + # to pass it. + args = [ rebase_path(host_executable, root_build_dir) ] + invoker.args + } +} + +template("compiled_action_foreach") { + assert(defined(invoker.sources), "sources must be defined for $target_name") + assert(defined(invoker.tool), "tool must be defined for $target_name") + assert(defined(invoker.outputs), "outputs must be defined for $target_name") + assert(defined(invoker.args), "args must be defined for $target_name") + + action_foreach(target_name) { + forward_variables_from(invoker, + [ + "deps", + "inputs", + "outputs", + "sources", + "testonly", + "visibility", + ]) + if (!defined(deps)) { + deps = [] + } + if (!defined(inputs)) { + inputs = [] + } + + script = "//build/gn_run_binary.py" + + # Constuct the host toolchain version of the tool. + host_tool = invoker.tool + "($host_toolchain)" + + # Get the path to the executable. Currently, this assumes that the tool + # does not specify output_name so that the target name is the name to use. + # If that's not the case, we'll need another argument to the script to + # specify this, since we can't know what the output name is (it might be in + # another file not processed yet). + host_executable = + get_label_info(host_tool, "root_out_dir") + "/" + + get_label_info(host_tool, "name") + _host_executable_suffix + + # Add the executable itself as an input. + inputs += [ host_executable ] + + deps += [ host_tool ] + + # The script takes as arguments the binary to run, and then the arguments + # to pass it. + args = [ rebase_path(host_executable, root_build_dir) ] + invoker.args + } +}
--- a/media/webrtc/trunk/build/compiler_version.py +++ b/media/webrtc/trunk/build/compiler_version.py @@ -9,68 +9,120 @@ Print gcc version as XY if you are runni This is used to tweak build flags for gcc 4.4. """ import os import re import subprocess import sys -def GetVersion(compiler): + +compiler_version_cache = {} # Map from (compiler, tool) -> version. + + +def Usage(program_name): + print '%s MODE TOOL' % os.path.basename(program_name) + print 'MODE: host or target.' + print 'TOOL: assembler or compiler or linker.' + return 1 + + +def ParseArgs(args): + if len(args) != 2: + raise Exception('Invalid number of arguments') + mode = args[0] + tool = args[1] + if mode not in ('host', 'target'): + raise Exception('Invalid mode: %s' % mode) + if tool not in ('assembler',): + raise Exception('Invalid tool: %s' % tool) + return mode, tool + + +def GetEnvironFallback(var_list, default): + """Look up an environment variable from a possible list of variable names.""" + for var in var_list: + if var in os.environ: + return os.environ[var] + return default + + +def GetVersion(compiler, tool): + tool_output = tool_error = None + cache_key = (compiler, tool) + cached_version = compiler_version_cache.get(cache_key) + if cached_version: + return cached_version try: # Note that compiler could be something tricky like "distcc g++". - compiler = compiler + " -dumpversion" - pipe = subprocess.Popen(compiler, shell=True, + if tool == "assembler": + compiler = compiler + " -Xassembler --version -x assembler -c /dev/null" + # Unmodified: GNU assembler (GNU Binutils) 2.24 + # Ubuntu: GNU assembler (GNU Binutils for Ubuntu) 2.22 + # Fedora: GNU assembler version 2.23.2 + version_re = re.compile(r"^GNU [^ ]+ .* (\d+).(\d+).*?$", re.M) + else: + raise Exception("Unknown tool %s" % tool) + + # Force the locale to C otherwise the version string could be localized + # making regex matching fail. + env = os.environ.copy() + env["LC_ALL"] = "C" + pipe = subprocess.Popen(compiler, shell=True, env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - gcc_output, gcc_error = pipe.communicate() + tool_output, tool_error = pipe.communicate() if pipe.returncode: raise subprocess.CalledProcessError(pipe.returncode, compiler) - result = re.match(r"(\d+)\.(\d+)", gcc_output) - return result.group(1) + result.group(2) + parsed_output = version_re.match(tool_output) + result = parsed_output.group(1) + parsed_output.group(2) + compiler_version_cache[cache_key] = result + return result except Exception, e: - if gcc_error: - sys.stderr.write(gcc_error) + if tool_error: + sys.stderr.write(tool_error) print >> sys.stderr, "compiler_version.py failed to execute:", compiler print >> sys.stderr, e return "" -def GetVersionFromEnvironment(compiler_env): - """ Returns the version of compiler - If the compiler was set by the given environment variable and exists, - return its version, otherwise None is returned. - """ - cxx = os.getenv(compiler_env, None) - if cxx: - cxx_version = GetVersion(cxx) - if cxx_version != "": - return cxx_version - return None +def main(args): + try: + (mode, tool) = ParseArgs(args[1:]) + except Exception, e: + sys.stderr.write(e.message + '\n\n') + return Usage(args[0]) + + ret_code, result = ExtractVersion(mode, tool) + if ret_code == 0: + print result + return ret_code + -def main(): - # Check if CXX_target or CXX environment variable exists an if it does use - # that compiler. - # TODO: Fix ninja (see http://crbug.com/140900) instead and remove this code - # In ninja's cross compile mode, the CXX_target is target compiler, while - # the CXX is host. The CXX_target needs be checked first, though the target - # and host compiler have different version, there seems no issue to use the - # target compiler's version number as gcc_version in Android. - cxx_version = GetVersionFromEnvironment("CXX_target") - if cxx_version: - print cxx_version - return 0 +def DoMain(args): + """Hook to be called from gyp without starting a separate python + interpreter.""" + (mode, tool) = ParseArgs(args) + ret_code, result = ExtractVersion(mode, tool) + if ret_code == 0: + return result + raise Exception("Failed to extract compiler version for args: %s" % args) + - cxx_version = GetVersionFromEnvironment("CXX") - if cxx_version: - print cxx_version - return 0 +def ExtractVersion(mode, tool): + # Check if various CXX environment variables exist and use them if they + # exist. The preferences and fallback order is a close approximation of + # GenerateOutputForConfig() in GYP's ninja generator. + # The main difference being not supporting GYP's make_global_settings. + environments = ['CXX_target', 'CXX'] + if mode == 'host': + environments = ['CXX_host'] + environments; + compiler = GetEnvironFallback(environments, 'c++') - # Otherwise we check the g++ version. - gccversion = GetVersion("g++") - if gccversion != "": - print gccversion - return 0 + if compiler: + compiler_version = GetVersion(compiler, tool) + if compiler_version != "": + return (0, compiler_version) + return (1, None) - return 1 if __name__ == "__main__": - sys.exit(main()) + sys.exit(main(sys.argv))
new file mode 100644 --- /dev/null +++ b/media/webrtc/trunk/build/config/BUILD.gn @@ -0,0 +1,383 @@ +# Copyright (c) 2013 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. + +import("//build/config/allocator.gni") +import("//build/config/chrome_build.gni") +import("//build/config/chromecast_build.gni") +import("//build/config/crypto.gni") +import("//build/config/dcheck_always_on.gni") +import("//build/config/features.gni") +import("//build/config/pch.gni") +import("//build/config/sanitizers/sanitizers.gni") +import("//build/config/ui.gni") +import("//build/toolchain/goma.gni") + +declare_args() { + # When set (the default) enables C++ iterator debugging in debug builds. + # Iterator debugging is always off in release builds (technically, this flag + # affects the "debug" config, which is always available but applied by + # default only in debug builds). + # + # Iterator debugging is generally useful for catching bugs. But it can + # introduce extra locking to check the state of an iterator against the state + # of the current object. For iterator- and thread-heavy code, this can + # significantly slow execution. + enable_iterator_debugging = true +} + +# ============================================== +# PLEASE DO NOT ADD MORE THINGS TO THIS LIST +# ============================================== +# +# Legacy feature defines applied to all targets. +# +# These are applied to every single compile in the build and most of them are +# only relevant to a few files. This bloats command lines and causes +# unnecessary recompiles when flags are flipped. +# +# To pass defines to source code from the build, use the buildflag system which +# will write headers containing the defines you need. This isolates the define +# and means its definition can participate in the build graph, only recompiling +# things when it actually changes. +# +# See //build/buildflag_header.gni for inntructions on generating headers. +# +# This will also allow you to scope your build flag to a BUILD.gn file (or a +# .gni file if you need it from more than one place) rather than making global +# flags. See //build/config/BUILDCONFIG.gn for advice on where to define +# build flags. +config("feature_flags") { + # Don't use deprecated V8 APIs anywhere. + defines = [ "V8_DEPRECATION_WARNINGS" ] + if (dcheck_always_on) { + defines += [ "DCHECK_ALWAYS_ON=1" ] + } + if (use_udev) { + # TODO(brettw) should probably be "=1". + defines += [ "USE_UDEV" ] + } + if (use_ash) { + defines += [ "USE_ASH=1" ] + } + if (use_aura) { + defines += [ "USE_AURA=1" ] + } + if (use_pango) { + defines += [ "USE_PANGO=1" ] + } + if (use_cairo) { + defines += [ "USE_CAIRO=1" ] + } + if (use_glib) { + defines += [ "USE_GLIB=1" ] + } + if (use_openssl_certs) { + defines += [ "USE_OPENSSL_CERTS=1" ] + } + if (use_nss_certs) { + defines += [ "USE_NSS_CERTS=1" ] + } + if (use_ozone) { + defines += [ "USE_OZONE=1" ] + } + if (use_x11) { + defines += [ "USE_X11=1" ] + } + if (use_allocator != "tcmalloc") { + defines += [ "NO_TCMALLOC" ] + } + if (is_asan || is_lsan || is_tsan || is_msan) { + defines += [ + "MEMORY_TOOL_REPLACES_ALLOCATOR", + "MEMORY_SANITIZER_INITIAL_SIZE", + ] + } + if (is_asan) { + defines += [ "ADDRESS_SANITIZER" ] + } + if (is_lsan) { + defines += [ "LEAK_SANITIZER" ] + } + if (is_tsan) { + defines += [ + "THREAD_SANITIZER", + "DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL=1", + "WTF_USE_DYNAMIC_ANNOTATIONS_NOIMPL=1", + ] + } + if (is_msan) { + defines += [ "MEMORY_SANITIZER" ] + } + if (is_ubsan || is_ubsan_null || is_ubsan_vptr || is_ubsan_security) { + defines += [ "UNDEFINED_SANITIZER" ] + } + if (!enable_nacl) { + defines += [ "DISABLE_NACL" ] + } + if (safe_browsing_mode == 1) { + defines += [ "FULL_SAFE_BROWSING" ] + defines += [ "SAFE_BROWSING_CSD" ] + defines += [ "SAFE_BROWSING_DB_LOCAL" ] + } else if (safe_browsing_mode == 2) { + defines += [ "SAFE_BROWSING_DB_REMOTE" ] + } + if (is_official_build) { + defines += [ "OFFICIAL_BUILD" ] + } + if (is_chrome_branded) { + defines += [ "GOOGLE_CHROME_BUILD" ] + } else { + defines += [ "CHROMIUM_BUILD" ] + } + if (is_syzyasan) { + defines += [ + "SYZYASAN", + "MEMORY_SANITIZER_INITIAL_SIZE", + ] + } + if (!fieldtrial_testing_like_official_build && !is_chrome_branded) { + defines += [ "FIELDTRIAL_TESTING_ENABLED" ] + } + + # ============================================== + # PLEASE DO NOT ADD MORE THINGS TO THIS LIST + # ============================================== + # + # See the comment at the top. +} + +# Debug/release ---------------------------------------------------------------- + +config("debug") { + defines = [ + "_DEBUG", + "DYNAMIC_ANNOTATIONS_ENABLED=1", + "WTF_USE_DYNAMIC_ANNOTATIONS=1", + ] + + if (is_nacl) { + defines += [ "DYNAMIC_ANNOTATIONS_PREFIX=NACL_" ] + } + + if (is_win) { + if (!enable_iterator_debugging) { + # Iterator debugging is enabled by default by the compiler on debug + # builds, and we have to tell it to turn it off. + defines += [ "_HAS_ITERATOR_DEBUGGING=0" ] + } + } else if (is_linux && current_cpu == "x64" && enable_iterator_debugging) { + # Enable libstdc++ debugging facilities to help catch problems early, see + # http://crbug.com/65151 . + # TODO(phajdan.jr): Should we enable this for all of POSIX? + defines += [ "_GLIBCXX_DEBUG=1" ] + } +} + +config("release") { + defines = [ "NDEBUG" ] + + # Sanitizers. + if (is_tsan) { + defines += [ + "DYNAMIC_ANNOTATIONS_ENABLED=1", + "WTF_USE_DYNAMIC_ANNOTATIONS=1", + ] + } else { + defines += [ "NVALGRIND" ] + if (!is_nacl) { + # NaCl always enables dynamic annotations. Currently this value is set to + # 1 for all .nexes. + defines += [ "DYNAMIC_ANNOTATIONS_ENABLED=0" ] + } + } + + if (is_ios) { + # Disable NSAssert and GTMDevAssert (from Google Toolbox for Mac). This + # follows XCode's default behavior for Release builds. + defines += [ "NS_BLOCK_ASSERTIONS=1" ] + } +} + +# Default libraries ------------------------------------------------------------ + +# This config defines the default libraries applied to all targets. +config("default_libs") { + if (is_win) { + # TODO(brettw) this list of defaults should probably be smaller, and + # instead the targets that use the less common ones (e.g. wininet or + # winspool) should include those explicitly. + libs = [ + "advapi32.lib", + "comdlg32.lib", + "dbghelp.lib", + "delayimp.lib", + "dnsapi.lib", + "gdi32.lib", + "kernel32.lib", + "msimg32.lib", + "odbc32.lib", + "odbccp32.lib", + "ole32.lib", + "oleaut32.lib", + "psapi.lib", + "shell32.lib", + "shlwapi.lib", + "user32.lib", + "usp10.lib", + "uuid.lib", + "version.lib", + "wininet.lib", + "winmm.lib", + "winspool.lib", + "ws2_32.lib", + + # Please don't add more stuff here. We should actually be making this + # list smaller, since all common things should be covered. If you need + # some extra libraries, please just add a libs = [ "foo.lib" ] to your + # target that needs it. + ] + } else if (is_android) { + libs = [ + "dl", + "m", + ] + } else if (is_mac) { + # Targets should choose to explicitly link frameworks they require. Since + # linking can have run-time side effects, nothing should be listed here. + libs = [] + } else if (is_ios) { + # The libraries listed here will be specified for both the target and the + # host. Only the common ones should be listed here. + libs = [ + "CoreFoundation.framework", + "CoreGraphics.framework", + "CoreText.framework", + "Foundation.framework", + ] + } else if (is_linux) { + libs = [ + "dl", + "rt", + ] + } +} + +# Dependencies that all executables and shared libraries should have. +group("exe_and_shlib_deps") { + public_deps = [] + if (using_sanitizer) { + public_deps += [ "//build/config/sanitizers:deps" ] + } + if (use_custom_libcxx) { + public_deps += [ "//buildtools/third_party/libc++:libcxx_proxy" ] + } + if (use_afl) { + public_deps += [ "//third_party/afl" ] + } +} + +# Executable configs ----------------------------------------------------------- + +# Windows linker setup for EXEs and DLLs. +if (is_win) { + _windows_linker_configs = [ + "//build/config/win:sdk_link", + "//build/config/win:common_linker_setup", + ] +} + +# This config defines the configs applied to all executables. +config("executable_config") { + configs = [] + + if (is_win) { + configs += _windows_linker_configs + + # Currently only turn on linker CFI for executables. + configs += [ "//build/config/win:cfi_linker" ] + } else if (is_mac) { + configs += [ + "//build/config/mac:mac_dynamic_flags", + "//build/config/mac:mac_executable_flags", + ] + } else if (is_ios) { + configs += [ + "//build/config/ios:ios_dynamic_flags", + "//build/config/ios:ios_executable_flags", + ] + } else if (is_linux || is_android || current_os == "aix") { + configs += [ "//build/config/gcc:executable_ldconfig" ] + if (is_android) { + configs += [ "//build/config/android:executable_config" ] + } else if (is_chromecast) { + configs += [ "//build/config/chromecast:executable_config" ] + } + } + + # If we're using the prebuilt instrumented libraries with the sanitizers, we + # need to add ldflags to every binary to make sure they are picked up. + if (prebuilt_instrumented_libraries_available) { + configs += [ "//third_party/instrumented_libraries:prebuilt_ldflags" ] + } + if (use_locally_built_instrumented_libraries) { + configs += [ "//third_party/instrumented_libraries:locally_built_ldflags" ] + } + configs += [ "//build/config/sanitizers:link_executable" ] +} + +# Shared library configs ------------------------------------------------------- + +# This config defines the configs applied to all shared libraries. +config("shared_library_config") { + configs = [] + + if (is_win) { + configs += _windows_linker_configs + } else if (is_mac) { + configs += [ "//build/config/mac:mac_dynamic_flags" ] + } else if (is_ios) { + configs += [ "//build/config/ios:ios_dynamic_flags" ] + } else if (is_chromecast) { + configs += [ "//build/config/chromecast:shared_library_config" ] + } + + # If we're using the prebuilt instrumented libraries with the sanitizers, we + # need to add ldflags to every binary to make sure they are picked up. + if (prebuilt_instrumented_libraries_available) { + configs += [ "//third_party/instrumented_libraries:prebuilt_ldflags" ] + } + if (use_locally_built_instrumented_libraries) { + configs += [ "//third_party/instrumented_libraries:locally_built_ldflags" ] + } + configs += [ "//build/config/sanitizers:link_shared_library" ] +} + +# Add this config to your target to enable precompiled headers. +# +# Precompiled headers are done on a per-target basis. If you have just a couple +# of files, the time it takes to precompile (~2 seconds) can actually be longer +# than the time saved. On a Z620, a 100 file target compiles about 2 seconds +# faster with precompiled headers, with greater savings for larger targets. +# +# Recommend precompiled headers for targets with more than 50 .cc files. +config("precompiled_headers") { + if (enable_precompiled_headers) { + if (is_win) { + # This is a string rather than a file GN knows about. It has to match + # exactly what's in the /FI flag below, and what might appear in the + # source code in quotes for an #include directive. + precompiled_header = "build/precompile.h" + + # This is a file that GN will compile with the above header. It will be + # implicitly added to the sources (potentially multiple times, with one + # variant for each language used in the target). + precompiled_source = "//build/precompile.cc" + + # Force include the header. + cflags = [ "/FI$precompiled_header" ] + } else if (is_mac) { + precompiled_source = "//build/precompile.h" + } + } +}
new file mode 100644 --- /dev/null +++ b/media/webrtc/trunk/build/config/BUILDCONFIG.gn @@ -0,0 +1,699 @@ +# Copyright (c) 2013 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. + +# ============================================================================= +# WHAT IS THIS FILE? +# ============================================================================= +# +# This is the master GN build configuration. This file is loaded after the +# build args (args.gn) for the build directory and after the toplevel ".gn" +# file (which points to this file as the build configuration). +# +# This file will be executed and the resulting context will be used to execute +# every other file in the build. So variables declared here (that don't start +# with an underscore) will be implicitly global. + +# ============================================================================= +# PLATFORM SELECTION +# ============================================================================= +# +# There are two main things to set: "os" and "cpu". The "toolchain" is the name +# of the GN thing that encodes combinations of these things. +# +# Users typically only set the variables "target_os" and "target_cpu" in "gn +# args", the rest are set up by our build and internal to GN. +# +# There are three different types of each of these things: The "host" +# represents the computer doing the compile and never changes. The "target" +# represents the main thing we're trying to build. The "current" represents +# which configuration is currently being defined, which can be either the +# host, the target, or something completely different (like nacl). GN will +# run the same build file multiple times for the different required +# configuration in the same build. +# +# This gives the following variables: +# - host_os, host_cpu, host_toolchain +# - target_os, target_cpu, default_toolchain +# - current_os, current_cpu, current_toolchain. +# +# Note the default_toolchain isn't symmetrical (you would expect +# target_toolchain). This is because the "default" toolchain is a GN built-in +# concept, and "target" is something our build sets up that's symmetrical with +# its GYP counterpart. Potentially the built-in default_toolchain variable +# could be renamed in the future. +# +# When writing build files, to do something only for the host: +# if (current_toolchain == host_toolchain) { ... + +if (target_os == "") { + target_os = host_os +} + +if (target_cpu == "") { + if (target_os == "android") { + # If we're building for Android, we should assume that we want to + # build for ARM by default, not the host_cpu (which is likely x64). + # This allows us to not have to specify both target_os and target_cpu + # on the command line. + target_cpu = "arm" + } else { + target_cpu = host_cpu + } +} + +if (current_cpu == "") { + current_cpu = target_cpu +} +if (current_os == "") { + current_os = target_os +} + +# ============================================================================= +# BUILD FLAGS +# ============================================================================= +# +# This block lists input arguments to the build, along with their default +# values. +# +# If a value is specified on the command line, it will overwrite the defaults +# given in a declare_args block, otherwise the default will be used. +# +# YOU SHOULD ALMOST NEVER NEED TO ADD FLAGS TO THIS FILE. GN allows any file in +# the build to declare build flags. If you need a flag for a single component, +# you can just declare it in the corresponding BUILD.gn file. +# +# - If your feature is a single target, say //components/foo, you can put +# a declare_args() block in //components/foo/BUILD.gn and use it there. +# Nobody else in the build needs to see the flag. +# +# - Defines based on build variables should be implemented via the generated +# build flag header system. See //build/buildflag_header.gni. You can put +# the buildflag_header target in the same file as the build flag itself. You +# should almost never set "defines" directly. +# +# - If your flag toggles a target on and off or toggles between different +# versions of similar things, write a "group" target that forwards to the +# right target (or no target) depending on the value of the build flag. This +# group can be in the same BUILD.gn file as the build flag, and targets can +# depend unconditionally on the group rather than duplicating flag checks +# across many targets. +# +# - If a semi-random set of build files REALLY needs to know about a define and +# the above pattern for isolating the build logic in a forwarding group +# doesn't work, you can put the argument in a .gni file. This should be put +# in the lowest level of the build that knows about this feature (which should +# almost always be outside of the //build directory!). +# +# Other flag advice: +# +# - Use boolean values when possible. If you need a default value that expands +# to some complex thing in the default case (like the location of the +# compiler which would be computed by a script), use a default value of -1 or +# the empty string. Outside of the declare_args block, conditionally expand +# the default value as necessary. +# +# - Use a name like "use_foo" or "is_foo" (whatever is more appropriate for +# your feature) rather than just "foo". +# +# - Write good comments directly above the declaration with no blank line. +# These comments will appear as documentation in "gn args --list". +# +# - Don't call exec_script inside declare_args. This will execute the script +# even if the value is overridden, which is wasteful. See first bullet. + +declare_args() { + # Set to enable the official build level of optimization. This has nothing + # to do with branding, but enables an additional level of optimization above + # release (!is_debug). This might be better expressed as a tri-state + # (debug, release, official) but for historical reasons there are two + # separate flags. + is_official_build = false + + # Whether we're a traditional desktop unix. + is_desktop_linux = current_os == "linux" + + # Set to true when compiling with the Clang compiler. Typically this is used + # to configure warnings. + is_clang = + current_os == "mac" || current_os == "ios" || current_os == "chromeos" || + current_os == "fuchsia" || + (current_os == "linux" && current_cpu != "s390x" && + current_cpu != "s390" && current_cpu != "ppc64" && current_cpu != "ppc") + + # Allows the path to a custom target toolchain to be injected as a single + # argument, and set as the default toolchain. + custom_toolchain = "" + + # This should not normally be set as a build argument. It's here so that + # every toolchain can pass through the "global" value via toolchain_args(). + host_toolchain = "" + + # DON'T ADD MORE FLAGS HERE. Read the comment above. +} + +declare_args() { + # Debug build. Enabling official builds automatically sets is_debug to false. + is_debug = !is_official_build +} + +declare_args() { + # Component build. Setting to true compiles targets declared as "components" + # as shared libraries loaded dynamically. This speeds up development time. + # When false, components will be linked statically. + # + # For more information see + # https://chromium.googlesource.com/chromium/src/+/master/docs/component_build.md + is_component_build = + is_debug && current_os != "ios" && current_os != "fuchsia" +} + +assert(!(is_debug && is_official_build), "Can't do official debug builds") + +# ============================================================================== +# TOOLCHAIN SETUP +# ============================================================================== +# +# Here we set the default toolchain, as well as the variable host_toolchain +# which will identify the toolchain corresponding to the local system when +# doing cross-compiles. When not cross-compiling, this will be the same as the +# default toolchain. +# +# We do this before anything else to make sure we complain about any +# unsupported os/cpu combinations as early as possible. + +if (host_toolchain == "") { + # This should only happen in the top-level context. + # In a specific toolchain context, the toolchain_args() + # block should have propagated a value down. + # TODO(dpranke): Add some sort of assert here that verifies that + # no toolchain omitted host_toolchain from its toolchain_args(). + + if (host_os == "linux") { + if (target_os != "linux") { + # TODO(dpranke) - is_clang normally applies only to the target + # build, and there is no way to indicate that you want to override + # it for both the target build *and* the host build. Do we need to + # support this? + host_toolchain = "//build/toolchain/linux:clang_$host_cpu" + } else if (is_clang) { + host_toolchain = "//build/toolchain/linux:clang_$host_cpu" + } else { + host_toolchain = "//build/toolchain/linux:$host_cpu" + } + } else if (host_os == "mac") { + host_toolchain = "//build/toolchain/mac:clang_$host_cpu" + } else if (host_os == "win") { + # On Windows always use the target CPU for host builds. On the + # configurations we support this will always work and it saves build steps. + if (is_clang) { + host_toolchain = "//build/toolchain/win:clang_$target_cpu" + } else { + host_toolchain = "//build/toolchain/win:$target_cpu" + } + } else if (host_os == "aix") { + host_toolchain = "//build/toolchain/aix:$host_cpu" + } else { + assert(false, "Unsupported host_os: $host_os") + } +} + +_default_toolchain = "" + +if (target_os == "android") { + assert(host_os == "linux" || host_os == "mac", + "Android builds are only supported on Linux and Mac hosts.") + if (is_clang) { + _default_toolchain = "//build/toolchain/android:android_clang_$target_cpu" + } else { + _default_toolchain = "//build/toolchain/android:android_$target_cpu" + } +} else if (target_os == "chromeos" || target_os == "linux") { + # See comments in build/toolchain/cros/BUILD.gn about board compiles. + if (is_clang) { + _default_toolchain = "//build/toolchain/linux:clang_$target_cpu" + } else { + _default_toolchain = "//build/toolchain/linux:$target_cpu" + } +} else if (target_os == "fuchsia") { + _default_toolchain = "//build/toolchain/fuchsia:$target_cpu" +} else if (target_os == "ios") { + _default_toolchain = "//build/toolchain/mac:ios_clang_$target_cpu" +} else if (target_os == "mac") { + assert(host_os == "mac", "Mac cross-compiles are unsupported.") + _default_toolchain = host_toolchain +} else if (target_os == "win") { + # On Windows we use the same toolchain for host and target by default. + assert(target_os == host_os, "Win cross-compiles only work on win hosts.") + if (is_clang) { + _default_toolchain = "//build/toolchain/win:clang_$target_cpu" + } else { + _default_toolchain = "//build/toolchain/win:$target_cpu" + } +} else if (target_os == "aix") { + _default_toolchain = "//build/toolchain/aix:$target_cpu" +} else if (target_os == "winrt_81" || target_os == "winrt_81_phone" || + target_os == "winrt_10") { + _default_toolchain = "//build/toolchain/win:winrt_$target_cpu" +} else { + assert(false, "Unsupported target_os: $target_os") +} + +# If a custom toolchain has been set in the args, set it as default. Otherwise, +# set the default toolchain for the platform (if any). +if (custom_toolchain != "") { + set_default_toolchain(custom_toolchain) +} else if (_default_toolchain != "") { + set_default_toolchain(_default_toolchain) +} + +# ============================================================================= +# OS DEFINITIONS +# ============================================================================= +# +# We set these various is_FOO booleans for convenience in writing OS-based +# conditions. +# +# - is_android, is_chromeos, is_ios, and is_win should be obvious. +# - is_mac is set only for desktop Mac. It is not set on iOS. +# - is_posix is true for mac and any Unix-like system (basically everything +# except Windows). +# - is_linux is true for desktop Linux and ChromeOS, but not Android (which is +# generally too different despite being based on the Linux kernel). +# +# Do not add more is_* variants here for random lesser-used Unix systems like +# aix or one of the BSDs. If you need to check these, just check the +# current_os value directly. + +if (current_os == "win" || current_os == "winrt_81" || + current_os == "winrt_81_phone" || current_os == "winrt_10") { + is_android = false + is_chromeos = false + is_fuchsia = false + is_ios = false + is_linux = false + is_mac = false + is_nacl = false + is_posix = false + is_win = true +} else if (current_os == "mac") { + is_android = false + is_chromeos = false + is_fuchsia = false + is_ios = false + is_linux = false + is_mac = true + is_nacl = false + is_posix = true + is_win = false +} else if (current_os == "android") { + is_android = true + is_chromeos = false + is_fuchsia = false + is_ios = false + is_linux = false + is_mac = false + is_nacl = false + is_posix = true + is_win = false +} else if (current_os == "chromeos") { + is_android = false + is_chromeos = true + is_fuchsia = false + is_ios = false + is_linux = true + is_mac = false + is_nacl = false + is_posix = true + is_win = false +} else if (current_os == "nacl") { + # current_os == "nacl" will be passed by the nacl toolchain definition. + # It is not set by default or on the command line. We treat is as a + # Posix variant. + is_android = false + is_chromeos = false + is_fuchsia = false + is_ios = false + is_linux = false + is_mac = false + is_nacl = true + is_posix = true + is_win = false +} else if (current_os == "fuchsia") { + is_android = false + is_chromeos = false + is_fuchsia = true + is_ios = false + is_linux = false + is_mac = false + is_nacl = false + is_posix = true + is_win = false +} else if (current_os == "ios") { + is_android = false + is_chromeos = false + is_fuchsia = false + is_ios = true + is_linux = false + is_mac = false + is_nacl = false + is_posix = true + is_win = false +} else if (current_os == "linux") { + is_android = false + is_chromeos = false + is_fuchsia = false + is_ios = false + is_linux = true + is_mac = false + is_nacl = false + is_posix = true + is_win = false +} else if (current_os == "aix") { + is_android = false + is_chromeos = false + is_ios = false + is_linux = false + is_mac = false + is_nacl = false + is_posix = true + is_win = false +} + +# ============================================================================= +# SOURCES FILTERS +# ============================================================================= +# +# These patterns filter out platform-specific files when assigning to the +# sources variable. The magic variable |sources_assignment_filter| is applied +# to each assignment or appending to the sources variable and matches are +# automatically removed. +# +# Note that the patterns are NOT regular expressions. Only "*" and "\b" (path +# boundary = end of string or slash) are supported, and the entire string +# must match the pattern (so you need "*.cc" to match all .cc files, for +# example). + +# DO NOT ADD MORE PATTERNS TO THIS LIST, see set_sources_assignment_filter call +# below. +sources_assignment_filter = [] +if (!is_posix) { + sources_assignment_filter += [ + "*_posix.h", + "*_posix.cc", + "*_posix_unittest.h", + "*_posix_unittest.cc", + "*\bposix/*", + ] +} + +if (!is_win) { + sources_assignment_filter += [ + "*_win.cc", + "*_win.h", + "*_win_unittest.cc", + "*\bwin/*", + "*.def", + "*.rc", + ] +} +if (!is_mac) { + sources_assignment_filter += [ + "*_mac.h", + "*_mac.cc", + "*_mac.mm", + "*_mac_unittest.h", + "*_mac_unittest.cc", + "*_mac_unittest.mm", + "*\bmac/*", + "*_cocoa.h", + "*_cocoa.cc", + "*_cocoa.mm", + "*_cocoa_unittest.h", + "*_cocoa_unittest.cc", + "*_cocoa_unittest.mm", + "*\bcocoa/*", + ] +} +if (!is_ios) { + sources_assignment_filter += [ + "*_ios.h", + "*_ios.cc", + "*_ios.mm", + "*_ios_unittest.h", + "*_ios_unittest.cc", + "*_ios_unittest.mm", + "*\bios/*", + ] +} +if (!is_mac && !is_ios) { + sources_assignment_filter += [ "*.mm" ] +} +if (!is_linux) { + sources_assignment_filter += [ + "*_linux.h", + "*_linux.cc", + "*_linux_unittest.h", + "*_linux_unittest.cc", + "*\blinux/*", + ] +} +if (!is_android) { + sources_assignment_filter += [ + "*_android.h", + "*_android.cc", + "*_android_unittest.h", + "*_android_unittest.cc", + "*\bandroid/*", + ] +} +if (!is_chromeos) { + sources_assignment_filter += [ + "*_chromeos.h", + "*_chromeos.cc", + "*_chromeos_unittest.h", + "*_chromeos_unittest.cc", + "*\bchromeos/*", + ] +} + +# DO NOT ADD MORE PATTERNS TO THIS LIST, see set_sources_assignment_filter call +# below. + +# Actually save this list. +# +# These patterns are executed for every file in the source tree of every run. +# Therefore, adding more patterns slows down the build for everybody. We should +# only add automatic patterns for configurations affecting hundreds of files +# across many projects in the tree. +# +# Therefore, we only add rules to this list corresponding to platforms on the +# Chromium waterfall. This is not for non-officially-supported platforms +# (FreeBSD, etc.) toolkits, (X11, GTK, etc.), or features. For these cases, +# write a conditional in the target to remove the file(s) from the list when +# your platform/toolkit/feature doesn't apply. +set_sources_assignment_filter(sources_assignment_filter) + +# ============================================================================= +# TARGET DEFAULTS +# ============================================================================= +# +# Set up the default configuration for every build target of the given type. +# The values configured here will be automatically set on the scope of the +# corresponding target. Target definitions can add or remove to the settings +# here as needed. + +# Holds all configs used for running the compiler. +default_compiler_configs = [ + "//build/config:feature_flags", + "//build/config/compiler:afdo", + "//build/config/compiler:compiler", + "//build/config/compiler:pthread", + "//build/config/compiler:clang_stackrealign", + "//build/config/compiler:compiler_arm_fpu", + "//build/config/compiler:compiler_arm_thumb", + "//build/config/compiler:chromium_code", + "//build/config/compiler:default_include_dirs", + "//build/config/compiler:default_optimization", + "//build/config/compiler:default_stack_frames", + "//build/config/compiler:default_symbols", + "//build/config/compiler:no_rtti", + "//build/config/compiler:runtime_library", + "//build/config/sanitizers:default_sanitizer_flags", +] +if (is_win) { + default_compiler_configs += [ + "//build/config/win:default_crt", + "//build/config/win:lean_and_mean", + "//build/config/win:nominmax", + "//build/config/win:unicode", + "//build/config/win:winver", + "//build/config/win:vs_code_analysis", + ] +} +if (current_os == "winrt_81" || current_os == "winrt_81_phone" || + current_os == "winrt_10") { + default_compiler_configs += [ "//build/config/win:target_winrt" ] +} + +if (is_posix) { + default_compiler_configs += [ "//build/config/gcc:no_exceptions" ] + if (current_os != "aix") { + default_compiler_configs += + [ "//build/config/gcc:symbol_visibility_hidden" ] + } +} + +if (is_android) { + default_compiler_configs += + [ "//build/config/android:default_cygprofile_instrumentation" ] +} + +if (is_clang && !is_nacl) { + default_compiler_configs += [ + "//build/config/clang:find_bad_constructs", + "//build/config/clang:extra_warnings", + ] +} + +# Debug/release-related defines. +if (is_debug) { + default_compiler_configs += [ "//build/config:debug" ] +} else { + default_compiler_configs += [ "//build/config:release" ] +} + +# Static libraries and source sets use only the compiler ones. +set_defaults("static_library") { + configs = default_compiler_configs +} +set_defaults("source_set") { + configs = default_compiler_configs +} + +# Compute the set of configs common to all linked targets (shared libraries, +# loadable modules, executables) to avoid duplication below. +if (is_win) { + # Many targets remove these configs, so they are not contained within + # //build/config:executable_config for easy removal. + _linker_configs = [ + "//build/config/win:default_incremental_linking", + + # Default to console-mode apps. Most of our targets are tests and such + # that shouldn't use the windows subsystem. + "//build/config/win:console", + ] +} else if (is_mac) { + _linker_configs = [ "//build/config/mac:strip_all" ] +} else { + _linker_configs = [] +} + +# Executable defaults. +default_executable_configs = default_compiler_configs + [ + "//build/config:default_libs", + "//build/config:executable_config", + ] + _linker_configs +set_defaults("executable") { + configs = default_executable_configs +} + +# Shared library and loadable module defaults (also for components in component +# mode). +default_shared_library_configs = default_compiler_configs + [ + "//build/config:default_libs", + "//build/config:shared_library_config", + ] + _linker_configs +if (is_android) { + # Strip native JNI exports from shared libraries by default. Binaries that + # want this can remove this config. + default_shared_library_configs += + [ "//build/config/android:hide_all_but_jni_onload" ] +} +set_defaults("shared_library") { + configs = default_shared_library_configs +} +set_defaults("loadable_module") { + configs = default_shared_library_configs + + # loadable_modules are generally used by other libs, not just via JNI. + if (is_android) { + configs -= [ "//build/config/android:hide_all_but_jni_onload" ] + } +} + +# ============================================================================== +# COMPONENT SETUP +# ============================================================================== + +# Defines a component, which equates to a shared_library when +# is_component_build == true and a static_library otherwise. +# +# Use static libraries for the static build rather than source sets because +# many of of our test binaries link many large dependencies but often don't +# use large portions of them. The static libraries are much more efficient to +# link in this situation since only the necessary object files are linked. +# +# The invoker can override the type of the target in the non-component-build +# case by setting static_component_type to either "source_set" or +# "static_library". If unset, the default will be used. +template("component") { + if (is_component_build) { + _component_mode = "shared_library" + } else if (defined(invoker.static_component_type)) { + assert(invoker.static_component_type == "static_library" || + invoker.static_component_type == "source_set") + _component_mode = invoker.static_component_type + } else if (is_android || !defined(invoker.sources)) { + # When there are no sources defined, use a source set to avoid creating + # an empty static library (which generally don't work). + # + # When we changed components to default from source sets to static + # libraries, an Android benchmark regressed slightly + # (https://crbug.com/619593). We don't have a good theory on why this might + # be since theoretically it should be the same. It could be something as + # silly as random code locality luck. + # + # There seems to be no build-time performance hit to using source sets on + # Android (the normal reason for defaulting to static libraries), so we + # make the default on Android to be source set. + # + # If it's been a long time since this was added and you're skeptical, + # please feel free to remove the Android exception and see if any + # benchmarks obviously regress. If not, it would be great to standardize + # with the rest of the platforms. + _component_mode = "source_set" + } else { + _component_mode = "static_library" + } + target(_component_mode, target_name) { + # Explicitly forward visibility, implicitly forward everything else. + # Forwarding "*" doesn't recurse into nested scopes (to avoid copying all + # globals into each template invocation), so won't pick up file-scoped + # variables. Normally this isn't too bad, but visibility is commonly + # defined at the file scope. Explicitly forwarding visibility and then + # excluding it from the "*" set works around this problem. + # See http://crbug.com/594610 + forward_variables_from(invoker, [ "visibility" ]) + forward_variables_from(invoker, "*", [ "visibility" ]) + + # All shared libraries must have the sanitizer deps to properly link in + # asan mode (this target will be empty in other cases). + if (!defined(deps)) { + deps = [] + } + deps += [ "//build/config:exe_and_shlib_deps" ] + } +} + +# Component defaults +set_defaults("component") { + if (is_component_build) { + configs = default_shared_library_configs + if (is_android) { + configs -= [ "//build/config/android:hide_all_but_jni_onload" ] + } + } else { + configs = default_compiler_configs + } +}
new file mode 100644 --- /dev/null +++ b/media/webrtc/trunk/build/config/OWNERS @@ -0,0 +1,6 @@ +brettw@chromium.org +dpranke@chromium.org +scottmg@chromium.org + +per-file BUILDCONFIG.gn=brettw@chromium.org +per-file BUILDCONFIG.gn=set noparent
new file mode 100644 --- /dev/null +++ b/media/webrtc/trunk/build/config/aix/BUILD.gn @@ -0,0 +1,50 @@ +# Copyright 2017 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. + +import("//build/config/sanitizers/sanitizers.gni") +import("//build/toolchain/toolchain.gni") + +# This is included by reference in the //build/config/compiler config that +# is applied to all targets. It is here to separate out the logic. + +config("compiler") { + # These flags are shared between the C compiler and linker. + defines = [ + "_LINUX_SOURCE_COMPAT=1", + "__STDC_FORMAT_MACROS", + "_ALL_SOURCE=1", + ] + + cflags = [ + "-Wall", + "-Wno-unused-parameter", + "-pthread", + "-Wmissing-field-initializers", + "-Wno-uninitialized", + "-mcpu=power5+", + "-mfprnd", + "-mno-popcntb", + "-maix64", + "-fdata-sections", + "-ffunction-sections", + "-O3", + + # "-Werror" + # We need to find a way to fix the TOC warnings if we want to enable this. + ] + + cflags_cc = [ + "-std=gnu++11", + "-fno-rtti", + "-fno-exceptions", + "-Wno-narrowing", + "-Wnon-virtual-dtor", + ] + + ldflags = [ + "-pthread", + "-maix64", + "-Wl,-bbigtoc", + ] +}
new file mode 100644 --- /dev/null +++ b/media/webrtc/trunk/build/config/allocator.gni @@ -0,0 +1,53 @@ +# 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. + +import("//build/config/sanitizers/sanitizers.gni") + +# Temporarily disable tcmalloc on arm64 linux to get rid of compilation errors. +if (is_android || current_cpu == "mipsel" || is_mac || is_ios || is_asan || + is_lsan || is_tsan || is_msan || is_win || is_syzyasan || is_fuchsia || + (is_linux && target_cpu == "arm64")) { + _default_allocator = "none" +} else { + _default_allocator = "tcmalloc" +} + +# The debug CRT on Windows has some debug features that are incompatible with +# the shim. NaCl in particular does seem to link some binaries statically +# against the debug CRT with "is_nacl=false". +if ((is_linux || is_android || is_mac || + (is_win && !is_component_build && !is_debug)) && !is_asan && !is_lsan && + !is_tsan && !is_msan) { + _default_use_allocator_shim = true +} else { + _default_use_allocator_shim = false +} + +declare_args() { + # Memory allocator to use. Set to "none" to use default allocator. + use_allocator = _default_allocator + + # Causes all the allocations to be routed via allocator_shim.cc. + use_allocator_shim = _default_use_allocator_shim +} + +if (is_nacl) { + # Turn off the build flag for NaCL builds to minimize confusion, as NaCL + # doesn't support the heap shim. + use_allocator_shim = false +} + +assert(use_allocator == "none" || use_allocator == "tcmalloc") + +assert(!is_win || use_allocator == "none", "Tcmalloc doesn't work on Windows.") +assert(!is_mac || use_allocator == "none", "Tcmalloc doesn't work on macOS.") + +assert( + !use_allocator_shim || is_linux || is_android || is_win || is_mac, + "use_allocator_shim is supported only on Linux, Android, Windows and macOS targets") + +if (is_win && use_allocator_shim) { + assert(!is_component_build, + "The allocator shim doesn't work for the component build on Windows.") +}
new file mode 100644 --- /dev/null +++ b/media/webrtc/trunk/build/config/android/BUILD.gn @@ -0,0 +1,237 @@ +# 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. + +import("//build/config/android/config.gni") +import("//build/config/sanitizers/sanitizers.gni") + +assert(is_android) + +# This is included by reference in the //build/config/compiler config that +# is applied to all targets. It is here to separate out the logic that is +# Android-only. +config("compiler") { + cflags = [ + "-ffunction-sections", + "-fno-short-enums", + ] + defines = [ + "ANDROID", + + # The NDK has these things, but doesn't define the constants to say that it + # does. Define them here instead. + "HAVE_SYS_UIO_H", + + # Forces full rebuilds on NDK rolls. + "ANDROID_NDK_VERSION=${android_ndk_version}", + ] + + if (is_clang) { + if (current_cpu == "mips64el") { + cflags += [ + # Have to force IAS for mips64. + "-fintegrated-as", + ] + } + } else { + # Clang doesn't support these flags. + cflags += [ "-finline-limit=64" ] + } + + ldflags = [ + "-Wl,--no-undefined", + + # Don't allow visible symbols from libgcc or libc++ to be + # re-exported. + "-Wl,--exclude-libs=libgcc.a", + "-Wl,--exclude-libs=libc++_static.a", + + # Don't allow visible symbols from libraries that contain + # assembly code with symbols that aren't hidden properly. + # http://crbug.com/448386 + "-Wl,--exclude-libs=libvpx_assembly_arm.a", + ] + + if (is_clang) { + if (current_cpu == "arm") { + abi_target = "arm-linux-androideabi" + } else if (current_cpu == "x86") { + abi_target = "i686-linux-androideabi" + } else if (current_cpu == "arm64") { + abi_target = "aarch64-linux-android" + } else if (current_cpu == "x64") { + # Place holder for x64 support, not tested. + # TODO: Enable clang support for Android x64. http://crbug.com/539781 + abi_target = "x86_64-linux-androideabi" + } else if (current_cpu == "mipsel") { + abi_target = "mipsel-linux-android" + } else if (current_cpu == "mips64el") { + # Place holder for mips64 support, not tested. + abi_target = "mips64el-linux-androideabi" + } else { + assert(false, "Architecture not supported") + } + cflags += [ "--target=$abi_target" ] + ldflags += [ "--target=$abi_target" ] + } + + # Assign any flags set for the C compiler to asmflags so that they are sent + # to the assembler. + asmflags = cflags +} + +# This is included by reference in the //build/config/compiler:runtime_library +# config that is applied to all targets. It is here to separate out the logic +# that is Android-only. Please see that target for advice on what should go in +# :runtime_library vs. :compiler. +config("runtime_library") { + # NOTE: The libc++ header include paths below are specified in cflags_cc + # rather than include_dirs because they need to come after include_dirs. + # Think of them like system headers, but don't use '-isystem' because the + # arm-linux-androideabi-4.4.3 toolchain (circa Gingerbread) will exhibit + # strange errors. The include ordering here is important; change with + # caution. + cflags_cc = [] + if (android_ndk_major_version >= 13) { + libcxx_include_path = + rebase_path("$android_libcpp_root/include", root_build_dir) + libcxxabi_include_path = + rebase_path("$android_ndk_root/sources/cxx-stl/llvm-libc++abi/include", + root_build_dir) + + if (!is_clang) { + # Per the release notes, GCC is not supported in the NDK starting with + # r13. It's still present, though, and has conflicting declarations of + # float abs(float). + cflags_cc += [ "-Wno-attributes" ] + } + } else { + libcxx_include_path = + rebase_path("$android_libcpp_root/libcxx/include", root_build_dir) + libcxxabi_include_path = rebase_path( + "$android_ndk_root/sources/cxx-stl/llvm-libc++abi/libcxxabi/include", + root_build_dir) + } + cflags_cc += [ + "-isystem" + libcxx_include_path, + "-isystem" + libcxxabi_include_path, + "-isystem" + + rebase_path("$android_ndk_root/sources/android/support/include", + root_build_dir), + ] + + defines = [ "__GNU_SOURCE=1" ] # Necessary for clone(). + ldflags = [ "-nostdlib" ] + lib_dirs = [ android_libcpp_lib_dir ] + + # The libc++ runtime library (must come first). + # ASan needs to dynamically link to libc++ even in static builds so + # that it can interpose operator new. + if (is_component_build || is_asan) { + libs = [ "c++_shared" ] + } else { + libs = [ "c++_static" ] + } + libs += [ + "c++abi", + "android_support", + ] + + # arm builds of libc++ starting in NDK r12 depend on unwind. + if (current_cpu == "arm") { + libs += [ "unwind" ] + } + + # Manually link the libgcc.a that the cross compiler uses. This is + # absolute because the linker will look inside the sysroot if it's not. + libs += [ + rebase_path(android_libgcc_file), + "c", + ] + + # Clang with libc++ does not require an explicit atomic library reference. + if (!is_clang) { + libs += [ "atomic" ] + } + + if (is_clang) { + # Work around incompatibilities between bionic and clang headers. + defines += [ + "__compiler_offsetof=__builtin_offsetof", + "nan=__builtin_nan", + ] + + if (current_cpu == "x64" || current_cpu == "arm64" || + current_cpu == "mips64el") { + # 64-bit targets build with NDK 21, 32-bit targets with NDK 16 + # (see ./config.gni). When using clang, NDK 21 defines snprintf to + # something for a kind of for of _FORTIFY_SOURCE support, see + # third_party/android_tools/ndk/platforms/android-21/arch-x86_64/usr/include/stdio.h + # Making snprintf a macro breaks base/strings/string_utils.h which + # defines base::snprintf(). So define snprintf to itself to force the + # NDK to not redefine it. This disables _chk for snprintf, but since + # 32-bit versions use NDK 16 which doesn't have any fortify support, that + # seems ok. b/32067310 tracks better fortify support with clang. + # TODO(thakis): Remove this once b/32067310 is fixed. + defines += [ "snprintf=snprintf" ] + } + } + + # TODO(jdduke) Re-enable on mips after resolving linking + # issues with libc++ (crbug.com/456380). + if (current_cpu != "mipsel" && current_cpu != "mips64el") { + ldflags += [ "-Wl,--warn-shared-textrel" ] + } +} + +config("executable_config") { + cflags = [ "-fPIE" ] + asmflags = [ "-fPIE" ] + ldflags = [ "-pie" ] +} + +config("hide_all_but_jni_onload") { + ldflags = [ "-Wl,--version-script=" + rebase_path( + "//build/android/android_only_explicit_jni_exports.lst") ] +} + +config("hide_all_but_jni") { + ldflags = [ "-Wl,--version-script=" + + rebase_path("//build/android/android_only_jni_exports.lst") ] +} + +# Instrumentation ------------------------------------------------------------- +# +# The BUILDCONFIG file sets the "default_cygprofile_instrumentation" config on +# targets by default. You can override whether the cygprofile instrumentation is +# used on a per-target basis: +# +# configs -= [ "//build/config/android:default_cygprofile_instrumentation" ] +# configs += [ "//build/config/android:no_cygprofile_instrumentation" ] + +config("default_cygprofile_instrumentation") { + if (use_order_profiling) { + configs = [ ":cygprofile_instrumentation" ] + } else { + configs = [ ":no_cygprofile_instrumentation" ] + } +} + +config("cygprofile_instrumentation") { + defines = [ "CYGPROFILE_INSTRUMENTATION=1" ] + cflags = [ "-finstrument-functions" ] + + if (!is_clang) { + cflags += [ + # Allow mmx intrinsics to inline, so that the compiler can expand the intrinsics. + "-finstrument-functions-exclude-file-list=mmintrin.h", + + # Avoid errors with current NDK: + # "third_party/android_tools/ndk/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.6/include/arm_neon.h:3426:3: error: argument must be a constant" + "-finstrument-functions-exclude-file-list=arm_neon.h", + ] + } +} + +config("no_cygprofile_instrumentation") { +}
new file mode 100644 --- /dev/null +++ b/media/webrtc/trunk/build/config/android/OWNERS @@ -0,0 +1,3 @@ +agrieve@chromium.org + +# COMPONENT: Build
new file mode 100644 --- /dev/null +++ b/media/webrtc/trunk/build/config/android/config.gni @@ -0,0 +1,374 @@ +# 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. + +# This file contains common system config stuff for the Android build. + +if (is_android) { + import("//build_overrides/build.gni") + + has_chrome_android_internal = + exec_script("//build/dir_exists.py", + [ rebase_path("//clank", root_build_dir) ], + "string") == "True" + + # We are using a separate declare_args block for only this argument so that + # we can decide if we have to pull in definitions from the internal config + # early. + declare_args() { + # Enables using the internal Chrome for Android repository. The default + # value depends on whether the repository is available, and if it's not but + # this argument is manually set to True, the generation will fail. + # The main purpose of this argument is to avoid having to maintain 2 + # repositories to support both public only and internal builds. + enable_chrome_android_internal = has_chrome_android_internal + } + + if (enable_chrome_android_internal) { + import("//clank/config.gni") + } + + if (!defined(extra_chrome_shared_library_configs)) { + extra_chrome_shared_library_configs = [] + } + + if (!defined(default_android_ndk_root)) { + default_android_ndk_root = "//third_party/android_tools/ndk" + default_android_ndk_version = "r12b" + default_android_ndk_major_version = 12 + } else { + assert(defined(default_android_ndk_version)) + assert(defined(default_android_ndk_major_version)) + } + + if (!defined(default_android_sdk_root)) { + default_android_sdk_root = "//third_party/android_tools/sdk" + default_android_sdk_version = "25" + default_android_sdk_build_tools_version = "25.0.2" + } + + if (!defined(default_lint_android_sdk_root)) { + # Purposefully repeated so that downstream can change + # default_android_sdk_root without changing lint version. + default_lint_android_sdk_root = "//third_party/android_tools/sdk" + default_lint_android_sdk_version = "25" + } + + if (!defined(default_extras_android_sdk_root)) { + # Purposefully repeated so that downstream can change + # default_android_sdk_root without changing where we load the SDK extras + # from. (Google Play services, etc.) + default_extras_android_sdk_root = "//third_party/android_tools/sdk" + } + + if (!defined(default_android_keystore_path)) { + default_android_keystore_path = + "//build/android/ant/chromium-debug.keystore" + default_android_keystore_name = "chromiumdebugkey" + default_android_keystore_password = "chromium" + } + + # TODO(paulmiller): Remove; superseded by google_play_services_package. + if (!defined(google_play_services_library)) { + google_play_services_library = + "//third_party/android_tools:google_play_services_default_java" + } + + # TODO(paulmiller): Remove; superseded by google_play_services_package. + if (!defined(google_play_services_resources)) { + google_play_services_resources = + "//third_party/android_tools:google_play_services_default_resources" + } + + # google_play_services_package contains the path where individual client + # targets (e.g. google_play_services_base_java) are located. + if (!defined(google_play_services_package)) { + google_play_services_package = "//third_party/android_tools" + } + + webview_public_framework_jar = + "//third_party/android_platform/webview/frameworks_7.1.1_r28.jar" + if (!defined(webview_framework_jar)) { + webview_framework_jar = webview_public_framework_jar + } + + declare_args() { + android_ndk_root = default_android_ndk_root + android_ndk_version = default_android_ndk_version + android_ndk_major_version = default_android_ndk_major_version + + android_sdk_root = default_android_sdk_root + android_sdk_version = default_android_sdk_version + android_sdk_build_tools_version = default_android_sdk_build_tools_version + + lint_android_sdk_root = default_lint_android_sdk_root + lint_android_sdk_version = default_lint_android_sdk_version + + # Libc++ library directory. Override to use a custom libc++ binary. + android_libcpp_lib_dir = "" + + # Android versionCode for android_apk()s that don't expclitly set one. + android_default_version_code = "1" + + # Android versionName for android_apk()s that don't expclitly set one. + android_default_version_name = "Developer Build" + + # The path to the keystore to use for signing builds. + android_keystore_path = default_android_keystore_path + + # The name of the keystore to use for signing builds. + android_keystore_name = default_android_keystore_name + + # The password for the keystore to use for signing builds. + android_keystore_password = default_android_keystore_password + + # Set to true to run findbugs on JAR targets. + run_findbugs = false + + # Set to true to enable verbose findbugs logging. This does nothing if + # run_findbugs is false. + findbugs_verbose = false + + # Enables verbose proguard output (summaries and unfiltered output). + proguard_verbose = false + + # Java debug on Android. Having this on enables multidexing, and turning it + # off will enable proguard. + is_java_debug = is_debug + + # Set to true to enable the Errorprone compiler + use_errorprone_java_compiler = false + + # Enables EMMA Java code coverage. Instruments classes during build to + # produce .ec files during runtime + emma_coverage = false + + # EMMA filter string consisting of a list of inclusion/exclusion patterns + # separated with whitespace and/or comma. Only has effect if + # emma_coverage==true + emma_filter = "" + + # Disables process isolation when building _incremental targets. + # Required for Android M+ due to SELinux policies (stronger sandboxing). + disable_incremental_isolated_processes = false + + # Speeds up incremental compiles by compiling only changed files. + enable_incremental_javac = false + + # Adds intrumentation to each function. Writes a file with the order that + # functions are called at startup. + use_order_profiling = false + + # Builds secondary abi for APKs, supports build 32-bit arch as secondary + # abi in 64-bit Monochrome and WebView. + build_apk_secondary_abi = true + + # Enables java8 language features (via retrolambda). + # work-in-progress (http://crbug.com/642600) + use_java8 = false + + # Build incremental targets whenever possible. + # Ex. with this arg set to true, the chrome_public_apk target result in + # chrome_public_apk_incremental being built. + incremental_apk_by_default = false + } + + # We need a second declare_args block to make sure we are using the overridden + # value of the arguments set above. + declare_args() { + # Speed up dexing using dx --incremental. + enable_incremental_dx = is_java_debug + } + + # Neither of these should ever be used for release builds since they are + # somewhat experimental and dx --incremental is known to not produce + # byte-for-byte identical output. + assert(!(enable_incremental_dx && !is_java_debug)) + assert(!(enable_incremental_javac && !is_java_debug)) + + # Host stuff ----------------------------------------------------------------- + + # Defines the name the Android build gives to the current host CPU + # architecture, which is different than the names GN uses. + if (host_cpu == "x64") { + android_host_arch = "x86_64" + } else if (host_cpu == "x86") { + android_host_arch = "x86" + } else { + assert(false, "Need Android toolchain support for your build CPU arch.") + } + + # Defines the name the Android build gives to the current host CPU + # architecture, which is different than the names GN uses. + if (host_os == "linux") { + android_host_os = "linux" + } else if (host_os == "mac") { + android_host_os = "darwin" + } else { + assert(false, "Need Android toolchain support for your build OS.") + } + + # Directories and files ------------------------------------------------------ + # + # We define may of the dirs strings here for each output architecture (rather + # than just the current one) since these are needed by the Android toolchain + # file to define toolchains for all possible targets in one pass. + + android_sdk = "${android_sdk_root}/platforms/android-${android_sdk_version}" + + # Path to the Android NDK and SDK. + android_ndk_include_dir = "$android_ndk_root/usr/include" + + android_sdk_tools = "${android_sdk_root}/tools" + android_sdk_build_tools = + "${android_sdk_root}/build-tools/$android_sdk_build_tools_version" + + # Path to the SDK's android.jar + android_sdk_jar = "$android_sdk/android.jar" + + zipalign_path = "$android_sdk_build_tools/zipalign" + + # Subdirectories inside android_ndk_root that contain the sysroot for the + # associated platform. + # If you raise this, reevaluate the snprintf=snprintf in ./BUILD.gn. + _android_api_level = 16 + x86_android_sysroot_subdir = + "platforms/android-${_android_api_level}/arch-x86" + arm_android_sysroot_subdir = + "platforms/android-${_android_api_level}/arch-arm" + mips_android_sysroot_subdir = + "platforms/android-${_android_api_level}/arch-mips" + + # If you raise this, reevaluate the snprintf=snprintf in ./BUILD.gn. + _android64_api_level = 21 + x86_64_android_sysroot_subdir = + "platforms/android-${_android64_api_level}/arch-x86_64" + arm64_android_sysroot_subdir = + "platforms/android-${_android64_api_level}/arch-arm64" + mips64_android_sysroot_subdir = + "platforms/android-${_android64_api_level}/arch-mips64" + + # Toolchain root directory for each build. The actual binaries are inside + # a "bin" directory inside of these. + _android_toolchain_version = "4.9" + _android_toolchain_detailed_version = "4.9.x" + x86_android_toolchain_root = "$android_ndk_root/toolchains/x86-${_android_toolchain_version}/prebuilt/${android_host_os}-${android_host_arch}" + arm_android_toolchain_root = "$android_ndk_root/toolchains/arm-linux-androideabi-${_android_toolchain_version}/prebuilt/${android_host_os}-${android_host_arch}" + mips_android_toolchain_root = "$android_ndk_root/toolchains/mipsel-linux-android-${_android_toolchain_version}/prebuilt/${android_host_os}-${android_host_arch}" + x86_64_android_toolchain_root = "$android_ndk_root/toolchains/x86_64-${_android_toolchain_version}/prebuilt/${android_host_os}-${android_host_arch}" + arm64_android_toolchain_root = "$android_ndk_root/toolchains/aarch64-linux-android-${_android_toolchain_version}/prebuilt/${android_host_os}-${android_host_arch}" + mips64_android_toolchain_root = "$android_ndk_root/toolchains/mips64el-linux-android-${_android_toolchain_version}/prebuilt/${android_host_os}-${android_host_arch}" + + # Location of libgcc. This is only needed for the current GN toolchain, so we + # only need to define the current one, rather than one for every platform + # like the toolchain roots. + if (current_cpu == "x86") { + android_prebuilt_arch = "android-x86" + _binary_prefix = "i686-linux-android" + android_toolchain_root = "$x86_android_toolchain_root" + android_libgcc_file = "$android_toolchain_root/lib/gcc/i686-linux-android/${_android_toolchain_detailed_version}/libgcc.a" + } else if (current_cpu == "arm") { + android_prebuilt_arch = "android-arm" + _binary_prefix = "arm-linux-androideabi" + android_toolchain_root = "$arm_android_toolchain_root" + android_libgcc_file = "$android_toolchain_root/lib/gcc/arm-linux-androideabi/${_android_toolchain_detailed_version}/libgcc.a" + } else if (current_cpu == "mipsel") { + android_prebuilt_arch = "android-mips" + _binary_prefix = "mipsel-linux-android" + android_toolchain_root = "$mips_android_toolchain_root" + android_libgcc_file = "$android_toolchain_root/lib/gcc/mipsel-linux-android/${_android_toolchain_detailed_version}/libgcc.a" + } else if (current_cpu == "x64") { + android_prebuilt_arch = "android-x86_64" + _binary_prefix = "x86_64-linux-android" + android_toolchain_root = "$x86_64_android_toolchain_root" + android_libgcc_file = "$android_toolchain_root/lib/gcc/x86_64-linux-android/${_android_toolchain_detailed_version}/libgcc.a" + } else if (current_cpu == "arm64") { + android_prebuilt_arch = "android-arm64" + _binary_prefix = "aarch64-linux-android" + android_toolchain_root = "$arm64_android_toolchain_root" + android_libgcc_file = "$android_toolchain_root/lib/gcc/aarch64-linux-android/${_android_toolchain_detailed_version}/libgcc.a" + } else if (current_cpu == "mips64el") { + android_prebuilt_arch = "android-mips64" + _binary_prefix = "mips64el-linux-android" + android_toolchain_root = "$mips64_android_toolchain_root" + android_libgcc_file = "$android_toolchain_root/lib/gcc/mips64el-linux-android/${_android_toolchain_detailed_version}/libgcc.a" + } else { + assert(false, "Need android libgcc support for your target arch.") + } + + android_tool_prefix = "$android_toolchain_root/bin/$_binary_prefix-" + android_readelf = "${android_tool_prefix}readelf" + android_objcopy = "${android_tool_prefix}objcopy" + android_gdbserver = + "$android_ndk_root/prebuilt/$android_prebuilt_arch/gdbserver/gdbserver" + + # Toolchain stuff ------------------------------------------------------------ + + android_libcpp_root = "$android_ndk_root/sources/cxx-stl/llvm-libc++" + + # ABI ------------------------------------------------------------------------ + + if (current_cpu == "x86") { + android_app_abi = "x86" + } else if (current_cpu == "arm") { + import("//build/config/arm.gni") + if (arm_version < 7) { + android_app_abi = "armeabi" + } else { + android_app_abi = "armeabi-v7a" + } + } else if (current_cpu == "mipsel") { + android_app_abi = "mips" + } else if (current_cpu == "x64") { + android_app_abi = "x86_64" + } else if (current_cpu == "arm64") { + android_app_abi = "arm64-v8a" + } else if (current_cpu == "mips64el") { + android_app_abi = "mips64" + } else { + assert(false, "Unknown Android ABI: " + current_cpu) + } + + if (android_libcpp_lib_dir == "") { + android_libcpp_lib_dir = "${android_libcpp_root}/libs/${android_app_abi}" + } + + # Secondary ABI ------------------------------------------------------------- + if (target_cpu == "arm64" || target_cpu == "x64" || target_cpu == "mips64el") { + android_64bit_target_cpu = true + } else if (target_cpu == "arm" || target_cpu == "x86" || + target_cpu == "mipsel") { + android_64bit_target_cpu = false + } else { + assert(false, "Unknown target CPU: $target_cpu") + } + + # Intentionally do not define android_app_secondary_abi_cpu and + # android_app_secondary_abi for 32-bit target_cpu, since they are not used. + if (target_cpu == "arm64") { + android_secondary_abi_cpu = "arm" + android_app_secondary_abi = "armeabi-v7a" + } else if (target_cpu == "x64") { + android_secondary_abi_cpu = "x86" + android_app_secondary_abi = "x86" + } else if (target_cpu == "mips64el") { + android_secondary_abi_cpu = "mipsel" + android_app_secondary_abi = "mips" + } + + if (defined(android_secondary_abi_cpu)) { + if (is_clang) { + android_secondary_abi_toolchain = + "//build/toolchain/android:android_clang_${android_secondary_abi_cpu}" + } else { + android_secondary_abi_toolchain = + "//build/toolchain/android:android_${android_secondary_abi_cpu}" + } + } +} + +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 +}
new file mode 100644 --- /dev/null +++ b/media/webrtc/trunk/build/config/android/internal_rules.gni @@ -0,0 +1,2894 @@ +# 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. + +# Do not add any imports to non-//build directories here. +# Some projects (e.g. V8) do not have non-build directories DEPS'ed in. +import("//build_overrides/build.gni") +import("//build/config/android/config.gni") +import("//build/config/dcheck_always_on.gni") +import("//build/config/sanitizers/sanitizers.gni") + +assert(is_android) + +# These identify targets that have .build_config files (except for android_apk, +# java_binary, resource_rewriter, since we never need to depend on these). +_java_target_whitelist = [ + "*:*_java", + "*:*_javalib", + "*:*_java_*", # e.g. java_test_support + "*:java", + "*:junit", + "*:junit_*", + "*:*_junit_*", + "*:*javatests", + "*:*_assets", + "*android*:assets", + "*:*_apk_*resources", + "*android*:resources", + "*:*_resources", + "*:*_grd", + "*:*locale_paks", + + # TODO(agrieve): Rename targets below to match above patterns. + "*android_webview/glue:glue", + "//chrome/test/android/cast_emulator:cast_emulator", +] + +# Targets that match the whitelist but are not actually java targets. +_java_target_blacklist = [ + "//chrome:packed_resources", + "*:*_unpack_aar", +] + +_default_proguard_jar_path = "//third_party/proguard/lib/proguard.jar" + +# Write the target's .build_config file. This is a json file that contains a +# dictionary of information about how to build this target (things that +# require knowledge about this target's dependencies and cannot be calculated +# at gn-time). There is a special syntax to add a value in that dictionary to +# an action/action_foreachs args: +# --python-arg=@FileArg($rebased_build_config_path:key0:key1) +# At runtime, such an arg will be replaced by the value in the build_config. +# See build/android/gyp/write_build_config.py and +# build/android/gyp/util/build_utils.py:ExpandFileArgs +template("write_build_config") { + type = invoker.type + _is_prebuilt_binary = + defined(invoker.is_prebuilt_binary) && invoker.is_prebuilt_binary + + # Don't need to enforce naming scheme for these targets since we never + # consider them in dependency chains. + if (!_is_prebuilt_binary && type != "android_apk" && type != "java_binary" && + type != "resource_rewriter" && type != "dist_jar") { + set_sources_assignment_filter(_java_target_whitelist) + _parent_invoker = invoker.invoker + _target_label = + get_label_info(":${_parent_invoker.target_name}", "label_no_toolchain") + sources = [ + _target_label, + ] + if (sources != []) { + set_sources_assignment_filter(_java_target_blacklist) + sources = [] + sources = [ + _target_label, + ] + if (sources != []) { + assert(false, "Invalid java target name: $_target_label") + } + } + sources = [] + } + + action(target_name) { + set_sources_assignment_filter([]) + build_config = invoker.build_config + + assert(type == "android_apk" || type == "java_library" || + type == "android_resources" || type == "deps_dex" || + type == "dist_jar" || type == "android_assets" || + type == "resource_rewriter" || type == "java_binary" || + type == "group" || type == "java_prebuilt" || type == "junit_binary") + + forward_variables_from(invoker, + [ + "deps", + "testonly", + ]) + if (!defined(deps)) { + deps = [] + } + + script = "//build/android/gyp/write_build_config.py" + depfile = "$target_gen_dir/$target_name.d" + inputs = [] + + _deps_configs = [] + if (defined(invoker.possible_config_deps)) { + foreach(_possible_dep, invoker.possible_config_deps) { + set_sources_assignment_filter(_java_target_whitelist) + _target_label = get_label_info(_possible_dep, "label_no_toolchain") + sources = [ + _target_label, + ] + if (sources == []) { + set_sources_assignment_filter(_java_target_blacklist) + sources = [] + sources = [ + _target_label, + ] + if (sources != []) { + deps += [ "${_target_label}__build_config" ] + _dep_gen_dir = get_label_info(_possible_dep, "target_gen_dir") + _dep_name = get_label_info(_possible_dep, "name") + _deps_configs += [ "$_dep_gen_dir/$_dep_name.build_config" ] + } + } + sources = [] + } + set_sources_assignment_filter([]) + } + _rebased_deps_configs = rebase_path(_deps_configs, root_build_dir) + + outputs = [ + build_config, + ] + + args = [ + "--type", + type, + "--depfile", + rebase_path(depfile, root_build_dir), + "--deps-configs=$_rebased_deps_configs", + "--build-config", + rebase_path(build_config, root_build_dir), + ] + + is_java = type == "java_library" || type == "java_binary" || + type == "java_prebuilt" + is_apk = type == "android_apk" + is_android_assets = type == "android_assets" + is_android_resources = type == "android_resources" + is_deps_dex = type == "deps_dex" + is_group = type == "group" + + supports_android = is_apk || is_android_assets || is_android_resources || + is_deps_dex || is_group || + (is_java && defined(invoker.supports_android) && + invoker.supports_android) + requires_android = + is_apk || is_android_assets || is_android_resources || is_deps_dex || + (is_java && defined(invoker.requires_android) && + invoker.requires_android) + + assert(!requires_android || supports_android, + "requires_android requires" + " supports_android") + + # Mark these variables as used. + assert(is_java || true) + assert(is_apk || true) + assert(is_android_resources || true) + assert(is_deps_dex || true) + assert(is_group || true) + + if (is_java || is_apk) { + args += [ + "--jar-path", + rebase_path(invoker.jar_path, root_build_dir), + ] + } + + if (is_java && defined(invoker.java_resources_jar)) { + args += [ + "--java-resources-jar-path", + rebase_path(invoker.java_resources_jar, root_build_dir), + ] + } + if (is_apk || is_deps_dex || (is_java && supports_android)) { + args += [ + "--dex-path", + rebase_path(invoker.dex_path, root_build_dir), + ] + } + if (supports_android) { + args += [ "--supports-android" ] + } + if (requires_android) { + args += [ "--requires-android" ] + } + if (defined(invoker.bypass_platform_checks) && + invoker.bypass_platform_checks) { + args += [ "--bypass-platform-checks" ] + } + + if (defined(invoker.apk_under_test)) { + deps += [ "${invoker.apk_under_test}__build_config" ] + apk_under_test_gen_dir = + get_label_info(invoker.apk_under_test, "target_gen_dir") + apk_under_test_name = get_label_info(invoker.apk_under_test, "name") + apk_under_test_config = + "$apk_under_test_gen_dir/$apk_under_test_name.build_config" + args += [ + "--tested-apk-config", + rebase_path(apk_under_test_config, root_build_dir), + ] + } + + if (is_android_assets) { + if (defined(invoker.asset_sources)) { + _rebased_asset_sources = + rebase_path(invoker.asset_sources, root_build_dir) + args += [ "--asset-sources=$_rebased_asset_sources" ] + } + if (defined(invoker.asset_renaming_sources)) { + _rebased_asset_renaming_sources = + rebase_path(invoker.asset_renaming_sources, root_build_dir) + args += [ "--asset-renaming-sources=$_rebased_asset_renaming_sources" ] + + # These are zip paths, so no need to rebase. + args += [ "--asset-renaming-destinations=${invoker.asset_renaming_destinations}" ] + } + if (defined(invoker.disable_compression) && invoker.disable_compression) { + args += [ "--disable-asset-compression" ] + } + } + + if (is_android_resources || is_apk) { + assert(defined(invoker.resources_zip)) + args += [ + "--resources-zip", + rebase_path(invoker.resources_zip, root_build_dir), + ] + if (defined(invoker.android_manifest)) { + inputs += [ invoker.android_manifest ] + args += [ + "--android-manifest", + rebase_path(invoker.android_manifest, root_build_dir), + ] + } else { + assert(!is_apk, "apk build configs require an android_manifest") + } + if (defined(invoker.custom_package)) { + args += [ + "--package-name", + invoker.custom_package, + ] + } + if (defined(invoker.r_text)) { + args += [ + "--r-text", + rebase_path(invoker.r_text, root_build_dir), + ] + } + } + + if (is_android_resources && defined(invoker.resource_dirs)) { + resource_dirs = rebase_path(invoker.resource_dirs, root_build_dir) + args += [ "--resource-dirs=$resource_dirs" ] + } + + if (is_apk) { + if (defined(invoker.shared_libraries_runtime_deps_file)) { + # Don't list shared_libraries_runtime_deps_file as an input in order to + # avoid having to depend on the runtime_deps target. See comment in + # rules.gni for why we do this. + args += [ + "--shared-libraries-runtime-deps", + rebase_path(invoker.shared_libraries_runtime_deps_file, + root_build_dir), + ] + } + + if (defined(invoker.secondary_abi_shared_libraries_runtime_deps_file)) { + # Don't list secondary_abi_shared_libraries_runtime_deps_file as an + # input in order to avoid having to depend on the runtime_deps target. + # See comment in rules.gni for why we do this. + args += [ + "--secondary-abi-shared-libraries-runtime-deps", + rebase_path(invoker.secondary_abi_shared_libraries_runtime_deps_file, + root_build_dir), + ] + } + + if (defined(invoker.proguard_enabled) && invoker.proguard_enabled) { + args += [ + "--proguard-enabled", + "--proguard-info", + rebase_path(invoker.proguard_info, root_build_dir), + ] + } + + if (defined(invoker.apk_path)) { + _rebased_apk_path = rebase_path(invoker.apk_path, root_build_dir) + _rebased_incremental_apk_path = + rebase_path(invoker.incremental_apk_path, root_build_dir) + _rebased_incremental_install_script_path = + rebase_path(invoker.incremental_install_script_path, root_build_dir) + _incremental_allowed = + defined(invoker.incremental_allowed) && invoker.incremental_allowed + args += [ "--apk-path=$_rebased_apk_path" ] + args += [ "--incremental-install-script-path=$_rebased_incremental_install_script_path" ] + + assert(_rebased_incremental_apk_path != "") # Mark as used. + if (_incremental_allowed) { + args += [ "--incremental-apk-path=$_rebased_incremental_apk_path" ] + } + } + } + + if (defined(invoker.java_sources_file)) { + args += [ + "--java-sources-file", + rebase_path(invoker.java_sources_file, root_build_dir), + ] + } + if (defined(invoker.srcjar)) { + args += [ + "--srcjar", + rebase_path(invoker.srcjar, root_build_dir), + ] + } + if (defined(invoker.bundled_srcjars)) { + _rebased_bundled_srcjars = + rebase_path(invoker.bundled_srcjars, root_build_dir) + args += [ "--bundled-srcjars=$_rebased_bundled_srcjars" ] + } + if (defined(invoker.input_jars_paths)) { + _rebased_input_jars_paths = + rebase_path(invoker.input_jars_paths, root_build_dir) + args += [ "--extra-classpath-jars=$_rebased_input_jars_paths" ] + } + if (defined(invoker.proguard_configs)) { + _rebased_proguard_configs = + rebase_path(invoker.proguard_configs, root_build_dir) + args += [ "--proguard-configs=$_rebased_proguard_configs" ] + } + if (defined(invoker.gradle_treat_as_prebuilt) && + invoker.gradle_treat_as_prebuilt) { + args += [ "--gradle-treat-as-prebuilt" ] + } + if (defined(invoker.main_class)) { + args += [ + "--main-class", + invoker.main_class, + ] + } + if (defined(invoker.alternative_android_sdk_ijar)) { + args += [ + "--bootclasspath", + rebase_path(invoker.alternative_android_sdk_ijar, root_build_dir), + ] + } + if (current_toolchain != default_toolchain) { + # This has to be a built-time error rather than a GN assert because many + # packages have a mix of java and non-java targets. For example, the + # following would fail even though nothing depends on :bar(//baz): + # + # shared_library("foo") { + # } + # + # android_library("bar") { + # deps = [ ":foo(//baz)" ] + # assert(current_toolchain == default_toolchain) + # } + _msg = [ + "Tried to build an Android target in a non-default toolchain.", + "target: " + get_label_info(":$target_name", "label_with_toolchain"), + "default_toolchain: $default_toolchain", + ] + args += [ "--fail=$_msg" ] + } + } +} + +template("copy_ex") { + set_sources_assignment_filter([]) + action(target_name) { + forward_variables_from(invoker, + [ + "data", + "deps", + "inputs", + "sources", + "testonly", + "visibility", + ]) + if (!defined(sources)) { + sources = [] + } + script = "//build/android/gyp/copy_ex.py" + depfile = "$target_gen_dir/$target_name.d" + + _stamp_file = "$target_gen_dir/$target_name.stamp" + outputs = [ + _stamp_file, + ] + + args = [ + "--depfile", + rebase_path(depfile, root_build_dir), + "--stamp", + rebase_path(_stamp_file, root_build_dir), + "--dest", + rebase_path(invoker.dest, root_build_dir), + ] + rebased_sources = rebase_path(sources, root_build_dir) + args += [ "--files=$rebased_sources" ] + + if (defined(invoker.clear_dir) && invoker.clear_dir) { + args += [ "--clear" ] + } + + if (defined(invoker.args)) { + args += invoker.args + } + + if (defined(invoker.renaming_sources) && + defined(invoker.renaming_destinations)) { + sources += invoker.renaming_sources + rebased_renaming_sources = + rebase_path(invoker.renaming_sources, root_build_dir) + args += [ "--renaming-sources=$rebased_renaming_sources" ] + + renaming_destinations = invoker.renaming_destinations + args += [ "--renaming-destinations=$renaming_destinations" ] + } + } +} + +# Generates a script in the build bin directory which runs the test +# target using the test runner script in build/android/test_runner.py. +template("test_runner_script") { + testonly = true + _test_name = invoker.test_name + _test_type = invoker.test_type + _incremental_install = + defined(invoker.incremental_install) && invoker.incremental_install + + _runtime_deps = + !defined(invoker.ignore_all_data_deps) || !invoker.ignore_all_data_deps + + if (_runtime_deps) { + # This runtime_deps file is used at runtime and thus cannot go in + # target_gen_dir. + _target_dir_name = get_label_info(":$target_name", "dir") + _runtime_deps_file = + "$root_out_dir/gen.runtime/$_target_dir_name/$target_name.runtime_deps" + _runtime_deps_target = "${target_name}__write_deps" + group(_runtime_deps_target) { + forward_variables_from(invoker, + [ + "data", + "data_deps", + "deps", + "public_deps", + ]) + write_runtime_deps = _runtime_deps_file + } + } + + action(target_name) { + forward_variables_from(invoker, + [ + "data_deps", + "deps", + ]) + if (!defined(deps)) { + deps = [] + } + if (!defined(data_deps)) { + data_deps = [] + } + + script = "//build/android/gyp/create_test_runner_script.py" + depfile = "$target_gen_dir/$target_name.d" + + data_deps += [ + "//build/android:test_runner_py", + "//build/android:logdog_wrapper_py", + ] + + data = [] + + test_runner_args = [ + _test_type, + "--output-directory", + rebase_path(root_build_dir, root_build_dir), + ] + + if (_runtime_deps) { + deps += [ ":$_runtime_deps_target" ] + data += [ _runtime_deps_file ] + test_runner_args += [ + "--runtime-deps-path", + rebase_path(_runtime_deps_file, root_build_dir), + ] + } + + # apk_target is not used for native executable tests + # (e.g. breakpad_unittests). + if (defined(invoker.apk_target)) { + assert(!defined(invoker.executable_dist_dir)) + deps += [ "${invoker.apk_target}__build_config" ] + _apk_build_config = + get_label_info(invoker.apk_target, "target_gen_dir") + "/" + + get_label_info(invoker.apk_target, "name") + ".build_config" + _rebased_apk_build_config = rebase_path(_apk_build_config, root_build_dir) + assert(_rebased_apk_build_config != "") # Mark as used. + } else if (_test_type == "gtest") { + assert( + defined(invoker.executable_dist_dir), + "Must define either apk_target or executable_dist_dir for test_runner_script()") + test_runner_args += [ + "--executable-dist-dir", + rebase_path(invoker.executable_dist_dir, root_build_dir), + ] + } + + _device_test = true + if (_test_type == "gtest") { + assert(defined(invoker.test_suite)) + test_runner_args += [ + "--suite", + invoker.test_suite, + ] + } else if (_test_type == "instrumentation") { + _test_apk = "@FileArg($_rebased_apk_build_config:deps_info:apk_path)" + if (_incremental_install) { + _test_apk = "@FileArg($_rebased_apk_build_config:deps_info:incremental_apk_path)" + } + test_runner_args += [ + "--test-apk=$_test_apk", + "--test-jar", + rebase_path(invoker.test_jar, root_build_dir), + ] + if (defined(invoker.apk_under_test)) { + deps += [ "${invoker.apk_under_test}__build_config" ] + _apk_under_test_build_config = + get_label_info(invoker.apk_under_test, "target_gen_dir") + "/" + + get_label_info(invoker.apk_under_test, "name") + ".build_config" + _rebased_apk_under_test_build_config = + rebase_path(_apk_under_test_build_config, root_build_dir) + _apk_under_test = + "@FileArg($_rebased_apk_under_test_build_config:deps_info:apk_path)" + if (_incremental_install) { + _apk_under_test = "@FileArg($_rebased_apk_under_test_build_config:deps_info:incremental_apk_path)" + } + test_runner_args += [ "--apk-under-test=$_apk_under_test" ] + } + if (emma_coverage) { + # Set a default coverage output directory (can be overridden by user + # passing the same flag). + test_runner_args += [ + "--coverage-dir", + rebase_path("$root_out_dir/coverage", root_build_dir), + ] + } + } else if (_test_type == "junit") { + assert(defined(invoker.test_suite)) + _device_test = false + test_runner_args += [ + "--test-suite", + invoker.test_suite, + ] + if (defined(invoker.android_manifest_path)) { + test_runner_args += [ + "--android-manifest-path", + rebase_path(invoker.android_manifest_path, root_build_dir), + ] + } + + if (defined(invoker.package_name)) { + test_runner_args += [ + "--package-name", + invoker.package_name, + ] + + deps += [ ":${invoker.test_suite}__build_config" ] + _junit_binary_build_config = + "${target_gen_dir}/${invoker.test_suite}.build_config" + _rebased_build_config = + rebase_path("$_junit_binary_build_config", root_build_dir) + test_runner_args += [ + "--resource-zips", + "@FileArg($_rebased_build_config:resources:dependency_zips)", + ] + } + + test_runner_args += [ + "--robolectric-runtime-deps-dir", + rebase_path("$root_build_dir/lib.java/third_party/robolectric", + root_build_dir), + ] + } else if (_test_type == "linker") { + test_runner_args += [ + "--test-apk", + "@FileArg($_rebased_apk_build_config:deps_info:apk_path)", + ] + } else { + assert(false, "Invalid test type: $_test_type.") + } + + if (defined(invoker.additional_apks)) { + foreach(additional_apk, invoker.additional_apks) { + deps += [ "${additional_apk}__build_config" ] + _build_config = get_label_info(additional_apk, "target_gen_dir") + "/" + + get_label_info(additional_apk, "name") + ".build_config" + _rebased_build_config = rebase_path(_build_config, root_build_dir) + test_runner_args += [ + "--additional-apk", + "@FileArg($_rebased_build_config:deps_info:apk_path)", + "--additional-apk-incremental", + "@FileArg($_rebased_build_config:deps_info:incremental_apk_path)", + ] + } + } + if (defined(invoker.shard_timeout)) { + test_runner_args += [ "--shard-timeout=${invoker.shard_timeout}" ] + } + if (_incremental_install) { + test_runner_args += [ + "--test-apk-incremental-install-script", + "@FileArg($_rebased_apk_build_config:deps_info:incremental_install_script_path)", + ] + if (defined(invoker.apk_under_test)) { + test_runner_args += [ + "--apk-under-test-incremental-install-script", + "@FileArg($_rebased_apk_under_test_build_config:deps_info:incremental_install_script_path)", + ] + } + test_runner_args += [ "--fast-local-dev" ] + } + if (_device_test && is_asan) { + test_runner_args += [ "--tool=asan" ] + } + + if (defined(invoker.generated_script)) { + assert(_test_name != "" || true) # Mark _test_name as used. + generated_script = invoker.generated_script + } else { + generated_script = "$root_build_dir/bin/run_${_test_name}" + } + outputs = [ + generated_script, + ] + data += [ generated_script ] + + args = [ + "--depfile", + rebase_path(depfile, root_build_dir), + "--script-output-path", + rebase_path(generated_script, root_build_dir), + ] + if (defined(android_test_runner_script)) { + args += [ + "--test-runner-path", + android_test_runner_script, + ] + } + + args += test_runner_args + } +} + +template("stack_script") { + forward_variables_from(invoker, [ "testonly" ]) + + _stack_target_name = invoker.stack_target_name + + action(target_name) { + forward_variables_from(invoker, + [ + "data_deps", + "deps", + ]) + if (!defined(deps)) { + deps = [] + } + if (!defined(data_deps)) { + data_deps = [] + } + + data_deps += + [ "//third_party/android_platform/development/scripts:stack_py" ] + + script = "//build/android/gyp/create_stack_script.py" + depfile = "$target_gen_dir/$target_name.d" + + _stack_script = "//third_party/android_platform/development/scripts/stack" + + _generated_script = "$root_build_dir/bin/stack_${_stack_target_name}" + + outputs = [ + _generated_script, + ] + data = [ + _generated_script, + ] + + args = [ + "--depfile", + rebase_path(depfile, root_build_dir), + "--output-directory", + rebase_path(root_build_dir, root_build_dir), + "--script-path", + rebase_path(_stack_script, root_build_dir), + "--script-output-path", + rebase_path(_generated_script, root_build_dir), + "--arch=$target_cpu", + ] + if (defined(invoker.packed_libraries)) { + args += [ + "--packed-libs", + invoker.packed_libraries, + ] + } + } +} + +if (enable_java_templates) { + import("//build/config/zip.gni") + import("//third_party/ijar/ijar.gni") + import("//third_party/android_platform/config.gni") + + rebased_android_sdk = rebase_path(android_sdk, root_build_dir) + rebased_android_sdk_build_tools = + rebase_path(android_sdk_build_tools, root_build_dir) + + android_sdk_jar = "$android_sdk/android.jar" + rebased_android_sdk_jar = rebase_path(android_sdk_jar, root_build_dir) + android_default_aapt_path = "$rebased_android_sdk_build_tools/aapt" + + android_configuration_name = "Release" + if (is_debug) { + android_configuration_name = "Debug" + } + + template("android_lint") { + action(target_name) { + forward_variables_from(invoker, + [ + "deps", + "data_deps", + "public_deps", + "testonly", + ]) + if (!defined(deps)) { + deps = [] + } + + if (!defined(lint_suppressions_file)) { + lint_suppressions_file = "//build/android/lint/suppressions.xml" + } + + _cache_dir = "$root_build_dir/android_lint_cache" + _result_path = "$target_gen_dir/$target_name/result.xml" + _config_path = "$target_gen_dir/$target_name/config.xml" + _suppressions_file = lint_suppressions_file + _platform_xml_path = + "${android_sdk_root}/platform-tools/api/api-versions.xml" + _rebased_lint_android_sdk_root = + rebase_path(lint_android_sdk_root, root_build_dir) + + script = "//build/android/gyp/lint.py" + depfile = "$target_gen_dir/$target_name.d" + inputs = [ + _platform_xml_path, + _suppressions_file, + invoker.android_manifest, + ] + + outputs = [ + _result_path, + _config_path, + ] + + args = [ + "--lint-path=$_rebased_lint_android_sdk_root/tools-lint/bin/lint", + "--cache-dir", + rebase_path(_cache_dir, root_build_dir), + "--platform-xml-path", + rebase_path(_platform_xml_path, root_build_dir), + "--android-sdk-version=${lint_android_sdk_version}", + "--depfile", + rebase_path(depfile, root_build_dir), + "--config-path", + rebase_path(_suppressions_file, root_build_dir), + "--manifest-path", + rebase_path(invoker.android_manifest, root_build_dir), + "--product-dir=.", + "--processed-config-path", + rebase_path(_config_path, root_build_dir), + "--result-path", + rebase_path(_result_path, root_build_dir), + ] + + if (defined(invoker.disable)) { + args += [ "--disable=${invoker.disable}" ] + } + + if (defined(invoker.create_cache) && invoker.create_cache) { + args += [ + "--create-cache", + "--silent", + ] + } else { + inputs += invoker.java_files + inputs += [ + invoker.jar_path, + invoker.build_config, + ] + if (invoker.java_files != []) { + inputs += [ invoker.java_sources_file ] + _rebased_java_sources_file = + rebase_path(invoker.java_sources_file, root_build_dir) + args += [ "--java-sources-file=$_rebased_java_sources_file" ] + } + deps += [ "//build/android:prepare_android_lint_cache" ] + + _rebased_build_config = + rebase_path(invoker.build_config, root_build_dir) + args += [ + "--jar-path", + rebase_path(invoker.jar_path, root_build_dir), + "--classpath=@FileArg($_rebased_build_config:javac:interface_classpath)", + "--resource-sources=@FileArg($_rebased_build_config:deps_info:owned_resources_dirs)", + "--resource-sources=@FileArg($_rebased_build_config:deps_info:owned_resources_zips)", + "--can-fail-build", + ] + } + } + } + + template("proguard") { + action(target_name) { + set_sources_assignment_filter([]) + forward_variables_from(invoker, + [ + "deps", + "data_deps", + "public_deps", + "testonly", + ]) + script = "//build/android/gyp/proguard.py" + if (defined(invoker.proguard_jar_path)) { + _proguard_jar_path = invoker.proguard_jar_path + } else { + _proguard_jar_path = _default_proguard_jar_path + } + _output_jar_path = invoker.output_jar_path + inputs = [ + _proguard_jar_path, + ] + if (defined(invoker.alternative_android_sdk_jar)) { + inputs += [ invoker.alternative_android_sdk_jar ] + _rebased_android_sdk_jar = + rebase_path(invoker.alternative_android_sdk_jar) + } else { + inputs += [ android_sdk_jar ] + _rebased_android_sdk_jar = rebased_android_sdk_jar + } + if (defined(invoker.inputs)) { + inputs += invoker.inputs + } + depfile = "${target_gen_dir}/${target_name}.d" + outputs = [ + _output_jar_path, + "$_output_jar_path.flags", + "$_output_jar_path.mapping", + "$_output_jar_path.seeds", + "$_output_jar_path.usage", + ] + args = [ + "--depfile", + rebase_path(depfile, root_build_dir), + "--proguard-path", + rebase_path(_proguard_jar_path, root_build_dir), + "--output-path", + rebase_path(_output_jar_path, root_build_dir), + "--classpath", + _rebased_android_sdk_jar, + ] + if (proguard_verbose) { + args += [ "--verbose" ] + } + if (defined(invoker.args)) { + args += invoker.args + } + if (defined(invoker.proguard_jar_path)) { + # We assume that if we are using a different ProGuard, this new version + # can handle the 'dangerous' optimizaions. + args += [ "--enable-dangerous-optimizations" ] + } + } + } + + template("findbugs") { + action(target_name) { + forward_variables_from(invoker, + [ + "deps", + "testonly", + ]) + script = "//build/android/findbugs_diff.py" + depfile = "$target_gen_dir/$target_name.d" + _result_path = "$target_gen_dir/$target_name/result.xml" + _exclusions_file = "//build/android/findbugs_filter/findbugs_exclude.xml" + + _rebased_build_config = rebase_path(invoker.build_config, root_build_dir) + + inputs = [ + "//build/android/pylib/utils/findbugs.py", + _exclusions_file, + invoker.jar_path, + invoker.build_config, + ] + + outputs = [ + _result_path, + ] + + args = [ + "--depfile", + rebase_path(depfile, root_build_dir), + "--exclude", + rebase_path(_exclusions_file, root_build_dir), + "--auxclasspath-gyp", + "@FileArg($_rebased_build_config:javac:classpath)", + "--output-file", + rebase_path(_result_path, root_build_dir), + rebase_path(invoker.jar_path, root_build_dir), + ] + + if (findbugs_verbose) { + args += [ "-vv" ] + } + } + } + + # Generates a script in the build bin directory to run a java binary. + # + # Variables + # main_class: The class containing the program entry point. + # jar_path: The path to the jar to run. + # script_name: Name of the script to generate. + # build_config: Path to .build_config for the jar (contains classpath). + # wrapper_script_args: List of extra arguments to pass to the executable. + # + template("java_binary_script") { + set_sources_assignment_filter([]) + forward_variables_from(invoker, [ "testonly" ]) + + _main_class = invoker.main_class + _build_config = invoker.build_config + _jar_path = invoker.jar_path + _script_name = invoker.script_name + + action(target_name) { + script = "//build/android/gyp/create_java_binary_script.py" + depfile = "$target_gen_dir/$_script_name.d" + java_script = "$root_build_dir/bin/$_script_name" + inputs = [ + _build_config, + ] + outputs = [ + java_script, + ] + forward_variables_from(invoker, [ "deps" ]) + _rebased_build_config = rebase_path(_build_config, root_build_dir) + args = [ + "--depfile", + rebase_path(depfile, root_build_dir), + "--output", + rebase_path(java_script, root_build_dir), + "--classpath=@FileArg($_rebased_build_config:deps_info:java:full_classpath)", + "--jar-path", + rebase_path(_jar_path, root_build_dir), + "--main-class", + _main_class, + ] + if (emma_coverage) { + args += [ + "--classpath", + rebase_path("//third_party/android_tools/sdk/tools/lib/emma.jar", + root_build_dir), + ] + args += [ "--noverify" ] + } + if (defined(invoker.wrapper_script_args)) { + args += [ "--" ] + invoker.wrapper_script_args + } + if (defined(invoker.bootclasspath)) { + args += [ + "--bootclasspath", + rebase_path(invoker.bootclasspath, root_build_dir), + ] + } + } + } + + template("dex") { + set_sources_assignment_filter([]) + + _enable_multidex = + defined(invoker.enable_multidex) && invoker.enable_multidex + + if (_enable_multidex) { + _main_dex_list_path = invoker.output + ".main_dex_list" + _main_dex_list_target_name = "${target_name}__main_dex_list" + action(_main_dex_list_target_name) { + forward_variables_from(invoker, + [ + "deps", + "inputs", + "sources", + "testonly", + ]) + + script = "//build/android/gyp/main_dex_list.py" + depfile = "$target_gen_dir/$target_name.d" + + main_dex_rules = "//build/android/main_dex_classes.flags" + + if (defined(invoker.proguard_jar_path)) { + _proguard_jar_path = invoker.proguard_jar_path + } else { + _proguard_jar_path = _default_proguard_jar_path + } + + if (!defined(inputs)) { + inputs = [] + } + inputs += [ + main_dex_rules, + _proguard_jar_path, + ] + + outputs = [ + _main_dex_list_path, + ] + + args = [ + "--depfile", + rebase_path(depfile, root_build_dir), + "--android-sdk-tools", + rebased_android_sdk_build_tools, + "--main-dex-list-path", + rebase_path(_main_dex_list_path, root_build_dir), + "--main-dex-rules-path", + rebase_path(main_dex_rules, root_build_dir), + "--proguard-path", + rebase_path(_proguard_jar_path, root_build_dir), + ] + + if (defined(invoker.extra_main_dex_proguard_config)) { + inputs += [ invoker.extra_main_dex_proguard_config ] + args += [ + "--main-dex-rules-path", + rebase_path(invoker.extra_main_dex_proguard_config, root_build_dir), + ] + } + + if (defined(invoker.args)) { + args += invoker.args + } + + if (defined(invoker.sources)) { + args += rebase_path(invoker.sources, root_build_dir) + } + } + } + + assert(defined(invoker.output)) + action(target_name) { + forward_variables_from(invoker, + [ + "deps", + "inputs", + "sources", + "testonly", + ]) + script = "//build/android/gyp/dex.py" + depfile = "$target_gen_dir/$target_name.d" + outputs = [ + invoker.output, + ] + + rebased_output = rebase_path(invoker.output, root_build_dir) + + args = [ + "--depfile", + rebase_path(depfile, root_build_dir), + "--android-sdk-tools", + rebased_android_sdk_build_tools, + "--dex-path", + rebased_output, + ] + + if (enable_incremental_dx) { + args += [ "--incremental" ] + } + + # EMMA requires --no-locals. + if (emma_coverage) { + args += [ "--no-locals=1" ] + } + + if (_enable_multidex) { + args += [ + "--multi-dex", + "--main-dex-list-path", + rebase_path(_main_dex_list_path, root_build_dir), + ] + deps += [ ":${_main_dex_list_target_name}" ] + inputs += [ _main_dex_list_path ] + } + + if (defined(invoker.args)) { + args += invoker.args + } + + if (defined(invoker.sources)) { + args += rebase_path(invoker.sources, root_build_dir) + } + } + } + + template("process_java_prebuilt") { + set_sources_assignment_filter([]) + forward_variables_from(invoker, [ "testonly" ]) + + assert(invoker.build_config != "") + _build_config = invoker.build_config + _rebased_build_config = rebase_path(_build_config, root_build_dir) + assert(_rebased_build_config != "" || true) # Mark used. + + _input_jar_path = invoker.input_jar_path + _output_jar_path = invoker.output_jar_path + + _jar_excluded_patterns = [] + if (defined(invoker.jar_excluded_patterns)) { + _jar_excluded_patterns = invoker.jar_excluded_patterns + } + _strip_resource_classes = defined(invoker.strip_resource_classes) && + invoker.strip_resource_classes + _filter_jar = _jar_excluded_patterns != [] || _strip_resource_classes + + _enable_assert = + defined(invoker.supports_android) && invoker.supports_android && + (is_java_debug || dcheck_always_on) + + _retrolambda = defined(invoker.supports_android) && + invoker.supports_android && use_java8 + + _deps = [] + _previous_output_jar = _input_jar_path + + if (_filter_jar) { + _filter_target = "${target_name}__filter" + _filter_input_jar = _previous_output_jar + _filter_output_jar = "$target_out_dir/$target_name-filtered.jar" + + action(_filter_target) { + script = "//build/android/gyp/jar.py" + deps = _deps + if (defined(invoker.deps)) { + deps += invoker.deps + } + if (defined(invoker.public_deps)) { + public_deps = invoker.public_deps + } + inputs = [ + _build_config, + _filter_input_jar, + ] + outputs = [ + _filter_output_jar, + ] + args = [ + "--input-jar", + rebase_path(_filter_input_jar, root_build_dir), + "--jar-path", + rebase_path(_filter_output_jar, root_build_dir), + "--excluded-classes=$_jar_excluded_patterns", + ] + if (_strip_resource_classes) { + args += [ "--strip-resource-classes-for=@FileArg($_rebased_build_config:javac:resource_packages)" ] + } + } + + _deps = [] + _deps = [ ":$_filter_target" ] + _previous_output_jar = _filter_output_jar + } + + if (_enable_assert) { + _assert_target = "${target_name}__assert" + _assert_input_jar = _previous_output_jar + _assert_output_jar = "$target_out_dir/$target_name-asserted.jar" + + action(_assert_target) { + script = "$root_build_dir/bin/helper/java_assertion_enabler" + deps = [ + "//build/android/java_assertion_enabler($default_toolchain)", + ] + deps += _deps + if (defined(invoker.deps)) { + deps += invoker.deps + } + if (defined(invoker.public_deps)) { + public_deps = invoker.public_deps + } + inputs = [ + _assert_input_jar, + ] + outputs = [ + _assert_output_jar, + ] + args = [ + rebase_path(_assert_input_jar, root_build_dir), + rebase_path(_assert_output_jar, root_build_dir), + ] + } + + _deps = [] + _deps = [ ":$_assert_target" ] + _previous_output_jar = _assert_output_jar + } + + if (_retrolambda) { + _retrolambda_target = "${target_name}__retrolambda" + _retrolambda_input_jar = _previous_output_jar + _retrolambda_output_jar = "$target_out_dir/$target_name-retrolambda.jar" + + android_sdk_jar = "$android_sdk/android.jar" + action(_retrolambda_target) { + script = "//build/android/gyp/retrolambda.py" + deps = _deps + if (defined(invoker.deps)) { + deps += invoker.deps + } + if (defined(invoker.public_deps)) { + public_deps = invoker.public_deps + } + inputs = [ + _build_config, + _retrolambda_input_jar, + ] + outputs = [ + _retrolambda_output_jar, + ] + args = [ + "--input-jar", + rebase_path(_retrolambda_input_jar, root_build_dir), + "--output-jar", + rebase_path(_retrolambda_output_jar, root_build_dir), + "--classpath=@FileArg($_rebased_build_config:javac:classpath)", + "--android-sdk-jar", + rebase_path(android_sdk_jar, root_build_dir), + ] + } + + _deps = [] + _deps = [ ":$_retrolambda_target" ] + _previous_output_jar = _retrolambda_output_jar + } + + _output_jar_target = "${target_name}__copy" + copy(_output_jar_target) { + deps = _deps + if (defined(invoker.deps)) { + deps += invoker.deps + } + if (defined(invoker.public_deps)) { + public_deps = invoker.public_deps + } + sources = [ + _previous_output_jar, + ] + outputs = [ + _output_jar_path, + ] + } + + group(target_name) { + forward_variables_from(invoker, + [ + "data_deps", + "visibility", + ]) + public_deps = [ + ":$_output_jar_target", + ] + } + } + + template("emma_instr") { + action(target_name) { + forward_variables_from(invoker, + [ + "deps", + "testonly", + ]) + + _coverage_file = "$target_out_dir/${target_name}.em" + _source_dirs_listing_file = "$target_out_dir/${target_name}_sources.txt" + _emma_jar = "${android_sdk_root}/tools/lib/emma.jar" + + script = "//build/android/gyp/emma_instr.py" + depfile = "${target_gen_dir}/${target_name}.d" + inputs = invoker.java_files + [ + _emma_jar, + invoker.input_jar_path, + ] + outputs = [ + _coverage_file, + _source_dirs_listing_file, + invoker.output_jar_path, + ] + args = [ + "instrument_jar", + "--input-path", + rebase_path(invoker.input_jar_path, root_build_dir), + "--output-path", + rebase_path(invoker.output_jar_path, root_build_dir), + "--depfile", + rebase_path(depfile, root_build_dir), + "--coverage-file", + rebase_path(_coverage_file, root_build_dir), + "--sources-list-file", + rebase_path(_source_dirs_listing_file, root_build_dir), + "--src-root", + rebase_path("//", root_build_dir), + "--emma-jar", + rebase_path(_emma_jar, root_build_dir), + ] + _rebased_java_sources_file = + rebase_path(invoker.java_sources_file, root_build_dir) + args += [ "--java-sources-file=$_rebased_java_sources_file" ] + + if (emma_filter != "") { + args += [ + "--filter-string", + emma_filter, + ] + } + } + } + + # Creates an unsigned .apk. + # + # Variables + # assets_build_config: Path to android_apk .build_config containing merged + # asset information. + # deps: Specifies the dependencies of this target. + # dex_path: Path to classes.dex file to include (optional). + # resource_packaged_apk_path: Path to .ap_ to use. + # output_apk_path: Output path for the generated .apk. + # native_lib_placeholders: List of placeholder filenames to add to the apk + # (optional). + # native_libs: List of native libraries. + # native_libs_filearg: @FileArg() of additionaly native libraries. + # write_asset_list: Adds an extra file to the assets, which contains a list of + # all other asset files. + template("package_apk") { + action(target_name) { + forward_variables_from(invoker, + [ + "deps", + "public_deps", + "testonly", + ]) + _native_lib_placeholders = [] + if (defined(invoker.native_lib_placeholders)) { + _native_lib_placeholders = invoker.native_lib_placeholders + } + + script = "//build/android/gyp/apkbuilder.py" + depfile = "$target_gen_dir/$target_name.d" + data_deps = [ + "//tools/android/md5sum", + ] # Used when deploying APKs + + inputs = invoker.native_libs + [ invoker.resource_packaged_apk_path ] + if (defined(invoker.dex_path)) { + inputs += [ invoker.dex_path ] + } + + outputs = [ + invoker.output_apk_path, + ] + + _rebased_resource_packaged_apk_path = + rebase_path(invoker.resource_packaged_apk_path, root_build_dir) + _rebased_packaged_apk_path = + rebase_path(invoker.output_apk_path, root_build_dir) + args = [ + "--depfile", + rebase_path(depfile, root_build_dir), + "--resource-apk=$_rebased_resource_packaged_apk_path", + "--output-apk=$_rebased_packaged_apk_path", + ] + if (defined(invoker.assets_build_config)) { + inputs += [ invoker.assets_build_config ] + _rebased_build_config = + rebase_path(invoker.assets_build_config, root_build_dir) + args += [ + "--assets=@FileArg($_rebased_build_config:assets)", + "--uncompressed-assets=@FileArg($_rebased_build_config:uncompressed_assets)", + ] + + # TODO(mlopatkin) We are relying on the fact that assets_build_config is + # an APK build_config. + args += [ "--java-resources=@FileArg($_rebased_build_config:java_resources_jars)" ] + } + if (defined(invoker.write_asset_list) && invoker.write_asset_list) { + args += [ "--write-asset-list" ] + } + if (defined(invoker.dex_path)) { + _rebased_dex_path = rebase_path(invoker.dex_path, root_build_dir) + args += [ "--dex-file=$_rebased_dex_path" ] + } + if (invoker.native_libs != [] || defined(invoker.native_libs_filearg) || + _native_lib_placeholders != []) { + args += [ "--android-abi=$android_app_abi" ] + } + if (invoker.native_libs != []) { + _rebased_native_libs = rebase_path(invoker.native_libs, root_build_dir) + args += [ "--native-libs=$_rebased_native_libs" ] + } + if (defined(invoker.native_libs_filearg)) { + args += [ "--native-libs=${invoker.native_libs_filearg}" ] + } + if (_native_lib_placeholders != []) { + args += [ "--native-lib-placeholders=$_native_lib_placeholders" ] + } + + # TODO (michaelbai): Remove the secondary_native_libs variable. + if (defined(invoker.secondary_abi_native_libs_filearg)) { + assert(defined(android_app_secondary_abi)) + args += [ + "--secondary-native-libs=${invoker.secondary_abi_native_libs_filearg}", + "--secondary-android-abi=$android_app_secondary_abi", + ] + } else if (defined(invoker.secondary_native_libs) && + invoker.secondary_native_libs != []) { + assert(defined(android_app_secondary_abi)) + inputs += invoker.secondary_native_libs + _secondary_native_libs = rebase_path(invoker.secondary_native_libs) + args += [ + "--secondary-native-libs=$_secondary_native_libs", + "--secondary-android-abi=$android_app_secondary_abi", + ] + } + + if (defined(invoker.uncompress_shared_libraries) && + invoker.uncompress_shared_libraries) { + args += [ "--uncompress-shared-libraries" ] + } + } + } + + # Signs & zipaligns an apk. + # + # Variables + # input_apk_path: Path of the .apk to be finalized. + # output_apk_path: Output path for the generated .apk. + # keystore_path: Path to keystore to use for signing. + # keystore_name: Key alias to use. + # keystore_password: Keystore password. + template("finalize_apk") { + action(target_name) { + deps = [] + script = "//build/android/gyp/finalize_apk.py" + depfile = "$target_gen_dir/$target_name.d" + forward_variables_from(invoker, + [ + "deps", + "data_deps", + "public_deps", + "testonly", + ]) + + sources = [ + invoker.input_apk_path, + ] + inputs = [ + invoker.keystore_path, + ] + outputs = [ + invoker.output_apk_path, + ] + data = [ + invoker.output_apk_path, + ] + + args = [ + "--depfile", + rebase_path(depfile, root_build_dir), + "--zipalign-path", + rebase_path(zipalign_path, root_build_dir), + "--unsigned-apk-path", + rebase_path(invoker.input_apk_path, root_build_dir), + "--final-apk-path", + rebase_path(invoker.output_apk_path, root_build_dir), + "--key-path", + rebase_path(invoker.keystore_path, root_build_dir), + "--key-name", + invoker.keystore_name, + "--key-passwd", + invoker.keystore_password, + ] + } + } + + # Packages resources, assets, dex, and native libraries into an apk. Signs and + # zipaligns the apk. + template("create_apk") { + set_sources_assignment_filter([]) + forward_variables_from(invoker, [ "testonly" ]) + + _android_manifest = invoker.android_manifest + _base_path = invoker.base_path + _final_apk_path = invoker.apk_path + _incremental_final_apk_path_helper = + process_file_template( + [ _final_apk_path ], + "{{source_dir}}/{{source_name_part}}_incremental.apk") + _incremental_final_apk_path = _incremental_final_apk_path_helper[0] + + if (defined(invoker.resources_zip)) { + _resources_zip = invoker.resources_zip + assert(_resources_zip != "") # Mark as used. + } + if (defined(invoker.dex_path)) { + _dex_path = invoker.dex_path + } + _load_library_from_apk = invoker.load_library_from_apk + + _deps = [] + if (defined(invoker.deps)) { + _deps = invoker.deps + } + _incremental_deps = [] + if (defined(invoker.incremental_deps)) { + _incremental_deps = invoker.incremental_deps + } + _native_libs = [] + if (defined(invoker.native_libs)) { + _native_libs = invoker.native_libs + } + _native_libs_even_when_incremental = [] + if (defined(invoker.native_libs_even_when_incremental)) { + _native_libs_even_when_incremental = + invoker.native_libs_even_when_incremental + } + + _version_code = invoker.version_code + _version_name = invoker.version_name + assert(_version_code != -1) # Mark as used. + assert(_version_name != "") # Mark as used. + + _base_apk_path = _base_path + ".apk_intermediates" + + _resource_packaged_apk_path = _base_apk_path + ".ap_" + _incremental_resource_packaged_apk_path = + _base_apk_path + "_incremental.ap_" + _packaged_apk_path = _base_apk_path + ".unfinished.apk" + _incremental_packaged_apk_path = + _base_apk_path + "_incremental.unfinished.apk" + _shared_resources = + defined(invoker.shared_resources) && invoker.shared_resources + assert(_shared_resources || true) # Mark as used. + _app_as_shared_lib = + defined(invoker.app_as_shared_lib) && invoker.app_as_shared_lib + assert(_app_as_shared_lib || true) # Mark as used. + assert(!(_shared_resources && _app_as_shared_lib)) + + _keystore_path = invoker.keystore_path + _keystore_name = invoker.keystore_name + _keystore_password = invoker.keystore_password + + _split_densities = [] + if (defined(invoker.create_density_splits) && + invoker.create_density_splits) { + _split_densities = [ + "hdpi", + "xhdpi", + "xxhdpi", + "xxxhdpi", + "tvdpi", + ] + } + + _split_languages = [] + if (defined(invoker.language_splits)) { + _split_languages = invoker.language_splits + } + + template("package_resources_helper") { + action(target_name) { + deps = invoker.deps + + script = "//build/android/gyp/package_resources.py" + depfile = "${target_gen_dir}/${target_name}.d" + inputs = [ + invoker.android_manifest, + ] + if (defined(_resources_zip)) { + inputs += [ _resources_zip ] + } + outputs = [ + invoker.resource_packaged_apk_path, + ] + + if (defined(invoker.android_aapt_path)) { + _android_aapt_path = invoker.android_aapt_path + } else { + _android_aapt_path = android_default_aapt_path + } + + if (defined(invoker.alternative_android_sdk_jar)) { + _rebased_android_sdk_jar = + rebase_path(invoker.alternative_android_sdk_jar) + } else { + _rebased_android_sdk_jar = rebased_android_sdk_jar + } + + args = [ + "--depfile", + rebase_path(depfile, root_build_dir), + "--android-sdk-jar", + _rebased_android_sdk_jar, + "--aapt-path", + _android_aapt_path, + "--configuration-name=$android_configuration_name", + "--android-manifest", + rebase_path(invoker.android_manifest, root_build_dir), + "--version-code", + _version_code, + "--version-name", + _version_name, + "--apk-path", + rebase_path(invoker.resource_packaged_apk_path, root_build_dir), + ] + + if (defined(_resources_zip)) { + args += [ + "--resource-zips", + rebase_path(_resources_zip, root_build_dir), + ] + } + if (_shared_resources) { + args += [ "--shared-resources" ] + } + if (_app_as_shared_lib) { + args += [ "--app-as-shared-lib" ] + } + if (_split_densities != []) { + args += [ "--create-density-splits" ] + foreach(_density, _split_densities) { + outputs += [ "${invoker.resource_packaged_apk_path}_${_density}" ] + } + } + if (_split_languages != []) { + args += [ "--language-splits=$_split_languages" ] + foreach(_language, _split_languages) { + outputs += [ "${invoker.resource_packaged_apk_path}_${_language}" ] + } + } + if (defined(invoker.aapt_locale_whitelist)) { + args += [ "--locale-whitelist=${invoker.aapt_locale_whitelist}" ] + } + if (defined(invoker.extensions_to_not_compress)) { + args += [ + "--no-compress", + invoker.extensions_to_not_compress, + ] + } + } + } + + _package_resources_target_name = "${target_name}__package_resources" + package_resources_helper(_package_resources_target_name) { + forward_variables_from(invoker, + [ + "aapt_locale_whitelist", + "alternative_android_sdk_jar", + "android_aapt_path", + "extensions_to_not_compress", + ]) + deps = _deps + android_manifest = _android_manifest + resource_packaged_apk_path = _resource_packaged_apk_path + } + + _generate_incremental_manifest_target_name = + "${target_name}_incremental_generate_manifest" + _incremental_android_manifest = + get_label_info(_generate_incremental_manifest_target_name, + "target_gen_dir") + "/AndroidManifest.xml" + action(_generate_incremental_manifest_target_name) { + deps = _incremental_deps + script = + "//build/android/incremental_install/generate_android_manifest.py" + depfile = "${target_gen_dir}/${target_name}.d" + inputs = [ + _android_manifest, + ] + outputs = [ + _incremental_android_manifest, + ] + + _rebased_src_manifest = rebase_path(_android_manifest, root_build_dir) + _rebased_incremental_manifest = + rebase_path(_incremental_android_manifest, root_build_dir) + _rebased_depfile = rebase_path(depfile, root_build_dir) + args = [ + "--src-manifest=$_rebased_src_manifest", + "--out-manifest=$_rebased_incremental_manifest", + "--depfile=$_rebased_depfile", + ] + if (disable_incremental_isolated_processes) { + args += [ "--disable-isolated-processes" ] + } + } + + _incremental_package_resources_target_name = + "${target_name}_incremental__package_resources" + + # TODO(agrieve): See if we can speed up this step by swapping the manifest + # from the result of the main package_resources step. + package_resources_helper(_incremental_package_resources_target_name) { + forward_variables_from(invoker, + [ + "aapt_locale_whitelist", + "alternative_android_sdk_jar", + "android_aapt_path", + "extensions_to_not_compress", + ]) + deps = + _incremental_deps + [ ":$_generate_incremental_manifest_target_name" ] + android_manifest = _incremental_android_manifest + resource_packaged_apk_path = _incremental_resource_packaged_apk_path + } + + package_target = "${target_name}__package" + package_apk(package_target) { + forward_variables_from(invoker, + [ + "assets_build_config", + "native_lib_placeholders", + "native_libs_filearg", + "secondary_abi_native_libs_filearg", + "secondary_native_libs", + "uncompress_shared_libraries", + "write_asset_list", + ]) + if (!defined(uncompress_shared_libraries)) { + uncompress_shared_libraries = _load_library_from_apk + } + deps = _deps + [ ":${_package_resources_target_name}" ] + native_libs = _native_libs + _native_libs_even_when_incremental + + if (defined(_dex_path)) { + dex_path = _dex_path + } + + output_apk_path = _packaged_apk_path + resource_packaged_apk_path = _resource_packaged_apk_path + } + + _incremental_package_target = "${target_name}_incremental__package" + package_apk(_incremental_package_target) { + forward_variables_from(invoker, + [ + "assets_build_config", + "secondary_native_libs", + "uncompress_shared_libraries", + ]) + if (!defined(uncompress_shared_libraries)) { + uncompress_shared_libraries = _load_library_from_apk + } + _dex_target = "//build/android/incremental_install:bootstrap_java__dex" + deps = _incremental_deps + [ + ":${_incremental_package_resources_target_name}", + _dex_target, + ] + + if (defined(_dex_path)) { + dex_path = + get_label_info(_dex_target, "target_gen_dir") + "/bootstrap.dex" + } + + native_libs = _native_libs_even_when_incremental + + # http://crbug.com/384638 + _has_native_libs = + defined(invoker.native_libs_filearg) || _native_libs != [] + if (_has_native_libs && _native_libs_even_when_incremental == []) { + native_lib_placeholders = [ "libfix.crbug.384638.so" ] + } + + output_apk_path = _incremental_packaged_apk_path + resource_packaged_apk_path = _incremental_resource_packaged_apk_path + } + + _finalize_apk_rule_name = "${target_name}__finalize" + finalize_apk(_finalize_apk_rule_name) { + input_apk_path = _packaged_apk_path + output_apk_path = _final_apk_path + keystore_path = _keystore_path + keystore_name = _keystore_name + keystore_password = _keystore_password + + public_deps = [ + # Generator of the _packaged_apk_path this target takes as input. + ":$package_target", + ] + } + + _incremental_finalize_apk_rule_name = "${target_name}_incremental__finalize" + finalize_apk(_incremental_finalize_apk_rule_name) { + input_apk_path = _incremental_packaged_apk_path + output_apk_path = _incremental_final_apk_path + keystore_path = _keystore_path + keystore_name = _keystore_name + keystore_password = _keystore_password + + public_deps = [ + ":$_incremental_package_target", + ] + } + + _split_deps = [] + + template("finalize_split") { + finalize_apk(target_name) { + _config = invoker.split_config + _type = invoker.split_type + input_apk_path = "${_resource_packaged_apk_path}_${_config}" + _output_paths = process_file_template( + [ _final_apk_path ], + "{{source_dir}}/{{source_name_part}}-${_type}-${_config}.apk") + output_apk_path = _output_paths[0] + keystore_path = _keystore_path + keystore_name = _keystore_name + keystore_password = _keystore_password + deps = [ + ":${_package_resources_target_name}", + ] + } + } + + foreach(_split, _split_densities) { + _split_rule = "${target_name}__finalize_${_split}_split" + finalize_split(_split_rule) { + split_type = "density" + split_config = _split + } + _split_deps += [ ":$_split_rule" ] + } + foreach(_split, _split_languages) { + _split_rule = "${target_name}__finalize_${_split}_split" + finalize_split(_split_rule) { + split_type = "lang" + split_config = _split + } + _split_deps += [ ":$_split_rule" ] + } + + group(target_name) { + public_deps = [ ":${_finalize_apk_rule_name}" ] + _split_deps + } + group("${target_name}_incremental") { + public_deps = [ ":${_incremental_finalize_apk_rule_name}" ] + _split_deps + } + } + + template("java_prebuilt_impl") { + set_sources_assignment_filter([]) + forward_variables_from(invoker, [ "testonly" ]) + _supports_android = + defined(invoker.supports_android) && invoker.supports_android + + assert(defined(invoker.jar_path)) + if (defined(invoker.output_name)) { + _output_name = invoker.output_name + } else { + _output_name = get_path_info(invoker.jar_path, "name") + } + _base_path = "${target_gen_dir}/$target_name" + + # Jar files can be needed at runtime (by Robolectric tests or java binaries), + # so do not put them under gen/. + _target_dir_name = get_label_info(":$target_name", "dir") + _jar_path = "$root_out_dir/lib.java$_target_dir_name/$_output_name.jar" + _ijar_path = + "$root_out_dir/lib.java$_target_dir_name/$_output_name.interface.jar" + _build_config = _base_path + ".build_config" + + if (_supports_android) { + _dex_path = _base_path + ".dex.jar" + } + _deps = [] + if (defined(invoker.deps)) { + _deps = invoker.deps + } + _jar_deps = [] + if (defined(invoker.jar_dep)) { + _jar_deps = [ invoker.jar_dep ] + } + + _template_name = target_name + + _build_config_target_name = "${_template_name}__build_config" + _process_jar_target_name = "${_template_name}__process_jar" + _ijar_target_name = "${_template_name}__ijar" + if (_supports_android) { + _dex_target_name = "${_template_name}__dex" + } + + write_build_config(_build_config_target_name) { + type = "java_prebuilt" + is_prebuilt_binary = defined(invoker.main_class) + forward_variables_from(invoker, + [ + "input_jars_paths", + "proguard_configs", + ]) + supports_android = _supports_android + requires_android = + defined(invoker.requires_android) && invoker.requires_android + + if (defined(invoker.deps)) { + possible_config_deps = _deps + } + build_config = _build_config + jar_path = _jar_path + if (_supports_android) { + dex_path = _dex_path + } + if (defined(invoker.include_java_resources) && + invoker.include_java_resources) { + # Use original jar_path because _jar_path points to a library without + # resources. + java_resources_jar = invoker.jar_path + } + } + + process_java_prebuilt(_process_jar_target_name) { + forward_variables_from(invoker, + [ + "jar_excluded_patterns", + "strip_resource_classes", + ]) + + visibility = [ + ":$_ijar_target_name", + ":$_template_name", + ] + if (_supports_android) { + visibility += [ ":$_dex_target_name" ] + } + + supports_android = _supports_android + build_config = _build_config + input_jar_path = invoker.jar_path + output_jar_path = _jar_path + + deps = [ ":$_build_config_target_name" ] + _deps + _jar_deps + } + + generate_interface_jar(_ijar_target_name) { + # Always used the unfiltered .jar to create the interface jar so that + # other targets will resolve filtered classes when depending on + # BuildConfig, NativeLibraries, etc. + input_jar = invoker.jar_path + deps = _deps + _jar_deps + output_jar = _ijar_path + } + + if (_supports_android) { + dex(_dex_target_name) { + sources = [ + _jar_path, + ] + output = _dex_path + deps = [ ":$_process_jar_target_name" ] + _deps + _jar_deps + } + } + + if (defined(invoker.main_class)) { + _binary_script_target_name = "${_template_name}__java_binary_script" + java_binary_script(_binary_script_target_name) { + forward_variables_from(invoker, + [ + "bootclasspath", + "deps", + "main_class", + "wrapper_script_args", + ]) + if (!defined(deps)) { + deps = [] + } + build_config = _build_config + jar_path = _jar_path + script_name = _template_name + if (defined(invoker.wrapper_script_name)) { + script_name = invoker.wrapper_script_name + } + deps += [ ":$_build_config_target_name" ] + } + } + + group(target_name) { + forward_variables_from(invoker, [ "data_deps" ]) + public_deps = [ + ":$_ijar_target_name", + ":$_process_jar_target_name", + ] + if (_supports_android) { + public_deps += [ ":$_dex_target_name" ] + } + if (defined(invoker.main_class)) { + # Some targets use the generated script while building, so make it a dep + # rather than a data_dep. + public_deps += [ ":$_binary_script_target_name" ] + } + } + } + + # Compiles and jars a set of java files. + # + # Outputs: + # $jar_path.jar + # $jar_path.interface.jar + # + # Variables + # java_files: List of .java files to compile (same as exists in java_sources_file) + # java_sources_file: Path to file containing list of files to compile. + # chromium_code: If true, enable extra warnings. + # srcjar_deps: List of srcjar dependencies. The .java files contained in the + # dependencies srcjar outputs will be compiled and added to the output jar. + # jar_path: Use this to explicitly set the output jar path. Defaults to + # "${target_gen_dir}/${target_name}.jar. + template("compile_java") { + set_sources_assignment_filter([]) + forward_variables_from(invoker, [ "testonly" ]) + + assert(defined(invoker.build_config)) + assert(defined(invoker.jar_path)) + + _build_config = invoker.build_config + + _chromium_code = false + if (defined(invoker.chromium_code)) { + _chromium_code = invoker.chromium_code + } + + _supports_android = true + if (defined(invoker.supports_android)) { + _supports_android = invoker.supports_android + } + + _requires_android = + defined(invoker.requires_android) && invoker.requires_android + + _enable_errorprone = use_errorprone_java_compiler + if (!_chromium_code) { + _enable_errorprone = false + } else if (defined(invoker.enable_errorprone)) { + _enable_errorprone = invoker.enable_errorprone + } + + _provider_configurations = [] + if (defined(invoker.provider_configurations)) { + _provider_configurations = invoker.provider_configurations + } + + _processors = [] + _enable_interface_jars_javac = true + if (defined(invoker.processors_javac)) { + _processors = invoker.processors_javac + _enable_interface_jars_javac = _processors == [] + } + + _processor_args = [] + if (defined(invoker.processor_args_javac)) { + _processor_args = invoker.processor_args_javac + } + + _additional_jar_files = [] + if (defined(invoker.additional_jar_files)) { + _additional_jar_files = invoker.additional_jar_files + } + + if (defined(invoker.enable_incremental_javac_override)) { + # Use invoker-specified override. + _enable_incremental_javac = invoker.enable_incremental_javac_override + } else { + # Default to build arg if not overridden. + _enable_incremental_javac = enable_incremental_javac + } + + _manifest_entries = [] + if (defined(invoker.manifest_entries)) { + _manifest_entries = invoker.manifest_entries + } + + _srcjar_deps = [] + if (defined(invoker.srcjar_deps)) { + _srcjar_deps += invoker.srcjar_deps + } + + _java_srcjars = [] + if (defined(invoker.srcjars)) { + _java_srcjars = invoker.srcjars + } + foreach(dep, _srcjar_deps) { + _dep_gen_dir = get_label_info(dep, "target_gen_dir") + _dep_name = get_label_info(dep, "name") + _java_srcjars += [ "$_dep_gen_dir/$_dep_name.srcjar" ] + } + + # Mark srcjar_deps as used. + assert(_srcjar_deps == [] || true) + + _javac_target_name = "${target_name}__javac" + _process_prebuilt_target_name = "${target_name}__process_prebuilt" + _ijar_target_name = "${target_name}__ijar" + _final_target_name = target_name + + _final_jar_path = invoker.jar_path + _javac_jar_path = "$target_gen_dir/$target_name.javac.jar" + _process_prebuilt_jar_path = _final_jar_path + _final_ijar_path = get_path_info(_final_jar_path, "dir") + "/" + + get_path_info(_final_jar_path, "name") + ".interface.jar" + + _emma_instrument = defined(invoker.emma_instrument) && + invoker.emma_instrument && invoker.java_files != [] + if (_emma_instrument) { + _emma_instr_target_name = "${target_name}__emma_instr" + _process_prebuilt_jar_path = + "$target_gen_dir/$target_name.process_prebuilt.jar" + } + + _rebased_build_config = rebase_path(_build_config, root_build_dir) + _rebased_jar_path = rebase_path(_javac_jar_path, root_build_dir) + + action(_javac_target_name) { + script = "//build/android/gyp/javac.py" + depfile = "$target_gen_dir/$target_name.d" + deps = _srcjar_deps + if (defined(invoker.deps)) { + deps += invoker.deps + } + + outputs = [ + _javac_jar_path, + _javac_jar_path + ".md5.stamp", + ] + sources = invoker.java_files + _java_srcjars + inputs = [ + _build_config, + ] + if (invoker.java_files != []) { + inputs += [ invoker.java_sources_file ] + } + + _rebased_java_srcjars = rebase_path(_java_srcjars, root_build_dir) + _rebased_depfile = rebase_path(depfile, root_build_dir) + args = [ + "--depfile=$_rebased_depfile", + "--jar-path=$_rebased_jar_path", + "--java-srcjars=$_rebased_java_srcjars", + "--java-srcjars=@FileArg($_rebased_build_config:javac:srcjars)", + ] + if (_enable_interface_jars_javac) { + args += [ "--classpath=@FileArg($_rebased_build_config:javac:interface_classpath)" ] + } else { + args += + [ "--classpath=@FileArg($_rebased_build_config:javac:classpath)" ] + } + if (_enable_incremental_javac) { + args += [ "--incremental" ] + deps += [ "//third_party/jmake($default_toolchain)" ] + inputs += [ "$root_build_dir/bin/jmake" ] + outputs += [ "${_javac_jar_path}.pdb" ] + } + if (_requires_android) { + if (defined(invoker.alternative_android_sdk_ijar)) { + deps += [ invoker.alternative_android_sdk_ijar_dep ] + _android_sdk_ijar = invoker.alternative_android_sdk_ijar + } else { + deps += [ "//build/android:android_ijar" ] + _android_sdk_ijar = "$root_out_dir/lib.java/android.interface.jar" + } + inputs += [ _android_sdk_ijar ] + _rebased_android_sdk_ijar = + rebase_path(_android_sdk_ijar, root_build_dir) + args += [ "--bootclasspath=$_rebased_android_sdk_ijar" ] + } + if (use_java8) { + args += [ "--java-version=1.8" ] + } else if (_supports_android) { + args += [ "--java-version=1.7" ] + } + foreach(e, _manifest_entries) { + args += [ "--manifest-entry=" + e ] + } + if (_chromium_code) { + args += [ "--chromium-code=1" ] + } + if (_enable_errorprone) { + deps += [ "//third_party/errorprone:chromium_errorprone" ] + args += [ + "--use-errorprone-path", + "bin/chromium_errorprone", + ] + } + foreach(e, _provider_configurations) { + args += [ "--provider-configuration=" + rebase_path(e, root_build_dir) ] + } + foreach(e, _processors) { + args += [ "--processor=" + e ] + } + foreach(e, _processor_args) { + args += [ "--processor-arg=" + e ] + } + foreach(file_tuple, _additional_jar_files) { + # Each element is of length two, [ path_to_file, path_to_put_in_jar ] + inputs += [ file_tuple[0] ] + args += + [ "--additional-jar-file=" + file_tuple[0] + ":" + file_tuple[1] ] + } + if (invoker.java_files != []) { + args += [ "@" + rebase_path(invoker.java_sources_file, root_build_dir) ] + } + } + + process_java_prebuilt(_process_prebuilt_target_name) { + forward_variables_from(invoker, [ "jar_excluded_patterns" ]) + supports_android = _supports_android + build_config = _build_config + input_jar_path = _javac_jar_path + output_jar_path = _process_prebuilt_jar_path + + deps = [ + ":$_javac_target_name", + ] + if (defined(invoker.deps)) { + deps += invoker.deps + } + } + + if (_emma_instrument) { + emma_instr(_emma_instr_target_name) { + forward_variables_from(invoker, + [ + "deps", + "java_files", + "java_sources_file", + ]) + + input_jar_path = _process_prebuilt_jar_path + output_jar_path = _final_jar_path + + if (!defined(deps)) { + deps = [] + } + deps += [ ":$_process_prebuilt_target_name" ] + } + } + + generate_interface_jar(_ijar_target_name) { + # Always used the unfiltered .jar to create the interface jar so that + # other targets will resolve filtered classes when depending on + # BuildConfig, NativeLibraries, etc. + input_jar = _javac_jar_path + deps = [ + ":$_javac_target_name", + ] + output_jar = _final_ijar_path + } + + group(_final_target_name) { + forward_variables_from(invoker, [ "visibility" ]) + public_deps = [ + ":$_ijar_target_name", + ":$_javac_target_name", + ] + if (_emma_instrument) { + public_deps += [ ":$_emma_instr_target_name" ] + } else { + public_deps += [ ":$_process_prebuilt_target_name" ] + } + } + } + + template("java_library_impl") { + set_sources_assignment_filter([]) + forward_variables_from(invoker, [ "testonly" ]) + _accumulated_deps = [] + if (defined(invoker.deps)) { + _accumulated_deps = invoker.deps + } + + # Caller overriding build config must have valid java sources file if it has + # java files. + assert(!defined(invoker.override_build_config) || + !defined(invoker.java_files) || defined(invoker.java_sources_file)) + + assert(defined(invoker.java_files) || defined(invoker.srcjars) || + defined(invoker.srcjar_deps)) + _base_path = "$target_gen_dir/$target_name" + + if (defined(invoker.output_name)) { + _output_name = invoker.output_name + } else { + _output_name = target_name + } + + # Jar files can be needed at runtime (by Robolectric tests or java binaries), + # so do not put them under gen/. + target_dir_name = get_label_info(":$target_name", "dir") + _jar_path = "$root_out_dir/lib.java$target_dir_name/$_output_name.jar" + if (defined(invoker.jar_path)) { + _jar_path = invoker.jar_path + } + _template_name = target_name + + _final_deps = [] + + _supports_android = + defined(invoker.supports_android) && invoker.supports_android + _requires_android = + defined(invoker.requires_android) && invoker.requires_android + assert(_requires_android || true) # Mark as used. + _android_manifest = "//build/android/AndroidManifest.xml" + if (defined(invoker.android_manifest)) { + _android_manifest = invoker.android_manifest + } + assert(_android_manifest != "") # Mark as used. + + if (defined(invoker.run_findbugs_override)) { + _run_findbugs = invoker.run_findbugs_override + } else { + _run_findbugs = run_findbugs # Default to build arg if not overridden. + } + assert(_run_findbugs || true) # Mark as used. + + # Don't enable coverage, lint, findbugs unless the target has some + # non-generated files. + if (defined(invoker.chromium_code)) { + _chromium_code = invoker.chromium_code + } else { + _chromium_code = defined(invoker.java_files) && invoker.java_files != [] + if (_chromium_code) { + # Make chromium_code = false be the default for targets within + # third_party which contain no chromium-namespaced java files. + set_sources_assignment_filter([ "*\bthird_party\b*" ]) + sources = [ + get_label_info(":$target_name", "dir"), + ] + if (sources == []) { + set_sources_assignment_filter([ "*\bchromium\b*" ]) + sources = invoker.java_files + _chromium_code = invoker.java_files != sources + } + set_sources_assignment_filter([]) + sources = [] + } + } + + _emma_never_instrument = !_chromium_code + if (defined(invoker.emma_never_instrument)) { + _emma_never_instrument = invoker.emma_never_instrument + } + assert(_emma_never_instrument || true) # Mark as used + _emma_instrument = emma_coverage && !_emma_never_instrument + + if (_supports_android) { + _dex_path = _base_path + ".dex.jar" + if (defined(invoker.dex_path)) { + _dex_path = invoker.dex_path + } + } + + _java_files = [] + if (defined(invoker.java_files)) { + _java_files += invoker.java_files + } + if (_java_files != []) { + if (defined(invoker.java_sources_file)) { + _java_sources_file = invoker.java_sources_file + } else { + _java_sources_file = "$_base_path.sources" + } + write_file(_java_sources_file, rebase_path(_java_files, root_build_dir)) + } + + # Define build_config_deps which will be a list of targets required to + # build the _build_config. + if (defined(invoker.override_build_config)) { + _build_config = invoker.override_build_config + } else { + _build_config = _base_path + ".build_config" + build_config_target_name = "${_template_name}__build_config" + + write_build_config(build_config_target_name) { + forward_variables_from(invoker, + [ + "alternative_android_sdk_ijar", + "gradle_treat_as_prebuilt", + "input_jars_paths", + "main_class", + "proguard_configs", + ]) + if (defined(invoker.is_java_binary) && invoker.is_java_binary) { + type = "java_binary" + } else { + type = "java_library" + } + if (defined(invoker.deps)) { + possible_config_deps = invoker.deps + } + supports_android = _supports_android + requires_android = _requires_android + bypass_platform_checks = defined(invoker.bypass_platform_checks) && + invoker.bypass_platform_checks + + build_config = _build_config + jar_path = _jar_path + if (_supports_android) { + dex_path = _dex_path + } + if (_java_files != []) { + java_sources_file = _java_sources_file + } + + if (defined(invoker.srcjar_deps)) { + bundled_srcjars = [] + foreach(d, invoker.srcjar_deps) { + _dep_gen_dir = get_label_info(d, "target_gen_dir") + _dep_name = get_label_info(d, "name") + bundled_srcjars += [ "$_dep_gen_dir/$_dep_name.srcjar" ] + } + } + } + _accumulated_deps += [ ":$build_config_target_name" ] + } + + _srcjar_deps = [] + if (defined(invoker.srcjar_deps)) { + _srcjar_deps = invoker.srcjar_deps + } + + _srcjars = [] + if (defined(invoker.srcjars)) { + _srcjars = invoker.srcjars + } + + assert(_java_files != [] || _srcjar_deps != [] || _srcjars != []) + + _compile_java_target = "${_template_name}__compile_java" + _final_deps += [ ":$_compile_java_target" ] + compile_java(_compile_java_target) { + forward_variables_from(invoker, + [ + "additional_jar_files", + "alternative_android_sdk_ijar", + "alternative_android_sdk_ijar_dep", + "dist_jar_path", + "enable_errorprone", + "enable_incremental_javac_override", + "jar_excluded_patterns", + "manifest_entries", + "processors_javac", + "processor_args_javac", + "provider_configurations", + ]) + jar_path = _jar_path + build_config = _build_config + java_files = _java_files + if (_java_files != []) { + java_sources_file = _java_sources_file + } + srcjar_deps = _srcjar_deps + srcjars = _srcjars + chromium_code = _chromium_code + supports_android = _supports_android + requires_android = _requires_android + emma_instrument = _emma_instrument + deps = _accumulated_deps + } + _accumulated_deps += [ ":$_compile_java_target" ] + assert(_accumulated_deps != []) # Mark used. + + if (defined(invoker.main_class)) { + # Targets might use the generated script while building, so make it a dep + # rather than a data_dep. + _final_deps += [ ":${_template_name}__java_binary_script" ] + java_binary_script("${_template_name}__java_binary_script") { + forward_variables_from(invoker, + [ + "bootclasspath", + "main_class", + "wrapper_script_args", + ]) + build_config = _build_config + jar_path = _jar_path + script_name = _template_name + if (defined(invoker.wrapper_script_name)) { + script_name = invoker.wrapper_script_name + } + deps = _accumulated_deps + } + } + + _has_lint_target = false + if (_supports_android) { + if (_chromium_code) { + _has_lint_target = true + android_lint("${_template_name}__lint") { + android_manifest = _android_manifest + build_config = _build_config + + # Run lint on javac output. + jar_path = "$target_gen_dir/$_compile_java_target.javac.jar" + + java_files = _java_files + if (_java_files != []) { + java_sources_file = _java_sources_file + } + deps = _accumulated_deps + if (_emma_instrument) { + # Disable the NewApi lint warning when building with coverage + # enabled. Coverage seems to mess with how the linter detects + # the usages of a new API within a conditional. See + # crbug.com/677320 for more. + disable = [ "NewApi" ] + } + } + + if (_run_findbugs) { + findbugs("${_template_name}__findbugs") { + build_config = _build_config + jar_path = _jar_path + deps = _accumulated_deps + } + } + + # Use an intermediate group() rather as the data_deps target in order to + # avoid lint artifacts showing up as runtime_deps (while still having lint + # run in parallel to other targets). + group("${_template_name}__analysis") { + public_deps = [ + ":${_template_name}__lint", + ] + if (_run_findbugs) { + public_deps += [ ":${_template_name}__findbugs" ] + } + } + } + + _final_deps += [ ":${_template_name}__dex" ] + dex("${_template_name}__dex") { + sources = [ + _jar_path, + ] + output = _dex_path + deps = [ + ":$_compile_java_target", + ] + } + } + + group(target_name) { + forward_variables_from(invoker, + [ + "data", + "data_deps", + "visibility", + ]) + if (!defined(data_deps)) { + data_deps = [] + } + public_deps = _final_deps + if (_has_lint_target) { + data_deps += [ ":${_template_name}__analysis" ] + } + } + } + + # Runs process_resources.py + template("process_resources") { + set_sources_assignment_filter([]) + forward_variables_from(invoker, [ "testonly" ]) + + zip_path = invoker.zip_path + srcjar_path = invoker.srcjar_path + r_text_out_path = invoker.r_text_out_path + build_config = invoker.build_config + android_manifest = invoker.android_manifest + + non_constant_id = true + if (defined(invoker.generate_constant_ids) && + invoker.generate_constant_ids) { + non_constant_id = false + } + + action(target_name) { + forward_variables_from(invoker, + [ + "deps", + "visibility", + ]) + script = "//build/android/gyp/process_resources.py" + + depfile = "$target_gen_dir/$target_name.d" + outputs = [ + zip_path, + srcjar_path, + r_text_out_path, + ] + + _all_resource_dirs = [] + sources = [] + + if (defined(invoker.resource_dirs)) { + _all_resource_dirs += invoker.resource_dirs + + # Speed up "gn gen" by short-circuiting the empty directory. + if (invoker.resource_dirs != [ "//build/android/ant/empty/res" ] && + invoker.resource_dirs != []) { + _sources_build_rel = + exec_script("//build/android/gyp/find.py", + rebase_path(invoker.resource_dirs, root_build_dir), + "list lines") + sources += rebase_path(_sources_build_rel, ".", root_build_dir) + } + } + + if (defined(invoker.generated_resource_dirs)) { + assert(defined(invoker.generated_resource_files)) + _all_resource_dirs += invoker.generated_resource_dirs + sources += invoker.generated_resource_files + } + + inputs = [ + build_config, + android_manifest, + ] + + _rebased_all_resource_dirs = + rebase_path(_all_resource_dirs, root_build_dir) + rebase_build_config = rebase_path(build_config, root_build_dir) + + if (defined(invoker.android_aapt_path)) { + _android_aapt_path = invoker.android_aapt_path + } else { + _android_aapt_path = android_default_aapt_path + } + + if (defined(invoker.alternative_android_sdk_jar)) { + _rebased_android_sdk_jar = + rebase_path(invoker.alternative_android_sdk_jar) + } else { + _rebased_android_sdk_jar = rebased_android_sdk_jar + } + + args = [ + "--depfile", + rebase_path(depfile, root_build_dir), + "--android-sdk-jar", + _rebased_android_sdk_jar, + "--aapt-path", + _android_aapt_path, + "--android-manifest", + rebase_path(android_manifest, root_build_dir), + "--resource-dirs=$_rebased_all_resource_dirs", + "--srcjar-out", + rebase_path(srcjar_path, root_build_dir), + "--resource-zip-out", + rebase_path(zip_path, root_build_dir), + "--r-text-out", + rebase_path(r_text_out_path, root_build_dir), + "--dependencies-res-zips=@FileArg($rebase_build_config:resources:dependency_zips)", + "--extra-res-packages=@FileArg($rebase_build_config:resources:extra_package_names)", + "--extra-r-text-files=@FileArg($rebase_build_config:resources:extra_r_text_files)", + ] + + if (defined(invoker.r_text_in_path)) { + _r_text_in_path = invoker.r_text_in_path + inputs += [ _r_text_in_path ] + args += [ + "--r-text-in", + rebase_path(_r_text_in_path, root_build_dir), + ] + } + + if (non_constant_id) { + args += [ "--non-constant-id" ] + } + + if (defined(invoker.custom_package)) { + args += [ + "--custom-package", + invoker.custom_package, + ] + } + + if (defined(invoker.v14_skip) && invoker.v14_skip) { + args += [ "--v14-skip" ] + } + + if (defined(invoker.shared_resources) && invoker.shared_resources) { + args += [ "--shared-resources" ] + } + + if (defined(invoker.app_as_shared_lib) && invoker.app_as_shared_lib) { + args += [ "--app-as-shared-lib" ] + } + + if (defined(invoker.include_all_resources) && + invoker.include_all_resources) { + args += [ "--include-all-resources" ] + } + + if (defined(invoker.all_resources_zip_path)) { + all_resources_zip = invoker.all_resources_zip_path + outputs += [ all_resources_zip ] + args += [ + "--all-resources-zip-out", + rebase_path(all_resources_zip, root_build_dir), + ] + } + + if (defined(invoker.proguard_file)) { + outputs += [ invoker.proguard_file ] + args += [ + "--proguard-file", + rebase_path(invoker.proguard_file, root_build_dir), + ] + } + + if (defined(invoker.proguard_file_main_dex)) { + outputs += [ invoker.proguard_file_main_dex ] + args += [ + "--proguard-file-main-dex", + rebase_path(invoker.proguard_file_main_dex, root_build_dir), + ] + } + + if (defined(invoker.args)) { + args += invoker.args + } + } + } + + # Produces a single .dex.jar out of a set of Java dependencies. + template("deps_dex") { + set_sources_assignment_filter([]) + build_config = "$target_gen_dir/${target_name}.build_config" + build_config_target_name = "${target_name}__build_config" + + write_build_config(build_config_target_name) { + forward_variables_from(invoker, [ "dex_path" ]) + if (defined(invoker.deps)) { + possible_config_deps = invoker.deps + } + type = "deps_dex" + build_config = build_config + } + + rebased_build_config = rebase_path(build_config, root_build_dir) + dex(target_name) { + inputs = [ + build_config, + ] + output = invoker.dex_path + dex_arg_key = "${rebased_build_config}:final_dex:dependency_dex_files" + args = [ "--inputs=@FileArg($dex_arg_key)" ] + if (defined(invoker.excluded_jars)) { + excluded_jars = rebase_path(invoker.excluded_jars, root_build_dir) + args += [ "--excluded-paths=${excluded_jars}" ] + } + deps = [ + ":$build_config_target_name", + ] + } + } + + # Creates an AndroidManifest.xml for an APK split. + template("generate_split_manifest") { + assert(defined(invoker.main_manifest)) + assert(defined(invoker.out_manifest)) + assert(defined(invoker.split_name)) + + action(target_name) { + forward_variables_from(invoker, + [ + "deps", + "testonly", + ]) + depfile = "$target_gen_dir/$target_name.d" + args = [ + "--main-manifest", + rebase_path(invoker.main_manifest, root_build_dir), + "--out-manifest", + rebase_path(invoker.out_manifest, root_build_dir), + "--split", + invoker.split_name, + ] + if (defined(invoker.version_code)) { + args += [ + "--version-code", + invoker.version_code, + ] + } + if (defined(invoker.version_name)) { + args += [ + "--version-name", + invoker.version_name, + ] + } + if (defined(invoker.has_code)) { + args += [ + "--has-code", + invoker.has_code, + ] + } + args += [ + "--depfile", + rebase_path(depfile, root_build_dir), + ] + + script = "//build/android/gyp/generate_split_manifest.py" + outputs = [ + invoker.out_manifest, + ] + inputs = [ + invoker.main_manifest, + ] + } + } + + template("pack_relocation_section") { + assert(defined(invoker.file_list_json)) + assert(defined(invoker.libraries_filearg)) + action(target_name) { + forward_variables_from(invoker, + [ + "deps", + "public_deps", + "inputs", + "testonly", + ]) + script = "//build/android/gyp/pack_relocations.py" + depfile = "$target_gen_dir/$target_name.d" + _packed_libraries_dir = "$target_gen_dir/$target_name/packed-libs" + outputs = [ + invoker.file_list_json, + ] + deps += [ relocation_packer_target ] + + args = [ + "--depfile", + rebase_path(depfile, root_build_dir), + "--enable-packing=1", + "--android-pack-relocations", + rebase_path(relocation_packer_exe, root_build_dir), + "--stripped-libraries-dir", + rebase_path(root_build_dir, root_build_dir), + "--packed-libraries-dir", + rebase_path(_packed_libraries_dir, root_build_dir), + "--libraries=${invoker.libraries_filearg}", + "--filelistjson", + rebase_path(invoker.file_list_json, root_build_dir), + ] + } + } +}
new file mode 100644 --- /dev/null +++ b/media/webrtc/trunk/build/config/android/rules.gni @@ -0,0 +1,2965 @@ +# 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. + +# Do not add any imports to non-//build directories here. +# Some projects (e.g. V8) do not have non-build directories DEPS'ed in. +import("//build/config/android/config.gni") +import("//build/config/android/internal_rules.gni") +import("//build/config/compiler/compiler.gni") +import("//build/config/dcheck_always_on.gni") +import("//build/toolchain/toolchain.gni") + +assert(is_android) + +# Creates a dist directory for a native executable. +# +# Running a native executable on a device requires all the shared library +# dependencies of that executable. To make it easier to install and run such an +# executable, this will create a directory containing the native exe and all +# it's library dependencies. +# +# Note: It's usually better to package things as an APK than as a native +# executable. +# +# Variables +# dist_dir: Directory for the exe and libraries. Everything in this directory +# will be deleted before copying in the exe and libraries. +# binary: Path to (stripped) executable. +# extra_files: List of extra files to copy in (optional). +# +# Example +# create_native_executable_dist("foo_dist") { +# dist_dir = "$root_build_dir/foo_dist" +# binary = "$root_build_dir/foo" +# deps = [ ":the_thing_that_makes_foo" ] +# } +template("create_native_executable_dist") { + forward_variables_from(invoker, [ "testonly" ]) + + _libraries_list = "${target_gen_dir}/${target_name}_library_dependencies.list" + + _find_deps_target_name = "${target_name}__find_library_dependencies" + + # TODO(agrieve): Extract dependent libs from GN rather than readelf. + action(_find_deps_target_name) { + forward_variables_from(invoker, [ "deps" ]) + + script = "//build/android/gyp/write_ordered_libraries.py" + depfile = "$target_gen_dir/$target_name.d" + inputs = [ + invoker.binary, + android_readelf, + ] + outputs = [ + _libraries_list, + ] + rebased_binaries = rebase_path([ invoker.binary ], root_build_dir) + args = [ + "--depfile", + rebase_path(depfile, root_build_dir), + "--input-libraries=$rebased_binaries", + "--libraries-dir", + rebase_path(root_shlib_dir, root_build_dir), + "--output", + rebase_path(_libraries_list, root_build_dir), + "--readelf", + rebase_path(android_readelf, root_build_dir), + ] + } + + copy_ex(target_name) { + clear_dir = true + + inputs = [ + _libraries_list, + invoker.binary, + ] + + dest = invoker.dist_dir + data = [ + "${invoker.dist_dir}/", + ] + + _rebased_libraries_list = rebase_path(_libraries_list, root_build_dir) + _rebased_binaries_list = rebase_path([ invoker.binary ], root_build_dir) + args = [ + "--files=@FileArg($_rebased_libraries_list:lib_paths)", + "--files=$_rebased_binaries_list", + ] + if (defined(invoker.extra_files)) { + _rebased_extra_files = rebase_path(invoker.extra_files, root_build_dir) + args += [ "--files=$_rebased_extra_files" ] + } + + deps = [ + ":$_find_deps_target_name", + ] + if (defined(invoker.deps)) { + deps += invoker.deps + } + } +} + +# Writes a script to root_out_dir/bin that passes --output-directory to the +# wrapped script, in addition to forwarding arguments. Most / all of these +# wrappers should be made deps of //tools/android:android_tools. +# +# Variables +# target: Script to wrap. +# flag_name: Default is "--output-directory" +# +# Example +# wrapper_script("foo_wrapper") { +# target = "//pkg/foo.py" +# } +template("wrapper_script") { + action(target_name) { + _name = get_path_info(invoker.target, "name") + _output = "$root_out_dir/bin/$_name" + + script = "//build/android/gyp/create_tool_wrapper.py" + outputs = [ + _output, + ] + + # The target isn't actually used by the script, but it's nice to have GN + # check that it exists. + inputs = [ + invoker.target, + ] + args = [ + "--output", + rebase_path(_output, root_build_dir), + "--target", + rebase_path(invoker.target, root_build_dir), + "--output-directory", + rebase_path(root_out_dir, root_build_dir), + ] + if (defined(invoker.flag_name)) { + args += [ "--flag-name=${invoker.flag_name}" ] + } + } +} + +if (enable_java_templates) { + import("//build/config/sanitizers/sanitizers.gni") + import("//tools/grit/grit_rule.gni") + + # Declare a jni target + # + # This target generates the native jni bindings for a set of .java files. + # + # See base/android/jni_generator/jni_generator.py for more info about the + # format of generating JNI bindings. + # + # Variables + # sources: list of .java files to generate jni for + # jni_package: subdirectory path for generated bindings + # + # Example + # generate_jni("foo_jni") { + # sources = [ + # "android/java/src/org/chromium/foo/Foo.java", + # "android/java/src/org/chromium/foo/FooUtil.java", + # ] + # jni_package = "foo" + # } + template("generate_jni") { + set_sources_assignment_filter([]) + forward_variables_from(invoker, [ "testonly" ]) + + assert(defined(invoker.sources)) + assert(defined(invoker.jni_package)) + jni_package = invoker.jni_package + base_output_dir = "${target_gen_dir}/${target_name}" + package_output_dir = "${base_output_dir}/${jni_package}" + jni_output_dir = "${package_output_dir}/jni" + + jni_generator_include = + "//base/android/jni_generator/jni_generator_helper.h" + + foreach_target_name = "${target_name}__jni_gen" + action_foreach(foreach_target_name) { + script = "//base/android/jni_generator/jni_generator.py" + depfile = "$target_gen_dir/$target_name.{{source_name_part}}.d" + sources = invoker.sources + outputs = [ + "${jni_output_dir}/{{source_name_part}}_jni.h", + ] + + args = [ + "--depfile", + rebase_path(depfile, root_build_dir), + "--input_file={{source}}", + "--optimize_generation=1", + "--ptr_type=long", + "--output_dir", + rebase_path(jni_output_dir, root_build_dir), + "--includes", + rebase_path(jni_generator_include, jni_output_dir), + "--native_exports_optional", + ] + + if (enable_profiling) { + args += [ "--enable_profiling" ] + } + } + + config("jni_includes_${target_name}") { + # TODO(cjhopman): #includes should probably all be relative to + # base_output_dir. Remove that from this config once the includes are + # updated. + include_dirs = [ + base_output_dir, + package_output_dir, + ] + } + + group(target_name) { + forward_variables_from(invoker, + [ + "deps", + "public_deps", + "visibility", + ]) + if (!defined(public_deps)) { + public_deps = [] + } + public_deps += [ ":$foreach_target_name" ] + public_configs = [ ":jni_includes_${target_name}" ] + } + } + + # Declare a jni target for a prebuilt jar + # + # This target generates the native jni bindings for a set of classes in a .jar. + # + # See base/android/jni_generator/jni_generator.py for more info about the + # format of generating JNI bindings. + # + # Variables + # classes: list of .class files in the jar to generate jni for. These should + # include the full path to the .class file. + # jni_package: subdirectory path for generated bindings + # jar_file: the path to the .jar. If not provided, will default to the sdk's + # android.jar + # + # deps, public_deps: As normal + # + # Example + # generate_jar_jni("foo_jni") { + # classes = [ + # "android/view/Foo.class", + # ] + # jni_package = "foo" + # } + template("generate_jar_jni") { + set_sources_assignment_filter([]) + forward_variables_from(invoker, [ "testonly" ]) + + assert(defined(invoker.classes)) + assert(defined(invoker.jni_package)) + + if (defined(invoker.jar_file)) { + jar_file = invoker.jar_file + } else { + jar_file = android_sdk_jar + } + + jni_package = invoker.jni_package + base_output_dir = "${root_gen_dir}/${target_name}/${jni_package}" + jni_output_dir = "${base_output_dir}/jni" + + jni_generator_include = + "//base/android/jni_generator/jni_generator_helper.h" + + # TODO(cjhopman): make jni_generator.py support generating jni for multiple + # .class files from a .jar. + jni_actions = [] + foreach(class, invoker.classes) { + _classname_list = [] + _classname_list = process_file_template([ class ], "{{source_name_part}}") + classname = _classname_list[0] + jni_target_name = "${target_name}__jni_${classname}" + jni_actions += [ ":$jni_target_name" ] + action(jni_target_name) { + # The sources aren't compiled so don't check their dependencies. + check_includes = false + depfile = "$target_gen_dir/$target_name.d" + script = "//base/android/jni_generator/jni_generator.py" + sources = [ + jar_file, + ] + outputs = [ + "${jni_output_dir}/${classname}_jni.h", + ] + + args = [ + "--depfile", + rebase_path(depfile, root_build_dir), + "--jar_file", + rebase_path(jar_file, root_build_dir), + "--input_file", + class, + "--optimize_generation=1", + "--ptr_type=long", + "--output_dir", + rebase_path(jni_output_dir, root_build_dir), + "--includes", + rebase_path(jni_generator_include, jni_output_dir), + "--native_exports_optional", + ] + + if (enable_profiling) { + args += [ "--enable_profiling" ] + } + } + } + + config("jni_includes_${target_name}") { + include_dirs = [ base_output_dir ] + } + + group(target_name) { + public_deps = [] + forward_variables_from(invoker, + [ + "deps", + "public_deps", + "visibility", + ]) + public_deps += jni_actions + public_configs = [ ":jni_includes_${target_name}" ] + } + } + + # Declare a target for c-preprocessor-generated java files + # + # NOTE: For generating Java conterparts to enums prefer using the java_cpp_enum + # rule instead. + # + # This target generates java files using the host C pre-processor. Each file in + # sources will be compiled using the C pre-processor. If include_path is + # specified, it will be passed (with --I) to the pre-processor. + # + # This target will create a single .srcjar. Adding this target to an + # android_library target's srcjar_deps will make the generated java files be + # included in that library's final outputs. + # + # Variables + # sources: list of files to be processed by the C pre-processor. For each + # file in sources, there will be one .java file in the final .srcjar. For a + # file named FooBar.template, a java file will be created with name + # FooBar.java. + # inputs: additional compile-time dependencies. Any files + # `#include`-ed in the templates should be listed here. + # package_path: this will be the subdirectory for each .java file in the + # .srcjar. + # + # Example + # java_cpp_template("foo_generated_enum") { + # sources = [ + # "android/java/templates/Foo.template", + # ] + # inputs = [ + # "android/java/templates/native_foo_header.h", + # ] + # + # package_path = "org/chromium/base/library_loader" + # include_path = "android/java/templates" + # } + template("java_cpp_template") { + set_sources_assignment_filter([]) + forward_variables_from(invoker, [ "testonly" ]) + + _include_path = "//" + if (defined(invoker.include_path)) { + _include_path = invoker.include_path + } + + _apply_gcc_target_name = "${target_name}__apply_gcc" + _base_gen_dir = "${target_gen_dir}/${target_name}/java_cpp_template" + + if (defined(invoker.package_path)) { + package_path = invoker.package_path + } else { + # TODO(jbudorick): Back this out once all clients have been switched to + # package_path. + assert(defined(invoker.package_name)) + package_path = invoker.package_name + } + + action_foreach(_apply_gcc_target_name) { + forward_variables_from(invoker, + [ + "deps", + "public_deps", + "data_deps", + ]) + script = "//build/android/gyp/gcc_preprocess.py" + if (defined(invoker.inputs)) { + inputs = invoker.inputs + [] + } + depfile = + "${target_gen_dir}/${invoker.target_name}_{{source_name_part}}.d" + + sources = invoker.sources + + outputs = [ + "$_base_gen_dir/${package_path}/{{source_name_part}}.java", + ] + + args = [ + "--depfile", + rebase_path(depfile, root_build_dir), + "--include-path", + rebase_path(_include_path, root_build_dir), + "--output", + rebase_path(outputs[0], root_build_dir), + "--template={{source}}", + ] + + if (defined(invoker.defines)) { + foreach(def, invoker.defines) { + args += [ + "--defines", + def, + ] + } + } + } + + # Filter out .d files. + set_sources_assignment_filter([ "*.d" ]) + sources = get_target_outputs(":$_apply_gcc_target_name") + + zip(target_name) { + forward_variables_from(invoker, [ "visibility" ]) + inputs = sources + output = "${target_gen_dir}/${target_name}.srcjar" + base_dir = _base_gen_dir + deps = [ + ":$_apply_gcc_target_name", + ] + } + } + + # Declare a target for generating Java classes from C++ enums. + # + # This target generates Java files from C++ enums using a script. + # + # This target will create a single .srcjar. Adding this target to an + # android_library target's srcjar_deps will make the generated java files be + # included in that library's final outputs. + # + # Variables + # sources: list of files to be processed by the script. For each annotated + # enum contained in the sources files the script will generate a .java + # file with the same name as the name of the enum. + # + # Example + # java_cpp_enum("foo_generated_enum") { + # sources = [ + # "src/native_foo_header.h", + # ] + # } + template("java_cpp_enum") { + action(target_name) { + # The sources aren't compiled so don't check their dependencies. + check_includes = false + set_sources_assignment_filter([]) + + assert(defined(invoker.sources)) + forward_variables_from(invoker, + [ + "sources", + "testonly", + "visibility", + ]) + + script = "//build/android/gyp/java_cpp_enum.py" + depfile = "$target_gen_dir/$target_name.d" + + _srcjar_path = "${target_gen_dir}/${target_name}.srcjar" + _rebased_srcjar_path = rebase_path(_srcjar_path, root_build_dir) + _rebased_sources = rebase_path(invoker.sources, root_build_dir) + + args = [ + "--depfile", + rebase_path(depfile, root_build_dir), + "--srcjar=$_rebased_srcjar_path", + ] + _rebased_sources + outputs = [ + _srcjar_path, + ] + } + } + + # Declare a target for processing a Jinja template. + # + # Variables + # input: The template file to be processed. + # output: Where to save the result. + # variables: (Optional) A list of variables to make available to the template + # processing environment, e.g. ["name=foo", "color=red"]. + # + # Example + # jinja_template("chrome_public_manifest") { + # input = "java/AndroidManifest.xml" + # output = "$target_gen_dir/AndroidManifest.xml" + # } + template("jinja_template") { + set_sources_assignment_filter([]) + forward_variables_from(invoker, [ "testonly" ]) + + assert(defined(invoker.input)) + assert(defined(invoker.output)) + + action(target_name) { + forward_variables_from(invoker, + [ + "visibility", + "deps", + ]) + + sources = [ + invoker.input, + ] + script = "//build/android/gyp/jinja_template.py" + depfile = "$target_gen_dir/$target_name.d" + + outputs = [ + invoker.output, + ] + + args = [ + "--loader-base-dir", + rebase_path("//", root_build_dir), + "--inputs", + rebase_path(invoker.input, root_build_dir), + "--output", + rebase_path(invoker.output, root_build_dir), + "--depfile", + rebase_path(depfile, root_build_dir), + ] + if (defined(invoker.variables)) { + variables = invoker.variables + args += [ "--variables=${variables}" ] + } + } + } + + # Declare a target for processing Android resources as Jinja templates. + # + # This takes an Android resource directory where each resource is a Jinja + # template, processes each template, then packages the results in a zip file + # which can be consumed by an android resources, library, or apk target. + # + # If this target is included in the deps of an android resources/library/apk, + # the resources will be included with that target. + # + # Variables + # resources: The list of resources files to process. + # res_dir: The resource directory containing the resources. + # variables: (Optional) A list of variables to make available to the template + # processing environment, e.g. ["name=foo", "color=red"]. + # + # Example + # jinja_template_resources("chrome_public_template_resources") { + # res_dir = "res_template" + # resources = ["res_template/xml/syncable.xml"] + # variables = ["color=red"] + # } + template("jinja_template_resources") { + set_sources_assignment_filter([]) + forward_variables_from(invoker, [ "testonly" ]) + + assert(defined(invoker.resources)) + assert(defined(invoker.res_dir)) + + _base_path = "$target_gen_dir/$target_name" + + # JUnit tests use resource zip files. These must not be put in gen/ + # directory or they will not be available to tester bots. + _resources_zip_rebased_path = rebase_path(target_gen_dir, root_gen_dir) + _resources_zip = "${root_out_dir}/resource_zips/${_resources_zip_rebased_path}/${target_name}.resources.zip" + _build_config = _base_path + ".build_config" + + write_build_config("${target_name}__build_config") { + build_config = _build_config + resources_zip = _resources_zip + type = "android_resources" + if (defined(invoker.deps)) { + possible_config_deps = invoker.deps + } + } + + action("${target_name}__template") { + forward_variables_from(invoker, [ "deps" ]) + sources = invoker.resources + script = "//build/android/gyp/jinja_template.py" + depfile = "$target_gen_dir/$target_name.d" + + outputs = [ + _resources_zip, + ] + + rebased_resources = rebase_path(invoker.resources, root_build_dir) + args = [ + "--inputs=${rebased_resources}", + "--inputs-base-dir", + rebase_path(invoker.res_dir, root_build_dir), + "--outputs-zip", + rebase_path(_resources_zip, root_build_dir), + "--depfile", + rebase_path(depfile, root_build_dir), + ] + if (defined(invoker.variables)) { + variables = invoker.variables + args += [ "--variables=${variables}" ] + } + } + + group(target_name) { + public_deps = [ + ":${target_name}__build_config", + ":${target_name}__template", + ] + } + } + + # Declare an Android resources target + # + # This creates a resources zip file that will be used when building an Android + # library or apk and included into a final apk. + # + # To include these resources in a library/apk, this target should be listed in + # the library's deps. A library/apk will also include any resources used by its + # own dependencies. + # + # Variables + # deps: Specifies the dependencies of this target. Any Android resources + # listed in deps will be included by libraries/apks that depend on this + # target. + # resource_dirs: List of directories containing resources for this target. + # generated_resource_dirs: List of directories containing resources for this + # target which are *generated* by a dependency. |generated_resource_files| + # must be specified if |generated_resource_dirs| is specified. + # generated_resource_files: List of all files in |generated_resource_dirs|. + # |generated_resource_dirs| must be specified in |generated_resource_files| + # is specified. + # android_manifest: AndroidManifest.xml for this target. Defaults to + # //build/android/AndroidManifest.xml. + # android_manifest_dep: Target that generates AndroidManifest (if applicable) + # custom_package: java package for generated .java files. + # v14_skip: If true, don't run v14 resource generator on this. Defaults to + # false. (see build/android/gyp/generate_v14_compatible_resources.py) + # shared_resources: If true make a resource package that can be loaded by a + # different application at runtime to access the package's resources. + # app_as_shared_lib: If true make a resource package that can be loaded as + # both shared_resources and normal application. + # r_text_file: (optional) path to pre-generated R.txt to be used when + # generating R.java instead of resource-based aapt-generated one. + + # Example: + # android_resources("foo_resources") { + # deps = [":foo_strings_grd"] + # resource_dirs = ["res"] + # custom_package = "org.chromium.foo" + # } + # + # android_resources("foo_resources_overrides") { + # deps = [":foo_resources"] + # resource_dirs = ["res_overrides"] + # } + template("android_resources") { + set_sources_assignment_filter([]) + forward_variables_from(invoker, [ "testonly" ]) + + assert(defined(invoker.resource_dirs)) + + base_path = "$target_gen_dir/$target_name" + + # JUnit tests use resource zip files. These must not be put in gen/ + # directory or they will not be available to tester bots. + _resources_zip_rebased_path = rebase_path(target_gen_dir, root_gen_dir) + zip_path = "${root_out_dir}/resource_zips/${_resources_zip_rebased_path}/${target_name}.resources.zip" + srcjar_path = base_path + ".srcjar" + r_text_out_path = base_path + "_R.txt" + build_config = base_path + ".build_config" + + build_config_target_name = "${target_name}__build_config" + process_resources_target_name = "${target_name}__process_resources" + final_target_name = target_name + + write_build_config(build_config_target_name) { + type = "android_resources" + forward_variables_from(invoker, + [ + "android_manifest", + "custom_package", + ]) + resource_dirs = [] + if (defined(invoker.resource_dirs)) { + resource_dirs += invoker.resource_dirs + } + if (defined(invoker.generated_resource_dirs)) { + resource_dirs += invoker.generated_resource_dirs + } + + if (defined(invoker.deps)) { + possible_config_deps = invoker.deps + } + if (defined(invoker.android_manifest_dep)) { + deps = [ + invoker.android_manifest_dep, + ] + } + + # No package means resources override their deps. + if (defined(custom_package) || defined(android_manifest)) { + r_text = r_text_out_path + } else { + assert(defined(invoker.deps), + "Must specify deps when custom_package is omitted.") + } + + resources_zip = zip_path + srcjar = srcjar_path + } + + process_resources(process_resources_target_name) { + forward_variables_from(invoker, + [ + "app_as_shared_lib", + "android_manifest", + "custom_package", + "deps", + "generated_resource_dirs", + "generated_resource_files", + "resource_dirs", + "shared_resources", + "v14_skip", + ]) + if (!defined(deps)) { + deps = [] + } + deps += [ ":$build_config_target_name" ] + if (defined(invoker.android_manifest_dep)) { + deps += [ invoker.android_manifest_dep ] + } + + if (defined(invoker.r_text_file)) { + r_text_in_path = invoker.r_text_file + } + + # Always generate R.onResourcesLoaded() method, it is required for + # compiling ResourceRewriter, there is no side effect because the + # generated R.class isn't used in final apk. + shared_resources = true + if (!defined(android_manifest)) { + android_manifest = "//build/android/AndroidManifest.xml" + } + } + + group(final_target_name) { + forward_variables_from(invoker, [ "visibility" ]) + public_deps = [ + ":${target_name}__process_resources", + ] + } + } + + # Declare an Android assets target. + # + # Defines a set of files to include as assets in a dependent apk. + # + # To include these assets in an apk, this target should be listed in + # the apk's deps, or in the deps of a library target used by an apk. + # + # Variables + # deps: Specifies the dependencies of this target. Any Android assets + # listed in deps will be included by libraries/apks that depend on this + # target. + # sources: List of files to include as assets. + # renaming_sources: List of files to include as assets and be renamed. + # renaming_destinations: List of asset paths for files in renaming_sources. + # disable_compression: Whether to disable compression for files that are + # known to be compressable (default: false). + # + # Example: + # android_assets("content_shell_assets") { + # deps = [ + # ":generates_foo", + # ":other_assets", + # ] + # sources = [ + # "//path/asset1.png", + # "//path/asset2.png", + # "$target_gen_dir/foo.dat", + # ] + # } + # + # android_assets("overriding_content_shell_assets") { + # deps = [ ":content_shell_assets" ] + # # Override foo.dat from content_shell_assets. + # sources = [ "//custom/foo.dat" ] + # renaming_sources = [ "//path/asset2.png" ] + # renaming_destinations = [ "renamed/asset2.png" ] + # } + template("android_assets") { + set_sources_assignment_filter([]) + forward_variables_from(invoker, [ "testonly" ]) + + _build_config = "$target_gen_dir/$target_name.build_config" + _build_config_target_name = "${target_name}__build_config" + + write_build_config(_build_config_target_name) { + type = "android_assets" + build_config = _build_config + + forward_variables_from(invoker, [ "disable_compression" ]) + + if (defined(invoker.deps)) { + possible_config_deps = invoker.deps + } + + if (defined(invoker.sources)) { + asset_sources = invoker.sources + } + if (defined(invoker.renaming_sources)) { + assert(defined(invoker.renaming_destinations)) + _source_count = 0 + foreach(_, invoker.renaming_sources) { + _source_count += 1 + } + _dest_count = 0 + foreach(_, invoker.renaming_destinations) { + _dest_count += 1 + } + assert( + _source_count == _dest_count, + "android_assets() renaming_sources.length != renaming_destinations.length") + asset_renaming_sources = invoker.renaming_sources + asset_renaming_destinations = invoker.renaming_destinations + } + } + + group(target_name) { + forward_variables_from(invoker, + [ + "deps", + "visibility", + ]) + public_deps = [ + ":$_build_config_target_name", + ] + } + } + + # Declare a group() that supports forwarding java dependency information. + # + # Example + # java_group("conditional_deps") { + # if (enable_foo) { + # deps = [":foo_java"] + # } + # } + template("java_group") { + forward_variables_from(invoker, [ "testonly" ]) + write_build_config("${target_name}__build_config") { + type = "group" + build_config = "$target_gen_dir/${invoker.target_name}.build_config" + if (defined(invoker.deps)) { + possible_config_deps = invoker.deps + } + } + group(target_name) { + forward_variables_from(invoker, "*") + if (!defined(deps)) { + deps = [] + } + deps += [ ":${target_name}__build_config" ] + } + } + + # 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") { + set_sources_assignment_filter([]) + forward_variables_from(invoker, [ "testonly" ]) + + base_path = "$target_gen_dir/$target_name" + + # JUnit tests use resource zip files. These must not be put in gen/ + # directory or they will not be available to tester bots. + _resources_zip_rebased_path = rebase_path(target_gen_dir, root_gen_dir) + resources_zip = "${root_out_dir}/resource_zips/${_resources_zip_rebased_path}/${target_name}.resources.zip" + build_config = base_path + ".build_config" + + write_build_config("${target_name}__build_config") { + type = "android_resources" + } + + # Put grit files into this subdirectory of target_gen_dir. + extra_output_path = target_name + "_grit_output" + + grit_target_name = "${target_name}__grit" + grit_output_dir = "$target_gen_dir/$extra_output_path" + + grit(grit_target_name) { + forward_variables_from(invoker, [ "deps" ]) + grit_flags = [ + "-E", + "ANDROID_JAVA_TAGGED_ONLY=false", + ] + output_dir = grit_output_dir + resource_ids = "" + source = invoker.grd_file + outputs = invoker.outputs + } + + # This needs to get outputs from grit's internal target, not the final + # source_set. + generate_strings_outputs = get_target_outputs(":${grit_target_name}_grit") + + zip("${target_name}__zip") { + base_dir = grit_output_dir + inputs = generate_strings_outputs + output = resources_zip + deps = [ + ":$grit_target_name", + ] + } + + group(target_name) { + public_deps = [ + ":${target_name}__build_config", + ":${target_name}__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") { + set_sources_assignment_filter([]) + forward_variables_from(invoker, [ "testonly" ]) + + base_path = "$target_gen_dir/$target_name" + + # JUnit tests use resource zip files. These must not be put in gen/ + # directory or they will not be available to tester bots. + _resources_zip_rebased_path = rebase_path(target_gen_dir, root_gen_dir) + resources_zip = "${root_out_dir}/resource_zips/${_resources_zip_rebased_path}/${target_name}.resources.zip" + build_config = base_path + ".build_config" + + build_config_target_name = "${target_name}__build_config" + zip_target_name = "${target_name}__zip" + final_target_name = target_name + + write_build_config(build_config_target_name) { + type = "android_resources" + } + + zip(zip_target_name) { + visibility = [ ":$final_target_name" ] + + base_dir = invoker.grit_output_dir + inputs = rebase_path(invoker.generated_files, ".", base_dir) + output = resources_zip + deps = [ + ":$build_config_target_name", + ] + if (defined(invoker.deps)) { + deps += invoker.deps + } + } + + group(final_target_name) { + forward_variables_from(invoker, [ "visibility" ]) + public_deps = [ + ":$zip_target_name", + ] + } + } + + # Declare a Java executable target + # + # This target creates an executable from java code and libraries. The executable + # will be in the output folder's /bin/ directory. + # + # Variables + # deps: Specifies the dependencies of this target. Java targets in this list + # will be included in the executable (and the javac classpath). + # java_files: List of .java files included in this library. + # srcjar_deps: List of srcjar dependencies. The .java files in the srcjars + # will be added to java_files and be included in this library. + # srcjars: List of srcjars to be included in this library, together with the + # ones obtained from srcjar_deps. + # bypass_platform_checks: Disables checks about cross-platform (Java/Android) + # dependencies for this target. This will allow depending on an + # android_library target, for example. + # chromium_code: If true, extra analysis warning/errors will be enabled. + # enable_errorprone: If true, enables the errorprone compiler. + # enable_incremental_javac_override: Overrides the + # global enable_incremental_javac. + # main_class: When specified, a wrapper script is created within + # $root_build_dir/bin to launch the binary with the given class as the + # entrypoint. + # wrapper_script_args: List of additional arguments for the wrapper script. + # + # data_deps, testonly + # + # Example + # java_binary("foo") { + # java_files = [ "org/chromium/foo/FooMain.java" ] + # deps = [ ":bar_java" ] + # main_class = "org.chromium.foo.FooMain" + # } + template("java_binary") { + set_sources_assignment_filter([]) + + java_library_impl(target_name) { + forward_variables_from(invoker, "*") + supports_android = false + main_class = invoker.main_class + is_java_binary = true + } + } + + # Declare a Junit executable target + # + # This target creates an executable from java code for running as a junit test + # suite. The executable will be in the output folder's /bin/ directory. + # + # Variables + # deps: Specifies the dependencies of this target. Java targets in this list + # will be included in the executable (and the javac classpath). + # + # java_files: List of .java files included in this library. + # srcjar_deps: List of srcjar dependencies. The .java files in the srcjars + # will be added to java_files and be included in this library. + # srcjars: List of srcjars to be included in this library, together with the + # ones obtained from srcjar_deps. + # + # chromium_code: If true, extra analysis warning/errors will be enabled. + # + # Example + # junit_binary("foo") { + # java_files = [ "org/chromium/foo/FooTest.java" ] + # deps = [ ":bar_java" ] + # } + template("junit_binary") { + set_sources_assignment_filter([]) + testonly = true + + _java_binary_target_name = "${target_name}__java_binary" + _test_runner_target_name = "${target_name}__test_runner_script" + + _build_config = "$target_gen_dir/$target_name.build_config" + _build_config_target_name = "${target_name}__build_config" + write_build_config(_build_config_target_name) { + type = "junit_binary" + build_config = _build_config + if (defined(invoker.deps)) { + possible_config_deps = invoker.deps + } + } + + test_runner_script(_test_runner_target_name) { + test_name = invoker.target_name + test_suite = invoker.target_name + test_type = "junit" + ignore_all_data_deps = true + forward_variables_from(invoker, + [ + "android_manifest_path", + "package_name", + ]) + } + + java_binary(_java_binary_target_name) { + deps = [] + output_name = invoker.target_name + forward_variables_from(invoker, "*") + testonly = true + bypass_platform_checks = true + main_class = "org.chromium.testing.local.JunitTestMain" + wrapper_script_name = "helper/$target_name" + deps += [ + "//testing/android/junit:junit_test_support", + "//third_party/junit", + "//third_party/mockito:mockito_java", + "//third_party/robolectric:robolectric_all_java", + ] + } + group(target_na