diff options
author | Richard Purdie <richard.purdie@linuxfoundation.org> | 2022-07-23 13:41:38 +0100 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2022-07-28 11:07:33 +0100 |
commit | 1e04c8aafbe562d2c87ca9de53fbb27703b0c51a (patch) | |
tree | 999d6eea83251701fecb3f993e63651f2b5749f7 /meta/classes | |
parent | a02bb3b794fe97cbd64d6740db494de00c17134b (diff) | |
download | poky-1e04c8aafbe562d2c87ca9de53fbb27703b0c51a.tar.gz |
rust-target-config: Create new class to contain target json config generation
Currently most of the rust recipes use this code but it is all piecemeal.
Turn the code into a class where things can start to be rationalised. Ultimately
some of the data and python code should be moved to a python library but one step
at a time.
No functionality changes.
(From OE-Core rev: 3795285cbf362e13b8151bfdbe1bce999ac28641)
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/classes')
-rw-r--r-- | meta/classes/rust-target-config.bbclass | 368 |
1 files changed, 368 insertions, 0 deletions
diff --git a/meta/classes/rust-target-config.bbclass b/meta/classes/rust-target-config.bbclass new file mode 100644 index 0000000000..4db91d36d5 --- /dev/null +++ b/meta/classes/rust-target-config.bbclass | |||
@@ -0,0 +1,368 @@ | |||
1 | # Right now this is focused on arm-specific tune features. | ||
2 | # We get away with this for now as one can only use x86-64 as the build host | ||
3 | # (not arm). | ||
4 | # Note that TUNE_FEATURES is _always_ refering to the target, so we really | ||
5 | # don't want to use this for the host/build. | ||
6 | def llvm_features_from_tune(d): | ||
7 | f = [] | ||
8 | feat = d.getVar('TUNE_FEATURES') | ||
9 | if not feat: | ||
10 | return [] | ||
11 | feat = frozenset(feat.split()) | ||
12 | |||
13 | mach_overrides = d.getVar('MACHINEOVERRIDES') | ||
14 | mach_overrides = frozenset(mach_overrides.split(':')) | ||
15 | |||
16 | if 'vfpv4' in feat: | ||
17 | f.append("+vfp4") | ||
18 | if 'vfpv3' in feat: | ||
19 | f.append("+vfp3") | ||
20 | if 'vfpv3d16' in feat: | ||
21 | f.append("+d16") | ||
22 | |||
23 | if 'vfpv2' in feat or 'vfp' in feat: | ||
24 | f.append("+vfp2") | ||
25 | |||
26 | if 'neon' in feat: | ||
27 | f.append("+neon") | ||
28 | |||
29 | if 'mips32' in feat: | ||
30 | f.append("+mips32") | ||
31 | |||
32 | if 'mips32r2' in feat: | ||
33 | f.append("+mips32r2") | ||
34 | |||
35 | if target_is_armv7(d): | ||
36 | f.append('+v7') | ||
37 | |||
38 | if ('armv6' in mach_overrides) or ('armv6' in feat): | ||
39 | f.append("+v6") | ||
40 | if 'armv5te' in feat: | ||
41 | f.append("+strict-align") | ||
42 | f.append("+v5te") | ||
43 | elif 'armv5' in feat: | ||
44 | f.append("+strict-align") | ||
45 | f.append("+v5") | ||
46 | |||
47 | if ('armv4' in mach_overrides) or ('armv4' in feat): | ||
48 | f.append("+strict-align") | ||
49 | |||
50 | if 'dsp' in feat: | ||
51 | f.append("+dsp") | ||
52 | |||
53 | if 'thumb' in feat: | ||
54 | if d.getVar('ARM_THUMB_OPT') == "thumb": | ||
55 | if target_is_armv7(d): | ||
56 | f.append('+thumb2') | ||
57 | f.append("+thumb-mode") | ||
58 | |||
59 | if 'cortexa5' in feat: | ||
60 | f.append("+a5") | ||
61 | if 'cortexa7' in feat: | ||
62 | f.append("+a7") | ||
63 | if 'cortexa9' in feat: | ||
64 | f.append("+a9") | ||
65 | if 'cortexa15' in feat: | ||
66 | f.append("+a15") | ||
67 | if 'cortexa17' in feat: | ||
68 | f.append("+a17") | ||
69 | if ('riscv64' in feat) or ('riscv32' in feat): | ||
70 | f.append("+a,+c,+d,+f,+m") | ||
71 | return f | ||
72 | llvm_features_from_tune[vardepvalue] = "${@llvm_features_from_tune(d)}" | ||
73 | |||
74 | # TARGET_CC_ARCH changes from build/cross/target so it'll do the right thing | ||
75 | # this should go away when https://github.com/rust-lang/rust/pull/31709 is | ||
76 | # stable (1.9.0?) | ||
77 | def llvm_features_from_cc_arch(d): | ||
78 | f = [] | ||
79 | feat = d.getVar('TARGET_CC_ARCH') | ||
80 | if not feat: | ||
81 | return [] | ||
82 | feat = frozenset(feat.split()) | ||
83 | |||
84 | if '-mmmx' in feat: | ||
85 | f.append("+mmx") | ||
86 | if '-msse' in feat: | ||
87 | f.append("+sse") | ||
88 | if '-msse2' in feat: | ||
89 | f.append("+sse2") | ||
90 | if '-msse3' in feat: | ||
91 | f.append("+sse3") | ||
92 | if '-mssse3' in feat: | ||
93 | f.append("+ssse3") | ||
94 | if '-msse4.1' in feat: | ||
95 | f.append("+sse4.1") | ||
96 | if '-msse4.2' in feat: | ||
97 | f.append("+sse4.2") | ||
98 | if '-msse4a' in feat: | ||
99 | f.append("+sse4a") | ||
100 | if '-mavx' in feat: | ||
101 | f.append("+avx") | ||
102 | if '-mavx2' in feat: | ||
103 | f.append("+avx2") | ||
104 | |||
105 | return f | ||
106 | |||
107 | def llvm_features_from_target_fpu(d): | ||
108 | # TARGET_FPU can be hard or soft. +soft-float tell llvm to use soft float | ||
109 | # ABI. There is no option for hard. | ||
110 | |||
111 | fpu = d.getVar('TARGET_FPU', True) | ||
112 | return ["+soft-float"] if fpu == "soft" else [] | ||
113 | |||
114 | def llvm_features(d): | ||
115 | return ','.join(llvm_features_from_tune(d) + | ||
116 | llvm_features_from_cc_arch(d) + | ||
117 | llvm_features_from_target_fpu(d)) | ||
118 | |||
119 | llvm_features[vardepvalue] = "${@llvm_features(d)}" | ||
120 | |||
121 | ## arm-unknown-linux-gnueabihf | ||
122 | DATA_LAYOUT[arm-eabi] = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64" | ||
123 | TARGET_ENDIAN[arm-eabi] = "little" | ||
124 | TARGET_POINTER_WIDTH[arm-eabi] = "32" | ||
125 | TARGET_C_INT_WIDTH[arm-eabi] = "32" | ||
126 | MAX_ATOMIC_WIDTH[arm-eabi] = "64" | ||
127 | FEATURES[arm-eabi] = "+v6,+vfp2" | ||
128 | |||
129 | ## armv7-unknown-linux-gnueabihf | ||
130 | DATA_LAYOUT[armv7-eabi] = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64" | ||
131 | TARGET_ENDIAN[armv7-eabi] = "little" | ||
132 | TARGET_POINTER_WIDTH[armv7-eabi] = "32" | ||
133 | TARGET_C_INT_WIDTH[armv7-eabi] = "32" | ||
134 | MAX_ATOMIC_WIDTH[armv7-eabi] = "64" | ||
135 | FEATURES[armv7-eabi] = "+v7,+vfp2,+thumb2" | ||
136 | |||
137 | ## aarch64-unknown-linux-{gnu, musl} | ||
138 | DATA_LAYOUT[aarch64] = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" | ||
139 | TARGET_ENDIAN[aarch64] = "little" | ||
140 | TARGET_POINTER_WIDTH[aarch64] = "64" | ||
141 | TARGET_C_INT_WIDTH[aarch64] = "32" | ||
142 | MAX_ATOMIC_WIDTH[aarch64] = "128" | ||
143 | |||
144 | ## x86_64-unknown-linux-{gnu, musl} | ||
145 | DATA_LAYOUT[x86_64] = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | ||
146 | TARGET_ENDIAN[x86_64] = "little" | ||
147 | TARGET_POINTER_WIDTH[x86_64] = "64" | ||
148 | TARGET_C_INT_WIDTH[x86_64] = "32" | ||
149 | MAX_ATOMIC_WIDTH[x86_64] = "64" | ||
150 | |||
151 | ## x86_64-unknown-linux-gnux32 | ||
152 | DATA_LAYOUT[x86_64-x32] = "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" | ||
153 | TARGET_ENDIAN[x86_64-x32] = "little" | ||
154 | TARGET_POINTER_WIDTH[x86_64-x32] = "32" | ||
155 | TARGET_C_INT_WIDTH[x86_64-x32] = "32" | ||
156 | MAX_ATOMIC_WIDTH[x86_64-x32] = "64" | ||
157 | |||
158 | ## i686-unknown-linux-{gnu, musl} | ||
159 | DATA_LAYOUT[i686] = "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128" | ||
160 | TARGET_ENDIAN[i686] = "little" | ||
161 | TARGET_POINTER_WIDTH[i686] = "32" | ||
162 | TARGET_C_INT_WIDTH[i686] = "32" | ||
163 | MAX_ATOMIC_WIDTH[i686] = "64" | ||
164 | |||
165 | ## XXX: a bit of a hack so qemux86 builds, clone of i686-unknown-linux-{gnu, musl} above | ||
166 | DATA_LAYOUT[i586] = "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128" | ||
167 | TARGET_ENDIAN[i586] = "little" | ||
168 | TARGET_POINTER_WIDTH[i586] = "32" | ||
169 | TARGET_C_INT_WIDTH[i586] = "32" | ||
170 | MAX_ATOMIC_WIDTH[i586] = "64" | ||
171 | |||
172 | ## mips-unknown-linux-{gnu, musl} | ||
173 | DATA_LAYOUT[mips] = "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64" | ||
174 | TARGET_ENDIAN[mips] = "big" | ||
175 | TARGET_POINTER_WIDTH[mips] = "32" | ||
176 | TARGET_C_INT_WIDTH[mips] = "32" | ||
177 | MAX_ATOMIC_WIDTH[mips] = "32" | ||
178 | |||
179 | ## mipsel-unknown-linux-{gnu, musl} | ||
180 | DATA_LAYOUT[mipsel] = "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64" | ||
181 | TARGET_ENDIAN[mipsel] = "little" | ||
182 | TARGET_POINTER_WIDTH[mipsel] = "32" | ||
183 | TARGET_C_INT_WIDTH[mipsel] = "32" | ||
184 | MAX_ATOMIC_WIDTH[mipsel] = "32" | ||
185 | |||
186 | ## mips64-unknown-linux-{gnu, musl} | ||
187 | DATA_LAYOUT[mips64] = "E-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128" | ||
188 | TARGET_ENDIAN[mips64] = "big" | ||
189 | TARGET_POINTER_WIDTH[mips64] = "64" | ||
190 | TARGET_C_INT_WIDTH[mips64] = "64" | ||
191 | MAX_ATOMIC_WIDTH[mips64] = "64" | ||
192 | |||
193 | ## mips64el-unknown-linux-{gnu, musl} | ||
194 | DATA_LAYOUT[mips64el] = "e-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128" | ||
195 | TARGET_ENDIAN[mips64el] = "little" | ||
196 | TARGET_POINTER_WIDTH[mips64el] = "64" | ||
197 | TARGET_C_INT_WIDTH[mips64el] = "64" | ||
198 | MAX_ATOMIC_WIDTH[mips64el] = "64" | ||
199 | |||
200 | ## powerpc-unknown-linux-{gnu, musl} | ||
201 | DATA_LAYOUT[powerpc] = "E-m:e-p:32:32-i64:64-n32" | ||
202 | TARGET_ENDIAN[powerpc] = "big" | ||
203 | TARGET_POINTER_WIDTH[powerpc] = "32" | ||
204 | TARGET_C_INT_WIDTH[powerpc] = "32" | ||
205 | MAX_ATOMIC_WIDTH[powerpc] = "32" | ||
206 | |||
207 | ## powerpc64-unknown-linux-{gnu, musl} | ||
208 | DATA_LAYOUT[powerpc64] = "E-m:e-i64:64-n32:64-S128-v256:256:256-v512:512:512" | ||
209 | TARGET_ENDIAN[powerpc64] = "big" | ||
210 | TARGET_POINTER_WIDTH[powerpc64] = "64" | ||
211 | TARGET_C_INT_WIDTH[powerpc64] = "64" | ||
212 | MAX_ATOMIC_WIDTH[powerpc64] = "64" | ||
213 | |||
214 | ## powerpc64le-unknown-linux-{gnu, musl} | ||
215 | DATA_LAYOUT[powerpc64le] = "e-m:e-i64:64-n32:64-v256:256:256-v512:512:512" | ||
216 | TARGET_ENDIAN[powerpc64le] = "little" | ||
217 | TARGET_POINTER_WIDTH[powerpc64le] = "64" | ||
218 | TARGET_C_INT_WIDTH[powerpc64le] = "64" | ||
219 | MAX_ATOMIC_WIDTH[powerpc64le] = "64" | ||
220 | |||
221 | ## riscv32-unknown-linux-{gnu, musl} | ||
222 | DATA_LAYOUT[riscv32] = "e-m:e-p:32:32-i64:64-n32-S128" | ||
223 | TARGET_ENDIAN[riscv32] = "little" | ||
224 | TARGET_POINTER_WIDTH[riscv32] = "32" | ||
225 | TARGET_C_INT_WIDTH[riscv32] = "32" | ||
226 | MAX_ATOMIC_WIDTH[riscv32] = "32" | ||
227 | |||
228 | ## riscv64-unknown-linux-{gnu, musl} | ||
229 | DATA_LAYOUT[riscv64] = "e-m:e-p:64:64-i64:64-i128:128-n64-S128" | ||
230 | TARGET_ENDIAN[riscv64] = "little" | ||
231 | TARGET_POINTER_WIDTH[riscv64] = "64" | ||
232 | TARGET_C_INT_WIDTH[riscv64] = "64" | ||
233 | MAX_ATOMIC_WIDTH[riscv64] = "64" | ||
234 | |||
235 | # Convert a normal arch (HOST_ARCH, TARGET_ARCH, BUILD_ARCH, etc) to something | ||
236 | # rust's internals won't choke on. | ||
237 | def arch_to_rust_target_arch(arch): | ||
238 | if arch == "i586" or arch == "i686": | ||
239 | return "x86" | ||
240 | elif arch == "mipsel": | ||
241 | return "mips" | ||
242 | elif arch == "mip64sel": | ||
243 | return "mips64" | ||
244 | elif arch == "armv7": | ||
245 | return "arm" | ||
246 | elif arch == "powerpc64le": | ||
247 | return "powerpc64" | ||
248 | else: | ||
249 | return arch | ||
250 | |||
251 | # generates our target CPU value | ||
252 | def llvm_cpu(d): | ||
253 | cpu = d.getVar('PACKAGE_ARCH') | ||
254 | target = d.getVar('TRANSLATED_TARGET_ARCH') | ||
255 | |||
256 | trans = {} | ||
257 | trans['corei7-64'] = "corei7" | ||
258 | trans['core2-32'] = "core2" | ||
259 | trans['x86-64'] = "x86-64" | ||
260 | trans['i686'] = "i686" | ||
261 | trans['i586'] = "i586" | ||
262 | trans['powerpc'] = "powerpc" | ||
263 | trans['mips64'] = "mips64" | ||
264 | trans['mips64el'] = "mips64" | ||
265 | trans['riscv64'] = "generic-rv64" | ||
266 | trans['riscv32'] = "generic-rv32" | ||
267 | |||
268 | if target in ["mips", "mipsel"]: | ||
269 | feat = frozenset(d.getVar('TUNE_FEATURES').split()) | ||
270 | if "mips32r2" in feat: | ||
271 | trans['mipsel'] = "mips32r2" | ||
272 | trans['mips'] = "mips32r2" | ||
273 | elif "mips32" in feat: | ||
274 | trans['mipsel'] = "mips32" | ||
275 | trans['mips'] = "mips32" | ||
276 | |||
277 | try: | ||
278 | return trans[cpu] | ||
279 | except: | ||
280 | return trans.get(target, "generic") | ||
281 | |||
282 | llvm_cpu[vardepvalue] = "${@llvm_cpu(d)}" | ||
283 | |||
284 | def rust_gen_target(d, thing, wd, arch): | ||
285 | import json | ||
286 | sys = d.getVar('{}_SYS'.format(thing)) | ||
287 | prefix = d.getVar('{}_PREFIX'.format(thing)) | ||
288 | |||
289 | abi = None | ||
290 | cpu = "generic" | ||
291 | features = "" | ||
292 | |||
293 | if thing == "TARGET": | ||
294 | abi = d.getVar('ABIEXTENSION') | ||
295 | cpu = llvm_cpu(d) | ||
296 | if bb.data.inherits_class('native', d): | ||
297 | features = ','.join(llvm_features_from_cc_arch(d)) | ||
298 | else: | ||
299 | features = llvm_features(d) or "" | ||
300 | # arm and armv7 have different targets in llvm | ||
301 | if arch == "arm" and target_is_armv7(d): | ||
302 | arch = 'armv7' | ||
303 | |||
304 | rust_arch = oe.rust.arch_to_rust_arch(arch) | ||
305 | |||
306 | if abi: | ||
307 | arch_abi = "{}-{}".format(rust_arch, abi) | ||
308 | else: | ||
309 | arch_abi = rust_arch | ||
310 | |||
311 | features = features or d.getVarFlag('FEATURES', arch_abi) or "" | ||
312 | features = features.strip() | ||
313 | |||
314 | llvm_target = d.getVar('RUST_TARGET_SYS') | ||
315 | if thing == "BUILD": | ||
316 | llvm_target = d.getVar('RUST_HOST_SYS') | ||
317 | |||
318 | # build tspec | ||
319 | tspec = {} | ||
320 | tspec['llvm-target'] = llvm_target | ||
321 | tspec['data-layout'] = d.getVarFlag('DATA_LAYOUT', arch_abi) | ||
322 | tspec['max-atomic-width'] = int(d.getVarFlag('MAX_ATOMIC_WIDTH', arch_abi)) | ||
323 | tspec['target-pointer-width'] = d.getVarFlag('TARGET_POINTER_WIDTH', arch_abi) | ||
324 | tspec['target-c-int-width'] = d.getVarFlag('TARGET_C_INT_WIDTH', arch_abi) | ||
325 | tspec['target-endian'] = d.getVarFlag('TARGET_ENDIAN', arch_abi) | ||
326 | tspec['arch'] = arch_to_rust_target_arch(rust_arch) | ||
327 | tspec['os'] = "linux" | ||
328 | if "musl" in tspec['llvm-target']: | ||
329 | tspec['env'] = "musl" | ||
330 | else: | ||
331 | tspec['env'] = "gnu" | ||
332 | if "riscv64" in tspec['llvm-target']: | ||
333 | tspec['llvm-abiname'] = "lp64d" | ||
334 | if "riscv32" in tspec['llvm-target']: | ||
335 | tspec['llvm-abiname'] = "ilp32d" | ||
336 | tspec['vendor'] = "unknown" | ||
337 | tspec['target-family'] = "unix" | ||
338 | tspec['linker'] = "{}{}gcc".format(d.getVar('CCACHE'), prefix) | ||
339 | tspec['cpu'] = cpu | ||
340 | if features != "": | ||
341 | tspec['features'] = features | ||
342 | tspec['dynamic-linking'] = True | ||
343 | tspec['executables'] = True | ||
344 | tspec['linker-is-gnu'] = True | ||
345 | tspec['linker-flavor'] = "gcc" | ||
346 | tspec['has-rpath'] = True | ||
347 | tspec['has-elf-tls'] = True | ||
348 | tspec['position-independent-executables'] = True | ||
349 | tspec['panic-strategy'] = d.getVar("RUST_PANIC_STRATEGY") | ||
350 | |||
351 | # write out the target spec json file | ||
352 | with open(wd + sys + '.json', 'w') as f: | ||
353 | json.dump(tspec, f, indent=4) | ||
354 | |||
355 | # These are accounted for in tmpdir path names so don't need to be in the task sig | ||
356 | rust_gen_target[vardepsexclude] += "RUST_HOST_SYS RUST_TARGET_SYS ABIEXTENSION llvm_cpu" | ||
357 | |||
358 | do_rust_gen_targets[vardeps] += "DATA_LAYOUT TARGET_ENDIAN TARGET_POINTER_WIDTH TARGET_C_INT_WIDTH MAX_ATOMIC_WIDTH FEATURES" | ||
359 | |||
360 | python do_rust_gen_targets () { | ||
361 | wd = d.getVar('WORKDIR') + '/targets/' | ||
362 | build_arch = d.getVar('BUILD_ARCH') | ||
363 | rust_gen_target(d, 'BUILD', wd, build_arch) | ||
364 | } | ||
365 | |||
366 | addtask rust_gen_targets after do_patch before do_compile | ||
367 | do_rust_gen_targets[dirs] += "${WORKDIR}/targets" | ||
368 | |||