OLD | NEW |
1 # Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
| 5 import("//build/toolchain/toolchain.gni") |
| 6 |
5 # This value will be inherited in the toolchain below. | 7 # This value will be inherited in the toolchain below. |
6 concurrent_links = exec_script("get_concurrent_links.py", [], "value") | 8 concurrent_links = exec_script("get_concurrent_links.py", [], "value") |
7 | 9 |
8 # This template defines a toolchain for something that works like gcc | 10 # This template defines a toolchain for something that works like gcc |
9 # (including clang). | 11 # (including clang). |
10 # | 12 # |
11 # It requires the following variables specifying the executables to run: | 13 # It requires the following variables specifying the executables to run: |
12 # - cc | 14 # - cc |
13 # - cxx | 15 # - cxx |
14 # - ar | 16 # - ar |
(...skipping 12 matching lines...) Expand all Loading... |
27 # at the beginning and end for all targets in a toolchain. | 29 # at the beginning and end for all targets in a toolchain. |
28 # - solink_libs_section_prefix | 30 # - solink_libs_section_prefix |
29 # - solink_libs_section_postfix | 31 # - solink_libs_section_postfix |
30 # Same as libs_section_{pre,post}fix except used for solink instead of link
. | 32 # Same as libs_section_{pre,post}fix except used for solink instead of link
. |
31 # - post_solink | 33 # - post_solink |
32 # The content of this string, if specified, will be appended to the solink | 34 # The content of this string, if specified, will be appended to the solink |
33 # command. | 35 # command. |
34 # - deps | 36 # - deps |
35 # Just forwarded to the toolchain definition. | 37 # Just forwarded to the toolchain definition. |
36 # - is_clang | 38 # - is_clang |
| 39 # Whether to use clang instead of gcc. |
| 40 # - strip |
| 41 # Location of the strip executable. When specified, strip will be run on |
| 42 # all shared libraries and executables as they are built. The pre-stripped |
| 43 # artifacts will be put in lib.stripped/ and exe.stripped/. |
37 template("gcc_toolchain") { | 44 template("gcc_toolchain") { |
38 toolchain(target_name) { | 45 toolchain(target_name) { |
39 assert(defined(invoker.cc), "gcc_toolchain() must specify a \"cc\" value") | 46 assert(defined(invoker.cc), "gcc_toolchain() must specify a \"cc\" value") |
40 assert(defined(invoker.cxx), "gcc_toolchain() must specify a \"cxx\" value") | 47 assert(defined(invoker.cxx), "gcc_toolchain() must specify a \"cxx\" value") |
41 assert(defined(invoker.ar), "gcc_toolchain() must specify a \"ar\" value") | 48 assert(defined(invoker.ar), "gcc_toolchain() must specify a \"ar\" value") |
42 assert(defined(invoker.ld), "gcc_toolchain() must specify a \"ld\" value") | 49 assert(defined(invoker.ld), "gcc_toolchain() must specify a \"ld\" value") |
43 assert(defined(invoker.toolchain_cpu), | 50 assert(defined(invoker.toolchain_cpu), |
44 "gcc_toolchain() must specify a \"toolchain_cpu\"") | 51 "gcc_toolchain() must specify a \"toolchain_cpu\"") |
45 assert(defined(invoker.toolchain_os), | 52 assert(defined(invoker.toolchain_os), |
46 "gcc_toolchain() must specify a \"toolchain_os\"") | 53 "gcc_toolchain() must specify a \"toolchain_os\"") |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
131 outputs = [ | 138 outputs = [ |
132 "{{target_out_dir}}/{{target_output_name}}{{output_extension}}", | 139 "{{target_out_dir}}/{{target_output_name}}{{output_extension}}", |
133 ] | 140 ] |
134 default_output_extension = ".a" | 141 default_output_extension = ".a" |
135 output_prefix = "lib" | 142 output_prefix = "lib" |
136 } | 143 } |
137 | 144 |
138 tool("solink") { | 145 tool("solink") { |
139 soname = "{{target_output_name}}{{output_extension}}" # e.g. "libfoo.so". | 146 soname = "{{target_output_name}}{{output_extension}}" # e.g. "libfoo.so". |
140 sofile = "{{root_out_dir}}/$soname" # Possibly including toolchain dir. | 147 sofile = "{{root_out_dir}}/$soname" # Possibly including toolchain dir. |
| 148 if (shlib_subdir != ".") { |
| 149 sofile = "{{root_out_dir}}/$shlib_subdir/$soname" |
| 150 } |
141 rspfile = sofile + ".rsp" | 151 rspfile = sofile + ".rsp" |
142 | 152 |
| 153 unstripped_sofile = sofile |
| 154 if (defined(invoker.strip)) { |
| 155 unstripped_sofile = "{{root_out_dir}}/lib.unstripped/$soname" |
| 156 } |
| 157 |
143 # These variables are not built into GN but are helpers that implement | 158 # These variables are not built into GN but are helpers that implement |
144 # (1) linking to produce a .so, (2) extracting the symbols from that file | 159 # (1) linking to produce a .so, (2) extracting the symbols from that file |
145 # to a temporary file, (3) if the temporary file has differences from the | 160 # to a temporary file, (3) if the temporary file has differences from the |
146 # existing .TOC file, overwrite it, otherwise, don't change it. | 161 # existing .TOC file, overwrite it, otherwise, don't change it. |
147 tocfile = sofile + ".TOC" | 162 tocfile = sofile + ".TOC" |
148 temporary_tocname = sofile + ".tmp" | 163 temporary_tocname = sofile + ".tmp" |
149 link_command = | 164 |
150 "$ld -shared {{ldflags}} -o $sofile -Wl,-soname=$soname @$rspfile" | 165 link_command = "$ld -shared {{ldflags}} -o $unstripped_sofile -Wl,-soname=
$soname @$rspfile" |
151 assert(defined(readelf), "to solink you must have a readelf") | 166 assert(defined(readelf), "to solink you must have a readelf") |
152 assert(defined(nm), "to solink you must have an nm") | 167 assert(defined(nm), "to solink you must have an nm") |
153 toc_command = "{ $readelf -d $sofile | grep SONAME ; $nm -gD -f p $sofile
| cut -f1-2 -d' '; } > $temporary_tocname" | 168 toc_command = "{ $readelf -d $unstripped_sofile | grep SONAME ; $nm -gD -f
p $unstripped_sofile | cut -f1-2 -d' '; } > $temporary_tocname" |
154 replace_command = "if ! cmp -s $temporary_tocname $tocfile; then mv $tempo
rary_tocname $tocfile; fi" | 169 replace_command = "if ! cmp -s $temporary_tocname $tocfile; then mv $tempo
rary_tocname $tocfile; fi" |
155 | 170 |
156 command = "$link_command && $toc_command && $replace_command" | 171 command = "$link_command && $toc_command && $replace_command" |
157 if (defined(invoker.postsolink)) { | 172 if (defined(invoker.strip)) { |
158 command += " && " + invoker.postsolink | 173 strip_command = |
| 174 "${invoker.strip} --strip-unneeded -o $sofile $unstripped_sofile" |
| 175 command += " && " + strip_command |
159 } | 176 } |
160 rspfile_content = "-Wl,--whole-archive {{inputs}} {{solibs}} -Wl,--no-whol
e-archive $solink_libs_section_prefix {{libs}} $solink_libs_section_postfix" | 177 rspfile_content = "-Wl,--whole-archive {{inputs}} {{solibs}} -Wl,--no-whol
e-archive $solink_libs_section_prefix {{libs}} $solink_libs_section_postfix" |
161 | 178 |
162 description = "SOLINK $sofile" | 179 description = "SOLINK $sofile" |
163 | 180 |
164 # Use this for {{output_extension}} expansions unless a target manually | 181 # Use this for {{output_extension}} expansions unless a target manually |
165 # overrides it (in which case {{output_extension}} will be what the target | 182 # overrides it (in which case {{output_extension}} will be what the target |
166 # specifies). | 183 # specifies). |
167 default_output_extension = ".so" | 184 default_output_extension = shlib_extension |
168 if (defined(invoker.default_output_extension)) { | 185 if (defined(invoker.default_output_extension)) { |
169 default_output_extension = invoker.default_output_extension | 186 default_output_extension = invoker.default_output_extension |
170 } | 187 } |
171 | 188 |
172 output_prefix = "lib" | 189 output_prefix = "lib" |
173 | 190 |
174 # Since the above commands only updates the .TOC file when it changes, ask | 191 # Since the above commands only updates the .TOC file when it changes, ask |
175 # Ninja to check if the timestamp actually changed to know if downstream | 192 # Ninja to check if the timestamp actually changed to know if downstream |
176 # dependencies should be recompiled. | 193 # dependencies should be recompiled. |
177 restat = true | 194 restat = true |
178 | 195 |
179 # Tell GN about the output files. It will link to the sofile but use the | 196 # Tell GN about the output files. It will link to the sofile but use the |
180 # tocfile for dependency management. | 197 # tocfile for dependency management. |
181 outputs = [ | 198 outputs = [ |
182 sofile, | 199 sofile, |
183 tocfile, | 200 tocfile, |
184 ] | 201 ] |
185 if (defined(invoker.solink_outputs)) { | 202 if (sofile != unstripped_sofile) { |
186 outputs += invoker.solink_outputs | 203 outputs += [ unstripped_sofile ] |
187 } | 204 } |
188 link_output = sofile | 205 link_output = sofile |
189 depend_output = tocfile | 206 depend_output = tocfile |
190 } | 207 } |
191 | 208 |
192 tool("link") { | 209 tool("link") { |
193 outfile = "{{root_out_dir}}/{{target_output_name}}{{output_extension}}" | 210 exename = "{{target_output_name}}{{output_extension}}" |
| 211 outfile = "{{root_out_dir}}/$exename" |
194 rspfile = "$outfile.rsp" | 212 rspfile = "$outfile.rsp" |
195 command = "$ld {{ldflags}} -o $outfile -Wl,--start-group @$rspfile {{solib
s}} -Wl,--end-group $libs_section_prefix {{libs}} $libs_section_postfix" | 213 unstripped_outfile = outfile |
196 if (defined(invoker.postlink)) { | 214 if (defined(invoker.strip)) { |
197 command += " && " + invoker.postlink | 215 unstripped_outfile = "{{root_out_dir}}/exe.unstripped/$exename" |
| 216 } |
| 217 |
| 218 command = "$ld {{ldflags}} -o $unstripped_outfile -Wl,--start-group @$rspf
ile {{solibs}} -Wl,--end-group $libs_section_prefix {{libs}} $libs_section_postf
ix" |
| 219 if (defined(invoker.strip)) { |
| 220 strip_command = |
| 221 "${invoker.strip} --strip-unneeded -o $outfile $unstripped_outfile" |
| 222 command += " && " + strip_command |
198 } | 223 } |
199 description = "LINK $outfile" | 224 description = "LINK $outfile" |
200 rspfile_content = "{{inputs}}" | 225 rspfile_content = "{{inputs}}" |
201 outputs = [ | 226 outputs = [ |
202 outfile, | 227 outfile, |
203 ] | 228 ] |
204 if (defined(invoker.link_outputs)) { | 229 if (outfile != unstripped_outfile) { |
205 outputs += invoker.link_outputs | 230 outputs += [ unstripped_outfile ] |
206 } | 231 } |
207 } | 232 } |
208 | 233 |
209 tool("stamp") { | 234 tool("stamp") { |
210 command = "touch {{output}}" | 235 command = "touch {{output}}" |
211 description = "STAMP {{output}}" | 236 description = "STAMP {{output}}" |
212 } | 237 } |
213 | 238 |
214 tool("copy") { | 239 tool("copy") { |
215 command = "ln -f {{source}} {{output}} 2>/dev/null || (rm -rf {{output}} &
& cp -af {{source}} {{output}})" | 240 command = "ln -f {{source}} {{output}} 2>/dev/null || (rm -rf {{output}} &
& cp -af {{source}} {{output}})" |
(...skipping 13 matching lines...) Expand all Loading... |
229 if (defined(invoker.is_clang)) { | 254 if (defined(invoker.is_clang)) { |
230 is_clang = invoker.is_clang | 255 is_clang = invoker.is_clang |
231 } | 256 } |
232 } | 257 } |
233 | 258 |
234 if (defined(invoker.deps)) { | 259 if (defined(invoker.deps)) { |
235 deps = invoker.deps | 260 deps = invoker.deps |
236 } | 261 } |
237 } | 262 } |
238 } | 263 } |
OLD | NEW |