192b42cb3SPatrick Williams# 292b42cb3SPatrick Williams# Copyright OpenEmbedded Contributors 392b42cb3SPatrick Williams# 492b42cb3SPatrick Williams# SPDX-License-Identifier: MIT 592b42cb3SPatrick Williams# 692b42cb3SPatrick Williams 7ac13d5f3SPatrick WilliamsUNINATIVE_LOADER ?= "${UNINATIVE_STAGING_DIR}-uninative/${BUILD_ARCH}-linux/lib/${@bb.utils.contains('BUILD_ARCH', 'x86_64', 'ld-linux-x86-64.so.2', '', d)}${@bb.utils.contains('BUILD_ARCH', 'i686', 'ld-linux.so.2', '', d)}${@bb.utils.contains('BUILD_ARCH', 'aarch64', 'ld-linux-aarch64.so.1', '', d)}${@bb.utils.contains('BUILD_ARCH', 'ppc64le', 'ld64.so.2', '', d)}${@bb.utils.contains('BUILD_ARCH', 'riscv64', 'ld-linux-riscv64-lp64d.so.1', '', d)}" 892b42cb3SPatrick WilliamsUNINATIVE_STAGING_DIR ?= "${STAGING_DIR}" 992b42cb3SPatrick Williams 1092b42cb3SPatrick WilliamsUNINATIVE_URL ?= "unset" 1192b42cb3SPatrick WilliamsUNINATIVE_TARBALL ?= "${BUILD_ARCH}-nativesdk-libc-${UNINATIVE_VERSION}.tar.xz" 1292b42cb3SPatrick Williams# Example checksums 1392b42cb3SPatrick Williams#UNINATIVE_CHECKSUM[aarch64] = "dead" 1492b42cb3SPatrick Williams#UNINATIVE_CHECKSUM[i686] = "dead" 1592b42cb3SPatrick Williams#UNINATIVE_CHECKSUM[x86_64] = "dead" 1692b42cb3SPatrick WilliamsUNINATIVE_DLDIR ?= "${DL_DIR}/uninative/" 1792b42cb3SPatrick Williams 1892b42cb3SPatrick Williams# Enabling uninative will change the following variables so they need to go the parsing ignored variables list to prevent multiple recipe parsing 1992b42cb3SPatrick WilliamsBB_HASHCONFIG_IGNORE_VARS += "NATIVELSBSTRING SSTATEPOSTUNPACKFUNCS BUILD_LDFLAGS" 2092b42cb3SPatrick Williams 2192b42cb3SPatrick Williamsaddhandler uninative_event_fetchloader 2292b42cb3SPatrick Williamsuninative_event_fetchloader[eventmask] = "bb.event.BuildStarted" 2392b42cb3SPatrick Williams 2492b42cb3SPatrick Williamsaddhandler uninative_event_enable 2592b42cb3SPatrick Williamsuninative_event_enable[eventmask] = "bb.event.ConfigParsed" 2692b42cb3SPatrick Williams 2792b42cb3SPatrick Williamspython uninative_event_fetchloader() { 2892b42cb3SPatrick Williams """ 2992b42cb3SPatrick Williams This event fires on the parent and will try to fetch the tarball if the 3092b42cb3SPatrick Williams loader isn't already present. 3192b42cb3SPatrick Williams """ 3292b42cb3SPatrick Williams 3392b42cb3SPatrick Williams chksum = d.getVarFlag("UNINATIVE_CHECKSUM", d.getVar("BUILD_ARCH")) 3492b42cb3SPatrick Williams if not chksum: 3592b42cb3SPatrick Williams bb.fatal("Uninative selected but not configured correctly, please set UNINATIVE_CHECKSUM[%s]" % d.getVar("BUILD_ARCH")) 3692b42cb3SPatrick Williams 3792b42cb3SPatrick Williams loader = d.getVar("UNINATIVE_LOADER") 3892b42cb3SPatrick Williams loaderchksum = loader + ".chksum" 3992b42cb3SPatrick Williams if os.path.exists(loader) and os.path.exists(loaderchksum): 4092b42cb3SPatrick Williams with open(loaderchksum, "r") as f: 4192b42cb3SPatrick Williams readchksum = f.read().strip() 4292b42cb3SPatrick Williams if readchksum == chksum: 43517393d9SAndrew Geissler if "uninative" not in d.getVar("SSTATEPOSTUNPACKFUNCS"): 44517393d9SAndrew Geissler enable_uninative(d) 4592b42cb3SPatrick Williams return 4692b42cb3SPatrick Williams 4792b42cb3SPatrick Williams import subprocess 4892b42cb3SPatrick Williams try: 4992b42cb3SPatrick Williams # Save and restore cwd as Fetch.download() does a chdir() 5092b42cb3SPatrick Williams olddir = os.getcwd() 5192b42cb3SPatrick Williams 5292b42cb3SPatrick Williams tarball = d.getVar("UNINATIVE_TARBALL") 5392b42cb3SPatrick Williams tarballdir = os.path.join(d.getVar("UNINATIVE_DLDIR"), chksum) 5492b42cb3SPatrick Williams tarballpath = os.path.join(tarballdir, tarball) 5592b42cb3SPatrick Williams 5692b42cb3SPatrick Williams if not os.path.exists(tarballpath + ".done"): 5792b42cb3SPatrick Williams bb.utils.mkdirhier(tarballdir) 5892b42cb3SPatrick Williams if d.getVar("UNINATIVE_URL") == "unset": 5992b42cb3SPatrick Williams bb.fatal("Uninative selected but not configured, please set UNINATIVE_URL") 6092b42cb3SPatrick Williams 6192b42cb3SPatrick Williams localdata = bb.data.createCopy(d) 6292b42cb3SPatrick Williams localdata.setVar('FILESPATH', "") 6392b42cb3SPatrick Williams localdata.setVar('DL_DIR', tarballdir) 6492b42cb3SPatrick Williams # Our games with path manipulation of DL_DIR mean standard PREMIRRORS don't work 6592b42cb3SPatrick Williams # and we can't easily put 'chksum' into the url path from a url parameter with 6692b42cb3SPatrick Williams # the current fetcher url handling 6792b42cb3SPatrick Williams premirrors = bb.fetch2.mirror_from_string(localdata.getVar("PREMIRRORS")) 6892b42cb3SPatrick Williams for line in premirrors: 6992b42cb3SPatrick Williams try: 7092b42cb3SPatrick Williams (find, replace) = line 7192b42cb3SPatrick Williams except ValueError: 7292b42cb3SPatrick Williams continue 7392b42cb3SPatrick Williams if find.startswith("http"): 7492b42cb3SPatrick Williams localdata.appendVar("PREMIRRORS", " ${UNINATIVE_URL}${UNINATIVE_TARBALL} %s/uninative/%s/${UNINATIVE_TARBALL}" % (replace, chksum)) 7592b42cb3SPatrick Williams 7692b42cb3SPatrick Williams srcuri = d.expand("${UNINATIVE_URL}${UNINATIVE_TARBALL};sha256sum=%s" % chksum) 7792b42cb3SPatrick Williams bb.note("Fetching uninative binary shim %s (will check PREMIRRORS first)" % srcuri) 7892b42cb3SPatrick Williams 7992b42cb3SPatrick Williams fetcher = bb.fetch2.Fetch([srcuri], localdata, cache=False) 8092b42cb3SPatrick Williams fetcher.download() 8192b42cb3SPatrick Williams localpath = fetcher.localpath(srcuri) 8292b42cb3SPatrick Williams if localpath != tarballpath and os.path.exists(localpath) and not os.path.exists(tarballpath): 8392b42cb3SPatrick Williams # Follow the symlink behavior from the bitbake fetch2. 8492b42cb3SPatrick Williams # This will cover the case where an existing symlink is broken 8592b42cb3SPatrick Williams # as well as if there are two processes trying to create it 8692b42cb3SPatrick Williams # at the same time. 8792b42cb3SPatrick Williams if os.path.islink(tarballpath): 8892b42cb3SPatrick Williams # Broken symbolic link 8992b42cb3SPatrick Williams os.unlink(tarballpath) 9092b42cb3SPatrick Williams 9192b42cb3SPatrick Williams # Deal with two processes trying to make symlink at once 9292b42cb3SPatrick Williams try: 9392b42cb3SPatrick Williams os.symlink(localpath, tarballpath) 9492b42cb3SPatrick Williams except FileExistsError: 9592b42cb3SPatrick Williams pass 9692b42cb3SPatrick Williams 9792b42cb3SPatrick Williams # ldd output is "ldd (Ubuntu GLIBC 2.23-0ubuntu10) 2.23", extract last option from first line 9892b42cb3SPatrick Williams glibcver = subprocess.check_output(["ldd", "--version"]).decode('utf-8').split('\n')[0].split()[-1] 9992b42cb3SPatrick Williams if bb.utils.vercmp_string(d.getVar("UNINATIVE_MAXGLIBCVERSION"), glibcver) < 0: 10092b42cb3SPatrick Williams raise RuntimeError("Your host glibc version (%s) is newer than that in uninative (%s). Disabling uninative so that sstate is not corrupted." % (glibcver, d.getVar("UNINATIVE_MAXGLIBCVERSION"))) 10192b42cb3SPatrick Williams 10292b42cb3SPatrick Williams cmd = d.expand("\ 10392b42cb3SPatrick Williamsmkdir -p ${UNINATIVE_STAGING_DIR}-uninative; \ 10492b42cb3SPatrick Williamscd ${UNINATIVE_STAGING_DIR}-uninative; \ 10592b42cb3SPatrick Williamstar -xJf ${UNINATIVE_DLDIR}/%s/${UNINATIVE_TARBALL}; \ 10692b42cb3SPatrick Williams${UNINATIVE_STAGING_DIR}-uninative/relocate_sdk.py \ 10792b42cb3SPatrick Williams ${UNINATIVE_STAGING_DIR}-uninative/${BUILD_ARCH}-linux \ 10892b42cb3SPatrick Williams ${UNINATIVE_LOADER} \ 10992b42cb3SPatrick Williams ${UNINATIVE_LOADER} \ 11092b42cb3SPatrick Williams ${UNINATIVE_STAGING_DIR}-uninative/${BUILD_ARCH}-linux/${bindir_native}/patchelf-uninative \ 11192b42cb3SPatrick Williams ${UNINATIVE_STAGING_DIR}-uninative/${BUILD_ARCH}-linux${base_libdir_native}/libc*.so*" % chksum) 11292b42cb3SPatrick Williams subprocess.check_output(cmd, shell=True) 11392b42cb3SPatrick Williams 11492b42cb3SPatrick Williams with open(loaderchksum, "w") as f: 11592b42cb3SPatrick Williams f.write(chksum) 11692b42cb3SPatrick Williams 11792b42cb3SPatrick Williams enable_uninative(d) 11892b42cb3SPatrick Williams 11992b42cb3SPatrick Williams except RuntimeError as e: 12092b42cb3SPatrick Williams bb.warn(str(e)) 12192b42cb3SPatrick Williams except bb.fetch2.BBFetchException as exc: 12292b42cb3SPatrick Williams bb.warn("Disabling uninative as unable to fetch uninative tarball: %s" % str(exc)) 12392b42cb3SPatrick Williams bb.warn("To build your own uninative loader, please bitbake uninative-tarball and set UNINATIVE_TARBALL appropriately.") 12492b42cb3SPatrick Williams except subprocess.CalledProcessError as exc: 12592b42cb3SPatrick Williams bb.warn("Disabling uninative as unable to install uninative tarball: %s" % str(exc)) 12692b42cb3SPatrick Williams bb.warn("To build your own uninative loader, please bitbake uninative-tarball and set UNINATIVE_TARBALL appropriately.") 12792b42cb3SPatrick Williams finally: 12892b42cb3SPatrick Williams os.chdir(olddir) 12992b42cb3SPatrick Williams} 13092b42cb3SPatrick Williams 13192b42cb3SPatrick Williamspython uninative_event_enable() { 13292b42cb3SPatrick Williams """ 13392b42cb3SPatrick Williams This event handler is called in the workers and is responsible for setting 13492b42cb3SPatrick Williams up uninative if a loader is found. 13592b42cb3SPatrick Williams """ 13692b42cb3SPatrick Williams enable_uninative(d) 13792b42cb3SPatrick Williams} 13892b42cb3SPatrick Williams 13992b42cb3SPatrick Williamsdef enable_uninative(d): 14092b42cb3SPatrick Williams loader = d.getVar("UNINATIVE_LOADER") 14192b42cb3SPatrick Williams if os.path.exists(loader): 14292b42cb3SPatrick Williams bb.debug(2, "Enabling uninative") 14392b42cb3SPatrick Williams d.setVar("NATIVELSBSTRING", "universal%s" % oe.utils.host_gcc_version(d)) 14492b42cb3SPatrick Williams d.appendVar("SSTATEPOSTUNPACKFUNCS", " uninative_changeinterp") 14592b42cb3SPatrick Williams d.appendVarFlag("SSTATEPOSTUNPACKFUNCS", "vardepvalueexclude", "| uninative_changeinterp") 146*03514f19SPatrick Williams d.appendVar("BUILD_LDFLAGS", " -Wl,--allow-shlib-undefined -Wl,--dynamic-linker=${UNINATIVE_LOADER} -pthread") 147*03514f19SPatrick Williams d.appendVarFlag("BUILD_LDFLAGS", "vardepvalueexclude", "| -Wl,--allow-shlib-undefined -Wl,--dynamic-linker=${UNINATIVE_LOADER} -pthread") 14892b42cb3SPatrick Williams d.appendVarFlag("BUILD_LDFLAGS", "vardepsexclude", "UNINATIVE_LOADER") 1495082cc7fSAndrew Geissler d.prependVar("PATH", "${UNINATIVE_STAGING_DIR}-uninative/${BUILD_ARCH}-linux${bindir_native}:") 15092b42cb3SPatrick Williams 15192b42cb3SPatrick Williamspython uninative_changeinterp () { 15292b42cb3SPatrick Williams import subprocess 15392b42cb3SPatrick Williams import stat 15492b42cb3SPatrick Williams import oe.qa 15592b42cb3SPatrick Williams 15692b42cb3SPatrick Williams if not (bb.data.inherits_class('native', d) or bb.data.inherits_class('crosssdk', d) or bb.data.inherits_class('cross', d)): 15792b42cb3SPatrick Williams return 15892b42cb3SPatrick Williams 15992b42cb3SPatrick Williams sstateinst = d.getVar('SSTATE_INSTDIR') 16092b42cb3SPatrick Williams for walkroot, dirs, files in os.walk(sstateinst): 16192b42cb3SPatrick Williams for file in files: 16292b42cb3SPatrick Williams if file.endswith(".so") or ".so." in file: 16392b42cb3SPatrick Williams continue 16492b42cb3SPatrick Williams f = os.path.join(walkroot, file) 16592b42cb3SPatrick Williams if os.path.islink(f): 16692b42cb3SPatrick Williams continue 16792b42cb3SPatrick Williams s = os.stat(f) 16892b42cb3SPatrick Williams if not ((s[stat.ST_MODE] & stat.S_IXUSR) or (s[stat.ST_MODE] & stat.S_IXGRP) or (s[stat.ST_MODE] & stat.S_IXOTH)): 16992b42cb3SPatrick Williams continue 17092b42cb3SPatrick Williams elf = oe.qa.ELFFile(f) 17192b42cb3SPatrick Williams try: 17292b42cb3SPatrick Williams elf.open() 17392b42cb3SPatrick Williams except oe.qa.NotELFFileError: 17492b42cb3SPatrick Williams continue 17592b42cb3SPatrick Williams if not elf.isDynamic(): 17692b42cb3SPatrick Williams continue 17792b42cb3SPatrick Williams 17892b42cb3SPatrick Williams os.chmod(f, s[stat.ST_MODE] | stat.S_IWUSR) 17992b42cb3SPatrick Williams subprocess.check_output(("patchelf-uninative", "--set-interpreter", d.getVar("UNINATIVE_LOADER"), f), stderr=subprocess.STDOUT) 18092b42cb3SPatrick Williams os.chmod(f, s[stat.ST_MODE]) 18192b42cb3SPatrick Williams} 182