1# Copyright (C) 2017 The Android Open Source Project
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#      http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15import("//gn/perfetto_check_build_deps.gni")
16import("//gn/standalone/android.gni")
17import("//gn/standalone/libc++/libc++.gni")
18import("//gn/standalone/sanitizers/sanitizers.gni")
19import("//gn/standalone/toolchain/msvc.gni")
20import("//gn/standalone/wasm.gni")
21
22# These warnings have been introduced with the newest version of clang (only in
23# the hermetic build) and are enabled just with -Werror.
24hermetic_clang_suppressions = [ "-Wno-c99-designator" ]
25
26# We deal with three toolchains here:
27# 1. Clang, used in most cases.
28# 2. GCC, used in some Linux cases.
29# 3. MSVC, used in some Windows cases.
30# Clang vs gcc is typically not a problem: both support roughly the same
31# switches. -Wno-unknown-warning-option fixes the mismatching ones.
32# The situation on Windows is a bit trickier: clang-cl.exe really pretends to be
33# cl.exe (MSVC), so we should use MSVC-style switches (e.g. /W2). However,
34# clang-cl.exe still supports some -Wclang-style-switches for flags that don't
35# have a corresponding version in MSVC.
36#
37# In the rules below, the conditionals should be interpreted as follows:
38# is_win -> can be either clang-cl.exe or cl.exe (MSVC). Only MSVC-style
39#           switches (the common denominator) should be used.
40# is_clang -> could be clang-on-linux, clang-on-mac or clang-cl.exe.
41
42config("extra_warnings") {
43  if (is_win) {
44    cflags = [
45      "/W2",
46      "/wd4244",  # conversion from 'float' to 'int', possible loss of data
47      "/wd4267",  # conversion from 'size_t' to 'int', possible loss of data
48    ]
49    if (is_clang) {
50      cflags += [
51        "-Wno-float-equal",
52        "-Wno-unused-macros",
53        "-Wno-old-style-cast",
54      ]
55    }
56  } else {
57    # Clang or Gcc. On linux, Android and Mac.
58    cflags = [
59      "-Wall",
60      "-Wextra",
61      "-Wpedantic",
62    ]
63  }
64
65  # Disable variadic macro warning as we make extensive use of them in trace
66  # processor and client API.
67  if (is_clang) {
68    if (!is_fuzzer) {
69      # Disable Weverything on fuzzers to avoid breakages when new versions of
70      # clang are rolled into OSS-fuzz.
71      cflags += [ "-Weverything" ]
72    }
73    cflags += [
74      "-Wno-c++98-compat-pedantic",
75      "-Wno-c++98-compat",
76      "-Wno-disabled-macro-expansion",
77      "-Wno-documentation-unknown-command",
78      "-Wno-gnu-include-next",
79      "-Wno-gnu-statement-expression",
80      "-Wno-gnu-zero-variadic-macro-arguments",
81      "-Wno-padded",
82      "-Wno-poison-system-directories",
83      "-Wno-reserved-id-macro",
84      "-Wno-unknown-sanitizers",
85      "-Wno-unknown-warning-option",
86    ]
87  } else if (!is_clang && !is_win) {
88    # Use return std::move(...) for compatibility with old GCC compilers.
89    cflags += [ "-Wno-redundant-move" ]
90  }
91}
92
93config("no_exceptions") {
94  # Exceptions are disabled by default on Windows (Use /EHsc to enable them).
95  if (!is_win) {
96    cflags_cc = [ "-fno-exceptions" ]
97  }
98}
99
100config("no_rtti") {
101  if (is_win) {
102    cflags_cc = [ "/GR-" ]
103  } else {
104    cflags_cc = [ "-fno-rtti" ]
105  }
106}
107
108config("c++11") {
109  # C++11 is the default on Windows.
110  if (!is_win) {
111    cflags_cc = [ "-std=c++11" ]
112  } else if (is_win && !is_clang) {
113    # Enable standards-conforming compiler behavior.
114    cflags_cc = [ "/permissive-" ]
115  }
116}
117
118# This is needed to compile libunwindstack.
119config("c++17") {
120  if (is_win) {
121    cflags_cc = [ "/std:c++17" ]
122  } else {
123    cflags_cc = [ "-std=c++17" ]
124  }
125}
126
127config("visibility_hidden") {
128  if (!is_win) {
129    cflags = [ "-fvisibility=hidden" ]
130  }
131}
132
133config("win32_lean_and_mean") {
134  if (is_win) {
135    defines = [ "WIN32_LEAN_AND_MEAN" ]
136  }
137}
138
139config("default") {
140  asmflags = []
141  cflags = []
142  cflags_c = []
143  cflags_cc = []
144  defines = []
145  include_dirs = []
146  ldflags = []
147  libs = []
148
149  if ((is_android || is_linux) && !is_wasm) {
150    ldflags += [ "-Wl,--build-id" ]
151  }
152
153  if (is_clang || !is_win) {  # Clang or GCC, but not MSVC.
154    cflags += [
155      "-fstrict-aliasing",
156      "-Wformat",
157    ]
158  }
159
160  if (is_win) {
161    cflags += [
162      "/bigobj",  # Some of our files are bigger than the regular limits.
163      "/Gy",  # Enable function-level linking.
164    ]
165    defines += [
166      "_CRT_NONSTDC_NO_WARNINGS",
167      "_CRT_SECURE_NO_DEPRECATE",
168      "_CRT_SECURE_NO_WARNINGS",  # Disables warnings on some POSIX-compat API.
169      "_SCL_SECURE_NO_DEPRECATE",
170      "NOMINMAX",
171    ]
172    if (!use_custom_libcxx) {
173      defines += [ "_HAS_EXCEPTIONS=0" ]  # Disables exceptions in MSVC STL.
174    }
175  } else if (!is_wasm) {  # !is_win
176    cflags += [
177      "-g",
178      "-fPIC",
179      "-fstack-protector-strong",
180    ]
181  }
182
183  # Treat warnings as errors, but give up on fuzzer builds.
184  if (!is_fuzzer) {
185    if (is_win) {
186      cflags += [ "/WX" ]
187    } else {
188      cflags += [ "-Werror" ]
189    }
190  }
191
192  if (is_clang) {
193    cflags += [ "-fcolor-diagnostics" ]
194    if (!is_win) {
195      cflags += [ "-fdiagnostics-show-template-tree" ]
196    }
197  }
198
199  if (is_hermetic_clang && is_linux && !is_wasm) {
200    cflags += hermetic_clang_suppressions
201  } else {
202    not_needed([ "hermetic_clang_suppressions" ])
203  }
204
205  if (is_lto) {
206    cflags += [ "-flto=full" ]
207    ldflags += [ "-flto=full" ]
208  }
209
210  # We support only x64 builds on Windows.
211  assert(!is_win || current_cpu == "x64")
212
213  if (current_cpu == "arm") {
214    cflags += [
215      "-march=armv7-a",
216      "-mfpu=neon",
217      "-mthumb",
218    ]
219  } else if (current_cpu == "x86") {
220    asmflags += [ "-m32" ]
221    cflags += [
222      "-m32",
223      "-msse2",
224      "-mfpmath=sse",
225    ]
226    ldflags += [
227      "-m32",
228      "-lgcc",
229    ]
230  } else if (current_cpu == "arm64") {
231    cflags += [ "-fno-omit-frame-pointer" ]
232  }
233
234  if (is_linux) {
235    libs += [
236      "pthread",
237      "rt",
238    ]
239  }
240
241  if (is_win && !is_clang) {
242    # When using MSVC we need to manually pass the include dirs. clang-cl.exe
243    # doesn't need them because it's smart enough to figure out the right path
244    # by querying the registry on its own.
245    include_dirs = win_msvc_inc_dirs  # Defined in msvc.gni.
246  }
247
248  if (is_debug) {
249    if (is_win) {
250      cflags += [ "/Z7" ]
251      if (is_clang) {
252        # Required to see symbols in windbg when building with clang-cl.exe.
253        cflags += [ "-gcodeview-ghash" ]
254        ldflags = [ "/DEBUG:GHASH" ]
255      }
256    } else {
257      libs += [ "dl" ]
258    }
259  }
260
261  if (is_android) {
262    asmflags += [ "--target=$android_abi_target" ]
263    cflags += [
264      "--sysroot=$android_compile_sysroot",
265      "-isystem$android_compile_sysroot/$android_compile_sysroot_subdir",
266      "-isystem$android_compile_sysroot",
267      "-DANDROID",
268      "-D__ANDROID_API__=${android_api_level}",
269      "--target=$android_abi_target",
270    ]
271    cflags_cc += [
272      "-I$android_ndk_root/sources/cxx-stl/llvm-libc++/include",
273      "-I$android_ndk_root/sources/android/support/include",
274      "-I$android_ndk_root/sources/cxx-stl/llvm-libc++abi/include",
275
276      # This is needed for NDK libc++. Using -isystem instead of -I above
277      # results in build breakage related to cmath.h.
278      "-Wno-format-nonliteral",
279    ]
280    ldflags += [
281      "-Wl,-z,nocopyreloc",
282      "-gcc-toolchain",
283      "$android_toolchain_root",
284      "--sysroot=$android_ndk_root/$android_link_sysroot_subdir",
285      "--target=$android_abi_target",
286      "-Wl,--exclude-libs,libunwind.a",
287      "-Wl,--exclude-libs,libgcc.a",
288      "-Wl,--exclude-libs,libc++_static.a",
289      "-Wl,--no-undefined",
290      "-Wl,-z,noexecstack",
291      "-Wl,-z,relro",
292      "-Wl,-z,now",
293      "-Wl,--warn-shared-textrel",
294      "-Wl,--fatal-warnings",
295
296      # New NDKs need setting this to not give "unable to find library -lc++".
297      # See https://github.com/android/ndk/issues/951#issuecomment-501017894.
298      "-nostdlib++",
299    ]
300    lib_dirs = [
301      "$android_ndk_root/sources/cxx-stl/llvm-libc++/libs/$android_app_abi",
302    ]
303    libs += [
304      "gcc",
305      "c++_static",
306      "c++abi",
307    ]
308
309    if (current_cpu == "arm") {
310      # New NDKs don't have libandroid_support for arm64.
311      libs += [ "android_support" ]
312    }
313  }
314}
315
316config("debug_symbols") {
317  cflags = []
318  if (is_win) {
319    cflags = [ "/Od" ]
320  } else {
321    cflags = [ "-O0" ]
322  }
323  if (is_android || is_linux) {
324    cflags += [ "-funwind-tables" ]
325  }
326}
327
328config("release") {
329  # Compiler flags for release builds.
330  if (is_win) {
331    cflags = [
332      "/O2",
333      "/Zc:inline",
334    ]
335  } else if (is_android) {
336    cflags = [ "-O2" ]
337  } else if (is_fuzzer) {
338    cflags = [ "-O1" ]
339  } else {
340    cflags = [ "-O3" ]
341  }
342  if (!is_win) {
343    cflags += [
344      "-fdata-sections",
345      "-ffunction-sections",
346    ]
347  }
348
349  # Linker flags for release builds.
350  if (is_win) {
351    ldflags = [
352      "/OPT:REF",
353      "/OPT:ICF",
354      "/INCREMENTAL:NO",
355      "/FIXED:NO",
356    ]
357  } else if (is_mac) {
358    ldflags = [ "-dead_strip" ]
359  } else if (!is_win && !is_wasm) {
360    ldflags = [
361      "-Wl,--gc-sections",
362      "-Wl,--icf=all",
363      "-Wl,-O1",
364    ]
365  }
366  defines = [ "NDEBUG" ]
367}
368
369config("shared_library") {
370  if (is_android || is_linux) {
371    ldflags = [ "-fPIC" ]
372  }
373}
374
375config("executable") {
376  ldflags = []
377
378  # Android will refuse to run executables if they aren't position independent.
379  # Instead on Linux there isn't any need and they break ASan (goo.gl/paFR6K).
380  # The OSS-Fuzz provided AFL library is not PIC, so we we cannot use -fPIE
381  # for the fuzzer executables.
382  if ((is_android || is_linux) && !is_wasm && !is_fuzzer) {
383    asmflags = [ "-fPIE" ]
384    cflags = [ "-fPIE" ]
385    ldflags += [ "-pie" ]
386  }
387
388  # -rpath stores the path to the linked shared libraries into the binary, so
389  # that they can be launched without passing any LD_LIBRARY_PATH. It's
390  # supported only by Linux, not Android. But concretely we need this only when
391  # use_custom_libcxx=true && custom_libcxx_is_static=false, which happens only
392  # on Linux right now.
393  if (is_linux && !is_wasm) {
394    ldflags += [
395      "-Wl,-rpath=\$ORIGIN/.",
396      "-Wl,-rpath-link=.",
397    ]
398  }
399}
400
401# This config is only added to certain leaf target types (see BUILDCONFIG.gn).
402# This allows us to remove the config (and thus the dependency) on a per-target
403# basis. If the config was applied to source_sets, then they would unavoidably
404# carry the dependency onto liblog to the final target.
405config("android_liblog") {
406  if (is_android) {
407    libs = [ "log" ]
408  }
409}
410
411# Checks that tools/install-build-deps has been run since it last changed.
412perfetto_check_build_deps("check_build_deps") {
413  args = []
414}
415
416perfetto_check_build_deps("check_build_deps_android") {
417  args = [ "--android" ]
418}
419