blob: e9b506b1a8c9c3a522ace37c643e089b415589dc [file] [log] [blame]
Keir Mierle58671912019-11-14 00:15:41 -08001# Copyright 2019 The Pigweed Authors
2#
3# Licensed under the Apache License, Version 2.0 (the "License"); you may not
4# use this file except in compliance with the License. You may obtain a copy of
5# the License at
6#
7# https://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, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations under
13# the License.
14
Aaron Greene8449d12020-04-06 19:24:30 -070015declare_args() {
16 # Sets the sanitizer to pass to clang. Valid values are those for "-fsanitize"
17 # listed in https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html.
18 pw_sanitizer = ""
19
20 # Indicates if this build is a part of OSS-Fuzz, which needs to be able to
21 # provide its own compiler and flags. This violates the build hermeticisim and
22 # should only be used for OSS-Fuzz.
23 oss_fuzz_enabled = false
24}
25
Keir Mierle58671912019-11-14 00:15:41 -080026# Generates a host clang toolchain for a specific target.
27#
28# Args:
29# toolchain_cflags: Additional C/C++ compiler flags for the target.
30# toolchain_ldflags: Additional linker flags for the target.
31template("host_clang") {
32 # Toolchain C flags
33 _cflags_list = [
34 # Colorize output. Ninja's Clang invocation disables color by default.
35 "-fdiagnostics-color",
36 ]
37 if (defined(invoker.toolchain_cflags)) {
38 _cflags_list += invoker.toolchain_cflags
39 }
Rob Mohr4b501c62019-12-19 09:11:52 -080040
41 if (host_os == "mac") {
42 _xcode_sysroot = exec_script("$dir_pw_build/py/exec.py",
43 [
Alexei Frolov77af7192019-12-20 11:55:11 -080044 "--",
Rob Mohr4b501c62019-12-19 09:11:52 -080045 "/usr/bin/xcrun",
46 "--show-sdk-path",
47 ],
48 "trim string")
49 _cflags_list += [ "--sysroot=$_xcode_sysroot" ]
50 }
51
Aaron Greenb3ae1dc2020-04-13 11:37:05 -070052 _cflags_c_list = []
Keir Mierle58671912019-11-14 00:15:41 -080053
Aaron Greene8449d12020-04-06 19:24:30 -070054 # Toolchain C++ flags
55 _cflags_cc_list = [
56 # Specify the default C++ version, which targets can override with a config.
57 "-std=c++17",
58 "-Wno-register",
59 ]
Wyatt Hepler21192402020-01-15 15:40:51 -080060
Keir Mierle58671912019-11-14 00:15:41 -080061 # Toolchain LD flags
Aaron Greene8449d12020-04-06 19:24:30 -070062 _ldflags_list = []
Keir Mierle58671912019-11-14 00:15:41 -080063 if (defined(invoker.toolchain_ldflags)) {
Aaron Greene8449d12020-04-06 19:24:30 -070064 _ldflags_list += invoker.toolchain_ldflags
Keir Mierle58671912019-11-14 00:15:41 -080065 }
Keir Mierle95a980b2020-03-04 16:05:44 -080066 if (host_os == "mac") {
67 # The CIPD provided Clang/LLVM toolchain must link against the matched
68 # libc++ which is also from CIPD. However, by default, Clang on Mac (but
69 # not on Linux) will fall back to the system libc++, which is
70 # incompatible due to an ABI change.
71 #
72 # Pull the appropriate path from our Pigweed env setup.
73 assert(getenv("PW_PIGWEED_CIPD_INSTALL_DIR") != "",
74 "You forgot to activate the Pigweed environment; " +
75 "did you source pw_env_setup/setup.sh?")
Aaron Greene8449d12020-04-06 19:24:30 -070076 _ldflags_list += [
77 # Force dropping the system libc++
78 "-nostdlib++",
Keir Mierle95a980b2020-03-04 16:05:44 -080079
Aaron Greene8449d12020-04-06 19:24:30 -070080 # Use the libc++ from CIPD.
81 getenv("PW_PIGWEED_CIPD_INSTALL_DIR") + "/lib/libc++.a",
82 ]
Keir Mierle95a980b2020-03-04 16:05:44 -080083 }
Keir Mierle58671912019-11-14 00:15:41 -080084
85 # Note: On macOS, there is no "llvm-ar", only "ar", which happens to be LLVM
86 # ar. This should get updated for linux systems.
87 _ar = "ar"
88 _cc = "clang"
89 _cxx = "clang++"
90
Aaron Greene8449d12020-04-06 19:24:30 -070091 # OSS-Fuzz needs to be able to specify its own compilers and add flags.
92 if (oss_fuzz_enabled) {
93 _cc = getenv("CC")
94 _cxx = getenv("CXX")
Aaron Greenb3ae1dc2020-04-13 11:37:05 -070095 _cflags_c_list += string_split(getenv("CFLAGS"))
Aaron Greene8449d12020-04-06 19:24:30 -070096 _cflags_cc_list += string_split(getenv("CXXFLAGS"))
Aaron Greenb3ae1dc2020-04-13 11:37:05 -070097 _ldflags_list += string_split(getenv("CXXFLAGS"))
Aaron Greena0fdec92020-04-08 19:02:56 -070098
99 # TODO(pwbug/184): OSS-Fuzz sets -stdlib=libc++, but pw_minimal_cpp_stdlib
100 # sets -nostdinc++. Find a more flexible mechanism to achieve this and
101 # similar needs (like removing -fno-rtti fro UBSan).
102 _cflags_cc_list += [ "-Wno-unused-command-line-argument" ]
Aaron Greene8449d12020-04-06 19:24:30 -0700103 }
104
105 _toolchain_cflags = string_join(" ", _cflags_list)
Aaron Greenb3ae1dc2020-04-13 11:37:05 -0700106 _toolchain_cflags_c = string_join(" ", _cflags_c_list)
Aaron Greene8449d12020-04-06 19:24:30 -0700107 _toolchain_cflags_cc = string_join(" ", _cflags_cc_list)
108 _toolchain_ldflags = string_join(" ", _ldflags_list)
109
Keir Mierle58671912019-11-14 00:15:41 -0800110 toolchain(target_name) {
111 tool("asm") {
112 depfile = "{{output}}.d"
113 command = string_join(" ",
114 [
115 "$_cc",
116 "-MMD -MF $depfile", # Write out dependencies.
Wyatt Hepler21192402020-01-15 15:40:51 -0800117 _toolchain_cflags,
Keir Mierle58671912019-11-14 00:15:41 -0800118 "{{defines}}",
119 "{{include_dirs}}",
120 "{{asmflags}}",
121 "-c {{source}}",
122 "-o {{output}}",
123 ])
124 depsformat = "gcc"
125 description = "as {{output}}"
126 outputs = [
Wyatt Heplerc3a2d472020-01-09 12:24:24 -0800127 # Use {{source_file_part}}, which includes the extension, instead of
128 # {{source_name_part}} so that object files created from <file_name>.c
129 # and <file_name>.cc sources are unique.
130 "{{source_out_dir}}/{{target_output_name}}.{{source_file_part}}.o",
Keir Mierle58671912019-11-14 00:15:41 -0800131 ]
132 }
133
134 tool("cc") {
135 depfile = "{{output}}.d"
Wyatt Heplercca0daf2019-11-14 11:29:04 -0800136 command = string_join(" ",
Keir Mierle58671912019-11-14 00:15:41 -0800137 [
138 "$_cc",
139 "-MMD -MF $depfile", # Write out dependencies.
Aaron Greenb3ae1dc2020-04-13 11:37:05 -0700140 _toolchain_cflags_c,
Wyatt Hepler21192402020-01-15 15:40:51 -0800141 _toolchain_cflags,
Keir Mierle58671912019-11-14 00:15:41 -0800142 "{{defines}}",
143 "{{include_dirs}}",
144 "{{cflags}}",
145 "{{cflags_c}}",
146 "-c {{source}}",
147 "-o {{output}}",
148 ])
149 depsformat = "gcc"
150 description = "cc {{output}}"
Rob Mohra0ba54f2020-02-27 11:43:49 -0800151 outputs =
152 [ "{{source_out_dir}}/{{target_output_name}}.{{source_file_part}}.o" ]
Keir Mierle58671912019-11-14 00:15:41 -0800153 }
154
155 tool("cxx") {
156 depfile = "{{output}}.d"
157 command = string_join(" ",
158 [
159 "$_cxx",
160 "-MMD -MF $depfile", # Write out dependencies.
Wyatt Hepler21192402020-01-15 15:40:51 -0800161 _toolchain_cflags_cc,
162 _toolchain_cflags,
Keir Mierle58671912019-11-14 00:15:41 -0800163 "{{defines}}",
164 "{{include_dirs}}",
165 "{{cflags}}",
166 "{{cflags_cc}}",
167 "-c {{source}}",
168 "-o {{output}}",
169 ])
170 depsformat = "gcc"
171 description = "c++ {{output}}"
Rob Mohra0ba54f2020-02-27 11:43:49 -0800172 outputs =
173 [ "{{source_out_dir}}/{{target_output_name}}.{{source_file_part}}.o" ]
Keir Mierle58671912019-11-14 00:15:41 -0800174 }
175
176 tool("alink") {
177 command = "rm -f {{output}} && $_ar rcs {{output}} {{inputs}}"
178 description = "ar {{target_output_name}}{{output_extension}}"
Rob Mohra0ba54f2020-02-27 11:43:49 -0800179 outputs =
180 [ "{{target_out_dir}}/{{target_output_name}}{{output_extension}}" ]
Keir Mierle58671912019-11-14 00:15:41 -0800181 default_output_extension = ".a"
182 }
183
184 lib_switch = "-l"
185 lib_dir_switch = "-L"
186
187 _link_outfile = "{{output_dir}}/{{target_output_name}}{{output_extension}}"
Wyatt Heplercca0daf2019-11-14 11:29:04 -0800188
189 _link_flags = [
190 "$_cxx",
191 "{{ldflags}}",
192
Wyatt Hepler21192402020-01-15 15:40:51 -0800193 _toolchain_ldflags,
Aaron Greenb3ae1dc2020-04-13 11:37:05 -0700194 _toolchain_cflags,
Wyatt Heplercca0daf2019-11-14 11:29:04 -0800195
196 "{{inputs}}",
197 "{{libs}}",
198
199 "-o $_link_outfile",
200 ]
201
Keir Mierle58671912019-11-14 00:15:41 -0800202 _link_mapfile = "{{output_dir}}/{{target_output_name}}.map"
Keir Mierle58671912019-11-14 00:15:41 -0800203
Alexei Frolovdddc4fd2020-01-22 12:41:36 -0800204 if (host_os == "mac") {
Wyatt Heplercca0daf2019-11-14 11:29:04 -0800205 _link_flags += [
206 # Output a map file that shows symbols and their location.
207 "-Wl,-map,$_link_mapfile",
Keir Mierle58671912019-11-14 00:15:41 -0800208
Wyatt Heplercca0daf2019-11-14 11:29:04 -0800209 # Delete unreferenced sections. Helpful with -ffunction-sections.
210 "-Wl,-dead_strip",
211 ]
Alexei Frolovdddc4fd2020-01-22 12:41:36 -0800212 } else {
213 _link_flags += [
214 # Output a map file that shows symbols and their location.
215 "-Wl,-Map,$_link_mapfile",
216
217 # Delete unreferenced sections. Helpful with -ffunction-sections.
218 "-Wl,--gc-sections",
219 ]
Wyatt Heplercca0daf2019-11-14 11:29:04 -0800220 }
Keir Mierle58671912019-11-14 00:15:41 -0800221
Wyatt Heplercca0daf2019-11-14 11:29:04 -0800222 _link_command = string_join(" ", _link_flags)
Keir Mierle58671912019-11-14 00:15:41 -0800223
224 tool("link") {
225 command = _link_command
226 description = "ld $_link_outfile"
Rob Mohra0ba54f2020-02-27 11:43:49 -0800227 outputs = [ _link_outfile ]
Keir Mierle58671912019-11-14 00:15:41 -0800228 default_output_dir = "{{target_out_dir}}"
Alexei Frolov73de2a32020-03-19 11:34:28 -0700229
230 if (host_os == "win") {
231 default_output_extension = ".exe"
232 } else {
233 default_output_extension = ""
234 }
Keir Mierle58671912019-11-14 00:15:41 -0800235 }
236
237 tool("solink") {
238 command = _link_command + " -shared"
239 description = "ld -shared $_link_outfile"
Rob Mohra0ba54f2020-02-27 11:43:49 -0800240 outputs = [ _link_outfile ]
Keir Mierle58671912019-11-14 00:15:41 -0800241 default_output_dir = "{{target_out_dir}}"
242 default_output_extension = ".so"
243 }
244
245 tool("stamp") {
Wyatt Hepler9bc159f2020-01-15 08:06:11 -0800246 if (host_os == "win") {
247 command = "cmd /c type nul > \"{{output}}\""
248 } else {
249 command = "touch {{output}}"
250 }
Keir Mierle58671912019-11-14 00:15:41 -0800251 description = "stamp {{output}}"
252 }
253
254 tool("copy") {
255 command = "cp -af {{source}} {{output}}"
256 description = "cp {{source}} {{output}}"
257 }
258 }
259}