| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 1 |  | 
|  | 2 | oe_soinstall() { | 
|  | 3 | # Purpose: Install shared library file and | 
|  | 4 | #          create the necessary links | 
| Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 5 | # Example: oe_soinstall libfoo.so.1.2.3 ${D}${libdir} | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 6 | libname=`basename $1` | 
| Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 7 | case "$libname" in | 
|  | 8 | *.so) | 
|  | 9 | bbfatal "oe_soinstall: Shared library must haved versioned filename (e.g. libfoo.so.1.2.3)" | 
|  | 10 | ;; | 
|  | 11 | esac | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 12 | install -m 755 $1 $2/$libname | 
|  | 13 | sonamelink=`${HOST_PREFIX}readelf -d $1 |grep 'Library soname:' |sed -e 's/.*\[\(.*\)\].*/\1/'` | 
| Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 14 | if [ -z $sonamelink ]; then | 
|  | 15 | bbfatal "oe_soinstall: $libname is missing ELF tag 'SONAME'." | 
|  | 16 | fi | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 17 | solink=`echo $libname | sed -e 's/\.so\..*/.so/'` | 
|  | 18 | ln -sf $libname $2/$sonamelink | 
|  | 19 | ln -sf $libname $2/$solink | 
|  | 20 | } | 
|  | 21 |  | 
|  | 22 | oe_libinstall() { | 
|  | 23 | # Purpose: Install a library, in all its forms | 
|  | 24 | # Example | 
|  | 25 | # | 
|  | 26 | # oe_libinstall libltdl ${STAGING_LIBDIR}/ | 
|  | 27 | # oe_libinstall -C src/libblah libblah ${D}/${libdir}/ | 
|  | 28 | dir="" | 
|  | 29 | libtool="" | 
|  | 30 | silent="" | 
|  | 31 | require_static="" | 
|  | 32 | require_shared="" | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 33 | while [ "$#" -gt 0 ]; do | 
|  | 34 | case "$1" in | 
|  | 35 | -C) | 
|  | 36 | shift | 
|  | 37 | dir="$1" | 
|  | 38 | ;; | 
|  | 39 | -s) | 
|  | 40 | silent=1 | 
|  | 41 | ;; | 
|  | 42 | -a) | 
|  | 43 | require_static=1 | 
|  | 44 | ;; | 
|  | 45 | -so) | 
|  | 46 | require_shared=1 | 
|  | 47 | ;; | 
|  | 48 | -*) | 
|  | 49 | bbfatal "oe_libinstall: unknown option: $1" | 
|  | 50 | ;; | 
|  | 51 | *) | 
|  | 52 | break; | 
|  | 53 | ;; | 
|  | 54 | esac | 
|  | 55 | shift | 
|  | 56 | done | 
|  | 57 |  | 
|  | 58 | libname="$1" | 
|  | 59 | shift | 
|  | 60 | destpath="$1" | 
|  | 61 | if [ -z "$destpath" ]; then | 
|  | 62 | bbfatal "oe_libinstall: no destination path specified" | 
|  | 63 | fi | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 64 |  | 
|  | 65 | __runcmd () { | 
|  | 66 | if [ -z "$silent" ]; then | 
|  | 67 | echo >&2 "oe_libinstall: $*" | 
|  | 68 | fi | 
|  | 69 | $* | 
|  | 70 | } | 
|  | 71 |  | 
|  | 72 | if [ -z "$dir" ]; then | 
|  | 73 | dir=`pwd` | 
|  | 74 | fi | 
|  | 75 |  | 
|  | 76 | dotlai=$libname.lai | 
|  | 77 |  | 
|  | 78 | # Sanity check that the libname.lai is unique | 
|  | 79 | number_of_files=`(cd $dir; find . -name "$dotlai") | wc -l` | 
|  | 80 | if [ $number_of_files -gt 1 ]; then | 
|  | 81 | bbfatal "oe_libinstall: $dotlai is not unique in $dir" | 
|  | 82 | fi | 
|  | 83 |  | 
|  | 84 |  | 
|  | 85 | dir=$dir`(cd $dir;find . -name "$dotlai") | sed "s/^\.//;s/\/$dotlai\$//;q"` | 
|  | 86 | olddir=`pwd` | 
|  | 87 | __runcmd cd $dir | 
|  | 88 |  | 
|  | 89 | lafile=$libname.la | 
|  | 90 |  | 
|  | 91 | # If such file doesn't exist, try to cut version suffix | 
|  | 92 | if [ ! -f "$lafile" ]; then | 
|  | 93 | libname1=`echo "$libname" | sed 's/-[0-9.]*$//'` | 
|  | 94 | lafile1=$libname.la | 
|  | 95 | if [ -f "$lafile1" ]; then | 
|  | 96 | libname=$libname1 | 
|  | 97 | lafile=$lafile1 | 
|  | 98 | fi | 
|  | 99 | fi | 
|  | 100 |  | 
|  | 101 | if [ -f "$lafile" ]; then | 
|  | 102 | # libtool archive | 
|  | 103 | eval `cat $lafile|grep "^library_names="` | 
|  | 104 | libtool=1 | 
|  | 105 | else | 
|  | 106 | library_names="$libname.so* $libname.dll.a $libname.*.dylib" | 
|  | 107 | fi | 
|  | 108 |  | 
|  | 109 | __runcmd install -d $destpath/ | 
|  | 110 | dota=$libname.a | 
|  | 111 | if [ -f "$dota" -o -n "$require_static" ]; then | 
|  | 112 | rm -f $destpath/$dota | 
|  | 113 | __runcmd install -m 0644 $dota $destpath/ | 
|  | 114 | fi | 
|  | 115 | if [ -f "$dotlai" -a -n "$libtool" ]; then | 
|  | 116 | rm -f $destpath/$libname.la | 
|  | 117 | __runcmd install -m 0644 $dotlai $destpath/$libname.la | 
|  | 118 | fi | 
|  | 119 |  | 
|  | 120 | for name in $library_names; do | 
|  | 121 | files=`eval echo $name` | 
|  | 122 | for f in $files; do | 
|  | 123 | if [ ! -e "$f" ]; then | 
|  | 124 | if [ -n "$libtool" ]; then | 
|  | 125 | bbfatal "oe_libinstall: $dir/$f not found." | 
|  | 126 | fi | 
|  | 127 | elif [ -L "$f" ]; then | 
|  | 128 | __runcmd cp -P "$f" $destpath/ | 
|  | 129 | elif [ ! -L "$f" ]; then | 
|  | 130 | libfile="$f" | 
|  | 131 | rm -f $destpath/$libfile | 
|  | 132 | __runcmd install -m 0755 $libfile $destpath/ | 
|  | 133 | fi | 
|  | 134 | done | 
|  | 135 | done | 
|  | 136 |  | 
|  | 137 | if [ -z "$libfile" ]; then | 
|  | 138 | if  [ -n "$require_shared" ]; then | 
|  | 139 | bbfatal "oe_libinstall: unable to locate shared library" | 
|  | 140 | fi | 
|  | 141 | elif [ -z "$libtool" ]; then | 
|  | 142 | # special case hack for non-libtool .so.#.#.# links | 
|  | 143 | baselibfile=`basename "$libfile"` | 
|  | 144 | if (echo $baselibfile | grep -qE '^lib.*\.so\.[0-9.]*$'); then | 
|  | 145 | sonamelink=`${HOST_PREFIX}readelf -d $libfile |grep 'Library soname:' |sed -e 's/.*\[\(.*\)\].*/\1/'` | 
|  | 146 | solink=`echo $baselibfile | sed -e 's/\.so\..*/.so/'` | 
|  | 147 | if [ -n "$sonamelink" -a x"$baselibfile" != x"$sonamelink" ]; then | 
|  | 148 | __runcmd ln -sf $baselibfile $destpath/$sonamelink | 
|  | 149 | fi | 
|  | 150 | __runcmd ln -sf $baselibfile $destpath/$solink | 
|  | 151 | fi | 
|  | 152 | fi | 
|  | 153 |  | 
|  | 154 | __runcmd cd "$olddir" | 
|  | 155 | } | 
|  | 156 |  | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 157 | create_cmdline_wrapper () { | 
|  | 158 | # Create a wrapper script where commandline options are needed | 
|  | 159 | # | 
| Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 160 | # These are useful to work around relocation issues, by passing extra options | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 161 | # to a program | 
|  | 162 | # | 
|  | 163 | # Usage: create_cmdline_wrapper FILENAME <extra-options> | 
|  | 164 |  | 
|  | 165 | cmd=$1 | 
|  | 166 | shift | 
|  | 167 |  | 
|  | 168 | echo "Generating wrapper script for $cmd" | 
|  | 169 |  | 
|  | 170 | mv $cmd $cmd.real | 
|  | 171 | cmdname=`basename $cmd` | 
| Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame] | 172 | dirname=`dirname $cmd` | 
|  | 173 | cmdoptions=$@ | 
|  | 174 | if [ "${base_prefix}" != "" ]; then | 
|  | 175 | relpath=`python3 -c "import os; print(os.path.relpath('${D}${base_prefix}', '$dirname'))"` | 
|  | 176 | cmdoptions=`echo $@ | sed -e "s:${base_prefix}:\\$realdir/$relpath:g"` | 
|  | 177 | fi | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 178 | cat <<END >$cmd | 
|  | 179 | #!/bin/bash | 
|  | 180 | realpath=\`readlink -fn \$0\` | 
| Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame] | 181 | realdir=\`dirname \$realpath\` | 
| Andrew Geissler | d159c7f | 2021-09-02 21:05:58 -0500 | [diff] [blame] | 182 | exec -a \$realdir/$cmdname \$realdir/$cmdname.real $cmdoptions "\$@" | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 183 | END | 
|  | 184 | chmod +x $cmd | 
|  | 185 | } | 
|  | 186 |  | 
| Andrew Geissler | 615f2f1 | 2022-07-15 14:00:58 -0500 | [diff] [blame^] | 187 | create_cmdline_shebang_wrapper () { | 
|  | 188 | # Create a wrapper script where commandline options are needed | 
|  | 189 | # | 
|  | 190 | # These are useful to work around shebang relocation issues, where shebangs are too | 
|  | 191 | # long or have arguments in them, thus preventing them from using the /usr/bin/env | 
|  | 192 | # shebang | 
|  | 193 | # | 
|  | 194 | # Usage: create_cmdline_wrapper FILENAME <extra-options> | 
|  | 195 |  | 
|  | 196 | cmd=$1 | 
|  | 197 | shift | 
|  | 198 |  | 
|  | 199 | echo "Generating wrapper script for $cmd" | 
|  | 200 |  | 
|  | 201 | # Strip #! and get remaining interpreter + arg | 
|  | 202 | argument="$(sed -ne 's/^#! *//p;q' $cmd)" | 
|  | 203 | # strip the shebang from the real script as we do not want it to be usable anyway | 
|  | 204 | tail -n +2 $cmd > $cmd.real | 
|  | 205 | chown --reference=$cmd $cmd.real | 
|  | 206 | chmod --reference=$cmd $cmd.real | 
|  | 207 | rm -f $cmd | 
|  | 208 | cmdname=$(basename $cmd) | 
|  | 209 | dirname=$(dirname $cmd) | 
|  | 210 | cmdoptions=$@ | 
|  | 211 | if [ "${base_prefix}" != "" ]; then | 
|  | 212 | relpath=`python3 -c "import os; print(os.path.relpath('${D}${base_prefix}', '$dirname'))"` | 
|  | 213 | cmdoptions=`echo $@ | sed -e "s:${base_prefix}:\\$realdir/$relpath:g"` | 
|  | 214 | fi | 
|  | 215 | cat <<END >$cmd | 
|  | 216 | #!/usr/bin/env bash | 
|  | 217 | realpath=\`readlink -fn \$0\` | 
|  | 218 | realdir=\`dirname \$realpath\` | 
|  | 219 | exec -a \$realdir/$cmdname $argument \$realdir/$cmdname.real $cmdoptions "\$@" | 
|  | 220 | END | 
|  | 221 | chmod +x $cmd | 
|  | 222 | } | 
|  | 223 |  | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 224 | create_wrapper () { | 
|  | 225 | # Create a wrapper script where extra environment variables are needed | 
|  | 226 | # | 
|  | 227 | # These are useful to work around relocation issues, by setting environment | 
|  | 228 | # variables which point to paths in the filesystem. | 
|  | 229 | # | 
|  | 230 | # Usage: create_wrapper FILENAME [[VAR=VALUE]..] | 
|  | 231 |  | 
|  | 232 | cmd=$1 | 
|  | 233 | shift | 
|  | 234 |  | 
|  | 235 | echo "Generating wrapper script for $cmd" | 
|  | 236 |  | 
|  | 237 | mv $cmd $cmd.real | 
|  | 238 | cmdname=`basename $cmd` | 
| Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame] | 239 | dirname=`dirname $cmd` | 
|  | 240 | exportstring=$@ | 
|  | 241 | if [ "${base_prefix}" != "" ]; then | 
|  | 242 | relpath=`python3 -c "import os; print(os.path.relpath('${D}${base_prefix}', '$dirname'))"` | 
|  | 243 | exportstring=`echo $@ | sed -e "s:${base_prefix}:\\$realdir/$relpath:g"` | 
|  | 244 | fi | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 245 | cat <<END >$cmd | 
|  | 246 | #!/bin/bash | 
|  | 247 | realpath=\`readlink -fn \$0\` | 
| Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame] | 248 | realdir=\`dirname \$realpath\` | 
|  | 249 | export $exportstring | 
| Brad Bishop | 1932369 | 2019-04-05 15:28:33 -0400 | [diff] [blame] | 250 | exec -a "\$0" \$realdir/$cmdname.real "\$@" | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 251 | END | 
|  | 252 | chmod +x $cmd | 
|  | 253 | } | 
|  | 254 |  | 
|  | 255 | # Copy files/directories from $1 to $2 but using hardlinks | 
|  | 256 | # (preserve symlinks) | 
|  | 257 | hardlinkdir () { | 
|  | 258 | from=$1 | 
|  | 259 | to=$2 | 
|  | 260 | (cd $from; find . -print0 | cpio --null -pdlu $to) | 
|  | 261 | } | 
|  | 262 |  | 
|  | 263 |  | 
|  | 264 | def check_app_exists(app, d): | 
| Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 265 | app = d.expand(app).split()[0].strip() | 
| Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame] | 266 | path = d.getVar('PATH') | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 267 | return bool(bb.utils.which(path, app)) | 
|  | 268 |  | 
|  | 269 | def explode_deps(s): | 
|  | 270 | return bb.utils.explode_deps(s) | 
|  | 271 |  | 
|  | 272 | def base_set_filespath(path, d): | 
|  | 273 | filespath = [] | 
| Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame] | 274 | extrapaths = (d.getVar("FILESEXTRAPATHS") or "") | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 275 | # Remove default flag which was used for checking | 
|  | 276 | extrapaths = extrapaths.replace("__default:", "") | 
|  | 277 | # Don't prepend empty strings to the path list | 
|  | 278 | if extrapaths != "": | 
|  | 279 | path = extrapaths.split(":") + path | 
|  | 280 | # The ":" ensures we have an 'empty' override | 
| Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame] | 281 | overrides = (":" + (d.getVar("FILESOVERRIDES") or "")).split(":") | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 282 | overrides.reverse() | 
|  | 283 | for o in overrides: | 
|  | 284 | for p in path: | 
| Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 285 | if p != "": | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 286 | filespath.append(os.path.join(p, o)) | 
|  | 287 | return ":".join(filespath) | 
|  | 288 |  | 
|  | 289 | def extend_variants(d, var, extend, delim=':'): | 
|  | 290 | """Return a string of all bb class extend variants for the given extend""" | 
|  | 291 | variants = [] | 
| Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame] | 292 | whole = d.getVar(var) or "" | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 293 | for ext in whole.split(): | 
|  | 294 | eext = ext.split(delim) | 
|  | 295 | if len(eext) > 1 and eext[0] == extend: | 
|  | 296 | variants.append(eext[1]) | 
|  | 297 | return " ".join(variants) | 
|  | 298 |  | 
|  | 299 | def multilib_pkg_extend(d, pkg): | 
| Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame] | 300 | variants = (d.getVar("MULTILIB_VARIANTS") or "").split() | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 301 | if not variants: | 
|  | 302 | return pkg | 
|  | 303 | pkgs = pkg | 
|  | 304 | for v in variants: | 
|  | 305 | pkgs = pkgs + " " + v + "-" + pkg | 
|  | 306 | return pkgs | 
|  | 307 |  | 
| Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame] | 308 | def get_multilib_datastore(variant, d): | 
| Brad Bishop | 316dfdd | 2018-06-25 12:45:53 -0400 | [diff] [blame] | 309 | return oe.utils.get_multilib_datastore(variant, d) | 
| Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame] | 310 |  | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 311 | def all_multilib_tune_values(d, var, unique = True, need_split = True, delim = ' '): | 
|  | 312 | """Return a string of all ${var} in all multilib tune configuration""" | 
|  | 313 | values = [] | 
| Brad Bishop | 1a4b7ee | 2018-12-16 17:11:34 -0800 | [diff] [blame] | 314 | variants = (d.getVar("MULTILIB_VARIANTS") or "").split() + [''] | 
|  | 315 | for item in variants: | 
| Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame] | 316 | localdata = get_multilib_datastore(item, d) | 
| Brad Bishop | d5ae7d9 | 2018-06-14 09:52:03 -0700 | [diff] [blame] | 317 | # We need WORKDIR to be consistent with the original datastore | 
|  | 318 | localdata.setVar("WORKDIR", d.getVar("WORKDIR")) | 
| Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame] | 319 | value = localdata.getVar(var) or "" | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 320 | if value != "": | 
|  | 321 | if need_split: | 
|  | 322 | for item in value.split(delim): | 
|  | 323 | values.append(item) | 
|  | 324 | else: | 
|  | 325 | values.append(value) | 
|  | 326 | if unique: | 
|  | 327 | #we do this to keep order as much as possible | 
|  | 328 | ret = [] | 
|  | 329 | for value in values: | 
|  | 330 | if not value in ret: | 
|  | 331 | ret.append(value) | 
|  | 332 | else: | 
|  | 333 | ret = values | 
|  | 334 | return " ".join(ret) | 
| Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 335 |  | 
|  | 336 | def all_multilib_tune_list(vars, d): | 
|  | 337 | """ | 
|  | 338 | Return a list of ${VAR} for each variable VAR in vars from each | 
|  | 339 | multilib tune configuration. | 
|  | 340 | Is safe to be called from a multilib recipe/context as it can | 
|  | 341 | figure out the original tune and remove the multilib overrides. | 
|  | 342 | """ | 
|  | 343 | values = {} | 
|  | 344 | for v in vars: | 
|  | 345 | values[v] = [] | 
| Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 346 | values['ml'] = [''] | 
| Brad Bishop | 1a4b7ee | 2018-12-16 17:11:34 -0800 | [diff] [blame] | 347 |  | 
|  | 348 | variants = (d.getVar("MULTILIB_VARIANTS") or "").split() + [''] | 
|  | 349 | for item in variants: | 
| Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame] | 350 | localdata = get_multilib_datastore(item, d) | 
|  | 351 | values[v].append(localdata.getVar(v)) | 
| Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 352 | values['ml'].append(item) | 
|  | 353 | return values | 
| Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 354 | all_multilib_tune_list[vardepsexclude] = "OVERRIDES" | 
| Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 355 |  | 
|  | 356 | # If the user hasn't set up their name/email, set some defaults | 
|  | 357 | check_git_config() { | 
|  | 358 | if ! git config user.email > /dev/null ; then | 
|  | 359 | git config --local user.email "${PATCH_GIT_USER_EMAIL}" | 
|  | 360 | fi | 
|  | 361 | if ! git config user.name > /dev/null ; then | 
|  | 362 | git config --local user.name "${PATCH_GIT_USER_NAME}" | 
|  | 363 | fi | 
|  | 364 | } |