diff options
Diffstat (limited to 'classes/base.bbclass')
| -rw-r--r-- | classes/base.bbclass | 1200 |
1 files changed, 889 insertions, 311 deletions
diff --git a/classes/base.bbclass b/classes/base.bbclass index 0d29de144a..e6cfeccc46 100644 --- a/classes/base.bbclass +++ b/classes/base.bbclass @@ -1,21 +1,190 @@ -PATCHES_DIR="${S}" +BB_DEFAULT_TASK ?= "build" + +# like os.path.join but doesn't treat absolute RHS specially +def base_path_join(a, *p): + path = a + for b in p: + if path == '' or path.endswith('/'): + path += b + else: + path += '/' + b + return path + +def base_path_relative(src, dest): + """ Return a relative path from src to dest. + + >>> base_path_relative("/usr/bin", "/tmp/foo/bar") + ../../tmp/foo/bar + + >>> base_path_relative("/usr/bin", "/usr/lib") + ../lib + + >>> base_path_relative("/tmp", "/tmp/foo/bar") + foo/bar + """ + from os.path import sep, pardir, normpath, commonprefix + + destlist = normpath(dest).split(sep) + srclist = normpath(src).split(sep) + + # Find common section of the path + common = commonprefix([destlist, srclist]) + commonlen = len(common) + + # Climb back to the point where they differentiate + relpath = [ pardir ] * (len(srclist) - commonlen) + if commonlen < len(destlist): + # Add remaining portion + relpath += destlist[commonlen:] + + return sep.join(relpath) + +def base_path_out(path, d): + """ Prepare a path for display to the user. """ + rel = base_path_relative(d.getVar("TOPDIR", 1), path) + if len(rel) > len(path): + return path + else: + return rel + +# for MD5/SHA handling +def base_chk_load_parser(config_paths): + import ConfigParser + parser = ConfigParser.ConfigParser() + if len(parser.read(config_paths)) < 1: + raise ValueError("no ini files could be found") + + return parser + +def base_chk_file_vars(parser, localpath, params, data): + try: + name = params["name"] + except KeyError: + return False + flagName = "%s.md5sum" % name + want_md5sum = bb.data.getVarFlag("SRC_URI", flagName, data) + flagName = "%s.sha256sum" % name + want_sha256sum = bb.data.getVarFlag("SRC_URI", flagName, data) + + if (want_sha256sum == None and want_md5sum == None): + # no checksums to check, nothing to do + return False + + if not os.path.exists(localpath): + localpath = base_path_out(localpath, data) + bb.note("The localpath does not exist '%s'" % localpath) + raise Exception("The path does not exist '%s'" % localpath) + + if want_md5sum: + try: + md5pipe = os.popen('PATH=%s md5sum %s' % (bb.data.getVar('PATH', data, True), localpath)) + md5data = (md5pipe.readline().split() or [ "" ])[0] + md5pipe.close() + except OSError, e: + raise Exception("Executing md5sum failed") + if want_md5sum != md5data: + bb.note("The MD5Sums did not match. Wanted: '%s' and Got: '%s'" % (want_md5sum, md5data)) + raise Exception("MD5 Sums do not match. Wanted: '%s' Got: '%s'" % (want_md5sum, md5data)) + + if want_sha256sum: + try: + shapipe = os.popen('PATH=%s oe_sha256sum %s' % (bb.data.getVar('PATH', data, True), localpath)) + sha256data = (shapipe.readline().split() or [ "" ])[0] + shapipe.close() + except OSError, e: + raise Exception("Executing shasum failed") + if want_sha256sum != sha256data: + bb.note("The SHA256Sums did not match. Wanted: '%s' and Got: '%s'" % (want_sha256sum, sha256data)) + raise Exception("SHA256 Sums do not match. Wanted: '%s' Got: '%s'" % (want_sha256sum, sha256data)) + + return True + + +def base_chk_file(parser, pn, pv, src_uri, localpath, data): + no_checksum = False + # Try PN-PV-SRC_URI first and then try PN-SRC_URI + # we rely on the get method to create errors + pn_pv_src = "%s-%s-%s" % (pn,pv,src_uri) + pn_src = "%s-%s" % (pn,src_uri) + if parser.has_section(pn_pv_src): + md5 = parser.get(pn_pv_src, "md5") + sha256 = parser.get(pn_pv_src, "sha256") + elif parser.has_section(pn_src): + md5 = parser.get(pn_src, "md5") + sha256 = parser.get(pn_src, "sha256") + elif parser.has_section(src_uri): + md5 = parser.get(src_uri, "md5") + sha256 = parser.get(src_uri, "sha256") + else: + no_checksum = True + + # md5 and sha256 should be valid now + if not os.path.exists(localpath): + localpath = base_path_out(localpath, data) + bb.note("The localpath does not exist '%s'" % localpath) + raise Exception("The path does not exist '%s'" % localpath) + + + # call md5(sum) and shasum + try: + md5pipe = os.popen('PATH=%s md5sum %s' % (bb.data.getVar('PATH', data, True), localpath)) + md5data = (md5pipe.readline().split() or [ "" ])[0] + md5pipe.close() + except OSError: + raise Exception("Executing md5sum failed") + + try: + shapipe = os.popen('PATH=%s oe_sha256sum %s' % (bb.data.getVar('PATH', data, True), localpath)) + shadata = (shapipe.readline().split() or [ "" ])[0] + shapipe.close() + except OSError: + raise Exception("Executing shasum failed") + + if no_checksum == True: # we do not have conf/checksums.ini entry + try: + file = open("%s/checksums.ini" % bb.data.getVar("TMPDIR", data, 1), "a") + except: + return False + + if not file: + raise Exception("Creating checksums.ini failed") + + file.write("[%s]\nmd5=%s\nsha256=%s\n\n" % (src_uri, md5data, shadata)) + file.close() + if not bb.data.getVar("OE_STRICT_CHECKSUMS",data, True): + bb.note("This package has no entry in checksums.ini, please add one") + bb.note("\n[%s]\nmd5=%s\nsha256=%s" % (src_uri, md5data, shadata)) + return True + else: + bb.note("Missing checksum") + return False + + if not md5 == md5data: + bb.note("The MD5Sums did not match. Wanted: '%s' and Got: '%s'" % (md5,md5data)) + raise Exception("MD5 Sums do not match. Wanted: '%s' Got: '%s'" % (md5, md5data)) + + if not sha256 == shadata: + bb.note("The SHA256 Sums do not match. Wanted: '%s' Got: '%s'" % (sha256,shadata)) + raise Exception("SHA256 Sums do not match. Wanted: '%s' Got: '%s'" % (sha256, shadata)) + + return True + def base_dep_prepend(d): - import bb; # # Ideally this will check a flag so we will operate properly in # the case where host == build == target, for now we don't work in # that case though. # - deps = "" + deps = "shasum-native coreutils-native" + if bb.data.getVar('PN', d, True) == "shasum-native" or bb.data.getVar('PN', d, True) == "stagemanager-native": + deps = "" + if bb.data.getVar('PN', d, True) == "coreutils-native": + deps = "shasum-native" # INHIBIT_DEFAULT_DEPS doesn't apply to the patch command. Whether or not # we need that built is the responsibility of the patch function / class, not # the application. - patchdeps = bb.data.getVar("PATCH_DEPENDS", d, 1) - if patchdeps and not patchdeps in bb.data.getVar("PROVIDES", d, 1): - deps = patchdeps - if not bb.data.getVar('INHIBIT_DEFAULT_DEPS', d): if (bb.data.getVar('HOST_SYS', d, 1) != bb.data.getVar('BUILD_SYS', d, 1)): @@ -23,35 +192,77 @@ def base_dep_prepend(d): return deps def base_read_file(filename): - import bb try: f = file( filename, "r" ) except IOError, reason: - raise bb.build.FuncFailed("can't read from file '%s' (%s)", (filename,reason)) + return "" # WARNING: can't raise an error now because of the new RDEPENDS handling. This is a bit ugly. :M: else: return f.read().strip() return None +def base_ifelse(condition, iftrue = True, iffalse = False): + if condition: + return iftrue + else: + return iffalse + def base_conditional(variable, checkvalue, truevalue, falsevalue, d): - import bb if bb.data.getVar(variable,d,1) == checkvalue: return truevalue else: return falsevalue +def base_less_or_equal(variable, checkvalue, truevalue, falsevalue, d): + if float(bb.data.getVar(variable,d,1)) <= float(checkvalue): + return truevalue + else: + return falsevalue + +def base_version_less_or_equal(variable, checkvalue, truevalue, falsevalue, d): + result = bb.vercmp(bb.data.getVar(variable,d,True), checkvalue) + if result <= 0: + return truevalue + else: + return falsevalue + +def base_contains(variable, checkvalues, truevalue, falsevalue, d): + matches = 0 + if type(checkvalues).__name__ == "str": + checkvalues = [checkvalues] + for value in checkvalues: + if bb.data.getVar(variable,d,1).find(value) != -1: + matches = matches + 1 + if matches == len(checkvalues): + return truevalue + return falsevalue + +def base_both_contain(variable1, variable2, checkvalue, d): + if bb.data.getVar(variable1,d,1).find(checkvalue) != -1 and bb.data.getVar(variable2,d,1).find(checkvalue) != -1: + return checkvalue + else: + return "" + DEPENDS_prepend="${@base_dep_prepend(d)} " +DEPENDS_virtclass-native_prepend="${@base_dep_prepend(d)} " +DEPENDS_virtclass-nativesdk_prepend="${@base_dep_prepend(d)} " + +def base_prune_suffix(var, suffixes, d): + # See if var ends with any of the suffixes listed and + # remove it if found + for suffix in suffixes: + if var.endswith(suffix): + return var.replace(suffix, "") + return var def base_set_filespath(path, d): - import os, bb + bb.note("base_set_filespath usage is deprecated, %s should be fixed" % d.getVar("P", 1)) filespath = [] + # The ":" ensures we have an 'empty' override + overrides = (bb.data.getVar("OVERRIDES", d, 1) or "") + ":" for p in path: - overrides = bb.data.getVar("OVERRIDES", d, 1) or "" - overrides = overrides + ":" for o in overrides.split(":"): filespath.append(os.path.join(p, o)) - bb.data.setVar("FILESPATH", ":".join(filespath), d) - -FILESPATH = "${@base_set_filespath([ "${FILE_DIRNAME}/${PF}", "${FILE_DIRNAME}/${P}", "${FILE_DIRNAME}/${PN}", "${FILE_DIRNAME}/files", "${FILE_DIRNAME}" ], d)}" + return ":".join(filespath) def oe_filter(f, str, d): from re import match @@ -124,6 +335,7 @@ oe_libinstall() { silent="" require_static="" require_shared="" + staging_install="" while [ "$#" -gt 0 ]; do case "$1" in -C) @@ -155,6 +367,10 @@ oe_libinstall() { if [ -z "$destpath" ]; then oefatal "oe_libinstall: no destination path specified" fi + if echo "$destpath/" | egrep '^${STAGING_LIBDIR}/' >/dev/null + then + staging_install=1 + fi __runcmd () { if [ -z "$silent" ]; then @@ -166,13 +382,32 @@ oe_libinstall() { if [ -z "$dir" ]; then dir=`pwd` fi - if [ -d "$dir/.libs" ]; then - dir=$dir/.libs + + 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 + oefatal "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="` @@ -186,9 +421,19 @@ oe_libinstall() { if [ -f "$dota" -o -n "$require_static" ]; then __runcmd install -m 0644 $dota $destpath/ fi - dotlai=$libname.lai - if [ -f "$dotlai" -o -n "$libtool" ]; then - __runcmd install -m 0644 $dotlai $destpath/$libname.la + if [ -f "$dotlai" -a -n "$libtool" ]; then + if test -n "$staging_install" + then + # stop libtool using the final directory name for libraries + # in staging: + __runcmd rm -f $destpath/$libname.la + __runcmd sed -e 's/^installed=yes$/installed=no/' \ + -e '/^dependency_libs=/s,${WORKDIR}[[:alnum:]/\._+-]*/\([[:alnum:]\._+-]*\),${STAGING_LIBDIR}/\1,g' \ + -e "/^dependency_libs=/s,\([[:space:]']\)${libdir},\1${STAGING_LIBDIR},g" \ + $dotlai >$destpath/$libname.la + else + __runcmd install -m 0644 $dotlai $destpath/$libname.la + fi fi for name in $library_names; do @@ -199,7 +444,7 @@ oe_libinstall() { oefatal "oe_libinstall: $dir/$f not found." fi elif [ -L "$f" ]; then - __runcmd cp --no-dereference "$f" $destpath/ + __runcmd cp -P "$f" $destpath/ elif [ ! -L "$f" ]; then libfile="$f" __runcmd install -m 0755 $libfile $destpath/ @@ -227,6 +472,24 @@ oe_libinstall() { __runcmd cd "$olddir" } +def package_stagefile(file, d): + + if bb.data.getVar('PSTAGING_ACTIVE', d, True) == "1": + destfile = file.replace(bb.data.getVar("TMPDIR", d, 1), bb.data.getVar("PSTAGE_TMPDIR_STAGE", d, 1)) + bb.mkdirhier(os.path.dirname(destfile)) + #print "%s to %s" % (file, destfile) + bb.copyfile(file, destfile) + +package_stagefile_shell() { + if [ "$PSTAGING_ACTIVE" = "1" ]; then + srcfile=$1 + destfile=`echo $srcfile | sed s#${TMPDIR}#${PSTAGE_TMPDIR_STAGE}#` + destdir=`dirname $destfile` + mkdir -p $destdir + cp -dp $srcfile $destfile + fi +} + oe_machinstall() { # Purpose: Install machine dependent files, if available # If not available, check if there is a default @@ -257,18 +520,6 @@ oe_machinstall() { fi } -addtask showdata -do_showdata[nostamp] = "1" -python do_showdata() { - import sys - # emit variables and shell functions - bb.data.emit_env(sys.__stdout__, d, True) - # emit the metadata which isnt valid shell - for e in d.keys(): - if bb.data.getVarFlag(e, 'python', d): - sys.__stdout__.write("\npython %s () {\n%s}\n" % (e, bb.data.getVar(e, d, 1))) -} - addtask listtasks do_listtasks[nostamp] = "1" python do_listtasks() { @@ -284,35 +535,95 @@ python do_listtasks() { addtask clean do_clean[dirs] = "${TOPDIR}" do_clean[nostamp] = "1" -do_clean[bbdepcmd] = "" python base_do_clean() { """clear the build and temp directories""" dir = bb.data.expand("${WORKDIR}", d) if dir == '//': raise bb.build.FuncFailed("wrong DATADIR") - bb.note("removing " + dir) + bb.note("removing " + base_path_out(dir, d)) os.system('rm -rf ' + dir) dir = "%s.*" % bb.data.expand(bb.data.getVar('STAMP', d), d) - bb.note("removing " + dir) + bb.note("removing " + base_path_out(dir, d)) os.system('rm -f '+ dir) } +python do_cleanall() { + pass +} +do_cleanall[recrdeptask] = "do_clean" +addtask cleanall after do_clean + +addtask rebuild after do_${BB_DEFAULT_TASK} +do_rebuild[dirs] = "${TOPDIR}" +do_rebuild[nostamp] = "1" +python base_do_rebuild() { + """rebuild a package""" +} + addtask mrproper do_mrproper[dirs] = "${TOPDIR}" do_mrproper[nostamp] = "1" -do_mrproper[bbdepcmd] = "" python base_do_mrproper() { """clear downloaded sources, build and temp directories""" dir = bb.data.expand("${DL_DIR}", d) if dir == '/': bb.build.FuncFailed("wrong DATADIR") bb.debug(2, "removing " + dir) os.system('rm -rf ' + dir) - bb.build.exec_task('do_clean', d) + bb.build.exec_func('do_clean', d) } +addtask distclean +do_distclean[dirs] = "${TOPDIR}" +do_distclean[nostamp] = "1" +python base_do_distclean() { + """clear downloaded sources, build and temp directories""" + + bb.build.exec_func('do_clean', d) + + src_uri = bb.data.getVar('SRC_URI', d, 1) + if not src_uri: + return + + for uri in src_uri.split(): + if bb.decodeurl(uri)[0] == "file": + continue + + try: + local = bb.data.expand(bb.fetch.localpath(uri, d), d) + except bb.MalformedUrl, e: + bb.debug(1, 'Unable to generate local path for malformed uri: %s' % e) + else: + bb.note("removing %s" % base_path_out(local, d)) + try: + if os.path.exists(local + ".md5"): + os.remove(local + ".md5") + if os.path.exists(local): + os.remove(local) + except OSError, e: + bb.note("Error in removal: %s" % e) +} + +SCENEFUNCS += "base_scenefunction" + +python base_do_setscene () { + for f in (bb.data.getVar('SCENEFUNCS', d, 1) or '').split(): + bb.build.exec_func(f, d) + if not os.path.exists(bb.data.getVar('STAMP', d, 1) + ".do_setscene"): + bb.build.make_stamp("do_setscene", d) +} +do_setscene[selfstamp] = "1" +addtask setscene before do_fetch + +python base_scenefunction () { + stamp = bb.data.getVar('STAMP', d, 1) + ".needclean" + if os.path.exists(stamp): + bb.build.exec_func("do_clean", d) +} + + addtask fetch do_fetch[dirs] = "${DL_DIR}" -do_fetch[nostamp] = "1" +do_fetch[depends] = "shasum-native:do_populate_staging" python base_do_fetch() { import sys @@ -328,6 +639,9 @@ python base_do_fetch() { except bb.fetch.NoMethodError: (type, value, traceback) = sys.exc_info() raise bb.build.FuncFailed("No method: %s" % value) + except bb.MalformedUrl: + (type, value, traceback) = sys.exc_info() + raise bb.build.FuncFailed("Malformed URL: %s" % value) try: bb.fetch.go(localdata) @@ -337,10 +651,110 @@ python base_do_fetch() { except bb.fetch.FetchError: (type, value, traceback) = sys.exc_info() raise bb.build.FuncFailed("Fetch failed: %s" % value) + except bb.fetch.MD5SumError: + (type, value, traceback) = sys.exc_info() + raise bb.build.FuncFailed("MD5 failed: %s" % value) + except: + (type, value, traceback) = sys.exc_info() + raise bb.build.FuncFailed("Unknown fetch Error: %s" % value) + + + # Verify the SHA and MD5 sums we have in OE and check what do + # in + checksum_paths = bb.data.getVar('BBPATH', d, True).split(":") + + # reverse the list to give precedence to directories that + # appear first in BBPATH + checksum_paths.reverse() + + checksum_files = ["%s/conf/checksums.ini" % path for path in checksum_paths] + try: + parser = base_chk_load_parser(checksum_files) + except ValueError: + bb.note("No conf/checksums.ini found, not checking checksums") + return + except: + bb.note("Creating the CheckSum parser failed: %s:%s" % (sys.exc_info()[0], sys.exc_info()[1])) + return + + pv = bb.data.getVar('PV', d, True) + pn = bb.data.getVar('PN', d, True) + + # Check each URI + for url in src_uri.split(): + localpath = bb.data.expand(bb.fetch.localpath(url, localdata), localdata) + (type,host,path,_,_,params) = bb.decodeurl(url) + uri = "%s://%s%s" % (type,host,path) + try: + if type in [ "http", "https", "ftp", "ftps" ]: + if not (base_chk_file_vars(parser, localpath, params, d) or base_chk_file(parser, pn, pv,uri, localpath, d)): + if not bb.data.getVar("OE_ALLOW_INSECURE_DOWNLOADS", d, True): + bb.fatal("%s-%s: %s has no checksum defined, cannot check archive integrity" % (pn,pv,uri)) + else: + bb.note("%s-%s: %s has no checksum defined, archive integrity not checked" % (pn,pv,uri)) + except Exception: + raise bb.build.FuncFailed("Checksum of '%s' failed" % uri) +} + +addtask fetchall after do_fetch +do_fetchall[recrdeptask] = "do_fetch" +base_do_fetchall() { + : +} + +addtask checkuri +do_checkuri[nostamp] = "1" +python do_checkuri() { + import sys + + localdata = bb.data.createCopy(d) + bb.data.update_data(localdata) + + src_uri = bb.data.getVar('SRC_URI', localdata, 1) + + try: + bb.fetch.init(src_uri.split(),d) + except bb.fetch.NoMethodError: + (type, value, traceback) = sys.exc_info() + raise bb.build.FuncFailed("No method: %s" % value) + + try: + bb.fetch.checkstatus(localdata) + except bb.fetch.MissingParameterError: + (type, value, traceback) = sys.exc_info() + raise bb.build.FuncFailed("Missing parameters: %s" % value) + except bb.fetch.FetchError: + (type, value, traceback) = sys.exc_info() + raise bb.build.FuncFailed("Fetch failed: %s" % value) + except bb.fetch.MD5SumError: + (type, value, traceback) = sys.exc_info() + raise bb.build.FuncFailed("MD5 failed: %s" % value) + except: + (type, value, traceback) = sys.exc_info() + raise bb.build.FuncFailed("Unknown fetch Error: %s" % value) +} + +addtask checkuriall after do_checkuri +do_checkuriall[recrdeptask] = "do_checkuri" +do_checkuriall[nostamp] = "1" +base_do_checkuriall() { + : +} + +addtask buildall after do_build +do_buildall[recrdeptask] = "do_build" +base_do_buildall() { + : } +def subprocess_setup(): + import signal + # Python installs a SIGPIPE handler by default. This is usually not what + # non-Python subprocesses expect. + signal.signal(signal.SIGPIPE, signal.SIG_DFL) + def oe_unpack_file(file, data, url = None): - import bb, os + import subprocess if not url: url = "file://%s" % file dots = file.split(".") @@ -351,27 +765,34 @@ def oe_unpack_file(file, data, url = None): cmd = None if file.endswith('.tar'): cmd = 'tar x --no-same-owner -f %s' % file - elif file.endswith('.tgz') or file.endswith('.tar.gz'): + elif file.endswith('.tgz') or file.endswith('.tar.gz') or file.endswith('.tar.Z'): cmd = 'tar xz --no-same-owner -f %s' % file - elif file.endswith('.tbz') or file.endswith('.tar.bz2'): + elif file.endswith('.tbz') or file.endswith('.tbz2') or file.endswith('.tar.bz2'): cmd = 'bzip2 -dc %s | tar x --no-same-owner -f -' % file elif file.endswith('.gz') or file.endswith('.Z') or file.endswith('.z'): cmd = 'gzip -dc %s > %s' % (file, efile) elif file.endswith('.bz2'): cmd = 'bzip2 -dc %s > %s' % (file, efile) - elif file.endswith('.zip'): - cmd = 'unzip -q %s' % file + elif file.endswith('.zip') or file.endswith('.jar'): + cmd = 'unzip -q -o' + (type, host, path, user, pswd, parm) = bb.decodeurl(url) + if 'dos' in parm: + cmd = '%s -a' % cmd + cmd = '%s %s' % (cmd, file) elif os.path.isdir(file): - filesdir = os.path.realpath(bb.data.getVar("FILESDIR", data, 1)) destdir = "." - if file[0:len(filesdir)] == filesdir: - destdir = file[len(filesdir):file.rfind('/')] - destdir = destdir.strip('/') - if len(destdir) < 1: - destdir = "." - elif not os.access("%s/%s" % (os.getcwd(), destdir), os.F_OK): - os.makedirs("%s/%s" % (os.getcwd(), destdir)) - cmd = 'cp -a %s %s/%s/' % (file, os.getcwd(), destdir) + filespath = bb.data.getVar("FILESPATH", data, 1).split(":") + for fp in filespath: + if file[0:len(fp)] == fp: + destdir = file[len(fp):file.rfind('/')] + destdir = destdir.strip('/') + if len(destdir) < 1: + destdir = "." + elif not os.access("%s/%s" % (os.getcwd(), destdir), os.F_OK): + os.makedirs("%s/%s" % (os.getcwd(), destdir)) + break + + cmd = 'cp -pPR %s %s/%s/' % (file, os.getcwd(), destdir) else: (type, host, path, user, pswd, parm) = bb.decodeurl(url) if not 'patch' in parm: @@ -383,17 +804,35 @@ def oe_unpack_file(file, data, url = None): destdir = "." bb.mkdirhier("%s/%s" % (os.getcwd(), destdir)) cmd = 'cp %s %s/%s/' % (file, os.getcwd(), destdir) + if not cmd: return True + + dest = os.path.join(os.getcwd(), os.path.basename(file)) + if os.path.exists(dest): + if os.path.samefile(file, dest): + return True + + # Change to subdir before executing command + save_cwd = os.getcwd(); + parm = bb.decodeurl(url)[5] + if 'subdir' in parm: + newdir = ("%s/%s" % (os.getcwd(), parm['subdir'])) + bb.mkdirhier(newdir) + os.chdir(newdir) + cmd = "PATH=\"%s\" %s" % (bb.data.getVar('PATH', data, 1), cmd) - bb.note("Unpacking %s to %s/" % (file, os.getcwd())) - ret = os.system(cmd) + bb.note("Unpacking %s to %s/" % (base_path_out(file, data), base_path_out(os.getcwd(), data))) + ret = subprocess.call(cmd, preexec_fn=subprocess_setup, shell=True) + + os.chdir(save_cwd) + return ret == 0 addtask unpack after do_fetch do_unpack[dirs] = "${WORKDIR}" python base_do_unpack() { - import re, os + import re localdata = bb.data.createCopy(d) bb.data.update_data(localdata) @@ -406,103 +845,121 @@ python base_do_unpack() { try: local = bb.data.expand(bb.fetch.localpath(url, localdata), localdata) except bb.MalformedUrl, e: - raise FuncFailed('Unable to generate local path for malformed uri: %s' % e) - # dont need any parameters for extraction, strip them off - local = re.sub(';.*$', '', local) + raise bb.build.FuncFailed('Unable to generate local path for malformed uri: %s' % e) + if not local: + raise bb.build.FuncFailed('Unable to locate local file for %s' % url) local = os.path.realpath(local) ret = oe_unpack_file(local, localdata, url) if not ret: raise bb.build.FuncFailed() } -addtask patch after do_unpack -do_patch[dirs] = "${WORKDIR}" -python base_do_patch() { - import re - import bb.fetch - - src_uri = (bb.data.getVar('SRC_URI', d, 1) or '').split() - if not src_uri: - return - - patchcleancmd = bb.data.getVar('PATCHCLEANCMD', d, 1) - if patchcleancmd: - bb.data.setVar("do_patchcleancmd", patchcleancmd, d) - bb.data.setVarFlag("do_patchcleancmd", "func", 1, d) - bb.build.exec_func("do_patchcleancmd", d) +METADATA_SCM = "${@base_get_scm(d)}" +METADATA_REVISION = "${@base_get_scm_revision(d)}" +METADATA_BRANCH = "${@base_get_scm_branch(d)}" + +def base_get_scm(d): + from bb import which + baserepo = os.path.dirname(os.path.dirname(which(d.getVar("BBPATH", 1), "classes/base.bbclass"))) + for (scm, scmpath) in {"svn": ".svn", + "git": ".git", + "monotone": "_MTN"}.iteritems(): + if os.path.exists(os.path.join(baserepo, scmpath)): + return "%s %s" % (scm, baserepo) + return "<unknown> %s" % baserepo + +def base_get_scm_revision(d): + (scm, path) = d.getVar("METADATA_SCM", 1).split() + try: + if scm != "<unknown>": + return globals()["base_get_metadata_%s_revision" % scm](path, d) + else: + return scm + except KeyError: + return "<unknown>" - workdir = bb.data.getVar('WORKDIR', d, 1) - for url in src_uri: +def base_get_scm_branch(d): + (scm, path) = d.getVar("METADATA_SCM", 1).split() + try: + if scm != "<unknown>": + return globals()["base_get_metadata_%s_branch" % scm](path, d) + else: + return scm + except KeyError: + return "<unknown>" - (type, host, path, user, pswd, parm) = bb.decodeurl(url) - if not "patch" in parm: - continue +def base_get_metadata_monotone_branch(path, d): + monotone_branch = "<unknown>" + try: + monotone_branch = file( "%s/_MTN/options" % path ).read().strip() + if monotone_branch.startswith( "database" ): + monotone_branch_words = monotone_branch.split() + monotone_branch = monotone_branch_words[ monotone_branch_words.index( "branch" )+1][1:-1] + except: + pass + return monotone_branch - bb.fetch.init([url], d) - url = bb.encodeurl((type, host, path, user, pswd, [])) - local = os.path.join('/', bb.fetch.localpath(url, d)) +def base_get_metadata_monotone_revision(path, d): + monotone_revision = "<unknown>" + try: + monotone_revision = file( "%s/_MTN/revision" % path ).read().strip() + if monotone_revision.startswith( "format_version" ): + monotone_revision_words = monotone_revision.split() + monotone_revision = monotone_revision_words[ monotone_revision_words.index( "old_revision" )+1][1:-1] + except IOError: + pass + return monotone_revision - # did it need to be unpacked? - dots = os.path.basename(local).split(".") - if dots[-1] in ['gz', 'bz2', 'Z']: - unpacked = os.path.join(bb.data.getVar('WORKDIR', d),'.'.join(dots[0:-1])) - else: - unpacked = local - unpacked = bb.data.expand(unpacked, d) +def base_get_metadata_svn_revision(path, d): + revision = "<unknown>" + try: + revision = file( "%s/.svn/entries" % path ).readlines()[3].strip() + except IOError: + pass + return revision - if "pnum" in parm: - pnum = parm["pnum"] - else: - pnum = "1" +def base_get_metadata_git_branch(path, d): + branch = os.popen('cd %s; PATH=%s git symbolic-ref HEAD 2>/dev/null' % (path, d.getVar("PATH", 1))).read().rstrip() - if "pname" in parm: - pname = parm["pname"] - else: - pname = os.path.basename(unpacked) + if len(branch) != 0: + return branch.replace("refs/heads/", "") + return "<unknown>" - bb.note("Applying patch '%s'" % pname) - bb.data.setVar("do_patchcmd", bb.data.getVar("PATCHCMD", d, 1) % (pnum, pname, unpacked), d) - bb.data.setVarFlag("do_patchcmd", "func", 1, d) - bb.data.setVarFlag("do_patchcmd", "dirs", "${WORKDIR} ${S}", d) - bb.build.exec_func("do_patchcmd", d) -} +def base_get_metadata_git_revision(path, d): + rev = os.popen("cd %s; PATH=%s git show-ref HEAD 2>/dev/null" % (path, d.getVar("PATH", 1))).read().split(" ")[0].rstrip() + if len(rev) != 0: + return rev + return "<unknown>" addhandler base_eventhandler python base_eventhandler() { from bb import note, error, data from bb.event import Handled, NotHandled, getName - import os - messages = {} - messages["Completed"] = "completed" - messages["Succeeded"] = "completed" - messages["Started"] = "started" - messages["Failed"] = "failed" name = getName(e) - msg = "" - if name.startswith("Pkg"): - msg += "package %s: " % data.getVar("P", e.data, 1) - msg += messages.get(name[3:]) or name[3:] - elif name.startswith("Task"): - msg += "package %s: task %s: " % (data.getVar("PF", e.data, 1), e.task) - msg += messages.get(name[4:]) or name[4:] - elif name.startswith("Build"): - msg += "build %s: " % e.name - msg += messages.get(name[5:]) or name[5:] + if name == "TaskCompleted": + msg = "package %s: task %s is complete." % (data.getVar("PF", e.data, 1), e.task) elif name == "UnsatisfiedDep": - msg += "package %s: dependency %s %s" % (e.pkg, e.dep, name[:-3].lower()) - note(msg) + msg = "package %s: dependency %s %s" % (e.pkg, e.dep, name[:-3].lower()) + else: + return NotHandled + + # Only need to output when using 1.8 or lower, the UI code handles it + # otherwise + if (int(bb.__version__.split(".")[0]) <= 1 and int(bb.__version__.split(".")[1]) <= 8): + if msg: + note(msg) if name.startswith("BuildStarted"): - statusvars = ['TARGET_ARCH', 'TARGET_OS', 'MACHINE', 'DISTRO', - 'TARGET_FPU'] - statuslines = ["%-13s = \"%s\"" % (i, bb.data.getVar(i, e.data, 1) or '') for i in statusvars] - statusmsg = "\nOE Build Configuration:\n%s\n" % '\n'.join(statuslines) + bb.data.setVar( 'BB_VERSION', bb.__version__, e.data ) + statusvars = bb.data.getVar("BUILDCFG_VARS", e.data, 1).split() + statuslines = ["%-17s = \"%s\"" % (i, bb.data.getVar(i, e.data, 1) or '') for i in statusvars] + statusmsg = "\n%s\n%s\n" % (bb.data.getVar("BUILDCFG_HEADER", e.data, 1), "\n".join(statuslines)) print statusmsg - needed_vars = [ "TARGET_ARCH", "TARGET_OS" ] + needed_vars = bb.data.getVar("BUILDCFG_NEEDEDVARS", e.data, 1).split() pesteruser = [] for v in needed_vars: val = bb.data.getVar(v, e.data, 1) @@ -511,6 +968,18 @@ python base_eventhandler() { if pesteruser: bb.fatal('The following variable(s) were not set: %s\nPlease set them directly, or choose a MACHINE or DISTRO that sets them.' % ', '.join(pesteruser)) + # + # Handle removing stamps for 'rebuild' task + # + if name.startswith("StampUpdate"): + for (fn, task) in e.targets: + #print "%s %s" % (task, fn) + if task == "do_rebuild": + dir = "%s.*" % e.stampPrefix[fn] + bb.note("Removing stamps: " + dir) + os.system('rm -f '+ dir) + os.system('touch ' + e.stampPrefix[fn] + '.needclean') + if not data in e.__dict__: return NotHandled @@ -525,14 +994,13 @@ python base_eventhandler() { addtask configure after do_unpack do_patch do_configure[dirs] = "${S} ${B}" -do_configure[bbdepcmd] = "do_populate_staging" +do_configure[deptask] = "do_populate_staging" base_do_configure() { : } addtask compile after do_configure do_compile[dirs] = "${S} ${B}" -do_compile[bbdepcmd] = "do_populate_staging" base_do_compile() { if [ -e Makefile -o -e makefile ]; then oe_runmake || die "make failed" @@ -542,52 +1010,160 @@ base_do_compile() { } -addtask stage after do_compile -base_do_stage () { - : +sysroot_stage_dir() { + src="$1" + dest="$2" + # This will remove empty directories so we can ignore them + rmdir "$src" 2> /dev/null || true + if [ -d "$src" ]; then + mkdir -p "$dest" + cp -fpPR "$src"/* "$dest" + fi +} + +sysroot_stage_libdir() { + src="$1" + dest="$2" + + olddir=`pwd` + cd $src + las=$(find . -name \*.la -type f) + cd $olddir + echo "Found la files: $las" + for i in $las + do + sed -e 's/^installed=yes$/installed=no/' \ + -e '/^dependency_libs=/s,${WORKDIR}[[:alnum:]/\._+-]*/\([[:alnum:]\._+-]*\),${STAGING_LIBDIR}/\1,g' \ + -e "/^dependency_libs=/s,\([[:space:]']\)${libdir},\1${STAGING_LIBDIR},g" \ + -i $src/$i + done + sysroot_stage_dir $src $dest +} + +sysroot_stage_dirs() { + from="$1" + to="$2" + + sysroot_stage_dir $from${includedir} $to${STAGING_INCDIR} + if [ "${BUILD_SYS}" = "${HOST_SYS}" ]; then + sysroot_stage_dir $from${bindir} $to${STAGING_DIR_HOST}${bindir} + sysroot_stage_dir $from${sbindir} $to${STAGING_DIR_HOST}${sbindir} + sysroot_stage_dir $from${base_bindir} $to${STAGING_DIR_HOST}${base_bindir} + sysroot_stage_dir $from${base_sbindir} $to${STAGING_DIR_HOST}${base_sbindir} + sysroot_stage_dir $from${libexecdir} $to${STAGING_DIR_HOST}${libexecdir} + if [ "${prefix}/lib" != "${libdir}" ]; then + # python puts its files in here, make sure they are staged as well + autotools_stage_dir $from/${prefix}/lib $to${STAGING_DIR_HOST}${prefix}/lib + fi + fi + if [ -d $from${libdir} ] + then + sysroot_stage_libdir $from/${libdir} $to${STAGING_LIBDIR} + fi + if [ -d $from${base_libdir} ] + then + sysroot_stage_libdir $from${base_libdir} $to${STAGING_DIR_HOST}${base_libdir} + fi + sysroot_stage_dir $from${datadir} $to${STAGING_DATADIR} } -do_populate_staging[dirs] = "${STAGING_DIR}/${TARGET_SYS}/bin ${STAGING_DIR}/${TARGET_SYS}/lib \ - ${STAGING_DIR}/${TARGET_SYS}/include \ - ${STAGING_DIR}/${BUILD_SYS}/bin ${STAGING_DIR}/${BUILD_SYS}/lib \ - ${STAGING_DIR}/${BUILD_SYS}/include \ +sysroot_stage_all() { + sysroot_stage_dirs ${D} ${SYSROOT_DESTDIR} +} + +def is_legacy_staging(d): + stagefunc = bb.data.getVar('do_stage', d, True) + legacy = True + if stagefunc is None: + legacy = False + elif stagefunc.strip() == "autotools_stage_all": + legacy = False + elif stagefunc.strip() == "do_stage_native" and bb.data.getVar('AUTOTOOLS_NATIVE_STAGE_INSTALL', d, 1) == "1": + legacy = False + elif bb.data.getVar('NATIVE_INSTALL_WORKS', d, 1) == "1": + legacy = False + if bb.data.getVar('PSTAGE_BROKEN_DESTDIR', d, 1) == "1": + legacy = True + if bb.data.getVar('FORCE_LEGACY_STAGING', d, 1) == "1": + legacy = True + return legacy + +do_populate_staging[dirs] = "${STAGING_DIR_TARGET}/${bindir} ${STAGING_DIR_TARGET}/${libdir} \ + ${STAGING_DIR_TARGET}/${includedir} \ + ${STAGING_BINDIR_NATIVE} ${STAGING_LIBDIR_NATIVE} \ + ${STAGING_INCDIR_NATIVE} \ ${STAGING_DATADIR} \ ${S} ${B}" -addtask populate_staging after do_compile +# Could be compile but populate_staging and do_install shouldn't run at the same time +addtask populate_staging after do_install + +SYSROOT_PREPROCESS_FUNCS ?= "" +SYSROOT_DESTDIR = "${WORKDIR}/sysroot-destdir/" +SYSROOT_LOCK = "${STAGING_DIR}/staging.lock" -#python do_populate_staging () { -# if not bb.data.getVar('manifest', d): -# bb.build.exec_func('do_emit_manifest', d) -# if bb.data.getVar('do_stage', d): -# bb.build.exec_func('do_stage', d) -# else: -# bb.build.exec_func('manifest_do_populate_staging', d) -#} +python populate_staging_prehook () { + return +} + +python populate_staging_posthook () { + return +} + +packagedstaging_fastpath () { + : +} python do_populate_staging () { - if bb.data.getVar('manifest_do_populate_staging', d): - bb.build.exec_func('manifest_do_populate_staging', d) - else: - bb.build.exec_func('do_stage', d) + # + # if do_stage exists, we're legacy. In that case run the do_stage, + # modify the SYSROOT_DESTDIR variable and then run the staging preprocess + # functions against staging directly. + # |
