From 463622c0c6828e7fb970f46f9bf0dcf156345373 Mon Sep 17 00:00:00 2001 From: Tyler Hall Date: Mon, 13 Mar 2017 22:33:31 -0400 Subject: [PATCH] rust-bin: use linker to set rpath Patchelf should be reserved for when the ELF cannot be generated correctly in the first place. This is not the case here because we have control over the linker flags. The limitation is that -C link-args can only be specified once, so consolidate the generation of link-args. Also introduce some new intermediate variables in link-args generation for customization. Patchelf was running only in ${PKGD} because patching the ELF in ${D} would cause objcopy to fail when splitting the debug sections. This is not a problem when setting it correctly in the linker. The benefit is that the rpath is correct in the sysroot as well. This also switches the rpaths to be relative so that they work in both the sysroot and the target in the same way. Signed-off-by: Tyler Hall Signed-off-by: Steven Walter --- classes/rust-bin.bbclass | 68 ++++++++++++++++++++++++++++++---------- 1 file changed, 52 insertions(+), 16 deletions(-) diff --git a/classes/rust-bin.bbclass b/classes/rust-bin.bbclass index fc7113e..f756ffb 100644 --- a/classes/rust-bin.bbclass +++ b/classes/rust-bin.bbclass @@ -1,6 +1,5 @@ inherit rust -DEPENDS_append = " patchelf-native" RDEPENDS_${PN} += "${RUSTLIB_DEP}" RUSTC_ARCHFLAGS += "-C opt-level=3 -g -L ${STAGING_DIR_HOST}/${rustlibdir} -C linker=${RUST_TARGET_CCLD}" @@ -37,6 +36,44 @@ CRATE_TYPE ?= "dylib" BIN_SRC ?= "${S}/src/main.rs" LIB_SRC ?= "${S}/src/lib.rs" +rustbindest ?= "${bindir}" +rustlibdest ?= "${rustlibdir}" +RUST_RPATH_ABS ?= "${rustlibdir}:${rustlib}" + +def relative_rpaths(paths, base): + relpaths = set() + for p in paths.split(':'): + if p == base: + relpaths.add('$ORIGIN') + continue + relpaths.add(os.path.join('$ORIGIN', os.path.relpath(p, base))) + return '-rpath=' + ':'.join(relpaths) if len(relpaths) else '' + +RUST_LIB_RPATH_FLAGS ?= "${@relative_rpaths(d.getVar('RUST_RPATH_ABS', True), d.getVar('rustlibdest', True))}" +RUST_BIN_RPATH_FLAGS ?= "${@relative_rpaths(d.getVar('RUST_RPATH_ABS', True), d.getVar('rustbindest', True))}" + +def libfilename(d): + if d.getVar('CRATE_TYPE', True) == 'dylib': + return d.getVar('LIBNAME', True) + '.so' + else: + return d.getVar('LIBNAME', True) + '.rlib' + +def link_args(d, bin): + linkargs = [] + if bin: + rpaths = d.getVar('RUST_BIN_RPATH_FLAGS', False) + else: + rpaths = d.getVar('RUST_LIB_RPATH_FLAGS', False) + if d.getVar('CRATE_TYPE', True) == 'dylib': + linkargs.append('-soname') + linkargs.append(libfilename(d)) + if len(rpaths): + linkargs.append(rpaths) + if len(linkargs): + return ' '.join(['-Wl,' + arg for arg in linkargs]) + else: + return '' + get_overlap_externs () { externs= for dep in ${OVERLAP_DEPS}; do @@ -62,17 +99,16 @@ oe_runrustc () { } oe_compile_rust_lib () { - [ "${CRATE_TYPE}" == "dylib" ] && suffix=so || suffix=rlib rm -rf ${LIBNAME}.{rlib,so} local -a link_args - if [ "${CRATE_TYPE}" == "dylib" ]; then - link_args[0]="-C" - link_args[1]="link-args=-Wl,-soname -Wl,${LIBNAME}.$suffix" + if [ -n '${@link_args(d, False)}' ]; then + link_args[0]='-C' + link_args[1]='link-args=${@link_args(d, False)}' fi oe_runrustc $(get_overlap_externs) \ "${link_args[@]}" \ ${LIB_SRC} \ - -o ${LIBNAME}.$suffix \ + -o ${@libfilename(d)} \ --crate-name=${CRATE_NAME} --crate-type=${CRATE_TYPE} \ "$@" } @@ -80,20 +116,27 @@ oe_compile_rust_lib[vardeps] += "get_overlap_externs" oe_compile_rust_bin () { rm -rf ${BINNAME} - oe_runrustc $(get_overlap_externs) ${BIN_SRC} -o ${BINNAME} "$@" + local -a link_args + if [ -n '${@link_args(d, True)}' ]; then + link_args[0]='-C' + link_args[1]='link-args=${@link_args(d, True)}' + fi + oe_runrustc $(get_overlap_externs) \ + "${link_args[@]}" \ + ${BIN_SRC} -o ${BINNAME} "$@" } oe_compile_rust_bin[vardeps] += "get_overlap_externs" oe_install_rust_lib () { for lib in $(ls ${LIBNAME}.{so,rlib} 2>/dev/null); do echo Installing $lib - install -D -m 755 $lib ${D}/${rustlibdir}/$lib + install -D -m 755 $lib ${D}/${rustlibdest}/$lib done } oe_install_rust_bin () { echo Installing ${BINNAME} - install -D -m 755 ${BINNAME} ${D}/${bindir}/${BINNAME} + install -D -m 755 ${BINNAME} ${D}/${rustbindest}/${BINNAME} } do_rust_bin_fixups() { @@ -101,13 +144,6 @@ do_rust_bin_fixups() { echo "Strip rust note: $f" ${OBJCOPY} -R .note.rustc $f $f done - - for f in `find ${PKGD}`; do - file "$f" | grep -q ELF || continue - readelf -d "$f" | grep RUNPATH | grep -q rustlib || continue - echo "Set rpath:" "$f" - patchelf --set-rpath '$ORIGIN:'${rustlibdir}:${rustlib} "$f" - done } PACKAGE_PREPROCESS_FUNCS += "do_rust_bin_fixups"