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