convert things to python, cargo-native now works
This commit is contained in:
+171
-146
@@ -11,7 +11,132 @@ LIC_FILES_CHKSUM ="\
|
||||
file://COPYRIGHT;md5=0e8e4a3b5d8e1c90eb243d406369763a \
|
||||
"
|
||||
|
||||
def rust_triple(arch, vendor, os, d):
|
||||
export RUST_TARGET_PATH="${WORKDIR}/targets/"
|
||||
|
||||
## arm-unknown-linux-gnueabihf
|
||||
DATA_LAYOUT[arm] = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:128-a0:0:64-n32"
|
||||
LLVM_TARGET[arm] = "arm-unknown-linux-gnueabihf"
|
||||
TARGET_ENDIAN[arm] = "little"
|
||||
TARGET_WORD_SIZE[arm] = "32"
|
||||
FEATURES[arm] = "+v6,+vfp2"
|
||||
PRE_LINK_ARGS[arm] = "-Wl,--as-needed"
|
||||
|
||||
## x86_64-unknown-linux-gnu
|
||||
DATA_LAYOUT[x86_64] = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
|
||||
LLVM_TARGET[x86_64] = "x86_64-unknown-linux-gnu"
|
||||
TARGET_ENDIAN[x86_64] = "little"
|
||||
TARGET_WORD_SIZE[x86_64] = "64"
|
||||
PRE_LINK_ARGS[x86_64] = "-m64 -Wl,--as-needed"
|
||||
|
||||
def ldflags_for(d, thing):
|
||||
cc_arch = d.getVar('{}_CC_ARCH'.format(thing), True) or ""
|
||||
tc = d.getVar('TOOLCHAIN_OPTIONS', True) or ""
|
||||
ldflags = d.getVar('{}_LDFLAGS'.format(thing), True) or ""
|
||||
return tc.split() + ldflags.split() + cc_arch.split()
|
||||
|
||||
def arch_for(d, thing):
|
||||
return d.getVar('{}_ARCH'.format(thing), True)
|
||||
|
||||
def sys_for(d, thing):
|
||||
return d.getVar('{}_SYS'.format(thing), True)
|
||||
|
||||
def prefix_for(d, thing):
|
||||
return d.getVar('{}_PREFIX'.format(thing), True)
|
||||
|
||||
## FIXME: TOOLCHAIN_OPTIONS is set to "" by native.bbclass and cross.bbclass,
|
||||
## which prevents us from grabbing them when building a cross compiler (native doesn't matter).
|
||||
def cflags_for(d, thing):
|
||||
cc_arch = d.getVar('{}_CC_ARCH'.format(thing), True) or ""
|
||||
flags = d.getVar('{}_CFLAGS'.format(thing), True) or ""
|
||||
tc = d.getVar('TOOLCHAIN_OPTIONS', True) or ""
|
||||
return ' '.join([cc_arch, flags, tc])
|
||||
|
||||
def cxxflags_for(d, thing):
|
||||
cc_arch = d.getVar('{}_CC_ARCH'.format(thing), True) or ""
|
||||
flags = d.getVar('{}_CXXFLAGS'.format(thing), True) or ""
|
||||
tc = d.getVar('TOOLCHAIN_OPTIONS', True) or ""
|
||||
return ' '.join([cc_arch, flags, tc])
|
||||
|
||||
def as_json(list_):
|
||||
a = '['
|
||||
for e in list_:
|
||||
if type(e) == str:
|
||||
a += '"{}",'.format(e)
|
||||
else:
|
||||
raise Exception
|
||||
if len(e):
|
||||
a = a[:-1]
|
||||
a += ']'
|
||||
return a
|
||||
|
||||
def rust_gen_target(d, thing, wd):
|
||||
arch = arch_for(d, thing)
|
||||
ldflags = ldflags_for(d, thing)
|
||||
sys = sys_for(d, thing)
|
||||
prefix = prefix_for(d, thing)
|
||||
o = open(wd + sys + '.json', 'w')
|
||||
|
||||
data_layout = d.getVarFlag('DATA_LAYOUT', arch, True)
|
||||
llvm_target = d.getVarFlag('LLVM_TARGET', arch, True)
|
||||
target_word_size = d.getVarFlag('TARGET_WORD_SIZE', arch, True)
|
||||
prefix = d.getVar('{}_PREFIX'.format(thing), True)
|
||||
ccache = d.getVar('CCACHE', True)
|
||||
linker = "{}{}gcc".format(ccache, prefix)
|
||||
features = d.getVarFlag('FEATURES', arch, True) or ""
|
||||
|
||||
pre_link_args = (d.getVarFlag('PRE_LINK_ARGS', arch, True) or "").split()
|
||||
|
||||
o.write('''{{
|
||||
"data-layout": "{}",
|
||||
"llvm-target": "{}",
|
||||
"target-endian": "little",
|
||||
"target-word-size": "{}",
|
||||
"arch": "{}",
|
||||
"os": "linux",
|
||||
"linker": "{}",
|
||||
"features": "{}",
|
||||
"dynamic-linking": true,
|
||||
"executables": true,
|
||||
"morestack": true,
|
||||
"linker-is-gnu": true,
|
||||
"has-rpath": true,
|
||||
"position-independent-executables": true,
|
||||
"pre-link-args": {}
|
||||
}}'''.format(
|
||||
data_layout,
|
||||
llvm_target,
|
||||
target_word_size,
|
||||
arch,
|
||||
linker,
|
||||
features,
|
||||
as_json(pre_link_args)
|
||||
))
|
||||
o.close()
|
||||
|
||||
python do_rust_gen_targets () {
|
||||
import os
|
||||
wd = d.getVar('WORKDIR', True) + '/targets/'
|
||||
try:
|
||||
os.makedirs(wd)
|
||||
except OSError as e:
|
||||
if e.errno != 17:
|
||||
raise e
|
||||
|
||||
for thing in ['HOST', 'BUILD', 'TARGET']:
|
||||
rust_gen_target(d, thing, wd)
|
||||
}
|
||||
addtask do_rust_gen_targets after do_patch before do_compile
|
||||
|
||||
def rust_base_triple(d, thing):
|
||||
'''
|
||||
Mangle bitbake's *_SYS into something that rust might support (see
|
||||
rust/mk/cfg/* for a list)
|
||||
'''
|
||||
|
||||
arch = d.getVar('{}_ARCH'.format(thing), True)
|
||||
vendor = d.getVar('{}_VENDOR'.format(thing), True)
|
||||
os = d.getVar('{}_OS'.format(thing), True)
|
||||
|
||||
if arch.startswith("arm"):
|
||||
vendor = "-unknown"
|
||||
if os.endswith("gnueabi"):
|
||||
@@ -22,156 +147,56 @@ def rust_triple(arch, vendor, os, d):
|
||||
os = "linux-gnu"
|
||||
return arch + vendor + '-' + os
|
||||
|
||||
export RUST_TARGET_PATH="${WORKDIR}/targets/"
|
||||
def rust_gen_mk_cfg(d, thing):
|
||||
''''
|
||||
Rust's build system adds support for new archs via 2 things:
|
||||
1. a file in mk/cfg which defines how the runtime libraries are built
|
||||
2. and rustc arch definition either built into the compiler or supplied as a .json file
|
||||
|
||||
## arm-unknown-linux-gnueabihf
|
||||
DATA_LAYOUT[arm] = "e-p:32:32:32\
|
||||
-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
|
||||
-f32:32:32-f64:64:64\
|
||||
-v64:64:64-v128:64:128\
|
||||
-a0:0:64-n32"
|
||||
LLVM_TARGET[arm] = "arm-unknown-linux-gnueabihf"
|
||||
TARGET_ENDIAN[arm] = "little"
|
||||
TARGET_WORD_SIZE[arm] = "32"
|
||||
FEATURES[arm] = "+v6,+vfp2"
|
||||
This generates a new #1 for the given 'thing' (one of HOST, TARGET, BUILD)
|
||||
using a "similar" config that rust already supplies as a template.
|
||||
|
||||
## x86_64-unknown-linux-gnu
|
||||
DATA_LAYOUT[x86_64] = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-\
|
||||
f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-\
|
||||
s0:64:64-f80:128:128-n8:16:32:64-S128"
|
||||
LLVM_TARGET[x86_64] = "x86_64-unknown-linux-gnu"
|
||||
TARGET_ENDIAN[x86_64] = "little"
|
||||
TARGET_WORD_SIZE[x86_64] = "64"
|
||||
PRE_LINK_ARGS[x86_64] = "-m64"
|
||||
Note that the configure process also depends on the existence of #1, so we
|
||||
have to run this before do_configure
|
||||
'''
|
||||
|
||||
python rust_gen_targets () {
|
||||
import shutil, subprocess
|
||||
rust_base_sys = rust_base_triple(d, thing)
|
||||
arch = arch_for(d, thing)
|
||||
sys = sys_for(d, thing)
|
||||
prefix = prefix_for(d, thing)
|
||||
|
||||
p = d.getVar('S', True) + '/mk/cfg/'
|
||||
|
||||
o = open(p + sys_for(d, thing), 'w')
|
||||
|
||||
r = subprocess.call(['sed',
|
||||
# update all triplets to the new one
|
||||
'-e', 's/{}/{}/g'.format(rust_base_sys, sys),
|
||||
|
||||
# Replace tools with our own (CROSS_PREFIX is appended to all tools
|
||||
# by rust's build system)
|
||||
'-e', 's/^CROSS_PREFIX_{}.*$/CROSS_PREFIX_{} := {}/'.format(sys, sys, prefix),
|
||||
'-e', 's/^CC_{}=.*$/CC_{} := gcc/'.format(sys, sys),
|
||||
'-e', 's/^CXX_{}.*$/CXX_{} := g++/'.format(sys, sys),
|
||||
'-e', 's/^CPP_{}.*$/CPP_{} := gcc -E/'.format(sys, sys),
|
||||
'-e', 's/^AR_{}.*$/AR_{} := ar/'.format(sys, sys),
|
||||
|
||||
# Append our flags to the existing ones
|
||||
'-e', '/^CFG_GCCISH_CFLAGS/ s;$; {};'.format(cflags_for(d, thing)),
|
||||
'-e', '/^CFG_GCCISH_CXXFLAGS/ s;$; {};'.format(cxxflags_for(d, thing)),
|
||||
'-e', '/^CFG_GCCISH_LINK_FLAGS/ s;$; {};'.format(" ".join(ldflags_for(d, thing))),
|
||||
|
||||
p + rust_base_sys
|
||||
], stdout=o)
|
||||
if r:
|
||||
raise Exception
|
||||
|
||||
python do_rust_arch_fixup () {
|
||||
for thing in ['HOST', 'BUILD', 'TARGET']:
|
||||
rust_gen_mk_cfg(d, thing)
|
||||
}
|
||||
|
||||
# Generates a config file suitable for use as a compiler-and-runtime-build-time
|
||||
# target specification (distinct from those target specifications used by
|
||||
# `rustc --target`)
|
||||
#
|
||||
# Designed to operate where $1={host,target,build}, and creates targets for
|
||||
# these using our triples in *_SYS.
|
||||
rust_gen_mk_cfg () {
|
||||
|
||||
deref() {
|
||||
eval echo "\$$1"
|
||||
}
|
||||
|
||||
ARCH="$(deref $u_ARCH)"
|
||||
|
||||
local u=`echo $1 | tr '[:lower:]' '[:upper:]'`
|
||||
local sys=$(deref ${u}_SYS)
|
||||
local rust_base_sys=$(deref RUST_BASE_${u}_SYS)
|
||||
local p="${S}/mk/cfg/"
|
||||
|
||||
if [ -z "$sys" ]; then
|
||||
bbnote "Rust: no SYS for $u"
|
||||
return
|
||||
fi
|
||||
if [ -z "$rust_base_sys" ]; then
|
||||
bbfatal "Rust: no RUST_BUILD_SYS for $u (sys=$sys)"
|
||||
fi
|
||||
|
||||
if ! [ -e "$p$rust_base_sys" ]; then
|
||||
bberror "Could not find RUST_BASE_${u}_SYS = ${rust_base_sys}"
|
||||
bbfatal "file '$p/$rust_base_sys'"
|
||||
fi
|
||||
|
||||
# Use one of the existing configs as our base
|
||||
cp -f "$p$rust_base_sys" "$p$sys"
|
||||
|
||||
# FIXME: right now we assume our targets lack regex special characters
|
||||
# and assumes flags lack regex special chars and ';'
|
||||
|
||||
# 1. Fixup the target name for all variables
|
||||
# 2. Blank CROSS_PREFIX (XXX: should we set it to "${CCACHE}${$u_PREFIX}"
|
||||
# and adjust other vars as needed?)
|
||||
# 3. Edit in our:
|
||||
local bare_cc="$(deref ${u}_PREFIX)gcc"
|
||||
local cc="${CCACHE}${bare_cc} $(deref ${u}_CC_ARCH)"
|
||||
local cxx="${CCACHE}$(deref ${u}_PREFIX)g++ $(deref ${u}_CC_ARCH)"
|
||||
local cpp="$(deref ${u}_PREFIX)gcc $(deref ${u}_CC_ARCH) -E"
|
||||
local ar="$(deref ${u}_PREFIX)ar"
|
||||
|
||||
# 4. Append our:
|
||||
# FIXME: TOOLCHAIN_OPTIONS are only for TARGET (which is sometimes HOST)
|
||||
local c_flags="$(deref ${u}_CC_ARCH)${TOOLCHAIN_OPTIONS} $(deref ${u}_CFLAGS)"
|
||||
local cxx_flags="$(deref ${u}_CC_ARCH)${TOOLCHAIN_OPTIONS} $(deref ${u}_CXXFLAGS)"
|
||||
local link_flags="${TOOLCHAIN_OPTIONS} $(deref ${u}_LD_ARCH)"
|
||||
|
||||
sed -i \
|
||||
-e "s/${rust_base_sys}/$sys/g" \
|
||||
\
|
||||
-e "s/^CROSS_PREFIX_${sys}.*\$//" \
|
||||
-e "s/^CC_$sys=.\*\$/CC_$sys := ${cc}/" \
|
||||
-e "s/^CXX_$sys=.\*\$/CXX_$sys := ${cxx}/" \
|
||||
-e "s/^CPP_$sys=.\*\$/CPP_$sys := ${cpp}/" \
|
||||
-e "s/^AR_$sys=.\*\$/AR_$sys := ${ar}/" \
|
||||
\
|
||||
-e "/^CFG_GCCISH_CFLAGS/ s;\$; ${c_flags};" \
|
||||
-e "/^CFG_GCCISH_CXXFLAGS/ s;\$; ${cxx_flags};" \
|
||||
-e "/^CFG_GCCISH_LINK_FLAGS/ s;\$; ${link_flags};" \
|
||||
\
|
||||
"$p/$sys"
|
||||
|
||||
local t="${WORKDIR}/targets/"
|
||||
mkdir -p "$t"
|
||||
|
||||
local link_flags_vec='[ "-fPIC" ]'
|
||||
|
||||
cat >"$t$sys" <<-EOF
|
||||
{
|
||||
"data-layout": "$(deref DATA_LAYOUT__$ARCH)",
|
||||
"llvm_target": "${sys}",
|
||||
"target_endian": "little",
|
||||
"target-word-size": "$(deref TARGET_WORD_SIZE__$ARCH)",
|
||||
"arch": "$ARCH",
|
||||
"os": "linux",
|
||||
|
||||
"linker": "${bare_cc}",
|
||||
"pre_link_args": ${link_flags_vec},
|
||||
# post_link_args
|
||||
# cpu
|
||||
"features": "$(deref FEATURES__$ARCH)",
|
||||
"dynamic_linking": true,
|
||||
"executables": true,
|
||||
"morestack": true,
|
||||
# relocation_model
|
||||
# ...
|
||||
# is_like_windows
|
||||
"linker_is_gnu": true,
|
||||
"has_rpath": true,
|
||||
# no_compiler_rt
|
||||
"position_independent_executables": true,
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
do_rust_arch_fixup () {
|
||||
RUST_BASE_TARGET_SYS="${@rust_triple('${TARGET_ARCH}','${TARGET_VENDOR}','${TARGET_OS}', d)}"
|
||||
RUST_BASE_BUILD_SYS="${@rust_triple('${BUILD_ARCH}','${BUILD_VENDOR}','${BUILD_OS}', d)}"
|
||||
RUST_BASE_HOST_SYS="${@rust_triple('${HOST_ARCH}','${HOST_VENDOR}','${HOST_OS}', d)}"
|
||||
|
||||
# XXX: these are all hacks around having the variables be shell vars
|
||||
# instead of bitbake vars. It probably makes sense to convert this
|
||||
# entire mess into python so we don't have to do this.
|
||||
HOST_SYS="${HOST_SYS}"
|
||||
BUILD_SYS="${BUILD_SYS}"
|
||||
TARGET_SYS="${TARGET_SYS}"
|
||||
HOST_ARCH="${HOST_ARCH}"
|
||||
BUILD_ARCH="${BUILD_ARCH}"
|
||||
TARGET_ARCH="${TARGET_ARCH}"
|
||||
|
||||
|
||||
rust_gen_mk_cfg host
|
||||
rust_gen_mk_cfg build
|
||||
rust_gen_mk_cfg target
|
||||
}
|
||||
addtask rust_arch_fixup before do_configure after do_patch
|
||||
addtask do_rust_arch_fixup before do_configure after do_patch
|
||||
|
||||
do_configure () {
|
||||
# FIXME: allow --enable-local-rust
|
||||
@@ -208,7 +233,7 @@ rust_runmake () {
|
||||
env
|
||||
|
||||
# CFLAGS, LDFLAGS, CXXFLAGS, CPPFLAGS are used by rust's build for a
|
||||
# wide range of targets (not just HOST). Yocto's settings for them will
|
||||
# wide range of targets (not just TARGET). Yocto's settings for them will
|
||||
# be inappropriate, avoid using.
|
||||
unset CFLAGS
|
||||
unset LDFLAGS
|
||||
|
||||
Reference in New Issue
Block a user