diff options
Diffstat (limited to 'meta/classes-global/utils.bbclass')
-rw-r--r-- | meta/classes-global/utils.bbclass | 369 |
1 files changed, 369 insertions, 0 deletions
diff --git a/meta/classes-global/utils.bbclass b/meta/classes-global/utils.bbclass new file mode 100644 index 0000000000..957389928f --- /dev/null +++ b/meta/classes-global/utils.bbclass @@ -0,0 +1,369 @@ +# +# Copyright OpenEmbedded Contributors +# +# SPDX-License-Identifier: MIT +# + +oe_soinstall() { + # Purpose: Install shared library file and + # create the necessary links + # Example: oe_soinstall libfoo.so.1.2.3 ${D}${libdir} + libname=`basename $1` + case "$libname" in + *.so) + bbfatal "oe_soinstall: Shared library must haved versioned filename (e.g. libfoo.so.1.2.3)" + ;; + esac + install -m 755 $1 $2/$libname + sonamelink=`${READELF} -d $1 |grep 'Library soname:' |sed -e 's/.*\[\(.*\)\].*/\1/'` + if [ -z $sonamelink ]; then + bbfatal "oe_soinstall: $libname is missing ELF tag 'SONAME'." + fi + solink=`echo $libname | sed -e 's/\.so\..*/.so/'` + ln -sf $libname $2/$sonamelink + ln -sf $libname $2/$solink +} + +oe_libinstall() { + # Purpose: Install a library, in all its forms + # Example + # + # oe_libinstall libltdl ${STAGING_LIBDIR}/ + # oe_libinstall -C src/libblah libblah ${D}/${libdir}/ + dir="" + libtool="" + silent="" + require_static="" + require_shared="" + while [ "$#" -gt 0 ]; do + case "$1" in + -C) + shift + dir="$1" + ;; + -s) + silent=1 + ;; + -a) + require_static=1 + ;; + -so) + require_shared=1 + ;; + -*) + bbfatal "oe_libinstall: unknown option: $1" + ;; + *) + break; + ;; + esac + shift + done + + libname="$1" + shift + destpath="$1" + if [ -z "$destpath" ]; then + bbfatal "oe_libinstall: no destination path specified" + fi + + __runcmd () { + if [ -z "$silent" ]; then + echo >&2 "oe_libinstall: $*" + fi + $* + } + + if [ -z "$dir" ]; then + dir=`pwd` + fi + + dotlai=$libname.lai + + # Sanity check that the libname.lai is unique + number_of_files=`(cd $dir; find . -name "$dotlai") | wc -l` + if [ $number_of_files -gt 1 ]; then + bbfatal "oe_libinstall: $dotlai is not unique in $dir" + fi + + + dir=$dir`(cd $dir;find . -name "$dotlai") | sed "s/^\.//;s/\/$dotlai\$//;q"` + olddir=`pwd` + __runcmd cd $dir + + lafile=$libname.la + + # If such file doesn't exist, try to cut version suffix + if [ ! -f "$lafile" ]; then + libname1=`echo "$libname" | sed 's/-[0-9.]*$//'` + lafile1=$libname.la + if [ -f "$lafile1" ]; then + libname=$libname1 + lafile=$lafile1 + fi + fi + + if [ -f "$lafile" ]; then + # libtool archive + eval `cat $lafile|grep "^library_names="` + libtool=1 + else + library_names="$libname.so* $libname.dll.a $libname.*.dylib" + fi + + __runcmd install -d $destpath/ + dota=$libname.a + if [ -f "$dota" -o -n "$require_static" ]; then + rm -f $destpath/$dota + __runcmd install -m 0644 $dota $destpath/ + fi + if [ -f "$dotlai" -a -n "$libtool" ]; then + rm -f $destpath/$libname.la + __runcmd install -m 0644 $dotlai $destpath/$libname.la + fi + + for name in $library_names; do + files=`eval echo $name` + for f in $files; do + if [ ! -e "$f" ]; then + if [ -n "$libtool" ]; then + bbfatal "oe_libinstall: $dir/$f not found." + fi + elif [ -L "$f" ]; then + __runcmd cp -P "$f" $destpath/ + elif [ ! -L "$f" ]; then + libfile="$f" + rm -f $destpath/$libfile + __runcmd install -m 0755 $libfile $destpath/ + fi + done + done + + if [ -z "$libfile" ]; then + if [ -n "$require_shared" ]; then + bbfatal "oe_libinstall: unable to locate shared library" + fi + elif [ -z "$libtool" ]; then + # special case hack for non-libtool .so.#.#.# links + baselibfile=`basename "$libfile"` + if (echo $baselibfile | grep -qE '^lib.*\.so\.[0-9.]*$'); then + sonamelink=`${READELF} -d $libfile |grep 'Library soname:' |sed -e 's/.*\[\(.*\)\].*/\1/'` + solink=`echo $baselibfile | sed -e 's/\.so\..*/.so/'` + if [ -n "$sonamelink" -a x"$baselibfile" != x"$sonamelink" ]; then + __runcmd ln -sf $baselibfile $destpath/$sonamelink + fi + __runcmd ln -sf $baselibfile $destpath/$solink + fi + fi + + __runcmd cd "$olddir" +} + +create_cmdline_wrapper () { + # Create a wrapper script where commandline options are needed + # + # These are useful to work around relocation issues, by passing extra options + # to a program + # + # Usage: create_cmdline_wrapper FILENAME <extra-options> + + cmd=$1 + shift + + echo "Generating wrapper script for $cmd" + + mv $cmd $cmd.real + cmdname=`basename $cmd` + dirname=`dirname $cmd` + cmdoptions=$@ + if [ "${base_prefix}" != "" ]; then + relpath=`python3 -c "import os; print(os.path.relpath('${D}${base_prefix}', '$dirname'))"` + cmdoptions=`echo $@ | sed -e "s:${base_prefix}:\\$realdir/$relpath:g"` + fi + cat <<END >$cmd +#!/bin/bash +realpath=\`readlink -fn \$0\` +realdir=\`dirname \$realpath\` +exec -a \$realdir/$cmdname \$realdir/$cmdname.real $cmdoptions "\$@" +END + chmod +x $cmd +} + +create_cmdline_shebang_wrapper () { + # Create a wrapper script where commandline options are needed + # + # These are useful to work around shebang relocation issues, where shebangs are too + # long or have arguments in them, thus preventing them from using the /usr/bin/env + # shebang + # + # Usage: create_cmdline_wrapper FILENAME <extra-options> + + cmd=$1 + shift + + echo "Generating wrapper script for $cmd" + + # Strip #! and get remaining interpreter + arg + argument="$(sed -ne 's/^#! *//p;q' $cmd)" + # strip the shebang from the real script as we do not want it to be usable anyway + tail -n +2 $cmd > $cmd.real + chown --reference=$cmd $cmd.real + chmod --reference=$cmd $cmd.real + rm -f $cmd + cmdname=$(basename $cmd) + dirname=$(dirname $cmd) + cmdoptions=$@ + if [ "${base_prefix}" != "" ]; then + relpath=`python3 -c "import os; print(os.path.relpath('${D}${base_prefix}', '$dirname'))"` + cmdoptions=`echo $@ | sed -e "s:${base_prefix}:\\$realdir/$relpath:g"` + fi + cat <<END >$cmd +#!/usr/bin/env bash +realpath=\`readlink -fn \$0\` +realdir=\`dirname \$realpath\` +exec -a \$realdir/$cmdname $argument \$realdir/$cmdname.real $cmdoptions "\$@" +END + chmod +x $cmd +} + +create_wrapper () { + # Create a wrapper script where extra environment variables are needed + # + # These are useful to work around relocation issues, by setting environment + # variables which point to paths in the filesystem. + # + # Usage: create_wrapper FILENAME [[VAR=VALUE]..] + + cmd=$1 + shift + + echo "Generating wrapper script for $cmd" + + mv $cmd $cmd.real + cmdname=`basename $cmd` + dirname=`dirname $cmd` + exportstring=$@ + if [ "${base_prefix}" != "" ]; then + relpath=`python3 -c "import os; print(os.path.relpath('${D}${base_prefix}', '$dirname'))"` + exportstring=`echo $@ | sed -e "s:${base_prefix}:\\$realdir/$relpath:g"` + fi + cat <<END >$cmd +#!/bin/bash +realpath=\`readlink -fn \$0\` +realdir=\`dirname \$realpath\` +export $exportstring +exec -a "\$0" \$realdir/$cmdname.real "\$@" +END + chmod +x $cmd +} + +# Copy files/directories from $1 to $2 but using hardlinks +# (preserve symlinks) +hardlinkdir () { + from=$1 + to=$2 + (cd $from; find . -print0 | cpio --null -pdlu $to) +} + + +def check_app_exists(app, d): + app = d.expand(app).split()[0].strip() + path = d.getVar('PATH') + return bool(bb.utils.which(path, app)) + +def explode_deps(s): + return bb.utils.explode_deps(s) + +def base_set_filespath(path, d): + filespath = [] + extrapaths = (d.getVar("FILESEXTRAPATHS") or "") + # Remove default flag which was used for checking + extrapaths = extrapaths.replace("__default:", "") + # Don't prepend empty strings to the path list + if extrapaths != "": + path = extrapaths.split(":") + path + # The ":" ensures we have an 'empty' override + overrides = (":" + (d.getVar("FILESOVERRIDES") or "")).split(":") + overrides.reverse() + for o in overrides: + for p in path: + if p != "": + filespath.append(os.path.join(p, o)) + return ":".join(filespath) + +def extend_variants(d, var, extend, delim=':'): + """Return a string of all bb class extend variants for the given extend""" + variants = [] + whole = d.getVar(var) or "" + for ext in whole.split(): + eext = ext.split(delim) + if len(eext) > 1 and eext[0] == extend: + variants.append(eext[1]) + return " ".join(variants) + +def multilib_pkg_extend(d, pkg): + variants = (d.getVar("MULTILIB_VARIANTS") or "").split() + if not variants: + return pkg + pkgs = pkg + for v in variants: + pkgs = pkgs + " " + v + "-" + pkg + return pkgs + +def get_multilib_datastore(variant, d): + return oe.utils.get_multilib_datastore(variant, d) + +def all_multilib_tune_values(d, var, unique = True, need_split = True, delim = ' '): + """Return a string of all ${var} in all multilib tune configuration""" + values = [] + variants = (d.getVar("MULTILIB_VARIANTS") or "").split() + [''] + for item in variants: + localdata = get_multilib_datastore(item, d) + # We need WORKDIR to be consistent with the original datastore + localdata.setVar("WORKDIR", d.getVar("WORKDIR")) + value = localdata.getVar(var) or "" + if value != "": + if need_split: + for item in value.split(delim): + values.append(item) + else: + values.append(value) + if unique: + #we do this to keep order as much as possible + ret = [] + for value in values: + if not value in ret: + ret.append(value) + else: + ret = values + return " ".join(ret) + +def all_multilib_tune_list(vars, d): + """ + Return a list of ${VAR} for each variable VAR in vars from each + multilib tune configuration. + Is safe to be called from a multilib recipe/context as it can + figure out the original tune and remove the multilib overrides. + """ + values = {} + for v in vars: + values[v] = [] + values['ml'] = [''] + + variants = (d.getVar("MULTILIB_VARIANTS") or "").split() + [''] + for item in variants: + localdata = get_multilib_datastore(item, d) + values[v].append(localdata.getVar(v)) + values['ml'].append(item) + return values +all_multilib_tune_list[vardepsexclude] = "OVERRIDES" + +# If the user hasn't set up their name/email, set some defaults +check_git_config() { + if ! git config user.email > /dev/null ; then + git config --local user.email "${PATCH_GIT_USER_EMAIL}" + fi + if ! git config user.name > /dev/null ; then + git config --local user.name "${PATCH_GIT_USER_NAME}" + fi +} |