Move build -> gn/standalone
Make it explicit that those gn files are only for the standalone
build.
Bug: 68710794
Change-Id: I7e2a15219d63b62bf8f249becfdbf39fda2cc183
diff --git a/gn/BUILD.gn b/gn/BUILD.gn
index 92fba54..41b5217 100644
--- a/gn/BUILD.gn
+++ b/gn/BUILD.gn
@@ -83,8 +83,8 @@
public_configs = [ ":default_config" ]
if (!build_with_chromium) {
public_deps = [
- "//build/libc++:deps",
- "//build/sanitizers:deps",
+ "//gn/standalone/libc++:deps",
+ "//gn/standalone/sanitizers:deps",
]
}
}
diff --git a/gn/proto_library.gni b/gn/proto_library.gni
index 97b95d2..3ccdeab 100644
--- a/gn/proto_library.gni
+++ b/gn/proto_library.gni
@@ -15,9 +15,7 @@
import("//build_overrides/build.gni")
if (!build_with_chromium) {
- # TODO(primiano): Just move //build/proto_library.gni inside this branch,
- # there is no need to have that in //build at this point.
- import("//build/proto_library.gni")
+ import("//gn/standalone/proto_library.gni")
} else {
import("//third_party/protobuf/proto_library.gni")
}
diff --git a/gn/standalone/BUILD.gn b/gn/standalone/BUILD.gn
new file mode 100644
index 0000000..59f60fd
--- /dev/null
+++ b/gn/standalone/BUILD.gn
@@ -0,0 +1,200 @@
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("//gn/standalone/android.gni")
+import("//gn/standalone/sanitizers/sanitizers.gni")
+
+config("extra_warnings") {
+ cflags = [
+ "-Wextra",
+ "-Wno-missing-field-initializers",
+ "-Wno-unused-parameter",
+ ]
+ if (is_clang) {
+ cflags += [
+ "-Weverything",
+ "-Wno-c++98-compat-pedantic",
+ "-Wno-c++98-compat",
+ "-Wno-gnu-include-next",
+ "-Wno-gnu-statement-expression",
+ "-Wno-gnu-zero-variadic-macro-arguments",
+ "-Wno-padded",
+ "-Wno-reserved-id-macro",
+ "-Wno-weak-vtables",
+ ]
+ }
+}
+
+config("no_exceptions") {
+ cflags = [ "-fno-exceptions" ]
+}
+
+config("no_rtti") {
+ cflags = [ "-fno-rtti" ]
+}
+
+config("default") {
+ asmflags = []
+ cflags = []
+ cflags_c = []
+ cflags_cc = []
+ defines = []
+ ldflags = []
+ libs = []
+
+ cflags_cc += [ "-std=c++11" ]
+
+ cflags += [
+ "-fstrict-aliasing",
+ "-fstack-protector",
+ "-fPIC",
+ "-Wa,--noexecstack",
+ "-Wformat",
+ "-Wall",
+ "-Werror",
+ ]
+
+ # Color compiler output, see https://github.com/ninja-build/ninja/wiki/FAQ
+ if (is_clang) {
+ cflags += [
+ "-fcolor-diagnostics",
+ "-Wno-unknown-warning-option",
+ ]
+ } else {
+ cflags += [ "-Wno-unknown-warning" ]
+ }
+
+ if (current_cpu == "arm") {
+ cflags += [
+ "-march=armv7-a",
+ "-mfpu=neon",
+ "-mthumb",
+ ]
+ } else if (current_cpu == "x86") {
+ asmflags += [ "-m32" ]
+ cflags += [
+ "-m32",
+ "-msse2",
+ "-mfpmath=sse",
+ ]
+ ldflags += [ "-m32" ]
+ }
+
+ if (is_linux) {
+ libs += [
+ "pthread",
+ "rt",
+ ]
+ }
+
+ if (is_android) {
+ libs += [ "log" ]
+ }
+
+ if (is_android) {
+ asmflags += [ "--target=$android_abi_target" ]
+ cflags += [
+ "--sysroot=$android_compile_sysroot",
+ "-isystem$android_compile_sysroot/$android_compile_sysroot_subdir",
+ "-isystem$android_compile_sysroot",
+ "-DANDROID",
+ "-D__ANDROID_API__=21",
+ "--target=$android_abi_target",
+ ]
+ cflags_cc += [
+ "-I$android_ndk_root/sources/cxx-stl/llvm-libc++/include",
+ "-I$android_ndk_root/sources/android/support/include",
+ "-I$android_ndk_root/sources/cxx-stl/llvm-libc++abi/include",
+ ]
+ ldflags += [
+ "-Wl,-z,nocopyreloc",
+ "-gcc-toolchain",
+ "$android_toolchain_root",
+ "--sysroot=$android_ndk_root/$android_link_sysroot_subdir",
+ "--target=$android_abi_target",
+ "-Wl,--exclude-libs,libunwind.a",
+ "-Wl,--exclude-libs,libgcc.a",
+ "-Wl,--exclude-libs,libc++_static.a",
+ "-Wl,--build-id",
+ "-Wl,--no-undefined",
+ "-Wl,-z,noexecstack",
+ "-Wl,-z,relro",
+ "-Wl,-z,now",
+ "-Wl,--warn-shared-textrel",
+ "-Wl,--fatal-warnings",
+ ]
+ lib_dirs = [ "$android_ndk_root/sources/cxx-stl/llvm-libc++/libs/$android_app_abi" ]
+ libs += [
+ "gcc",
+ "c++_static",
+ "c++abi",
+ "android_support",
+ ]
+ }
+}
+
+config("debug_symbols") {
+ if (is_android) {
+ cflags = [
+ "-gline-tables-only",
+ "-funwind-tables",
+ ]
+ } else {
+ cflags = [ "-g2" ]
+ }
+}
+
+config("release") {
+ cflags = [
+ "-O3",
+ "-fdata-sections",
+ "-ffunction-sections",
+ ]
+ if (is_mac) {
+ ldflags = [ "-dead_strip" ]
+ } else {
+ ldflags = [ "-Wl,--gc-sections" ]
+ }
+ defines = [ "NDEBUG" ]
+}
+
+config("shared_library") {
+ if (is_android || is_linux) {
+ ldflags = [ "-fPIC" ]
+ }
+}
+
+config("executable") {
+ ldflags = []
+
+ # Android will refuse to run executables if they aren't position independent.
+ # Instead on Linux there isn't any need and they break ASan (goo.gl/paFR6K).
+ if (is_android) {
+ asmflags = [ "-fPIE" ]
+ cflags = [ "-fPIE" ]
+ ldflags += [ "-pie" ]
+ }
+
+ # -rpath stores the path to the linked shared libraries into the binary, so
+ # that they can be launched without passing any LD_LIBRARY_PATH. It's
+ # supported only by Linux, not Android. But concretely we need this only when
+ # use_custom_libcxx=true && custom_libcxx_is_static=false, which happens only
+ # on Linux right now.
+ if (is_linux) {
+ ldflags += [
+ "-Wl,-rpath=\$ORIGIN/.",
+ "-Wl,-rpath-link=.",
+ ]
+ }
+}
diff --git a/gn/standalone/BUILDCONFIG.gn b/gn/standalone/BUILDCONFIG.gn
new file mode 100644
index 0000000..b1d103f
--- /dev/null
+++ b/gn/standalone/BUILDCONFIG.gn
@@ -0,0 +1,83 @@
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+declare_args() {
+ is_debug = true
+ is_clang = true
+}
+
+declare_args() {
+ ar = "ar"
+}
+
+# Platform detection
+if (target_os == "") {
+ target_os = host_os
+}
+if (current_os == "") {
+ current_os = target_os
+}
+
+is_android = current_os == "android"
+is_linux = current_os == "linux"
+is_linux_host = host_os == "linux"
+is_mac = current_os == "mac"
+
+if (target_cpu == "") {
+ target_cpu = host_cpu
+ if (is_android) {
+ target_cpu = "arm"
+ }
+}
+if (current_cpu == "") {
+ current_cpu = target_cpu
+}
+
+default_configs = [
+ "//gn/standalone:debug_symbols",
+ "//gn/standalone:default",
+ "//gn/standalone:extra_warnings",
+ "//gn/standalone:no_exceptions",
+ "//gn/standalone:no_rtti",
+ "//gn/standalone/libc++:config",
+ "//gn/standalone/sanitizers:sanitizers_cflags",
+]
+
+if (!is_debug) {
+ default_configs += [ "//gn/standalone:release" ]
+}
+
+set_defaults("source_set") {
+ configs = default_configs
+}
+
+set_defaults("static_library") {
+ configs = default_configs
+}
+
+# Realistically the only shared_library that we build right now is libc++.so
+# when use_custom_libcxx=true (on Linux). Hence don't add a dependency on
+# libc++ itself on these targets.
+set_defaults("shared_library") {
+ configs = default_configs
+ configs += [ "//gn/standalone:shared_library" ]
+}
+
+set_defaults("executable") {
+ configs = default_configs
+ configs += [ "//gn/standalone:executable" ]
+}
+
+set_default_toolchain("//gn/standalone/toolchain:gcc_like")
+host_toolchain = "//gn/standalone/toolchain:gcc_like_host"
diff --git a/gn/standalone/android.gni b/gn/standalone/android.gni
new file mode 100644
index 0000000..e339eb2
--- /dev/null
+++ b/gn/standalone/android.gni
@@ -0,0 +1,81 @@
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+declare_args() {
+ android_api_level = 21
+ android_ndk_root = rebase_path("//buildtools/ndk")
+ _android_toolchain_version = "4.9"
+
+ if (host_os == "linux") {
+ android_host = "linux-x86_64"
+ } else if (host_os == "mac") {
+ android_host = "darwin-x86_64"
+ } else {
+ assert(false, "Need Android toolchain support for your build OS.")
+ }
+}
+
+declare_args() {
+ android_llvm_dir = "$android_ndk_root/toolchains/llvm/prebuilt/$android_host"
+ android_clangrt_dir = "$android_llvm_dir/lib64/clang/5.0/lib/linux"
+ android_compile_sysroot = "$android_ndk_root/sysroot/usr/include"
+
+ if (current_cpu == "x86") {
+ android_abi_target = "i686-linux-androideabi"
+ android_compile_sysroot_subdir = "i686-linux-android"
+ android_link_sysroot_subdir =
+ "platforms/android-${android_api_level}/arch-x86"
+ android_prebuilt_arch = "android-x86"
+ android_toolchain_root = "$android_ndk_root/toolchains/x86-${_android_toolchain_version}/prebuilt/$android_host"
+ android_llvm_arch = "i686"
+ } else if (current_cpu == "arm") {
+ android_abi_target = "arm-linux-androideabi"
+ android_compile_sysroot_subdir = "arm-linux-androideabi"
+ android_link_sysroot_subdir =
+ "platforms/android-${android_api_level}/arch-arm"
+ android_prebuilt_arch = "android-arm"
+ android_toolchain_root = "$android_ndk_root/toolchains/arm-linux-androideabi-${_android_toolchain_version}/prebuilt/$android_host"
+ android_llvm_arch = "arm"
+ } else if (current_cpu == "x64") {
+ android_abi_target = "x86_64-linux-androideabi"
+ android_compile_sysroot_subdir = "x86_64-linux-android"
+ android_link_sysroot_subdir =
+ "platforms/android-${android_api_level}/arch-x86_64"
+ android_prebuilt_arch = "android-x86_64"
+ android_toolchain_root = "$android_ndk_root/toolchains/x86_64-${_android_toolchain_version}/prebuilt/$android_host"
+ android_llvm_arch = "x86_64"
+ } else if (current_cpu == "arm64") {
+ android_abi_target = "aarch64-linux-android"
+ android_compile_sysroot_subdir = "aarch64-linux-android"
+ android_link_sysroot_subdir =
+ "platforms/android-${android_api_level}/arch-arm64"
+ android_prebuilt_arch = "android-arm64"
+ android_toolchain_root = "$android_ndk_root/toolchains/aarch64-linux-android-${_android_toolchain_version}/prebuilt/$android_host"
+ android_llvm_arch = "aarch64"
+ } else {
+ assert(false, "Need android libgcc support for this arch.")
+ }
+
+ if (current_cpu == "x86") {
+ android_app_abi = "x86"
+ } else if (current_cpu == "arm") {
+ android_app_abi = "armeabi-v7a"
+ } else if (current_cpu == "x64") {
+ android_app_abi = "x86_64"
+ } else if (current_cpu == "arm64") {
+ android_app_abi = "arm64-v8a"
+ } else {
+ assert(false, "Unknown ABI: " + current_cpu)
+ }
+}
diff --git a/gn/standalone/build_tool_wrapper.py b/gn/standalone/build_tool_wrapper.py
new file mode 100644
index 0000000..5b2f740
--- /dev/null
+++ b/gn/standalone/build_tool_wrapper.py
@@ -0,0 +1,33 @@
+#!/usr/bin/env python
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+""" Wrapper to invoke compiled build tools from the build system.
+
+This is just a workaround for GN assuming that all external scripts are
+python sources. It is used to invoke the built protoc compiler.
+"""
+
+import os
+import sys
+
+def main():
+ cmd = sys.argv[1:]
+ if not os.path.exists(cmd[0]):
+ print >> sys.stderr, 'Cannot find ' + cmd[0]
+ return 1
+ os.execv(cmd[0], cmd)
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/gn/standalone/libc++/BUILD.gn b/gn/standalone/libc++/BUILD.gn
new file mode 100644
index 0000000..a8ccba1
--- /dev/null
+++ b/gn/standalone/libc++/BUILD.gn
@@ -0,0 +1,49 @@
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("libc++.gni")
+
+config("config") {
+ if (use_custom_libcxx) {
+ defines = [
+ "_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS",
+ "_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS",
+ ]
+ cflags_cc = [
+ "-nostdinc++",
+ "-isystem" + rebase_path("$libcxx_prefix/include", root_build_dir),
+ "-isystem" + rebase_path("$libcxxabi_prefix/include", root_build_dir),
+ ]
+
+ # In theory here we want just -nostdlib++ to avoid linking both libc++ and
+ # libstdc++. Unfortunately the -nostdlib++ switch is available only in
+ # bleeding edge versions of clang. So, in order to get rid of libstdc++
+ # we have to remove all libs and then re-add the core ones like libc.
+ ldflags = [ "-nodefaultlibs" ]
+ libs = [
+ "c", # libc: the core C library.
+ "m", # libm: math library.
+ "dl", # libdl: dynamic linking.
+ "gcc_eh", # gcc exception handling, required by libunwind.
+ ]
+ }
+}
+
+group("deps") {
+ if (use_custom_libcxx) {
+ public_deps = [
+ "//buildtools:libc++",
+ ]
+ }
+}
diff --git a/gn/standalone/libc++/libc++.gni b/gn/standalone/libc++/libc++.gni
new file mode 100644
index 0000000..3306590
--- /dev/null
+++ b/gn/standalone/libc++/libc++.gni
@@ -0,0 +1,47 @@
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("//gn/standalone/sanitizers/sanitizers.gni")
+
+declare_args() {
+ # Background:
+ # there are mainly two C++ libraries around in the world: (i) GNU's
+ # libstdc++ and LLVM's libc++ (aka libcxx). By default Linux provides libstdc++
+ # (even building with clang on Linux uses that by default) while Mac and
+ # Android switched to libcxx.
+ # buildtools/libcxx(abi) contains a fixed version of the libcxx, the same one
+ # that Chrome uses on most production configurations (% lagging catching up
+ # with our DEPS).
+ # The variable use_custom_libcxx tells our build system to prefer the
+ # aforementioned copy to the system one.
+ #
+ # Now, there are two reasons for using the checked in copy of libcxx:
+ # 1) LLVM sanitizers require that the c++ library is built from sources,
+ # because they need to be instrumented with -fsanitize as well (see
+ # https://github.com/google/sanitizers/wiki/MemorySanitizerLibcxxHowTo).
+ # On top of this, they also require that the c++ library is dynamically
+ # linked to prevent duplicate symbol errors when linking (see Chrome's
+ # build/config/c++/c++.gni)
+ # 2) The libstdc++ situation is too wild on Linux. Modern debian distros are
+ # fine but Ubuntu Trusty still ships a libstdc++ that doesn't fully
+ # support C++11. Hence we enable this flag on Linux by default.
+ # We still retain libstdc++ coverage on the Travis bots by overriding
+ # use_custom_libcxx=false when we target a modern library (see the
+ # GCC7 target in .travis.yml).
+ use_custom_libcxx = is_linux && is_clang
+ custom_libcxx_is_static = !using_sanitizer
+}
+
+libcxx_prefix = "//buildtools/libcxx"
+libcxxabi_prefix = "//buildtools/libcxxabi"
diff --git a/gn/standalone/proto_library.gni b/gn/standalone/proto_library.gni
new file mode 100644
index 0000000..90c7819
--- /dev/null
+++ b/gn/standalone/proto_library.gni
@@ -0,0 +1,196 @@
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+template("proto_library") {
+ assert(defined(invoker.sources))
+ proto_sources = invoker.sources
+
+ # All the proto imports should be relative to the project root.
+ proto_in_dir = "//"
+ if (defined(invoker.proto_in_dir)) {
+ proto_in_dir = invoker.proto_in_dir
+ }
+ assert(defined(invoker.proto_out_dir),
+ "proto_out_dir must be explicitly defined")
+ proto_out_dir = invoker.proto_out_dir
+ assert(proto_out_dir == "protos_zero" || proto_out_dir == "protos_lite" ||
+ proto_out_dir == "protos_full",
+ "proto_out must be either 'proto_zero', 'proto_lite' or 'proto_full'")
+
+ # If false will not generate the default .pb.{cc,h} files. Used for custom
+ # codegen plugins.
+ generate_cc = true
+ if (defined(invoker.generate_cc)) {
+ generate_cc = invoker.generate_cc
+ }
+
+ if (defined(invoker.generator_plugin_label)) {
+ plugin_host_label = invoker.generator_plugin_label + "($host_toolchain)"
+ plugin_path = get_label_info(plugin_host_label, "root_out_dir") + "/" +
+ get_label_info(plugin_host_label, "name")
+ generate_with_plugin = true
+ } else if (defined(invoker.generator_plugin_script)) {
+ plugin_path = invoker.generator_plugin_script
+ generate_with_plugin = true
+ } else {
+ generate_with_plugin = false
+ }
+
+ if (generate_with_plugin) {
+ if (defined(invoker.generator_plugin_suffix)) {
+ generator_plugin_suffixes = [
+ "${invoker.generator_plugin_suffix}.h",
+ "${invoker.generator_plugin_suffix}.cc",
+ ]
+ } else {
+ generator_plugin_suffixes = invoker.generator_plugin_suffixes
+ }
+ }
+
+ cc_out_dir = "$root_gen_dir/" + proto_out_dir
+ rel_cc_out_dir = rebase_path(cc_out_dir, root_build_dir)
+
+ protos = rebase_path(proto_sources, proto_in_dir)
+ protogens = []
+
+ foreach(proto, protos) {
+ proto_dir = get_path_info(proto, "dir")
+ proto_name = get_path_info(proto, "name")
+ proto_path = proto_dir + "/" + proto_name
+
+ if (generate_cc) {
+ protogens += [
+ "$cc_out_dir/$proto_path.pb.h",
+ "$cc_out_dir/$proto_path.pb.cc",
+ ]
+ }
+ if (generate_with_plugin) {
+ foreach(suffix, generator_plugin_suffixes) {
+ protogens += [ "$cc_out_dir/${proto_path}${suffix}" ]
+ }
+ }
+ }
+
+ config_name = "${target_name}_config"
+ action_name = "${target_name}_gen"
+ source_set_name = target_name
+
+ config(config_name) {
+ include_dirs = [ cc_out_dir ]
+ }
+
+ # The XXX_gen action that generates the .pb.{cc,h} files.
+ action(action_name) {
+ visibility = [ ":$source_set_name" ]
+ script = "//gn/standalone/build_tool_wrapper.py"
+ sources = proto_sources
+ outputs = get_path_info(protogens, "abspath")
+
+ protoc_label = "//buildtools:protoc($host_toolchain)"
+ protoc_path = get_label_info(protoc_label, "root_out_dir") + "/protoc"
+ args = [
+ # Path should be rebased because |root_build_dir| for current toolchain
+ # may be different from |root_out_dir| of protoc built on host toolchain.
+ "./" + rebase_path(protoc_path, root_build_dir),
+ "--proto_path",
+ rebase_path(proto_in_dir, root_build_dir),
+ ]
+ if (generate_cc) {
+ args += [
+ "--cpp_out",
+ rel_cc_out_dir,
+ ]
+ }
+
+ if (generate_with_plugin) {
+ plugin_path_rebased = rebase_path(plugin_path, root_build_dir)
+ plugin_out_args = ""
+ if (defined(invoker.generator_plugin_options)) {
+ plugin_out_args += invoker.generator_plugin_options
+ }
+ plugin_out_args += ":$rel_cc_out_dir"
+
+ args += [
+ "--plugin=protoc-gen-plugin=$plugin_path_rebased",
+ "--plugin_out=$plugin_out_args",
+ ]
+ }
+
+ args += rebase_path(proto_sources, root_out_dir)
+
+ inputs = [
+ protoc_path,
+ ]
+
+ deps = [
+ protoc_label,
+ ]
+ if (generate_with_plugin) {
+ inputs += [ plugin_path ]
+ if (defined(plugin_host_label)) {
+ # Action depends on native generator plugin but for host toolchain only.
+ deps += [ plugin_host_label ]
+ }
+ }
+
+ if (defined(invoker.deps)) {
+ deps += invoker.deps
+ }
+ } # action "${target_name}_gen"
+
+ # The source_set that builds the generated .pb.cc files.
+ source_set(target_name) {
+ forward_variables_from(invoker,
+ [
+ "defines",
+ "include_dirs",
+ "public_configs",
+ "testonly",
+ "visibility",
+ ])
+
+ sources = get_target_outputs(":$action_name")
+
+ configs -= [ "//gn/standalone:extra_warnings" ]
+ if (defined(invoker.extra_configs)) {
+ configs += invoker.extra_configs
+ }
+
+ if (!defined(invoker.public_configs)) {
+ public_configs = []
+ }
+
+ public_configs += [
+ "//buildtools:protobuf_gen_config",
+ ":$config_name",
+ ]
+
+ # Use protobuf_full only for tests.
+ if (defined(invoker.use_protobuf_full) &&
+ invoker.use_protobuf_full == true) {
+ deps = [
+ "//buildtools:protobuf_full",
+ ]
+ } else {
+ deps = [
+ "//buildtools:protobuf_lite",
+ ]
+ }
+
+ deps += [ ":$action_name" ]
+ if (defined(invoker.deps)) {
+ deps += invoker.deps
+ }
+ } # source_set(target_name)
+} # template
diff --git a/gn/standalone/sanitizers/BUILD.gn b/gn/standalone/sanitizers/BUILD.gn
new file mode 100644
index 0000000..0fec24a
--- /dev/null
+++ b/gn/standalone/sanitizers/BUILD.gn
@@ -0,0 +1,119 @@
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("//gn/standalone/sanitizers/sanitizers.gni")
+
+# Link dependencies for sanitizers for executables.
+group("deps") {
+ visibility = [ "*" ]
+ if (using_sanitizer) {
+ public_configs = [ ":sanitizers_ldflags" ]
+ if (is_android && sanitizer_lib != "" && !sanitizer_lib_dir_is_static) {
+ deps = [
+ ":copy_sanitizer_lib",
+ ]
+ }
+ }
+}
+
+if (is_android && sanitizer_lib != "" && !sanitizer_lib_dir_is_static) {
+ copy("copy_sanitizer_lib") {
+ sources = [
+ "${sanitizer_lib_dir}/lib${sanitizer_lib}.so",
+ ]
+ outputs = [
+ "${root_out_dir}/sanitizer_libs/lib${sanitizer_lib}.so",
+ ]
+ }
+}
+
+config("sanitizers_cflags") {
+ if (using_sanitizer) {
+ blacklist_path_ = rebase_path("blacklist.txt", root_build_dir)
+ cflags = [
+ "-fno-omit-frame-pointer",
+ "-fsanitize-blacklist=$blacklist_path_",
+ ]
+ defines = []
+ }
+
+ if (is_asan) {
+ cflags += [ "-fsanitize=address" ]
+ defines += [ "ADDRESS_SANITIZER" ]
+ }
+ if (is_lsan) {
+ cflags += [ "-fsanitize=leak" ]
+ defines += [ "LEAK_SANITIZER" ]
+ }
+ if (is_tsan) {
+ cflags += [ "-fsanitize=thread" ]
+ defines += [
+ "THREAD_SANITIZER",
+ "DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL=1",
+ ]
+ }
+ if (is_msan) {
+ cflags += [
+ "-fsanitize=memory",
+ "-fsanitize-memory-track-origins=2",
+ ]
+ defines += [ "MEMORY_SANITIZER" ]
+ }
+ if (is_ubsan) {
+ cflags += [
+ "-fsanitize=bounds",
+ "-fsanitize=float-divide-by-zero",
+ "-fsanitize=integer-divide-by-zero",
+ "-fsanitize=null",
+ "-fsanitize=object-size",
+ "-fsanitize=return",
+ "-fsanitize=returns-nonnull-attribute",
+ "-fsanitize=shift-exponent",
+ "-fsanitize=signed-integer-overflow",
+ "-fsanitize=unreachable",
+ "-fsanitize=vla-bound",
+ ]
+ defines += [ "UNDEFINED_SANITIZER" ]
+ }
+}
+
+config("sanitizer_options_link_helper") {
+ if (is_mac) {
+ ldflags = [ "-Wl,-U,_sanitizer_options_link_helper" ]
+ }
+}
+
+config("sanitizers_ldflags") {
+ visibility = [ ":deps" ]
+ ldflags = []
+ if (is_asan) {
+ ldflags += [ "-fsanitize=address" ]
+ }
+ if (is_lsan) {
+ # This is not a copy/paste mistake. The LSan runtime library has
+ # moved into asan. So in order to make LSan work one has to build
+ # .cc files with -fsanitize=leak but link with -fsanitize=address.
+ ldflags += [ "-fsanitize=address" ]
+ }
+ if (is_tsan) {
+ ldflags += [ "-fsanitize=thread" ]
+ }
+ if (is_msan) {
+ ldflags += [ "-fsanitize=memory" ]
+ }
+ if (is_ubsan) {
+ ldflags += [ "-fsanitize=undefined" ]
+ }
+ configs = [ ":sanitizer_options_link_helper" ]
+}
diff --git a/gn/standalone/sanitizers/blacklist.txt b/gn/standalone/sanitizers/blacklist.txt
new file mode 100644
index 0000000..e0e315b
--- /dev/null
+++ b/gn/standalone/sanitizers/blacklist.txt
@@ -0,0 +1 @@
+# The rules in this file are only applied at compile time.
diff --git a/gn/standalone/sanitizers/sanitizers.gni b/gn/standalone/sanitizers/sanitizers.gni
new file mode 100644
index 0000000..95f40d1
--- /dev/null
+++ b/gn/standalone/sanitizers/sanitizers.gni
@@ -0,0 +1,61 @@
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("//gn/standalone/android.gni")
+import("//gn/standalone/sanitizers/vars.gni")
+import("//gn/standalone/toolchain/llvm.gni")
+
+declare_args() {
+ sanitizer_lib_base_name_ = ""
+ if (is_asan || is_tsan || is_ubsan) {
+ if (is_asan) {
+ sanitizer_lib_base_name_ = "clang_rt.asan"
+ }
+ if (is_tsan) {
+ sanitizer_lib_base_name_ = "clang_rt.tsan"
+ }
+ if (is_ubsan) {
+ sanitizer_lib_base_name_ = "clang_rt.ubsan"
+ if (is_android || is_linux) {
+ sanitizer_lib_base_name_ += "_standalone"
+ }
+ }
+ }
+}
+
+declare_args() {
+ sanitizer_lib_dir = ""
+ sanitizer_lib = ""
+ sanitizer_lib_dir_is_static = false
+ if (sanitizer_lib_base_name_ != "") {
+ if (is_mac) {
+ sanitizer_lib = "${sanitizer_lib_base_name_}_osx_dynamic"
+ sanitizer_lib_dir = mac_clangrt_dir
+ }
+ if (is_linux) {
+ sanitizer_lib = "lib${sanitizer_lib_base_name_}-x86_64.a"
+ sanitizer_lib_dir_is_static = true
+ sanitizer_lib_dir = linux_clangrt_dir
+ }
+ if (is_android) {
+ sanitizer_lib = "${sanitizer_lib_base_name_}-${android_llvm_arch}-android"
+ sanitizer_lib_dir = android_clangrt_dir
+ }
+ }
+}
+
+using_sanitizer = is_asan || is_lsan || is_tsan || is_msan || is_ubsan
+assert(!using_sanitizer || is_clang, "is_*san requires is_clang=true'")
+assert(!is_msan || is_linux, "msan only supported on linux")
+assert(!is_tsan || (is_linux || is_mac), "tsan only supported on linux and mac")
diff --git a/gn/standalone/sanitizers/vars.gni b/gn/standalone/sanitizers/vars.gni
new file mode 100644
index 0000000..7ad54ab
--- /dev/null
+++ b/gn/standalone/sanitizers/vars.gni
@@ -0,0 +1,38 @@
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+declare_args() {
+ # Address Sanitizer: memory bugs (e.g., UAF).
+ is_asan = false
+
+ # Leak Sanitizer: memory leaks.
+ is_lsan = false
+
+ # Memory Sanitizer: uninitialized reads.
+ is_msan = false
+
+ # Thread Sanitizer: threading bugs.
+ is_tsan = false
+
+ # Undefined Behaviour Sanitizer.
+ is_ubsan = false
+}
+
+declare_args() {
+ using_sanitizer = is_asan || is_lsan || is_tsan || is_msan || is_ubsan
+}
+
+assert(!using_sanitizer || is_clang, "is_*san requires is_clang=true'")
+assert(!is_msan || is_linux, "msan only supported on linux")
+assert(!is_tsan || (is_linux || is_mac), "tsan only supported on linux and mac")
diff --git a/gn/standalone/toolchain/BUILD.gn b/gn/standalone/toolchain/BUILD.gn
new file mode 100644
index 0000000..251c7c2
--- /dev/null
+++ b/gn/standalone/toolchain/BUILD.gn
@@ -0,0 +1,164 @@
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("//gn/standalone/android.gni")
+import("llvm.gni")
+
+declare_args() {
+ if (is_clang) {
+ if (is_linux) {
+ cc = linux_clang_bin
+ cxx = linux_clangxx_bin
+ } else {
+ cc = "clang"
+ cxx = "clang++"
+ }
+ } else {
+ cc = "gcc"
+ cxx = "g++"
+ }
+}
+
+declare_args() {
+ host_ar = ar
+ if (is_linux_host && is_clang) {
+ host_cc = linux_clang_bin
+ host_cxx = linux_clangxx_bin
+ } else {
+ host_cc = cc
+ host_cxx = cxx
+ }
+
+ if (is_android) {
+ target_ar = "$android_toolchain_root/bin/ar"
+ target_cc = "$android_llvm_dir/bin/clang"
+ target_cxx = "$android_llvm_dir/bin/clang++"
+ } else {
+ target_ar = ar
+ target_cc = cc
+ target_cxx = cxx
+ }
+ cc_wrapper = ""
+}
+
+python = "python"
+stamp = "touch"
+
+template("gcc_like_toolchain") {
+ toolchain(target_name) {
+ ar = invoker.ar
+ cc = invoker.cc
+ cxx = invoker.cxx
+ lib_switch = "-l"
+ lib_dir_switch = "-L"
+
+ tool("cc") {
+ depfile = "{{output}}.d"
+ command = "$cc_wrapper $cc -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}} -c {{source}} -o {{output}}"
+ depsformat = "gcc"
+ outputs = [
+ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
+ ]
+ description = "compile {{source}}"
+ }
+
+ tool("cxx") {
+ depfile = "{{output}}.d"
+ command = "$cc_wrapper $cxx -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}} -c {{source}} -o {{output}}"
+ depsformat = "gcc"
+ outputs = [
+ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
+ ]
+ description = "compile {{source}}"
+ }
+
+ tool("asm") {
+ depfile = "{{output}}.d"
+ command = "$cc_wrapper $cc -MMD -MF $depfile {{defines}} {{include_dirs}} {{asmflags}} -c {{source}} -o {{output}}"
+ depsformat = "gcc"
+ outputs = [
+ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
+ ]
+ description = "assemble {{source}}"
+ }
+
+ tool("alink") {
+ rspfile = "{{output}}.rsp"
+ rspfile_content = "{{inputs}}"
+ command = "$ar {{output}} $rspfile"
+ outputs = [
+ "{{root_out_dir}}/{{target_output_name}}{{output_extension}}",
+ ]
+ default_output_extension = ".a"
+ output_prefix = "lib"
+ description = "link {{output}}"
+ }
+
+ tool("solink") {
+ soname = "{{target_output_name}}{{output_extension}}"
+
+ rpath = "-Wl,-soname,$soname"
+ if (is_mac) {
+ rpath = "-Wl,-install_name,@rpath/$soname"
+ }
+
+ command = "$cc_wrapper $cxx -shared {{ldflags}} {{inputs}} {{solibs}} {{libs}} $rpath -o {{output}}"
+ outputs = [
+ "{{root_out_dir}}/$soname",
+ ]
+ output_prefix = "lib"
+ default_output_extension = ".so"
+ description = "link {{output}}"
+ }
+
+ tool("link") {
+ command = "$cc_wrapper $cxx {{ldflags}} {{inputs}} {{solibs}} {{libs}} -o {{output}}"
+ outputs = [
+ "{{root_out_dir}}/{{target_output_name}}{{output_extension}}",
+ ]
+ description = "link {{output}}"
+ }
+
+ tool("stamp") {
+ command = "touch {{output}}"
+ description = "stamp {{output}}"
+ }
+
+ tool("copy") {
+ command = "cp -af {{source}} {{output}}"
+ description = "COPY {{source}} {{output}}"
+ }
+
+ toolchain_args = {
+ current_cpu = invoker.cpu
+ current_os = invoker.os
+ }
+ }
+}
+
+gcc_like_toolchain("gcc_like") {
+ cpu = current_cpu
+ os = current_os
+ ar = target_ar
+ cc = target_cc
+ cxx = target_cxx
+}
+
+gcc_like_toolchain("gcc_like_host") {
+ cpu = host_cpu
+ os = host_os
+ ar = host_ar
+ cc = host_cc
+ cxx = host_cxx
+}
diff --git a/gn/standalone/toolchain/linux_find_llvm.py b/gn/standalone/toolchain/linux_find_llvm.py
new file mode 100644
index 0000000..bccd17e
--- /dev/null
+++ b/gn/standalone/toolchain/linux_find_llvm.py
@@ -0,0 +1,40 @@
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os
+import subprocess
+import sys
+
+def main():
+ devnull = open(os.devnull, 'w')
+ for clang in ('clang', 'clang-3.8', 'clang-3.5'):
+ if subprocess.call(['which', clang], stdout=devnull, stderr=devnull) != 0:
+ continue
+ res = subprocess.check_output([clang, '-print-search-dirs'])
+ for line in res.splitlines():
+ if not line.startswith('libraries:'):
+ continue
+ libs = line.split('=', 1)[1].split(':')
+ for lib in libs:
+ if '/clang/' not in lib or not os.path.isdir(lib + '/lib'):
+ continue
+ print os.path.abspath(lib)
+ print clang
+ print clang.replace('clang', 'clang++')
+ return 0
+ print 'Could not find the LLVM lib dir'
+ return 1
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/gn/standalone/toolchain/llvm.gni b/gn/standalone/toolchain/llvm.gni
new file mode 100644
index 0000000..ae490ad
--- /dev/null
+++ b/gn/standalone/toolchain/llvm.gni
@@ -0,0 +1,44 @@
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("//gn/standalone/sanitizers/vars.gni")
+
+declare_args() {
+ is_hermetic_clang = is_clang && is_linux_host && using_sanitizer
+}
+
+assert(!is_hermetic_clang || is_clang, "is_hermetic_clang requires is_clang")
+
+declare_args() {
+ if (is_linux_host) {
+ if (is_hermetic_clang) {
+ _hermetic_llvm_dir = rebase_path("//buildtools/clang", root_build_dir)
+ linux_llvm_dir = "$_hermetic_llvm_dir/lib/clang/6.0.0/"
+ linux_clang_bin = "$_hermetic_llvm_dir/bin/clang"
+ linux_clangxx_bin = "$_hermetic_llvm_dir/bin/clang++"
+ linux_clangrt_dir = "$_hermetic_llvm_dir/lib/clang/6.0.0/lib/linux"
+ } else if (is_clang) {
+ # Guess the path for the system clang.
+ find_llvm_out = exec_script("linux_find_llvm.py", [], "list lines")
+ linux_llvm_dir = find_llvm_out[0]
+ linux_clang_bin = find_llvm_out[1]
+ linux_clangxx_bin = find_llvm_out[2]
+ linux_clangrt_dir = "$linux_llvm_dir/lib/linux"
+ }
+ } else if (is_mac) {
+ mac_toolchain_dirs_ = exec_script("mac_find_llvm.py", [], "list lines")
+ mac_toolchain_dir = mac_toolchain_dirs_[0]
+ mac_clangrt_dir = mac_toolchain_dirs_[1]
+ }
+}
diff --git a/gn/standalone/toolchain/mac_find_llvm.py b/gn/standalone/toolchain/mac_find_llvm.py
new file mode 100644
index 0000000..17d1ea1
--- /dev/null
+++ b/gn/standalone/toolchain/mac_find_llvm.py
@@ -0,0 +1,36 @@
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import glob
+import os
+import subprocess
+import sys
+
+def main():
+ job = subprocess.Popen(['xcrun', '-f', 'clang++'],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
+ out, err = job.communicate()
+ if job.returncode != 0:
+ print >> sys.stderr, out
+ print >> sys.stderr, err
+ return job.returncode
+ sdk_dir = os.path.dirname(os.path.dirname(out.rstrip()))
+ print sdk_dir
+ clang_dir = glob.glob(os.path.join(sdk_dir, 'lib', 'clang', '*', 'lib', 'darwin'))
+ print clang_dir[0] if clang_dir else 'CLANG_DIR_NOT_FOUND'
+
+
+if __name__ == '__main__':
+ sys.exit(main())