xref: /OK3568_Linux_fs/yocto/poky/meta/classes/rust-bin.bbclass (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyuninherit rust
2*4882a593Smuzhiyun
3*4882a593SmuzhiyunRDEPENDS:${PN}:append:class-target = " ${RUSTLIB_DEP}"
4*4882a593Smuzhiyun
5*4882a593SmuzhiyunRUSTC_ARCHFLAGS += "-C opt-level=3 -g -L ${STAGING_DIR_HOST}/${rustlibdir} -C linker=${RUST_TARGET_CCLD}"
6*4882a593SmuzhiyunEXTRA_OEMAKE += 'RUSTC_ARCHFLAGS="${RUSTC_ARCHFLAGS}"'
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun# Some libraries alias with the standard library but libstd is configured to
9*4882a593Smuzhiyun# make it difficult or imposisble to use its version. Unfortunately libstd
10*4882a593Smuzhiyun# must be explicitly overridden using extern.
11*4882a593SmuzhiyunOVERLAP_LIBS = "\
12*4882a593Smuzhiyun    libc \
13*4882a593Smuzhiyun    log \
14*4882a593Smuzhiyun    getopts \
15*4882a593Smuzhiyun    rand \
16*4882a593Smuzhiyun"
17*4882a593Smuzhiyundef get_overlap_deps(d):
18*4882a593Smuzhiyun    deps = d.getVar("DEPENDS").split()
19*4882a593Smuzhiyun    overlap_deps = []
20*4882a593Smuzhiyun    for o in d.getVar("OVERLAP_LIBS").split():
21*4882a593Smuzhiyun        l = len([o for dep in deps if (o + '-rs' in dep)])
22*4882a593Smuzhiyun        if l > 0:
23*4882a593Smuzhiyun            overlap_deps.append(o)
24*4882a593Smuzhiyun    return " ".join(overlap_deps)
25*4882a593SmuzhiyunOVERLAP_DEPS = "${@get_overlap_deps(d)}"
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun# Prevents multiple static copies of standard library modules
28*4882a593Smuzhiyun# See https://github.com/rust-lang/rust/issues/19680
29*4882a593SmuzhiyunRUSTC_PREFER_DYNAMIC = "-C prefer-dynamic"
30*4882a593SmuzhiyunRUSTC_FLAGS += "${RUSTC_PREFER_DYNAMIC}"
31*4882a593Smuzhiyun
32*4882a593SmuzhiyunCRATE_NAME ?= "${@d.getVar('BPN').replace('-rs', '').replace('-', '_')}"
33*4882a593SmuzhiyunBINNAME ?= "${BPN}"
34*4882a593SmuzhiyunLIBNAME ?= "lib${CRATE_NAME}-rs"
35*4882a593SmuzhiyunCRATE_TYPE ?= "dylib"
36*4882a593SmuzhiyunBIN_SRC ?= "${S}/src/main.rs"
37*4882a593SmuzhiyunLIB_SRC ?= "${S}/src/lib.rs"
38*4882a593Smuzhiyun
39*4882a593Smuzhiyunrustbindest ?= "${bindir}"
40*4882a593Smuzhiyunrustlibdest ?= "${rustlibdir}"
41*4882a593SmuzhiyunRUST_RPATH_ABS ?= "${rustlibdir}:${rustlib}"
42*4882a593Smuzhiyun
43*4882a593Smuzhiyundef relative_rpaths(paths, base):
44*4882a593Smuzhiyun    relpaths = set()
45*4882a593Smuzhiyun    for p in paths.split(':'):
46*4882a593Smuzhiyun        if p == base:
47*4882a593Smuzhiyun            relpaths.add('$ORIGIN')
48*4882a593Smuzhiyun            continue
49*4882a593Smuzhiyun        relpaths.add(os.path.join('$ORIGIN', os.path.relpath(p, base)))
50*4882a593Smuzhiyun    return '-rpath=' + ':'.join(relpaths) if len(relpaths) else ''
51*4882a593Smuzhiyun
52*4882a593SmuzhiyunRUST_LIB_RPATH_FLAGS ?= "${@relative_rpaths(d.getVar('RUST_RPATH_ABS', True), d.getVar('rustlibdest', True))}"
53*4882a593SmuzhiyunRUST_BIN_RPATH_FLAGS ?= "${@relative_rpaths(d.getVar('RUST_RPATH_ABS', True), d.getVar('rustbindest', True))}"
54*4882a593Smuzhiyun
55*4882a593Smuzhiyundef libfilename(d):
56*4882a593Smuzhiyun    if d.getVar('CRATE_TYPE', True) == 'dylib':
57*4882a593Smuzhiyun        return d.getVar('LIBNAME', True) + '.so'
58*4882a593Smuzhiyun    else:
59*4882a593Smuzhiyun        return d.getVar('LIBNAME', True) + '.rlib'
60*4882a593Smuzhiyun
61*4882a593Smuzhiyundef link_args(d, bin):
62*4882a593Smuzhiyun    linkargs = []
63*4882a593Smuzhiyun    if bin:
64*4882a593Smuzhiyun        rpaths = d.getVar('RUST_BIN_RPATH_FLAGS', False)
65*4882a593Smuzhiyun    else:
66*4882a593Smuzhiyun        rpaths = d.getVar('RUST_LIB_RPATH_FLAGS', False)
67*4882a593Smuzhiyun        if d.getVar('CRATE_TYPE', True) == 'dylib':
68*4882a593Smuzhiyun            linkargs.append('-soname')
69*4882a593Smuzhiyun            linkargs.append(libfilename(d))
70*4882a593Smuzhiyun    if len(rpaths):
71*4882a593Smuzhiyun        linkargs.append(rpaths)
72*4882a593Smuzhiyun    if len(linkargs):
73*4882a593Smuzhiyun        return ' '.join(['-Wl,' + arg for arg in linkargs])
74*4882a593Smuzhiyun    else:
75*4882a593Smuzhiyun        return ''
76*4882a593Smuzhiyun
77*4882a593Smuzhiyunget_overlap_externs () {
78*4882a593Smuzhiyun    externs=
79*4882a593Smuzhiyun    for dep in ${OVERLAP_DEPS}; do
80*4882a593Smuzhiyun        extern=$(ls ${STAGING_DIR_HOST}/${rustlibdir}/lib$dep-rs.{so,rlib} 2>/dev/null \
81*4882a593Smuzhiyun                    | awk '{print $1}');
82*4882a593Smuzhiyun        if [ -n "$extern" ]; then
83*4882a593Smuzhiyun            externs="$externs --extern $dep=$extern"
84*4882a593Smuzhiyun        else
85*4882a593Smuzhiyun            echo "$dep in depends but no such library found in ${rustlibdir}!" >&2
86*4882a593Smuzhiyun            exit 1
87*4882a593Smuzhiyun        fi
88*4882a593Smuzhiyun    done
89*4882a593Smuzhiyun    echo "$externs"
90*4882a593Smuzhiyun}
91*4882a593Smuzhiyun
92*4882a593Smuzhiyundo_configure () {
93*4882a593Smuzhiyun}
94*4882a593Smuzhiyun
95*4882a593Smuzhiyunoe_runrustc () {
96*4882a593Smuzhiyun	export RUST_TARGET_PATH="${RUST_TARGET_PATH}"
97*4882a593Smuzhiyun	bbnote ${RUSTC} ${RUSTC_ARCHFLAGS} ${RUSTC_FLAGS} "$@"
98*4882a593Smuzhiyun	"${RUSTC}" ${RUSTC_ARCHFLAGS} ${RUSTC_FLAGS} "$@"
99*4882a593Smuzhiyun}
100*4882a593Smuzhiyun
101*4882a593Smuzhiyunoe_compile_rust_lib () {
102*4882a593Smuzhiyun    rm -rf ${LIBNAME}.{rlib,so}
103*4882a593Smuzhiyun    local -a link_args
104*4882a593Smuzhiyun    if [ -n '${@link_args(d, False)}' ]; then
105*4882a593Smuzhiyun        link_args[0]='-C'
106*4882a593Smuzhiyun        link_args[1]='link-args=${@link_args(d, False)}'
107*4882a593Smuzhiyun    fi
108*4882a593Smuzhiyun    oe_runrustc $(get_overlap_externs) \
109*4882a593Smuzhiyun        "${link_args[@]}" \
110*4882a593Smuzhiyun        ${LIB_SRC} \
111*4882a593Smuzhiyun        -o ${@libfilename(d)} \
112*4882a593Smuzhiyun        --crate-name=${CRATE_NAME} --crate-type=${CRATE_TYPE} \
113*4882a593Smuzhiyun        "$@"
114*4882a593Smuzhiyun}
115*4882a593Smuzhiyunoe_compile_rust_lib[vardeps] += "get_overlap_externs"
116*4882a593Smuzhiyun
117*4882a593Smuzhiyunoe_compile_rust_bin () {
118*4882a593Smuzhiyun    rm -rf ${BINNAME}
119*4882a593Smuzhiyun    local -a link_args
120*4882a593Smuzhiyun    if [ -n '${@link_args(d, True)}' ]; then
121*4882a593Smuzhiyun        link_args[0]='-C'
122*4882a593Smuzhiyun        link_args[1]='link-args=${@link_args(d, True)}'
123*4882a593Smuzhiyun    fi
124*4882a593Smuzhiyun    oe_runrustc $(get_overlap_externs) \
125*4882a593Smuzhiyun        "${link_args[@]}" \
126*4882a593Smuzhiyun        ${BIN_SRC} -o ${BINNAME} "$@"
127*4882a593Smuzhiyun}
128*4882a593Smuzhiyunoe_compile_rust_bin[vardeps] += "get_overlap_externs"
129*4882a593Smuzhiyun
130*4882a593Smuzhiyunoe_install_rust_lib () {
131*4882a593Smuzhiyun    for lib in $(ls ${LIBNAME}.{so,rlib} 2>/dev/null); do
132*4882a593Smuzhiyun        echo Installing $lib
133*4882a593Smuzhiyun        install -D -m 755 $lib ${D}/${rustlibdest}/$lib
134*4882a593Smuzhiyun    done
135*4882a593Smuzhiyun}
136*4882a593Smuzhiyun
137*4882a593Smuzhiyunoe_install_rust_bin () {
138*4882a593Smuzhiyun    echo Installing ${BINNAME}
139*4882a593Smuzhiyun    install -D -m 755 ${BINNAME} ${D}/${rustbindest}/${BINNAME}
140*4882a593Smuzhiyun}
141*4882a593Smuzhiyun
142*4882a593Smuzhiyundo_rust_bin_fixups() {
143*4882a593Smuzhiyun    for f in `find ${PKGD} -name '*.so*'`; do
144*4882a593Smuzhiyun        echo "Strip rust note: $f"
145*4882a593Smuzhiyun        ${OBJCOPY} -R .note.rustc $f $f
146*4882a593Smuzhiyun    done
147*4882a593Smuzhiyun}
148*4882a593SmuzhiyunPACKAGE_PREPROCESS_FUNCS += "do_rust_bin_fixups"
149*4882a593Smuzhiyun
150