blob: ecd5c951f13643352ef8c58836cf2ef957f6ce2e [file] [log] [blame]
# 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/perfetto_check_build_deps.gni")
import("//gn/standalone/android.gni")
import("//gn/standalone/libc++/libc++.gni")
import("//gn/standalone/sanitizers/sanitizers.gni")
import("//gn/standalone/toolchain/msvc.gni")
import("//gn/standalone/wasm.gni")
# These warnings have been introduced with the newest version of clang (only in
# the hermetic build) and are enabled just with -Werror.
hermetic_clang_suppressions = [ "-Wno-c99-designator" ]
# We deal with three toolchains here:
# 1. Clang, used in most cases.
# 2. GCC, used in some Linux cases.
# 3. MSVC, used in some Windows cases.
# Clang vs gcc is typically not a problem: both support roughly the same
# switches. -Wno-unknown-warning-option fixes the mismatching ones.
# The situation on Windows is a bit trickier: clang-cl.exe really pretends to be
# cl.exe (MSVC), so we should use MSVC-style switches (e.g. /W2). However,
# clang-cl.exe still supports some -Wclang-style-switches for flags that don't
# have a corresponding version in MSVC.
#
# In the rules below, the conditionals should be interpreted as follows:
# is_win -> can be either clang-cl.exe or cl.exe (MSVC). Only MSVC-style
# switches (the common denominator) should be used.
# is_clang -> could be clang-on-linux, clang-on-mac or clang-cl.exe.
config("extra_warnings") {
if (is_win) {
cflags = [
"/W2",
"/wd4244", # conversion from 'float' to 'int', possible loss of data
"/wd4267", # conversion from 'size_t' to 'int', possible loss of data
]
if (is_clang) {
cflags += [
"-Wno-float-equal",
"-Wno-unused-macros",
"-Wno-old-style-cast",
]
}
} else {
# Clang or Gcc. On linux, Android and Mac.
cflags = [
"-Wall",
"-Wextra",
"-Wpedantic",
]
}
# Disable variadic macro warning as we make extensive use of them in trace
# processor and client API.
if (is_clang) {
# Only enable -Weverything on hermetic clang as system clang might be quite
# out of date.
if (is_hermetic_clang && current_toolchain == host_toolchain &&
!is_fuzzer) {
# Disable Weverything on fuzzers to avoid breakages when new versions of
# clang are rolled into OSS-fuzz.
cflags += [ "-Weverything" ]
}
cflags += [
"-Wno-c++98-compat-pedantic",
"-Wno-c++98-compat",
"-Wno-disabled-macro-expansion",
"-Wno-documentation-unknown-command",
"-Wno-gnu-include-next",
"-Wno-gnu-statement-expression",
"-Wno-gnu-zero-variadic-macro-arguments",
"-Wno-padded",
"-Wno-poison-system-directories",
"-Wno-pre-c11-compat",
"-Wno-reserved-id-macro",
"-Wno-reserved-identifier",
"-Wno-shadow-uncaptured-local",
"-Wno-unknown-sanitizers",
"-Wno-unknown-warning-option",
"-Wno-unsafe-buffer-usage",
# TODO(primiano): -Wswitch-default could be useful but will require a mass
# codebase cleanup.
"-Wno-switch-default",
]
} else if (!is_clang && !is_win) {
# Use return std::move(...) for compatibility with old GCC compilers.
cflags_cc = [ "-Wno-redundant-move" ]
# Use after free detection in GCC is still not good enough: it still fails
# on very obvious false-positives in trace processor.
cflags_cc += [ "-Wno-use-after-free" ]
# GCC 7's handling of uninitialized std::optional is flaky at best and
# causes many false positives.
# TODO(lalitm): remove this when we upgrade to a GCC version which is good
# enough to handle this.
cflags_cc += [ "-Wno-maybe-uninitialized" ]
# GCC's handling of detecting infinite recursion is flaky at best and
# causes some false positives.
# TODO(lalitm): remove this when we upgrade to a GCC version which is good
# enough to handle this.
cflags_cc += [ "-Wno-infinite-recursion" ]
# GCC's handling of detecting non null arguments is flaky at best and
# causes some false positives.
# TODO(lalitm): remove this when we upgrade to a GCC version which is good
# enough to handle this.
cflags_cc += [ "-Wno-nonnull" ]
}
}
config("no_exceptions") {
# Exceptions are disabled by default on Windows (Use /EHsc to enable them).
if (!is_win) {
cflags_cc = [ "-fno-exceptions" ]
}
}
config("no_rtti") {
if (is_win) {
cflags_cc = [ "/GR-" ]
} else {
cflags_cc = [ "-fno-rtti" ]
}
}
# Used in buildtools dependencies for standalone builds.
config("c++17") {
if (is_win) {
cflags_cc = [ "/std:c++17" ]
} else {
cflags_cc = [ "-std=c++17" ]
}
}
# Used in buildtools dependencies for standalone builds.
config("c++20") {
visibility = [ "//buildtools:libc++config" ]
if (is_win) {
cflags_cc = [ "/std:c++20" ]
} else {
cflags_cc = [ "-std=c++20" ]
}
}
config("visibility_hidden") {
if (!is_win) {
cflags = [ "-fvisibility=hidden" ]
}
}
config("win32_lean_and_mean") {
if (is_win) {
defines = [ "WIN32_LEAN_AND_MEAN" ]
}
}
config("default") {
asmflags = []
cflags = []
cflags_c = []
cflags_cc = []
defines = []
include_dirs = []
ldflags = []
libs = []
if ((is_android || is_linux) && !is_wasm) {
ldflags += [
"-Wl,--build-id",
"-Wl,-z,max-page-size=16384",
]
}
if (is_clang || !is_win) { # Clang or GCC, but not MSVC.
cflags += [
"-fstrict-aliasing",
"-Wformat",
]
}
if (is_clang && is_win) {
# clang-cl from version 16 does not like out-of-line definition of static
# constexpr, even in C++14 mode. Disable the deprecated warnings to work
# around the problem.
cflags += [ "-Wno-deprecated" ]
}
if (is_win) {
cflags += [
"/bigobj", # Some of our files are bigger than the regular limits.
"/Gy", # Enable function-level linking.
"/FS", # Preserve previous PDB behavior.
"/utf-8", # Assume UTF-8 by default to avoid code page dependencies.
"/Zc:__cplusplus", # Allow use of __cplusplus macro.
]
defines += [
"_CRT_NONSTDC_NO_WARNINGS",
"_CRT_SECURE_NO_DEPRECATE",
"_CRT_SECURE_NO_WARNINGS", # Disables warnings on some POSIX-compat API.
"_SCL_SECURE_NO_DEPRECATE",
"NOMINMAX",
]
if (!use_custom_libcxx) {
defines += [ "_HAS_EXCEPTIONS=0" ] # Disables exceptions in MSVC STL.
}
} else if (!is_wasm) { # !is_win
cflags += [
"-g",
"-fPIC",
"-fstack-protector-strong",
]
}
# Treat warnings as errors, but give up on fuzzer builds.
if (!is_fuzzer) {
if (is_win) {
cflags += [ "/WX" ]
} else {
cflags += [ "-Werror" ]
}
}
if (is_clang) {
cflags += [ "-fcolor-diagnostics" ]
if (!is_win) {
cflags += [ "-fdiagnostics-show-template-tree" ]
}
}
if (is_hermetic_clang && is_linux && !is_wasm) {
cflags += hermetic_clang_suppressions
} else {
not_needed([ "hermetic_clang_suppressions" ])
}
if (non_hermetic_clang_stdlib != "") {
if (is_clang && !is_hermetic_clang && !is_wasm) {
cflags_cc += [ "-stdlib=" + non_hermetic_clang_stdlib ]
ldflags += [ "-stdlib=" + non_hermetic_clang_stdlib ]
}
}
if (is_lto) {
cflags += [ "-flto=full" ]
ldflags += [ "-flto=full" ]
}
if (is_win) {
# We support only x86/x64 builds on Windows.
assert(current_cpu == "x64" || current_cpu == "x86")
} else if (current_cpu == "arm") {
cflags += [
"-march=armv7-a",
"-mfpu=neon",
"-mthumb",
]
} else if (current_cpu == "riscv64") {
if (!is_clang) {
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104338
libs += [ "atomic" ]
}
} else if (current_cpu == "x86") {
asmflags += [ "-m32" ]
cflags += [
"-m32",
"-msse2",
"-mfpmath=sse",
]
ldflags += [ "-m32" ]
} else if (current_cpu == "arm64") {
cflags += [ "-fno-omit-frame-pointer" ]
} else if (current_cpu == "x64") {
cflags += [ "-fno-omit-frame-pointer" ] # For perf profiling.
if (enable_perfetto_x64_cpu_opt) {
# When updating these flags, the CheckCpuOptimizations() in utils.cc must
# be updated accordingly.
cflags += [
"-mbmi",
"-mbmi2",
"-mavx2",
"-mpopcnt",
"-msse4.2",
]
}
}
if (is_wasm) {
# As of writing (2023-06-12) WASM 128bit SIMD is supported on
# stable Chrome, Safari, and Firefox. See:
# - https://webassembly.org/roadmap/
# - https://emscripten.org/docs/porting/simd.html
cflags += [ "-msimd128" ]
}
if (is_linux) {
# Enable LFS (large file support) for stat() and other syscalls.
cflags += [
"-D_FILE_OFFSET_BITS=64",
"-D_LARGEFILE_SOURCE",
"-D_LARGEFILE64_SOURCE",
]
libs += [
"pthread",
"rt",
]
}
if (is_win && !is_clang) {
# When using MSVC we need to manually pass the include dirs. clang-cl.exe
# doesn't need them because it's smart enough to figure out the right path
# by querying the registry on its own.
include_dirs = win_msvc_inc_dirs # Defined in msvc.gni.
}
if (is_win) {
cflags += [ "/Zi" ]
}
if (is_debug) {
if (is_win) {
if (is_clang) {
# Required to see symbols in windbg when building with clang-cl.exe.
cflags += [ "-gcodeview-ghash" ]
ldflags = [ "/DEBUG:GHASH" ]
}
} else {
libs += [ "dl" ]
}
}
if (is_android) {
asmflags += [ "--target=$android_abi_target" ]
cflags += [
"--sysroot=$android_compile_sysroot",
"-DANDROID",
"-D__ANDROID_API__=${android_api_level}",
"--target=$android_abi_target",
]
cflags_cc += [ "-isystem$android_compile_sysroot/c++/v1" ]
android_lib_dir = "$android_compile_sysroot/usr/lib/$android_abi_target/$android_api_level"
ldflags += [
"-Wl,-z,nocopyreloc",
"--sysroot=$android_compile_sysroot",
"-B${android_lib_dir}",
"--target=$android_abi_target",
"-Wl,--no-undefined",
"-Wl,-z,noexecstack",
"-Wl,-z,relro",
"-Wl,-z,now",
"-Wl,--warn-shared-textrel",
"-Wl,--fatal-warnings",
# From NDK docs: "although the option uses the name "libstdc++" for
# historical reasons, this is correct for libc++ as well.
"-static-libstdc++",
]
lib_dirs = [ android_lib_dir ]
}
}
config("debug_noopt") {
cflags = []
if (is_win) {
cflags = [ "/Od" ]
} else {
cflags = [ "-O0" ]
}
if (is_android || is_linux) {
cflags += [ "-funwind-tables" ]
}
}
config("release") {
# Compiler flags for release builds.
if (is_win) {
cflags = [
"/O2",
"/Zc:inline",
]
} else if (is_android) {
cflags = [ "-O2" ]
} else if (is_fuzzer) {
cflags = [ "-O1" ]
} else {
cflags = [ "-O3" ]
}
if (!is_win) {
cflags += [
"-fdata-sections",
"-ffunction-sections",
]
}
# Linker flags for release builds.
if (is_win) {
ldflags = [
"/OPT:REF",
"/OPT:ICF",
"/INCREMENTAL:NO",
"/FIXED:NO",
]
} else if (is_mac) {
ldflags = [ "-dead_strip" ]
} else if (!is_win && !is_wasm) {
ldflags = [
"-Wl,--gc-sections",
"-Wl,--icf=all",
"-Wl,-O1",
]
}
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).
# The OSS-Fuzz provided AFL library is not PIC, so we we cannot use -fPIE
# for the fuzzer executables.
if ((is_android || is_linux) && !is_wasm && !is_fuzzer) {
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 && !is_wasm) {
ldflags += [
"-Wl,-rpath=\$ORIGIN/.",
"-Wl,-rpath-link=.",
]
}
}
# This config is only added to certain leaf target types (see BUILDCONFIG.gn).
# This allows us to remove the config (and thus the dependency) on a per-target
# basis. If the config was applied to source_sets, then they would unavoidably
# carry the dependency onto liblog to the final target.
config("android_liblog") {
if (is_android) {
libs = [ "log" ]
}
}
# Checks that tools/install-build-deps has been run since it last changed.
perfetto_check_build_deps("check_build_deps") {
args = []
}
perfetto_check_build_deps("check_build_deps_android") {
args = [ "--android" ]
}