• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2013 The Chromium Authors
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import("//build/config/pch.gni")
6import("//build/config/rust.gni")
7import("clang.gni")
8
9if (is_ios) {
10  # For `target_environment` and `target_platform`.
11  import("//build/config/apple/mobile_config.gni")
12}
13
14# Helper function for adding cflags to use a clang plugin.
15# - `plugin` is the name of the plugin.
16# - `plugin_arguments` is a list of arguments to pass to the plugin.
17template("clang_plugin") {
18  config(target_name) {
19    forward_variables_from(invoker,
20                           [
21                             "cflags",
22                             "configs",
23                           ])
24    if (!defined(cflags)) {
25      cflags = []
26    }
27
28    if (defined(invoker.plugin)) {
29      cflags += [
30        "-Xclang",
31        "-add-plugin",
32        "-Xclang",
33        invoker.plugin,
34      ]
35    }
36
37    if (defined(invoker.plugin_arguments)) {
38      foreach(flag, invoker.plugin_arguments) {
39        cflags += [
40          "-Xclang",
41          "-plugin-arg-${invoker.plugin}",
42          "-Xclang",
43          flag,
44        ]
45      }
46    }
47  }
48}
49
50clang_plugin("raw_ptr_check") {
51  if (clang_use_chrome_plugins || clang_use_raw_ptr_plugin) {
52    # The plugin is built directly into clang, so there's no need to load it
53    # dynamically.
54    plugin = "raw-ptr-plugin"
55    plugin_arguments = [
56      "check-raw-ptr-to-stack-allocated",
57      "disable-check-raw-ptr-to-stack-allocated-error",
58
59      # TODO(crbug.com/40944547): Remove when raw_ptr check has been enabled
60      # for the dawn repo.
61      "raw-ptr-exclude-path=" +
62          rebase_path("//third_party/dawn/", root_build_dir),
63    ]
64
65    if (enable_check_raw_ptr_fields) {
66      plugin_arguments += [
67        "check-raw-ptr-fields",
68        "check-span-fields",
69      ]
70    }
71
72    if (enable_check_raw_ref_fields) {
73      plugin_arguments += [ "check-raw-ref-fields" ]
74    }
75  }
76}
77
78clang_plugin("find_bad_constructs") {
79  if (clang_use_chrome_plugins) {
80    # The plugin is built directly into clang, so there's no need to load it
81    # dynamically.
82    plugin = "find-bad-constructs"
83    plugin_arguments = [
84      "span-ctor-from-string-literal",
85      "raw-ref-template-as-trivial-member",
86      "raw-span-template-as-trivial-member",
87      "check-stack-allocated",
88    ]
89
90    if (is_linux || is_chromeos || is_android || is_fuchsia) {
91      plugin_arguments += [ "check-ipc" ]
92    }
93
94    configs = [ ":raw_ptr_check" ]
95  }
96}
97
98# A plugin for incrementally applying the -Wunsafe-buffer-usage warning.
99#
100# To use the plugin, the project must specify a path as
101# `clang_unsafe_buffers_paths` in the `//.gn` file. This path points to a text
102# file that controls where the warning is checked.
103#
104# See //build/config/unsafe_buffers_paths.txt for an example file, this it the
105# file used by Chromium.
106#
107# This build configuration is not supported when `enable_precompiled_headers`
108# is on because the pragmas that enable and disable unsafe-buffers warnings are
109# not serialized to precompiled header files, and thus we get warnings that we
110# should not.
111clang_plugin("unsafe_buffers") {
112  if (clang_use_chrome_plugins && clang_unsafe_buffers_paths != "" &&
113      !enable_precompiled_headers) {
114    cflags = [ "-DUNSAFE_BUFFERS_BUILD" ]
115    plugin = "unsafe-buffers"
116    plugin_arguments =
117        [ rebase_path(clang_unsafe_buffers_paths, root_build_dir) ]
118  }
119}
120
121# Enables some extra Clang-specific warnings. Some third-party code won't
122# compile with these so may want to remove this config.
123config("extra_warnings") {
124  cflags = [
125    "-Wheader-hygiene",
126
127    # Warns when a const char[] is converted to bool.
128    "-Wstring-conversion",
129
130    "-Wtautological-overlap-compare",
131  ]
132}
133
134group("llvm-symbolizer_data") {
135  if (is_win) {
136    data = [ "$clang_base_path/bin/llvm-symbolizer.exe" ]
137  } else {
138    data = [ "$clang_base_path/bin/llvm-symbolizer" ]
139  }
140}
141
142template("clang_lib") {
143  if (!defined(invoker.libname) || is_wasm) {
144    not_needed(invoker, "*")
145    config(target_name) {
146    }
147  } else {
148    config(target_name) {
149      _dir = ""
150      _libname = invoker.libname
151      _prefix = "lib"
152      _suffix = ""
153      _ext = "a"
154      if (is_win) {
155        _dir = "windows"
156        _prefix = ""
157        _ext = "lib"
158        if (current_cpu == "x64") {
159          _suffix = "-x86_64"
160        } else if (current_cpu == "x86") {
161          _suffix = "-i386"
162        } else if (current_cpu == "arm64") {
163          _suffix = "-aarch64"
164        } else {
165          assert(false)  # Unhandled cpu type
166        }
167      } else if (is_apple) {
168        _dir = "darwin"
169      } else if (is_linux || is_chromeos) {
170        if (current_cpu == "x64") {
171          _dir = "x86_64-unknown-linux-gnu"
172        } else if (current_cpu == "x86") {
173          _dir = "i386-unknown-linux-gnu"
174        } else if (current_cpu == "arm") {
175          _dir = "armv7-unknown-linux-gnueabihf"
176        } else if (current_cpu == "arm64") {
177          _dir = "aarch64-unknown-linux-gnu"
178        } else {
179          assert(false)  # Unhandled cpu type
180        }
181      } else if (is_fuchsia) {
182        if (current_cpu == "x64") {
183          _dir = "x86_64-unknown-fuchsia"
184        } else if (current_cpu == "arm64") {
185          _dir = "aarch64-unknown-fuchsia"
186        } else {
187          assert(false)  # Unhandled cpu type
188        }
189      } else if (is_android) {
190        _dir = "linux"
191        if (current_cpu == "x64") {
192          _suffix = "-x86_64-android"
193        } else if (current_cpu == "x86") {
194          _suffix = "-i686-android"
195        } else if (current_cpu == "arm") {
196          _suffix = "-arm-android"
197        } else if (current_cpu == "arm64") {
198          _suffix = "-aarch64-android"
199        } else if (current_cpu == "riscv64") {
200          _suffix = "-riscv64-android"
201        } else {
202          assert(false)  # Unhandled cpu type
203        }
204      } else {
205        assert(false)  # Unhandled target platform
206      }
207
208      _clang_lib_dir = "$clang_base_path/lib/clang/$clang_version/lib"
209      _lib_file = "${_prefix}clang_rt.${_libname}${_suffix}.${_ext}"
210      libs = [ "$_clang_lib_dir/$_dir/$_lib_file" ]
211    }
212  }
213}
214
215# Adds a dependency on the Clang runtime library clang_rt.builtins.
216clang_lib("compiler_builtins") {
217  if (is_mac) {
218    libname = "osx"
219  } else if (is_ios) {
220    if (target_platform == "iphoneos") {
221      if (target_environment == "simulator") {
222        libname = "iossim"
223      } else if (target_environment == "device") {
224        libname = "ios"
225      } else if (target_environment == "catalyst") {
226        libname = "osx"
227      } else {
228        assert(false, "unsupported target_environment=$target_environment")
229      }
230    } else if (target_platform == "tvos") {
231      if (target_environment == "simulator") {
232        libname = "tvossim"
233      } else if (target_environment == "device") {
234        libname = "tvos"
235      } else {
236        assert(false, "unsupported target_environment=$target_environment")
237      }
238    } else {
239      assert(false, "unsupported target_platform=$target_platform")
240    }
241  } else {
242    libname = "builtins"
243  }
244}
245
246# Adds a dependency on the Clang runtime library clang_rt.profile.
247clang_lib("compiler_profile") {
248  if (!toolchain_has_rust) {
249    # This is only used when `toolchain_has_rust` to support Rust linking.
250    #
251    # Don't define libname which makes this target do nothing.
252  } else if (is_mac) {
253    libname = "profile_osx"
254  } else if (is_ios) {
255    if (target_environment == "simulator") {
256      libname = "profile_iossim"
257    } else if (target_environment == "catalyst") {
258      # We don't enable clang coverage on iOS device builds, and the library is
259      # not part of the Clang package tarball as a result.
260      #
261      # Don't define libname which makes this target do nothing.
262    } else {
263      # We don't enable clang coverage on iOS device builds, and the library is
264      # not part of the Clang package tarball as a result.
265      #
266      # Don't define libname which makes this target do nothing.
267    }
268  } else {
269    libname = "profile"
270  }
271}
272