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 11 matching lines...) Expand all Loading... | |
26 # the libs section of the linker line. It allows one to inject libraries | 28 # the libs section of the linker line. It allows one to inject libraries |
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 |
brettw
2015/08/10 20:06:51
Can you document the new "strip" argument and its
agrieve
2015/08/10 20:33:47
Done.
| |
37 template("gcc_toolchain") { | 39 template("gcc_toolchain") { |
38 toolchain(target_name) { | 40 toolchain(target_name) { |
39 assert(defined(invoker.cc), "gcc_toolchain() must specify a \"cc\" value") | 41 assert(defined(invoker.cc), "gcc_toolchain() must specify a \"cc\" value") |
40 assert(defined(invoker.cxx), "gcc_toolchain() must specify a \"cxx\" value") | 42 assert(defined(invoker.cxx), "gcc_toolchain() must specify a \"cxx\" value") |
41 assert(defined(invoker.ar), "gcc_toolchain() must specify a \"ar\" value") | 43 assert(defined(invoker.ar), "gcc_toolchain() must specify a \"ar\" value") |
42 assert(defined(invoker.ld), "gcc_toolchain() must specify a \"ld\" value") | 44 assert(defined(invoker.ld), "gcc_toolchain() must specify a \"ld\" value") |
43 assert(defined(invoker.toolchain_cpu), | 45 assert(defined(invoker.toolchain_cpu), |
44 "gcc_toolchain() must specify a \"toolchain_cpu\"") | 46 "gcc_toolchain() must specify a \"toolchain_cpu\"") |
45 assert(defined(invoker.toolchain_os), | 47 assert(defined(invoker.toolchain_os), |
46 "gcc_toolchain() must specify a \"toolchain_os\"") | 48 "gcc_toolchain() must specify a \"toolchain_os\"") |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
131 outputs = [ | 133 outputs = [ |
132 "{{target_out_dir}}/{{target_output_name}}{{output_extension}}", | 134 "{{target_out_dir}}/{{target_output_name}}{{output_extension}}", |
133 ] | 135 ] |
134 default_output_extension = ".a" | 136 default_output_extension = ".a" |
135 output_prefix = "lib" | 137 output_prefix = "lib" |
136 } | 138 } |
137 | 139 |
138 tool("solink") { | 140 tool("solink") { |
139 soname = "{{target_output_name}}{{output_extension}}" # e.g. "libfoo.so". | 141 soname = "{{target_output_name}}{{output_extension}}" # e.g. "libfoo.so". |
140 sofile = "{{root_out_dir}}/$soname" # Possibly including toolchain dir. | 142 sofile = "{{root_out_dir}}/$soname" # Possibly including toolchain dir. |
143 if (shlib_subdir != ".") { | |
144 sofile = "{{root_out_dir}}/$shlib_subdir/$soname" | |
145 } | |
141 rspfile = sofile + ".rsp" | 146 rspfile = sofile + ".rsp" |
142 | 147 |
148 unstripped_sofile = sofile | |
149 if (defined(invoker.strip)) { | |
150 unstripped_sofile = "{{root_out_dir}}/lib.unstripped/$soname" | |
151 } | |
152 | |
143 # These variables are not built into GN but are helpers that implement | 153 # 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 | 154 # (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 | 155 # to a temporary file, (3) if the temporary file has differences from the |
146 # existing .TOC file, overwrite it, otherwise, don't change it. | 156 # existing .TOC file, overwrite it, otherwise, don't change it. |
147 tocfile = sofile + ".TOC" | 157 tocfile = sofile + ".TOC" |
148 temporary_tocname = sofile + ".tmp" | 158 temporary_tocname = sofile + ".tmp" |
149 link_command = | 159 |
150 "$ld -shared {{ldflags}} -o $sofile -Wl,-soname=$soname @$rspfile" | 160 link_command = "$ld -shared {{ldflags}} -o $unstripped_sofile -Wl,-soname= $soname @$rspfile" |
151 assert(defined(readelf), "to solink you must have a readelf") | 161 assert(defined(readelf), "to solink you must have a readelf") |
152 assert(defined(nm), "to solink you must have an nm") | 162 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" | 163 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" | 164 replace_command = "if ! cmp -s $temporary_tocname $tocfile; then mv $tempo rary_tocname $tocfile; fi" |
155 | 165 |
156 command = "$link_command && $toc_command && $replace_command" | 166 command = "$link_command && $toc_command && $replace_command" |
157 if (defined(invoker.postsolink)) { | 167 if (defined(invoker.strip)) { |
158 command += " && " + invoker.postsolink | 168 strip_command = |
169 "${invoker.strip} --strip-unneeded -o $sofile $unstripped_sofile" | |
170 command += " && " + strip_command | |
159 } | 171 } |
160 rspfile_content = "-Wl,--whole-archive {{inputs}} {{solibs}} -Wl,--no-whol e-archive $solink_libs_section_prefix {{libs}} $solink_libs_section_postfix" | 172 rspfile_content = "-Wl,--whole-archive {{inputs}} {{solibs}} -Wl,--no-whol e-archive $solink_libs_section_prefix {{libs}} $solink_libs_section_postfix" |
161 | 173 |
162 description = "SOLINK $sofile" | 174 description = "SOLINK $sofile" |
163 | 175 |
164 # Use this for {{output_extension}} expansions unless a target manually | 176 # Use this for {{output_extension}} expansions unless a target manually |
165 # overrides it (in which case {{output_extension}} will be what the target | 177 # overrides it (in which case {{output_extension}} will be what the target |
166 # specifies). | 178 # specifies). |
167 default_output_extension = ".so" | 179 default_output_extension = shlib_extension |
168 if (defined(invoker.default_output_extension)) { | 180 if (defined(invoker.default_output_extension)) { |
169 default_output_extension = invoker.default_output_extension | 181 default_output_extension = invoker.default_output_extension |
170 } | 182 } |
171 | 183 |
172 output_prefix = "lib" | 184 output_prefix = "lib" |
173 | 185 |
174 # Since the above commands only updates the .TOC file when it changes, ask | 186 # 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 | 187 # Ninja to check if the timestamp actually changed to know if downstream |
176 # dependencies should be recompiled. | 188 # dependencies should be recompiled. |
177 restat = true | 189 restat = true |
178 | 190 |
179 # Tell GN about the output files. It will link to the sofile but use the | 191 # Tell GN about the output files. It will link to the sofile but use the |
180 # tocfile for dependency management. | 192 # tocfile for dependency management. |
181 outputs = [ | 193 outputs = [ |
182 sofile, | 194 sofile, |
183 tocfile, | 195 tocfile, |
184 ] | 196 ] |
185 if (defined(invoker.solink_outputs)) { | 197 if (sofile != unstripped_sofile) { |
186 outputs += invoker.solink_outputs | 198 outputs += [ unstripped_sofile ] |
187 } | 199 } |
188 link_output = sofile | 200 link_output = sofile |
189 depend_output = tocfile | 201 depend_output = tocfile |
190 } | 202 } |
191 | 203 |
192 tool("link") { | 204 tool("link") { |
193 outfile = "{{root_out_dir}}/{{target_output_name}}{{output_extension}}" | 205 exename = "{{target_output_name}}{{output_extension}}" |
206 outfile = "{{root_out_dir}}/$exename" | |
194 rspfile = "$outfile.rsp" | 207 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" | 208 unstripped_outfile = outfile |
196 if (defined(invoker.postlink)) { | 209 if (defined(invoker.strip)) { |
197 command += " && " + invoker.postlink | 210 unstripped_outfile = "{{root_out_dir}}/exe.unstripped/$exename" |
211 } | |
212 | |
213 command = "$ld {{ldflags}} -o $unstripped_outfile -Wl,--start-group @$rspf ile {{solibs}} -Wl,--end-group $libs_section_prefix {{libs}} $libs_section_postf ix" | |
214 if (defined(invoker.strip)) { | |
215 strip_command = | |
216 "${invoker.strip} --strip-unneeded -o $outfile $unstripped_outfile" | |
217 command += " && " + strip_command | |
198 } | 218 } |
199 description = "LINK $outfile" | 219 description = "LINK $outfile" |
200 rspfile_content = "{{inputs}}" | 220 rspfile_content = "{{inputs}}" |
201 outputs = [ | 221 outputs = [ |
202 outfile, | 222 outfile, |
203 ] | 223 ] |
204 if (defined(invoker.link_outputs)) { | 224 if (outfile != unstripped_outfile) { |
205 outputs += invoker.link_outputs | 225 outputs += [ unstripped_outfile ] |
206 } | 226 } |
207 } | 227 } |
208 | 228 |
209 tool("stamp") { | 229 tool("stamp") { |
210 command = "touch {{output}}" | 230 command = "touch {{output}}" |
211 description = "STAMP {{output}}" | 231 description = "STAMP {{output}}" |
212 } | 232 } |
213 | 233 |
214 tool("copy") { | 234 tool("copy") { |
215 command = "ln -f {{source}} {{output}} 2>/dev/null || (rm -rf {{output}} & & cp -af {{source}} {{output}})" | 235 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)) { | 249 if (defined(invoker.is_clang)) { |
230 is_clang = invoker.is_clang | 250 is_clang = invoker.is_clang |
231 } | 251 } |
232 } | 252 } |
233 | 253 |
234 if (defined(invoker.deps)) { | 254 if (defined(invoker.deps)) { |
235 deps = invoker.deps | 255 deps = invoker.deps |
236 } | 256 } |
237 } | 257 } |
238 } | 258 } |
OLD | NEW |