Commit 9dcbadfa authored by brettw@chromium.org's avatar brettw@chromium.org

Work on Android GN build.

Adds arm version and some android configuration build flags.

This adds most of the logic from common.gypi to the Android GN build.

This is currently missing the crtbegin/end stuff and won't actually make real Android builds. The logic in this patch is just the initial conversion that will require testing and several more passes of fixes.

R=torne@chromium.org, torne

Review URL: https://codereview.chromium.org/121173005

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@243681 0039d316-1c4b-4281-b951-d872f2087c98
parent 82110212
# 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) {
declare_args() {
android_src = ""
# This is set when building the Android WebView inside the Android build
# system, using the 'android' gyp backend. The WebView code is still built
# when this is unset, but builds using the normal chromium build system.
is_android_webview_build = false
}
if (is_android_webview_build) {
assert(android_src != "",
"You must specify android_src for an Android WebView build.")
}
# android_ndk_root -----------------------------------------------------------
# Full system path to the Android NDK.
android_ndk_root =
rebase_path("//third_party/android_tools/ndk", ".", "")
# stlport stuff --------------------------------------------------------------
use_system_stlport = is_android_webview_build
if (use_system_stlport) {
android_stlport_library = "stlport"
} else if (component_mode == "shared_library") {
android_stlport_library = "stlport_shared"
} else {
android_stlport_library = "stlport_static"
}
# ABI ------------------------------------------------------------------------
if (cpu_arch == "x86") {
android_app_abi = "x86"
} else if (cpu_arch == "arm") {
import("//build/config/arm.gni")
if (arm_version < 7) {
android_app_abi = "armeabi"
} else {
android_app_abi = "armeabi-v7a"
}
} else if (cpu_arch == "mipsel") {
android_app_abi = "mips"
} else {
assert(false, "Unknown Android ABI")
}
} else {
if (!defined(is_android_webview_build)) {
is_android_webview_build = false
}
use_system_stlport = false
}
# 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.
declare_args() {
# Version of the ARM processor when compiling on ARM. Ignored on non-ARM
# platforms.
arm_version = 7
}
...@@ -2,13 +2,34 @@ ...@@ -2,13 +2,34 @@
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
import("//build/config/android/config.gni")
import("//build/config/sysroot.gni") import("//build/config/sysroot.gni")
# compiler ---------------------------------------------------------------------
#
# Base compiler configuration. # Base compiler configuration.
#
# See also "runtime_library" below for related stuff and a discusison about
# where stuff should go. Put warning related stuff in the "warnings" config.
config("compiler") { config("compiler") {
include_dirs = [ "//", root_gen_dir ] cflags = []
cflags_c = []
cflags_cc = []
ldflags = []
defines = []
include_dirs = []
include_dirs += [ "//", root_gen_dir ]
# In general, Windows is totally different, but all the other builds share
# some common GCC configuration. This section sets up Windows and the common
# GCC flags, and then we handle the other non-Windows platforms specifically
# below.
if (is_win) { if (is_win) {
cflags = [ # Windows compiler flags setup.
# -----------------------------
cflags += [
"/Gy", # Enable function-level linking. "/Gy", # Enable function-level linking.
"/GS", # Enable buffer security checking. "/GS", # Enable buffer security checking.
"/EHsc", # Assume C functions can't throw exceptions and don't catch "/EHsc", # Assume C functions can't throw exceptions and don't catch
...@@ -17,19 +38,15 @@ config("compiler") { ...@@ -17,19 +38,15 @@ config("compiler") {
} else { } else {
# Common GCC compiler flags setup. # Common GCC compiler flags setup.
# -------------------------------- # --------------------------------
cflags = [ cflags += [
"-fno-strict-aliasing", # See http://crbug.com/32204 "-fno-strict-aliasing", # See http://crbug.com/32204
"-fvisibility=hidden", "-fvisibility=hidden",
] ]
cflags_c = [ cflags_cc += [
]
cflags_cc = [
"-fno-exceptions", "-fno-exceptions",
"-fno-threadsafe-statics", "-fno-threadsafe-statics",
"-fvisibility-inlines-hidden", "-fvisibility-inlines-hidden",
] ]
ldflags = [
]
# Stack protection. # Stack protection.
if (is_mac) { if (is_mac) {
...@@ -37,114 +54,172 @@ config("compiler") { ...@@ -37,114 +54,172 @@ config("compiler") {
} else if (is_linux) { } else if (is_linux) {
cflags += [ "-fstack-protector", "--param=ssp-buffer-size=4" ] cflags += [ "-fstack-protector", "--param=ssp-buffer-size=4" ]
} }
}
if (is_mac) { # Mac-specific compiler flags setup.
# Mac-specific compiler flags setup. # ----------------------------------
# ---------------------------------- if (is_mac) {
# These flags are shared between the C compiler and linker.
common_mac_flags = [
"-isysroot", sysroot,
"-mmacosx-version-min=10.6",
]
# These flags are shared between the C compiler and linker. # CPU architecture.
common_mac_flags = [ if (cpu_arch == "x64") {
"-isysroot", sysroot, common_mac_flags += "-arch x86_64"
"-mmacosx-version-min=10.6", } else if (cpu_arch == "x86") {
] common_mac_flags += "-arch i386"
}
# CPU architecture. cflags += common_mac_flags + [
if (cpu_arch == "x64") { # Without this, the constructors and destructors of a C++ object inside
common_mac_flags += "-arch x86_64" # an Objective C struct won't be called, which is very bad.
} else if (cpu_arch == "x86") { "-fobjc-call-cxx-cdtors",
common_mac_flags += "-arch i386" ]
}
cflags += common_mac_flags + [ cflags_c += [ "-std=c99" ]
# Without this, the constructors and destructors of a C++ object inside cflags_cc += [ "-std=gnu++11" ]
# an Objective C struct won't be called, which is very bad.
"-fobjc-call-cxx-cdtors",
]
cflags_c += [ "-std=c99" ] ldflags += common_mac_flags + [
cflags_cc += [ "-std=gnu++11" ] "-L.",
ldflags += common_mac_flags + [ # TODO(brettW) I don't understand these options.
"-L.", "-Wl,-rpath,@loader_path/.",
"-Wl,-rpath,@loader_path/../../..",
]
} else if (is_posix) {
# Non-Mac Posix compiler flags setup.
# -----------------------------------
# CPU architecture. We may or may not be doing a cross compile now, so for
# simplicity we always explicitly set the architecture.
if (cpu_arch == "x64") {
cflags += "-m64"
ldflags += "-m64"
} else if (cpu_arch == "x86") {
cflags += "-m32"
ldflags += "-m32"
}
}
# TODO(brettW) I don't understand these options. # Linux-specific compiler flags setup.
"-Wl,-rpath,@loader_path/.", # ------------------------------------
"-Wl,-rpath,@loader_path/../../..", if (is_linux) {
] cflags += [
} else { "-fPIC",
# Non-Mac Posix compiler flags setup. "-pipe", # Use pipes for communicating between sub-processes. Faster.
# ----------------------------------- ]
if (!is_android) {
# CPU architecture. We may or may not be doing a cross compile now, so for cflags += [ "-pthread" ]
# simplicity we always explicitly set the architecture.
if (cpu_arch == "x64") {
cflags += "-m64"
ldflags += "-m64"
} else if (cpu_arch == "x86") {
cflags += "-m32"
ldflags += "-m32"
}
} }
# Linux-specific compiler flags setup. # Use gold for linking on 64-bit Linux only (on 32-bit it runs out of
# ------------------------------------ # address space, and it doesn't support cross-compiling).
if (is_linux) { if (cpu_arch == "x64") {
cflags += [ gold_path = rebase_path("//third_party/gold", ".", root_build_dir)
"-fPIC", ldflags += [
"-pthread", "-B$gold_path",
"-pipe", # Use pipes for communicating between sub-processes. Faster.
# There seems to be a conflict of --icf and -pie in gold which can
# generate crashy binaries. As a security measure, -pie takes
# precendence for now.
# TODO(brettw) common.gypi has this only for target toolset.
#"-Wl,--icf=safe",
"-Wl,--icf=none",
# Experimentation found that using four linking threads
# saved ~20% of link time.
# https://groups.google.com/a/chromium.org/group/chromium-dev/browse_thread/thread/281527606915bb36
# Only apply this to the target linker, since the host
# linker might not be gold, but isn't used much anyway.
"-Wl,--threads",
"-Wl,--thread-count=4",
] ]
}
# Use gold for linking on 64-bit Linux only (on 32-bit it runs out of if (sysroot != "") {
# address space, and it doesn't support cross-compiling). cflags += "--sysroot=" + sysroot
if (cpu_arch == "x64") { ldflags += "--sysroot=" + sysroot
gold_path = rebase_path("//third_party/gold", ".", root_build_dir)
ldflags += [
"-B$gold_path",
# There seems to be a conflict of --icf and -pie in gold which can
# generate crashy binaries. As a security measure, -pie takes
# precendence for now.
# TODO(brettw) common.gypi has this only for target toolset.
#"-Wl,--icf=safe",
"-Wl,--icf=none",
# Experimentation found that using four linking threads
# saved ~20% of link time.
# https://groups.google.com/a/chromium.org/group/chromium-dev/browse_thread/thread/281527606915bb36
# Only apply this to the target linker, since the host
# linker might not be gold, but isn't used much anyway.
"-Wl,--threads",
"-Wl,--thread-count=4",
]
}
if (sysroot != "") { # Need to get some linker flags out of the sysroot.
cflags += "--sysroot=" + sysroot ldflags += exec_script("../linux/sysroot_ld_path.py",
ldflags += "--sysroot=" + sysroot [rebase_path("../../linux/sysroot_ld_path.sh", ".", root_build_dir),
sysroot],
"value")
}
# Need to get some linker flags out of the sysroot. ldflags += [
ldflags += exec_script("../linux/sysroot_ld_path.py", "-fPIC",
[rebase_path("../../linux/sysroot_ld_path.sh", ".", root_build_dir), "-pthread",
sysroot], "-Wl,-z,noexecstack",
"value") "-Wl,-z,now",
} "-Wl,-z,relro",
]
}
# Clang-specific compiler flags setup.
# ------------------------------------
if (is_clang) {
cflags += [
"-fcolor-diagnostics",
]
}
# Android-specific flags setup.
# -----------------------------
if (is_android) {
cflags += [
"-ffunction-sections",
"-funwind-tables",
"-fno-short-enums",
"-finline-limit=64",
]
if (is_android_webview_build) {
# Android predefines this as 1; undefine it here so Chromium can redefine
# it later to be 2 for chromium code and unset for third party code. This
# works because cflags are added before defines.
# TODO(brettw) the above comment seems incorrect. We specify defines
# before cflags on our compiler command lines.
cflags += [ "-U_FORTIFY_SOURCE" ]
}
if (is_asan) {
# Android build relies on -Wl,--gc-sections removing unreachable code.
# ASan instrumentation for globals inhibits this and results in a library
# with unresolvable relocations.
# TODO(eugenis): find a way to reenable this.
cflags += [ "-mllvm -asan-globals=0" ]
}
defines += [ "ANDROID" ]
if (!is_android_webview_build) {
# The NDK has these things, but doesn't define the constants
# to say that it does. Define them here instead.
defines += [ "HAVE_SYS_UIO_H" ]
}
ldflags += [
"-Wl,--no-undefined",
# Don't export symbols from statically linked libraries.
"-Wl,--exclude-libs=ALL",
]
if (cpu_arch == "arm") {
ldflags += [ ldflags += [
"-fPIC", # Enable identical code folding to reduce size.
"-pthread", "-Wl,--icf=safe",
"-Wl,-z,noexecstack",
"-Wl,-z,now",
"-Wl,-z,relro",
] ]
} }
# Clang-specific compiler flags setup. if (cpu_arch == "arm") {
# ------------------------------------
if (is_clang) {
cflags += [ cflags += [
"-fcolor-diagnostics", "-target arm-linux-androideabi",
"-mllvm -arm-enable-ehabi",
] ]
ldflags += [ "-target arm-linux-androideabi" ]
} else if (cpu_arch == "x86") {
cflags += [ "-target x86-linux-androideabi" ]
ldflags += [ "-target x86-linux-androideabi" ]
} }
} }
} }
...@@ -153,21 +228,29 @@ config("compiler") { ...@@ -153,21 +228,29 @@ config("compiler") {
# #
# Sets the runtime library and associated options. # Sets the runtime library and associated options.
# #
# We don't bother making multiple versions that are toggle-able since there # How do you determine what should go in here vs. "compiler" above? Consider if
# is more than one axis of control (which makes it complicated) and there's # a target might choose to use a different runtime library (ignore for a moment
# no practical reason for anybody to change this since the CRT must agree. # if this is possible or reasonable on your system). If such a target would want
# to change or remove your option, put it in the runtime_library config. If a
# target wants the option regardless, put it in the compiler config.
config("runtime_library") { config("runtime_library") {
cflags = []
defines = []
ldflags = []
lib_dirs = []
libs = []
if (is_component_build) { if (is_component_build) {
# Component mode: dynamic CRT. # Component mode: dynamic CRT.
defines = [ "COMPONENT_BUILD" ] defines += [ "COMPONENT_BUILD" ]
if (is_win) { if (is_win) {
# Since the library is shared, it requires exceptions or will give errors # Since the library is shared, it requires exceptions or will give errors
# about things not matching, so keep exceptions on. # about things not matching, so keep exceptions on.
if (is_debug) { if (is_debug) {
cflags = [ "/MDd" ] cflags += [ "/MDd" ]
} else { } else {
cflags = [ "/MD" ] cflags += [ "/MD" ]
} }
} }
} else { } else {
...@@ -175,11 +258,11 @@ config("runtime_library") { ...@@ -175,11 +258,11 @@ config("runtime_library") {
if (is_win) { if (is_win) {
# We don't use exceptions, and when we link statically we can just get # We don't use exceptions, and when we link statically we can just get
# rid of them entirely. # rid of them entirely.
defines = [ "_HAS_EXCEPTIONS=0" ] defines += [ "_HAS_EXCEPTIONS=0" ]
if (is_debug) { if (is_debug) {
cflags = [ "/MTd" ] cflags += [ "/MTd" ]
} else { } else {
cflags = [ "/MT" ] cflags += [ "/MT" ]
} }
} }
} }
...@@ -196,6 +279,67 @@ config("runtime_library") { ...@@ -196,6 +279,67 @@ config("runtime_library") {
"UNICODE", "UNICODE",
] ]
} }
# Stlport setup. Android uses a different (smaller) version of the STL.
if (is_android) {
if (is_clang) {
# Work around incompatibilities between bionic and clang headers.
defines += [
"__compiler_offsetof=__builtin_offsetof",
"-Dnan=__builtin_nan",
]
}
defines += [
"USE_STLPORT=1",
"_STLP_USE_PTR_SPECIALIZATIONS=1",
"__GNU_SOURCE=1", # Necessary for clone().
]
ldflags += [
"-nostdlib",
]
libs += [
# TODO(brettw) write a version of this, hopefully we can express this
# without forking out to GCC just to get the library name. The android
# toolchain directory should probably be extracted into a .gni file that
# this file and the android toolchain .gn file can share.
# # Manually link the libgcc.a that the cross compiler uses.
# '<!(<(android_toolchain)/*-gcc -print-libgcc-file-name)',
"c",
"dl",
"m"
]
# NOTE: The stlport header include paths below are specified in cflags
# 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.
if (use_system_stlport) {
cflags += [
# For libstdc++/include, which is used by stlport.
"-I$android_src/bionic",
"-I$android_src/external/stlport/stlport",
]
libs += [
"stlport",
]
} else {
android_stlport_root = "$android_ndk_root/sources/cxx-stl/stlport"
cflags += [ "-I$android_stlport_root/stlport" ]
lib_dirs += [ "$android_stlport_root/libs/$android_app_abi" ]
if (component_mode == "shared_library") {
libs += [ "stlport_shared" ]
} else {
libs += [ "stlport_static" ]
}
}
}
} }
# chromium_code --------------------------------------------------------------- # chromium_code ---------------------------------------------------------------
...@@ -246,6 +390,20 @@ config("no_chromium_code") { ...@@ -246,6 +390,20 @@ config("no_chromium_code") {
"_CRT_NONSTDC_NO_DEPRECATE", "_CRT_NONSTDC_NO_DEPRECATE",
] ]
} }
if (is_android_webview_build) {
# There is a class of warning which:
# 1) Android always enables and also treats as errors
# 2) Chromium ignores in third party code
# So we re-enable those warnings when building Android.
cflags = [
"-Wno-address",
"-Wno-format-security",
"-Wno-return-type",
"-Wno-sequence-point",
]
cflags_cc = [ "-Wno-non-virtual-dtor" ]
}
} }
# rtti ------------------------------------------------------------------------ # rtti ------------------------------------------------------------------------
...@@ -266,6 +424,9 @@ config("no_rtti") { ...@@ -266,6 +424,9 @@ config("no_rtti") {
} }
# Warnings --------------------------------------------------------------------- # Warnings ---------------------------------------------------------------------
#
# This is where we disable various warnings that we've decided aren't
# worthwhile.
config("default_warnings") { config("default_warnings") {
if (is_win) { if (is_win) {
...@@ -277,9 +438,6 @@ config("default_warnings") { ...@@ -277,9 +438,6 @@ config("default_warnings") {
"/wd4125", # Decimal digit terminates octal escape sequence. "/wd4125", # Decimal digit terminates octal escape sequence.
"/wd4127", # Conditional expression is constant. "/wd4127", # Conditional expression is constant.
"/wd4130", # Logical operation on address of string constant. "/wd4130", # Logical operation on address of string constant.
# TODO(brettw) is this necessary? If so, it should probably be on whoever
# is silly enough to be doing this rather than globally.
#"/wd4131", # Function uses old-style declarator.
"/wd4189", # A variable was declared and initialized but never used. "/wd4189", # A variable was declared and initialized but never used.
"/wd4201", # Nonstandard extension used: nameless struct/union. "/wd4201", # Nonstandard extension used: nameless struct/union.
"/wd4238", # Nonstandard extension used: class rvalue used as lvalue. "/wd4238", # Nonstandard extension used: class rvalue used as lvalue.
...@@ -355,6 +513,27 @@ config("default_warnings") { ...@@ -355,6 +513,27 @@ config("default_warnings") {
"-Wstring-conversion", "-Wstring-conversion",
] ]
} }
if (is_android) {
# Disable any additional warnings enabled by the Android build system but
# which chromium does not build cleanly with (when treating warning as
# errors).
cflags += [
"-Wno-extra",
"-Wno-ignored-qualifiers",
"-Wno-type-limits",
]
cflags_cc = [
# Disabling c++0x-compat should be handled in WebKit, but
# this currently doesn't work because gcc_version is not set
# correctly when building with the Android build system.
# TODO(torne): Fix this in WebKit.
"-Wno-error=c++0x-compat",
# Other things unrelated to -Wextra:
"-Wno-non-virtual-dtor",
"-Wno-sign-promo",
]
}
} }
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
import("pkg_config.gni") import("//build/config/linux/pkg_config.gni")
# Sets up the dynamic library search path to include our "lib" directory. # Sets up the dynamic library search path to include our "lib" directory.
config("executable_ldconfig") { config("executable_ldconfig") {
......
...@@ -5,9 +5,24 @@ ...@@ -5,9 +5,24 @@
# This header file defines the "sysroot" variable which is the absolute path # This header file defines the "sysroot" variable which is the absolute path
# of the sysroot. If no sysroot applies, the variable will be an empty string. # of the sysroot. If no sysroot applies, the variable will be an empty string.
# For official linux builds, use the sysroot checked into the internal source if (is_android) {
# repo so that the builds work on older versions of Linux. import("//build/config/android/config.gni")
if (is_linux && is_chrome_branded && is_official_build && !is_chromeos) { if (!is_android_webview_build) {
if (cpu_arch == "x86") {
sysroot = "$android_ndk_root/platforms/android-14/arch-x86"
} else if (cpu_arch == "arm") {
sysroot = "$android_ndk_root/platforms/android-14/arch-arm"
} else if (cpu_arch == "mipsel") {
sysroot = "$android_ndk_root/platforms/android-14/arch-mips"
} else {
sysroot = ""
}
} else {
sysroot = ""
}
} else if (is_linux && is_chrome_branded && is_official_build && !is_chromeos) {
# For official builds, use the sysroot checked into the internal source repo
# so that the builds work on older versions of Linux.
if (cpu_arch == "x64") { if (cpu_arch == "x64") {
sysroot = rebase_path( sysroot = rebase_path(
"//chrome/installer/linux/debian_wheezy_amd64-sysroot", ".", "") "//chrome/installer/linux/debian_wheezy_amd64-sysroot", ".", "")
......
...@@ -148,6 +148,7 @@ def GetArgsStringForGN(supplemental_files): ...@@ -148,6 +148,7 @@ def GetArgsStringForGN(supplemental_files):
# These tuples of (key, value, gn_arg_string) use the gn_arg_string for # These tuples of (key, value, gn_arg_string) use the gn_arg_string for
# gn when the key is set to the given value in the GYP arguments. # gn when the key is set to the given value in the GYP arguments.
remap_cases = [ remap_cases = [
('android_webview_build', '1', 'is_android_webview_build=true'),
('branding', 'Chrome', 'is_chrome_branded=true'), ('branding', 'Chrome', 'is_chrome_branded=true'),
('buildtype', 'Official', 'is_official_build=true'), ('buildtype', 'Official', 'is_official_build=true'),
('component', 'shared_library', 'is_component_build=true'), ('component', 'shared_library', 'is_component_build=true'),
...@@ -171,11 +172,17 @@ def GetArgsStringForGN(supplemental_files): ...@@ -171,11 +172,17 @@ def GetArgsStringForGN(supplemental_files):
if i[0] in vars_dict and vars_dict[i[0]] == i[1]: if i[0] in vars_dict and vars_dict[i[0]] == i[1]:
gn_args += ' ' + i[2] gn_args += ' ' + i[2]
# These string arguments get passed directly. # These string arguments get passed directly as GN strings.
for v in ['windows_sdk_path']: for v in ['android_src', 'windows_sdk_path']:
if v in vars_dict: if v in vars_dict:
gn_args += ' ' + v + '=' + EscapeStringForGN(vars_dict[v]) gn_args += ' ' + v + '=' + EscapeStringForGN(vars_dict[v])
# These arguments get passed directly as integers (avoiding the quoting and
# escaping of the string ones above).
for v in ['arm_version']:
if v in vars_dict:
gn_args += ' %s=%s' % (v, vars_dict[v])
# Some other flags come from GYP environment variables. # Some other flags come from GYP environment variables.
gyp_msvs_version = os.environ.get('GYP_MSVS_VERSION', '') gyp_msvs_version = os.environ.get('GYP_MSVS_VERSION', '')
if gyp_msvs_version: if gyp_msvs_version:
......
...@@ -2,13 +2,10 @@ ...@@ -2,13 +2,10 @@
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
import("../clang.gni") import("//build/config/android/config.gni")
import("../goma.gni") import("//build/toolchain/clang.gni")
import("../gcc_toolchain.gni") import("//build/toolchain/goma.gni")
import("//build/toolchain/gcc_toolchain.gni")
# Get the location of the Android tools in our tree.
android_ndk_root =
rebase_path("//third_party/android_tools/ndk", ".", "")
# Get the Android version of the name of the build host's architecture. # Get the Android version of the name of the build host's architecture.
if (build_cpu_arch == "x64") { if (build_cpu_arch == "x64") {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment