-
Notifications
You must be signed in to change notification settings - Fork 21
/
clang.gni
194 lines (181 loc) · 7.24 KB
/
clang.gni
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# Copyright 2019 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("$zx/public/gn/prebuilt.gni")
declare_args() {
# If $clang_tool_dir is "", then this controls how the Clang toolchain
# binaries are found. If true, then the standard prebuilt is used.
# Otherwise the tools are just expected to be found by the shell via `PATH`.
use_prebuilt_clang = false
# Directory where the Clang toolchain binaries ("clang", "llvm-nm", etc.) are
# found. If this is "", then the behavior depends on $use_prebuilt_clang.
# This toolchain is expected to support both Fuchsia targets and the host.
clang_tool_dir = "/home/pan/clang/bin"
}
# This is a string identifying the particular toolchain version in use. Its
# only purpose is to be unique enough that it changes when switching to a new
# toolchain, so that recompilations with the new compiler can be triggered.
#
# When using the prebuilt, the CIPD instance ID of the prebuilt is perfect.
# When not using the prebuilt, there isn't a quick way to extract the compiler
# version. But at least changing the setting to a different compiler will
# change the string.
clang_version_string = clang_tool_dir
if (clang_tool_dir == "" && use_prebuilt_clang) {
_prebuilt_clang_dir = "$prebuilt_dir/third_party/clang/$host_platform"
clang_tool_dir = "$_prebuilt_clang_dir/bin"
_prebuilt_cipd_version = "go_away_stupid_cipd"
clang_version_string = "go_away_stupid_cipd"
}
_clang_lib_dir = "$clang_tool_dir/../lib"
# Human-readable identifier for the toolchain version.
#
# clang_version_string is useful for Fuchsia standard prebuilts, since it's
# the CIPD instance ID that can be looked up to find the compiler build.
# clang_version_description is something that can lead a human to find the
# specific toolchain, such as a source repository URL and revision identifier.
#
# TODO(mcgrathr): Make this the same repo/revision info from `clang --version`.
# e.g., clang_version_description = read_file("$_clang_lib_dir/VERSION")
clang_version_description = ""
# This file is provided by the toolchain to describe the runtime
# dependencies implied by linking a binary based on --target and other
# compiler switches. The file contains a JSON array of objects that map to
# the following GN schema. Each entry matches a single compilation mode
# and yields all the runtime dependencies implied by that mode.
#
# Type: list(scope)
#
# target
# Required: --target tuple a la ${toolchain.target_tuple}.
# Type: string
#
# cflags
# Optional: List of compilation flags that select this mode,
# e.g. "-fsanitizer=..." and the like.
# Type: list(string)
# Default: []
#
# ldflags
# Optional: Link-time flags that select this mode.
# This is either [ "-static-libstdc++" ] or [].
# Type: list(string)
# Default: []
#
# runtime
# Required: List of runtime files needed by binaries in this mode.
# Type: list(scope)
#
# soname
# Required: `DT_SONAME` string in the ELF shared library.
# Type: string
#
# dist
# Required: File to load to satisfy $soname `DT_NEEDED` entries.
# Type: path relative to JSON file's directory
#
# debug
# Optional: Unstripped or separate debug file matching $dist.
# Type: path relative to JSON file's directory
#
_clang_runtime_file = "$_clang_lib_dir/runtime.json"
clang_runtime = read_file(_clang_runtime_file, "json")
# Provide deps required by toolchain-provided runtime libraries.
#
# Every linking target, such as executable(), shared_library(), or
# loadable_module(), needs this in deps to represent the link-time and
# runtime dependencies of support code the compiler links in implicitly.
# The parameters indicate the compilation mode in terms of the link-time
# and compile-time flags used. These must exactly match lists supplied by
# the toolchain in $clang_runtime to select for things like instrumentation
# and shared vs static linking of the standard C++ library.
#
# Parameters
#
# cflags, ldflags
# Required: Flags to match in the runtimes manifest.
# Type: list(string)
#
template("toolchain_runtime_deps") {
group(target_name) {
forward_variables_from(invoker,
[
"testonly",
"visibility",
])
# This information comes out the same in the main and the shlib
# toolchains. But we don't want two copies to appear in the metadata
# collection, so we always redirect to the shlib toolchain (when there
# is one). Note that multiple toolchains (variants that aren't that
# different, e.g. uninstrumented variants) may produce identical
# manifest entries because they match the same entries in the
# clang_runtime and use the same ${toolchain.libprefix} string. That
# is less than ideal but it does no harm since the tools like zbi that
# consume manifests accept redundant entries if they are identical.
if (!defined(toolchain.shlib) || current_toolchain == toolchain.shlib) {
if (defined(toolchain.shlib) && defined(visibility)) {
visibility += [ ":$target_name" ]
}
match = false
foreach(config, clang_runtime) {
if (!defined(config.cflags)) {
config.cflags = []
}
if (!defined(config.ldflags)) {
config.ldflags = []
}
if (config.target + [ toolchain.target_tuple ] -
[ toolchain.target_tuple ] != config.target &&
invoker.cflags == config.cflags &&
invoker.ldflags == config.ldflags) {
match = config
}
}
assert(match != false,
"$_clang_runtime_file has no match for" +
" --target=${toolchain.target_tuple} + $invoker")
metadata = {
binaries = []
manifest_lines = []
foreach(lib, match.runtime) {
# For build_api_module("binaries") in $zx/BUILD.gn.
binaries += [
{
cpu = current_cpu
os = current_os
environment = toolchain.environment
label = get_label_info(":$target_name", "label_with_toolchain")
type = "shared_library"
dist = rebase_path(lib.dist, root_build_dir, _clang_lib_dir)
if (defined(lib.debug)) {
debug = rebase_path(lib.debug, root_build_dir, _clang_lib_dir)
}
target_tuple = match.target
cflags = match.cflags
ldflags = match.ldflags
if (clang_version_string != "") {
toolchain_id = clang_version_string
}
if (clang_version_description != "") {
toolchain_version = clang_version_description
}
},
]
# This is the main purpose of the whole target.
manifest_lines +=
[ "lib/${toolchain.libprefix}${lib.soname}=" +
rebase_path(lib.dist, root_build_dir, _clang_lib_dir) ]
}
}
} else {
public_deps = [
":$target_name(${toolchain.shlib})",
]
not_needed(invoker,
[
"cflags",
"ldflags",
])
}
}
}