diff options
Diffstat (limited to 'classes')
152 files changed, 9131 insertions, 2255 deletions
diff --git a/classes/.mtn2git_empty b/classes/.mtn2git_empty deleted file mode 100644 index e69de29bb2..0000000000 --- a/classes/.mtn2git_empty +++ /dev/null diff --git a/classes/angstrom-mirrors.bbclass b/classes/angstrom-mirrors.bbclass new file mode 100644 index 0000000000..10bf75044f --- /dev/null +++ b/classes/angstrom-mirrors.bbclass @@ -0,0 +1,4 @@ +MIRRORS_append () { +ftp://.*/.* http://www.angstrom-distribution.org/unstable/sources/ +https?$://.*/.* http://www.angstrom-distribution.org/unstable/sources/ +} diff --git a/classes/angstrom.bbclass b/classes/angstrom.bbclass new file mode 100644 index 0000000000..4a810a638a --- /dev/null +++ b/classes/angstrom.bbclass @@ -0,0 +1,19 @@ +# anonymous support class for angstrom +# +# Features: +# +# * blacklist handling, set ANGSTROM_BLACKLIST_pn-blah = "message" +# + +python () { + import bb + + blacklist = bb.data.getVar("ANGSTROM_BLACKLIST", d, 1) + pkgnm = bb.data.getVar("PN", d, 1) + + if blacklist: + bb.note("Angstrom DOES NOT support %s because %s" % (pkgnm, blacklist)) + raise bb.parse.SkipPackage("Angstrom DOES NOT support %s because %s" % (pkgnm, blacklist)) + +} + diff --git a/classes/autotools.bbclass b/classes/autotools.bbclass index 927e3432b7..1ea4b6f1d0 100644 --- a/classes/autotools.bbclass +++ b/classes/autotools.bbclass @@ -1,8 +1,7 @@ -inherit base +# use autotools_stage_all for native packages +AUTOTOOLS_NATIVE_STAGE_INSTALL = "1" def autotools_dep_prepend(d): - import bb; - if bb.data.getVar('INHIBIT_AUTOTOOLS_DEPS', d, 1): return '' @@ -15,16 +14,24 @@ def autotools_dep_prepend(d): if not pn in ['libtool', 'libtool-native', 'libtool-cross']: deps += 'libtool-native ' + if not bb.data.inherits_class('native', d) \ + and not bb.data.inherits_class('cross', d) \ + and not bb.data.inherits_class('sdk', d) \ + and not bb.data.getVar('INHIBIT_DEFAULT_DEPS', d, 1): + deps += 'libtool-cross ' return deps + 'gnu-config-native ' EXTRA_OEMAKE = "" + DEPENDS_prepend = "${@autotools_dep_prepend(d)}" +DEPENDS_virtclass-native_prepend = "${@autotools_dep_prepend(d)}" +DEPENDS_virtclass-nativesdk_prepend = "${@autotools_dep_prepend(d)}" + acpaths = "default" EXTRA_AUTORECONF = "--exclude=autopoint" def autotools_set_crosscompiling(d): - import bb if not bb.data.inherits_class('native', d): return " cross_compiling=yes" return "" @@ -93,9 +100,9 @@ autotools_do_configure() { AUTOV=`automake --version |head -n 1 |sed "s/.* //;s/\.[0-9]\+$//"` automake --version echo "AUTOV is $AUTOV" - install -d ${STAGING_DIR}/${HOST_SYS}/share/aclocal - install -d ${STAGING_DIR}/${HOST_SYS}/share/aclocal-$AUTOV - acpaths="$acpaths -I ${STAGING_DIR}/${HOST_SYS}/share/aclocal-$AUTOV -I ${STAGING_DIR}/${HOST_SYS}/share/aclocal" + install -d ${STAGING_DATADIR}/aclocal + install -d ${STAGING_DATADIR}/aclocal-$AUTOV + acpaths="$acpaths -I${STAGING_DATADIR}/aclocal-$AUTOV -I ${STAGING_DATADIR}/aclocal" # autoreconf is too shy to overwrite aclocal.m4 if it doesn't look # like it was auto-generated. Work around this by blowing it away # by hand, unless the package specifically asked not to run aclocal. @@ -107,7 +114,7 @@ autotools_do_configure() { else CONFIGURE_AC=configure.ac fi - if grep "^AM_GLIB_GNU_GETTEXT" $CONFIGURE_AC >/dev/null; then + if grep "^[[:space:]]*AM_GLIB_GNU_GETTEXT" $CONFIGURE_AC >/dev/null; then if grep "sed.*POTFILES" $CONFIGURE_AC >/dev/null; then : do nothing -- we still have an old unmodified configure.ac else @@ -115,19 +122,19 @@ autotools_do_configure() { echo "no" | glib-gettextize --force --copy fi fi - if grep "^AC_PROG_INTLTOOL" $CONFIGURE_AC >/dev/null; then + mkdir -p m4 + if grep "^[[:space:]]*[AI][CT]_PROG_INTLTOOL" $CONFIGURE_AC >/dev/null; then oenote Executing intltoolize --copy --force --automake intltoolize --copy --force --automake fi oenote Executing autoreconf --verbose --install --force ${EXTRA_AUTORECONF} $acpaths - mkdir -p m4 autoreconf -Wcross --verbose --install --force ${EXTRA_AUTORECONF} $acpaths || oefatal "autoreconf execution failed." cd $olddir fi ;; esac if [ -e ${S}/configure ]; then - oe_runconf + oe_runconf $@ else oenote "nothing to configure" fi @@ -137,6 +144,22 @@ autotools_do_install() { oe_runmake 'DESTDIR=${D}' install } +PACKAGE_PREPROCESS_FUNCS += "autotools_prepackage_lamangler" + +autotools_prepackage_lamangler () { + for i in `find ${PKGD} -name "*.la"` ; do \ + sed -i -e '/^dependency_libs=/s,${WORKDIR}[[:alnum:]/\._+-]*/\([[:alnum:]\._+-]*\),${libdir}/\1,g' $i + sed -i -e s:${CROSS_DIR}/${HOST_SYS}::g $i + sed -i -e s:${CROSS_DIR}::g $i + sed -i -e s:${STAGING_LIBDIR}:${libdir}:g $i + sed -i -e s:${STAGING_DIR_HOST}::g $i + sed -i -e s:${STAGING_DIR}::g $i + sed -i -e s:${S}::g $i + sed -i -e s:${T}::g $i + sed -i -e s:${D}::g $i + done +} + STAGE_TEMP="${WORKDIR}/temp-staging" autotools_stage_includes() { @@ -150,6 +173,14 @@ autotools_stage_includes() { fi } +autotools_stage_dir() { + sysroot_stage_dir $1 ${STAGE_TEMP_PREFIX}$2 +} + +autotools_stage_libdir() { + sysroot_stage_libdir $1 ${STAGE_TEMP_PREFIX}$2 +} + autotools_stage_all() { if [ "${INHIBIT_AUTO_STAGE}" = "1" ] then @@ -158,25 +189,11 @@ autotools_stage_all() { rm -rf ${STAGE_TEMP} mkdir -p ${STAGE_TEMP} oe_runmake DESTDIR="${STAGE_TEMP}" install - if [ -d ${STAGE_TEMP}/${includedir} ]; then - cp -fpPR ${STAGE_TEMP}/${includedir}/* ${STAGING_INCDIR} - fi - if [ -d ${STAGE_TEMP}/${libdir} ] - then - for i in ${STAGE_TEMP}/${libdir}/*.la - do - if [ ! -f "$i" ]; then - cp -fpPR ${STAGE_TEMP}/${libdir}/* ${STAGING_LIBDIR} - break - fi - oe_libinstall -so $(basename $i .la) ${STAGING_LIBDIR} - done - fi - if [ -d ${STAGE_TEMP}/${datadir}/aclocal ]; then - install -d ${STAGING_DATADIR}/aclocal - cp -fpPR ${STAGE_TEMP}/${datadir}/aclocal/* ${STAGING_DATADIR}/aclocal - fi + rm -rf ${STAGE_TEMP}/${mandir} || true + rm -rf ${STAGE_TEMP}/${infodir} || true + sysroot_stage_dirs ${STAGE_TEMP} ${STAGE_TEMP_PREFIX} rm -rf ${STAGE_TEMP} } EXPORT_FUNCTIONS do_configure do_install + diff --git a/classes/autotools_stage.bbclass b/classes/autotools_stage.bbclass new file mode 100644 index 0000000000..ff0f4cd880 --- /dev/null +++ b/classes/autotools_stage.bbclass @@ -0,0 +1,5 @@ +inherit autotools + +do_stage () { + autotools_stage_all +} diff --git a/classes/base.bbclass b/classes/base.bbclass index a9b61d26b1..e6cfeccc46 100644 --- a/classes/base.bbclass +++ b/classes/base.bbclass @@ -1,23 +1,190 @@ -BB_DEFAULT_TASK = "build" +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("PATCHTOOL", d, 1) - if patchdeps: - patchdeps = "%s-native" % patchdeps - if 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)): @@ -25,7 +192,6 @@ def base_dep_prepend(d): return deps def base_read_file(filename): - import bb try: f = file( filename, "r" ) except IOError, reason: @@ -34,41 +200,70 @@ def base_read_file(filename): 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_contains(variable, checkvalue, truevalue, falsevalue, d): - import bb - if bb.data.getVar(variable,d,1).find(checkvalue) != -1: - 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): - import bb 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)) return ":".join(filespath) -FILESPATH = "${@base_set_filespath([ "${FILE_DIRNAME}/${PF}", "${FILE_DIRNAME}/${P}", "${FILE_DIRNAME}/${PN}", "${FILE_DIRNAME}/files", "${FILE_DIRNAME}" ], d)}" - def oe_filter(f, str, d): from re import match return " ".join(filter(lambda x: match(f, x, 0), str.split())) @@ -187,7 +382,16 @@ oe_libinstall() { 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 + 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 @@ -195,10 +399,14 @@ oe_libinstall() { lafile=$libname.la # If such file doesn't exist, try to cut version suffix - if [ ! -f "$lafile" ]; then - libname=`echo "$libname" | sed 's/-[0-9.]*$//'` - lafile=$libname.la - fi + 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 @@ -219,7 +427,10 @@ oe_libinstall() { # 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' $dotlai >$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 @@ -261,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 @@ -291,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() { @@ -318,44 +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) } -addtask rebuild +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" -do_rebuild[bbdepcmd] = "" python base_do_rebuild() { """rebuild a package""" - bb.build.exec_task('do_clean', d) - bb.build.exec_task('do_' + bb.data.getVar('BB_DEFAULT_TASK', d, 1), d) } 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[depends] = "shasum-native:do_populate_staging" python base_do_fetch() { import sys @@ -371,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) @@ -380,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(".") @@ -396,28 +767,31 @@ def oe_unpack_file(file, data, url = None): cmd = 'tar x --no-same-owner -f %s' % file 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' + 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)) + 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) @@ -439,15 +813,26 @@ def oe_unpack_file(file, data, url = None): 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) @@ -460,63 +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() } +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>" + +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>" + +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 + +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 + +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 + +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 len(branch) != 0: + return branch.replace("refs/heads/", "") + return "<unknown>" + +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()) - if msg: - 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"): bb.data.setVar( 'BB_VERSION', bb.__version__, e.data ) - path_to_bbfiles = bb.data.getVar( 'BBFILES', e.data, 1 ) - path_to_packages = path_to_bbfiles[:path_to_bbfiles.rindex( "packages" )] - monotone_revision = "<unknown>" - try: - monotone_revision = file( "%s/_MTN/revision" % path_to_packages ).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 - bb.data.setVar( 'OE_REVISION', monotone_revision, e.data ) - statusvars = ['BB_VERSION', 'OE_REVISION', 'TARGET_ARCH', 'TARGET_OS', 'MACHINE', 'DISTRO', 'DISTRO_VERSION','TARGET_FPU'] - statuslines = ["%-14s = \"%s\"" % (i, bb.data.getVar(i, e.data, 1) or '') for i in statusvars] - statusmsg = "\nOE Build Configuration:\n%s\n" % '\n'.join(statuslines) + 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) @@ -525,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 @@ -539,7 +994,6 @@ 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() { : @@ -547,7 +1001,6 @@ 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" @@ -557,26 +1010,155 @@ 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} +} + +sysroot_stage_all() { + sysroot_stage_dirs ${D} ${SYSROOT_DESTDIR} } -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 \ +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_package +# 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 populate_staging_prehook () { + return +} + +python populate_staging_posthook () { + return +} + +packagedstaging_fastpath () { + : +} python do_populate_staging () { - 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. + # + # Otherwise setup a destdir, copy the results from do_install + # and run the staging preprocess against that + # + pstageactive = (bb.data.getVar("PSTAGING_ACTIVE", d, True) == "1") + lockfile = bb.data.getVar("SYSROOT_LOCK", d, True) + stagefunc = bb.data.getVar('do_stage', d, True) + legacy = is_legacy_staging(d) + if legacy: + bb.data.setVar("SYSROOT_DESTDIR", "", d) + bb.note("Legacy staging mode for %s" % bb.data.getVar("FILE", d, True)) + if bb.data.getVarFlags('do_stage', d) is None: + bb.fatal("This recipe (%s) has a do_stage_prepend or do_stage_append and do_stage now doesn't exist. Please rename this to do_stage()" % bb.data.getVar("FILE", d, True)) + lock = bb.utils.lockfile(lockfile) + bb.build.exec_func('populate_staging_prehook', d) + bb.build.exec_func('do_stage', d) + for f in (bb.data.getVar('SYSROOT_PREPROCESS_FUNCS', d, True) or '').split(): + bb.build.exec_func(f, d) + bb.build.exec_func('populate_staging_posthook', d) + bb.utils.unlockfile(lock) + else: + dest = bb.data.getVar('D', d, True) + sysrootdest = bb.data.expand('${SYSROOT_DESTDIR}${STAGING_DIR_TARGET}', d) + bb.mkdirhier(sysrootdest) + + bb.build.exec_func("sysroot_stage_all", d) + #os.system('cp -pPR %s/* %s/' % (dest, sysrootdest)) + for f in (bb.data.getVar('SYSROOT_PREPROCESS_FUNCS', d, True) or '').split(): + bb.build.exec_func(f, d) + bb.build.exec_func("packagedstaging_fastpath", d) + + lock = bb.utils.lockfile(lockfile) + os.system(bb.data.expand('cp -pPR ${SYSROOT_DESTDIR}${TMPDIR}/* ${TMPDIR}/', d)) + bb.utils.unlockfile(lock) } -addtask install after do_compile +addtask install after do_compile do_install[dirs] = "${D} ${S} ${B}" +# Remove and re-create ${D} so that is it guaranteed to be empty +do_install[cleandirs] = "${D}" base_do_install() { : @@ -590,12 +1172,11 @@ addtask build after do_populate_staging do_build = "" do_build[func] = "1" +inherit packagedata + # Functions that update metadata based on files outputted # during the build process. -SHLIBS = "" -RDEPENDS_prepend = " ${SHLIBS}" - def explode_deps(s): r = [] l = s.split() @@ -613,135 +1194,127 @@ def explode_deps(s): r.append(i) return r -python read_shlibdeps () { - packages = (bb.data.getVar('PACKAGES', d, 1) or "").split() - for pkg in packages: - rdepends = explode_deps(bb.data.getVar('RDEPENDS_' + pkg, d, 0) or bb.data.getVar('RDEPENDS', d, 0) or "") - shlibsfile = bb.data.expand("${WORKDIR}/install/" + pkg + ".shlibdeps", d) - if os.access(shlibsfile, os.R_OK): - fd = file(shlibsfile) - lines = fd.readlines() - fd.close() - for l in lines: - rdepends.append(l.rstrip()) - pcfile = bb.data.expand("${WORKDIR}/install/" + pkg + ".pcdeps", d) - if os.access(pcfile, os.R_OK): - fd = file(pcfile) - lines = fd.readlines() - fd.close() - for l in lines: - rdepends.append(l.rstrip()) - bb.data.setVar('RDEPENDS_' + pkg, " " + " ".join(rdepends), d) -} - -def read_pkgdatafile(fn): - pkgdata = {} - - def decode(str): - import codecs - c = codecs.getdecoder("string_escape") - return c(str)[0] - - import os - if os.access(fn, os.R_OK): - import re - f = file(fn, 'r') - lines = f.readlines() - f.close() - r = re.compile("([^:]+):\s*(.*)") - for l in lines: - m = r.match(l) - if m: - pkgdata[m.group(1)] = decode(m.group(2)) - - return pkgdata - -def has_subpkgdata(pkg, d): - import bb, os - fn = bb.data.expand('${STAGING_DIR}/pkgdata/runtime/%s' % pkg, d) - return os.access(fn, os.R_OK) - -def read_subpkgdata(pkg, d): - import bb, os - fn = bb.data.expand('${STAGING_DIR}/pkgdata/runtime/%s' % pkg, d) - return read_pkgdatafile(fn) - - -def has_pkgdata(pn, d): - import bb, os - fn = bb.data.expand('${STAGING_DIR}/pkgdata/%s' % pn, d) - return os.access(fn, os.R_OK) - -def read_pkgdata(pn, d): - import bb, os - fn = bb.data.expand('${STAGING_DIR}/pkgdata/%s' % pn, d) - return read_pkgdatafile(fn) - -python read_subpackage_metadata () { - import bb - data = read_pkgdata(bb.data.getVar('PN', d, 1), d) - - for key in data.keys(): - bb.data.setVar(key, data[key], d) - - for pkg in bb.data.getVar('PACKAGES', d, 1).split(): - sdata = read_subpkgdata(pkg, d) - for key in sdata.keys(): - bb.data.setVar(key, sdata[key], d) -} - -python __anonymous () { - import exceptions - need_host = bb.data.getVar('COMPATIBLE_HOST', d, 1) - if need_host: - import re - this_host = bb.data.getVar('HOST_SYS', d, 1) - if not re.match(need_host, this_host): - raise bb.parse.SkipPackage("incompatible with host %s" % this_host) - - need_machine = bb.data.getVar('COMPATIBLE_MACHINE', d, 1) - if need_machine: - import re - this_machine = bb.data.getVar('MACHINE', d, 1) - if this_machine and not re.match(need_machine, this_machine): - raise bb.parse.SkipPackage("incompatible with machine %s" % this_machine) - - pn = bb.data.getVar('PN', d, 1) - - srcdate = bb.data.getVar('SRCDATE_%s' % pn, d, 1) - if srcdate != None: - bb.data.setVar('SRCDATE', srcdate, d) - - use_nls = bb.data.getVar('USE_NLS_%s' % pn, d, 1) - if use_nls != None: - bb.data.setVar('USE_NLS', use_nls, d) -} +# Make sure MACHINE isn't exported +# (breaks binutils at least) +MACHINE[unexport] = "1" + +# Make sure TARGET_ARCH isn't exported +# (breaks Makefiles using implicit rules, e.g. quilt, as GNU make has this +# in them, undocumented) +TARGET_ARCH[unexport] = "1" + +# Make sure DISTRO isn't exported +# (breaks sysvinit at least) +DISTRO[unexport] = "1" + + +def base_after_parse(d): + import exceptions + + source_mirror_fetch = bb.data.getVar('SOURCE_MIRROR_FETCH', d, 0) + if not source_mirror_fetch: + need_host = bb.data.getVar('COMPATIBLE_HOST', d, 1) + if need_host: + import re + this_host = bb.data.getVar('HOST_SYS', d, 1) + if not re.match(need_host, this_host): + raise bb.parse.SkipPackage("incompatible with host %s" % this_host) + + need_machine = bb.data.getVar('COMPATIBLE_MACHINE', d, 1) + if need_machine: + import re + this_machine = bb.data.getVar('MACHINE', d, 1) + if this_machine and not re.match(need_machine, this_machine): + raise bb.parse.SkipPackage("incompatible with machine %s" % this_machine) + + pn = bb.data.getVar('PN', d, 1) + + # OBSOLETE in bitbake 1.7.4 + srcdate = bb.data.getVar('SRCDATE_%s' % pn, d, 1) + if srcdate != None: + bb.data.setVar('SRCDATE', srcdate, d) + + use_nls = bb.data.getVar('USE_NLS_%s' % pn, d, 1) + if use_nls != None: + bb.data.setVar('USE_NLS', use_nls, d) + + # Git packages should DEPEND on git-native + srcuri = bb.data.getVar('SRC_URI', d, 1) + if "git://" in srcuri: + depends = bb.data.getVarFlag('do_fetch', 'depends', d) or "" + depends = depends + " git-native:do_populate_staging" + bb.data.setVarFlag('do_fetch', 'depends', depends, d) + + # 'multimachine' handling + mach_arch = bb.data.getVar('MACHINE_ARCH', d, 1) + pkg_arch = bb.data.getVar('PACKAGE_ARCH', d, 1) + + if (pkg_arch == mach_arch): + # Already machine specific - nothing further to do + return + + # + # We always try to scan SRC_URI for urls with machine overrides + # unless the package sets SRC_URI_OVERRIDES_PACKAGE_ARCH=0 + # + override = bb.data.getVar('SRC_URI_OVERRIDES_PACKAGE_ARCH', d, 1) + if override != '0': + paths = [] + for p in [ "${PF}", "${P}", "${PN}", "files", "" ]: + path = bb.data.expand(os.path.join("${FILE_DIRNAME}", p, "${MACHINE}"), d) + if os.path.isdir(path): + paths.append(path) + if len(paths) != 0: + for s in srcuri.split(): + if not s.startswith("file://"): + continue + local = bb.data.expand(bb.fetch.localpath(s, d), d) + for mp in paths: + if local.startswith(mp): + #bb.note("overriding PACKAGE_ARCH from %s to %s" % (pkg_arch, mach_arch)) + bb.data.setVar('PACKAGE_ARCH', "${MACHINE_ARCH}", d) + bb.data.setVar('MULTIMACH_ARCH', mach_arch, d) + return + + multiarch = pkg_arch + + packages = bb.data.getVar('PACKAGES', d, 1).split() + for pkg in packages: + pkgarch = bb.data.getVar("PACKAGE_ARCH_%s" % pkg, d, 1) + + # We could look for != PACKAGE_ARCH here but how to choose + # if multiple differences are present? + # Look through PACKAGE_ARCHS for the priority order? + if pkgarch and pkgarch == mach_arch: + multiarch = mach_arch + break + + bb.data.setVar('MULTIMACH_ARCH', multiarch, d) python () { - import bb, os - mach_arch = bb.data.getVar('MACHINE_ARCH', d, 1) - old_arch = bb.data.getVar('PACKAGE_ARCH', d, 1) - if (old_arch == mach_arch): - # Nothing to do - return - if (bb.data.getVar('SRC_URI_OVERRIDES_PACKAGE_ARCH', d, 1) == '0'): - return - paths = [] - for p in [ "${FILE_DIRNAME}/${PF}", "${FILE_DIRNAME}/${P}", "${FILE_DIRNAME}/${PN}", "${FILE_DIRNAME}/files", "${FILE_DIRNAME}" ]: - paths.append(bb.data.expand(os.path.join(p, mach_arch), d)) - for s in bb.data.getVar('SRC_URI', d, 1).split(): - local = bb.data.expand(bb.fetch.localpath(s, d), d) - for mp in paths: - if local.startswith(mp): -# bb.note("overriding PACKAGE_ARCH from %s to %s" % (old_arch, mach_arch)) - bb.data.setVar('PACKAGE_ARCH', mach_arch, d) - return + base_after_parse(d) + if is_legacy_staging(d): + bb.debug(1, "Legacy staging mode for %s" % bb.data.getVar("FILE", d, True)) + if bb.data.getVarFlags('do_stage', d) is None: + bb.error("This recipe (%s) has a do_stage_prepend or do_stage_append and do_stage now doesn't exist. Please rename this to do_stage()" % bb.data.getVar("FILE", d, True)) + } +def check_app_exists(app, d): + from bb import which, data + + app = data.expand(app, d) + path = data.getVar('PATH', d, 1) + return len(which(path, app)) != 0 + # Patch handling inherit patch -EXPORT_FUNCTIONS do_clean do_mrproper do_fetch do_unpack do_configure do_compile do_install do_package do_populate_pkgs do_stage do_rebuild +# Configuration data from site files +# Move to autotools.bbclass? +inherit siteinfo + +EXPORT_FUNCTIONS do_setscene do_clean do_mrproper do_distclean do_fetch do_unpack do_configure do_compile do_install do_package do_populate_pkgs do_rebuild do_fetchall MIRRORS[func] = "0" MIRRORS () { @@ -764,16 +1337,15 @@ ${DEBIAN_MIRROR} ftp://ftp.es.debian.org/debian/pool ${DEBIAN_MIRROR} ftp://ftp.se.debian.org/debian/pool ${DEBIAN_MIRROR} ftp://ftp.tr.debian.org/debian/pool ${GNU_MIRROR} ftp://mirrors.kernel.org/gnu -${GNU_MIRROR} ftp://ftp.matrix.com.br/pub/gnu ${GNU_MIRROR} ftp://ftp.cs.ubc.ca/mirror2/gnu ${GNU_MIRROR} ftp://sunsite.ust.hk/pub/gnu ${GNU_MIRROR} ftp://ftp.ayamura.org/pub/gnu -ftp://ftp.kernel.org/pub http://www.kernel.org/pub -ftp://ftp.kernel.org/pub ftp://ftp.us.kernel.org/pub -ftp://ftp.kernel.org/pub ftp://ftp.uk.kernel.org/pub -ftp://ftp.kernel.org/pub ftp://ftp.hk.kernel.org/pub -ftp://ftp.kernel.org/pub ftp://ftp.au.kernel.org/pub -ftp://ftp.kernel.org/pub ftp://ftp.jp.kernel.org/pub +${KERNELORG_MIRROR} http://www.kernel.org/pub +${KERNELORG_MIRROR} ftp://ftp.us.kernel.org/pub +${KERNELORG_MIRROR} ftp://ftp.uk.kernel.org/pub +${KERNELORG_MIRROR} ftp://ftp.hk.kernel.org/pub +${KERNELORG_MIRROR} ftp://ftp.au.kernel.org/pub +${KERNELORG_MIRROR} ftp://ftp.jp.kernel.org/pub ftp://ftp.gnupg.org/gcrypt/ ftp://ftp.franken.de/pub/crypt/mirror/ftp.gnupg.org/gcrypt/ ftp://ftp.gnupg.org/gcrypt/ ftp://ftp.surfnet.nl/pub/security/gnupg/ ftp://ftp.gnupg.org/gcrypt/ http://gulus.USherbrooke.ca/pub/appl/GnuPG/ @@ -785,10 +1357,23 @@ ftp://ftp.gnutls.org/pub/gnutls ftp://ftp.gnupg.org/gcrypt/gnutls/ ftp://ftp.gnutls.org/pub/gnutls http://www.mirrors.wiretapped.net/security/network-security/gnutls/ ftp://ftp.gnutls.org/pub/gnutls ftp://ftp.mirrors.wiretapped.net/pub/security/network-security/gnutls/ ftp://ftp.gnutls.org/pub/gnutls http://josefsson.org/gnutls/releases/ +http://ftp.info-zip.org/pub/infozip/src/ http://mirror.switch.ch/ftp/mirror/infozip/src/ +http://ftp.info-zip.org/pub/infozip/src/ ftp://sunsite.icm.edu.pl/pub/unix/archiving/info-zip/src/ +ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/ ftp://ftp.cerias.purdue.edu/pub/tools/unix/sysutils/lsof/ +ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/ ftp://ftp.tau.ac.il/pub/unix/admin/ +ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/ ftp://ftp.cert.dfn.de/pub/tools/admin/lsof/ +ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/ ftp://ftp.fu-berlin.de/pub/unix/tools/lsof/ +ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/ ftp://ftp.kaizo.org/pub/lsof/ +ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/ ftp://ftp.tu-darmstadt.de/pub/sysadmin/lsof/ +ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/ ftp://ftp.tux.org/pub/sites/vic.cc.purdue.edu/tools/unix/lsof/ +ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/ ftp://gd.tuwien.ac.at/utils/admin-tools/lsof/ +ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/ ftp://sunsite.ualberta.ca/pub/Mirror/lsof/ +ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/ ftp://the.wiretapped.net/pub/security/host-security/lsof/ +http://www.apache.org/dist http://archive.apache.org/dist +ftp://.*/.* http://mirrors.openembedded.org/ +https?$://.*/.* http://mirrors.openembedded.org/ +ftp://.*/.* http://sources.openembedded.org/ +https?$://.*/.* http://sources.openembedded.org/ - - -ftp://.*/.*/ http://www.oesources.org/source/current/ -http://.*/.*/ http://www.oesources.org/source/current/ } diff --git a/classes/binconfig.bbclass b/classes/binconfig.bbclass index 34021845ee..b3b2236709 100644 --- a/classes/binconfig.bbclass +++ b/classes/binconfig.bbclass @@ -1,37 +1,58 @@ -inherit base +FILES_${PN}-dev += "${bindir}/*-config" # The namespaces can clash here hence the two step replace def get_binconfig_mangle(d): - import bb.data s = "-e ''" if not bb.data.inherits_class('native', d): optional_quote = r"\(\"\?\)" s += " -e 's:=%s${libdir}:=\\1OELIBDIR:;'" % optional_quote s += " -e 's:=%s${includedir}:=\\1OEINCDIR:;'" % optional_quote s += " -e 's:=%s${datadir}:=\\1OEDATADIR:'" % optional_quote - s += " -e 's:=%s${prefix}:=\\1OEPREFIX:'" % optional_quote - s += " -e 's:=%s${exec_prefix}:=\\1OEEXECPREFIX:'" % optional_quote + s += " -e 's:=%s${prefix}/:=\\1OEPREFIX/:'" % optional_quote + s += " -e 's:=%s${exec_prefix}/:=\\1OEEXECPREFIX/:'" % optional_quote s += " -e 's:-L${libdir}:-LOELIBDIR:;'" s += " -e 's:-I${includedir}:-IOEINCDIR:;'" s += " -e 's:OELIBDIR:${STAGING_LIBDIR}:;'" s += " -e 's:OEINCDIR:${STAGING_INCDIR}:;'" s += " -e 's:OEDATADIR:${STAGING_DATADIR}:'" - s += " -e 's:OEPREFIX:${STAGING_LIBDIR}/..:'" - s += " -e 's:OEEXECPREFIX:${STAGING_LIBDIR}/..:'" + s += " -e 's:OEPREFIX:${STAGING_DIR_HOST}${prefix}:'" + s += " -e 's:OEEXECPREFIX:${STAGING_DIR_HOST}${exec_prefix}:'" + s += " -e 's:-I${WORKDIR}:-I${STAGING_INCDIR}:'" + s += " -e 's:-L${WORKDIR}:-L${STAGING_LIBDIR}:'" + if bb.data.getVar("OE_BINCONFIG_EXTRA_MANGLE", d): + s += bb.data.getVar("OE_BINCONFIG_EXTRA_MANGLE", d) return s -# Native package configurations go in ${BINDIR}/<name>-config-native to prevent a collision with cross packages -def is_native(d): - import bb.data - return ["","-native"][bb.data.inherits_class('native', d)] - BINCONFIG_GLOB ?= "*-config" -do_stage_append() { +PACKAGE_PREPROCESS_FUNCS += "binconfig_package_preprocess" + +binconfig_package_preprocess () { + for config in `find ${PKGD} -name '${BINCONFIG_GLOB}'`; do + sed -i \ + -e 's:${STAGING_LIBDIR}:${libdir}:g;' \ + -e 's:${STAGING_INCDIR}:${includedir}:g;' \ + -e 's:${STAGING_DATADIR}:${datadir}:' \ + -e 's:${STAGING_DIR_HOST}${prefix}:${prefix}:' \ + $config + done + for lafile in `find ${PKGD} -name "*.la"` ; do + sed -i \ + -e 's:${STAGING_LIBDIR}:${libdir}:g;' \ + -e 's:${STAGING_INCDIR}:${includedir}:g;' \ + -e 's:${STAGING_DATADIR}:${datadir}:' \ + -e 's:${STAGING_DIR_HOST}${prefix}:${prefix}:' \ + $lafile + done +} + +SYSROOT_PREPROCESS_FUNCS += "binconfig_sysroot_preprocess" + +binconfig_sysroot_preprocess () { for config in `find ${S} -name '${BINCONFIG_GLOB}'`; do - configname=`basename $config`${@is_native(d)} - install -d ${STAGING_BINDIR} - cat $config | sed ${@get_binconfig_mangle(d)} > ${STAGING_BINDIR}/$configname - chmod u+x ${STAGING_BINDIR}/$configname + configname=`basename $config` + install -d ${SYSROOT_DESTDIR}${STAGING_BINDIR_CROSS} + cat $config | sed ${@get_binconfig_mangle(d)} > ${SYSROOT_DESTDIR}${STAGING_BINDIR_CROSS}/$configname + chmod u+x ${SYSROOT_DESTDIR}${STAGING_BINDIR_CROSS}/$configname done } diff --git a/classes/bootimg.bbclass b/classes/bootimg.bbclass index 820749a335..d58cf1f424 100644 --- a/classes/bootimg.bbclass +++ b/classes/bootimg.bbclass @@ -12,54 +12,65 @@ # ${APPEND} - an override list of append strings for each label # ${SYSLINUX_OPTS} - additional options to add to the syslinux file ';' delimited -DEPENDS_append=" dosfstools-native syslinux-native mtools-native cdrtools-native" +do_bootimg[depends] += "dosfstools-native:do_populate_staging \ + syslinux-native:do_populate_staging \ + mtools-native:do_populate_staging \ + cdrtools-native:do_populate_staging" -BDIR="${WORKDIR}/boot" -ISODIR="${IMAGE_ROOTFS}/isolinux/" +PACKAGES = " " -BOOTIMG_VOLUME_ID ?= "oe" +HDDDIR = "${S}/hdd/boot" +ISODIR = "${S}/cd/isolinux" + +BOOTIMG_VOLUME_ID ?= "oe" BOOTIMG_EXTRA_SPACE ?= "64" # Get the build_syslinux_cfg() function from the syslinux class -SYSLINUXCFG="${BDIR}/syslinux.cfg" -SYSLINUXMENU="${BDIR}/menu" +SYSLINUXCFG = "${HDDDIR}/syslinux.cfg" +SYSLINUXMENU = "${HDDDIR}/menu" + inherit syslinux + +IMAGE_POSTPROCESS_COMMAND ?= "" build_boot_bin() { - install -d ${BDIR} - install -m 0644 ${STAGING_KERNEL_DIR}/bzImage \ - ${BDIR}/vmlinuz + install -d ${HDDDIR} + install -m 0644 ${STAGING_DIR}/${MACHINE}${HOST_VENDOR}-${HOST_OS}/kernel/bzImage \ + ${HDDDIR}/vmlinuz if [ -n "${INITRD}" ] && [ -s "${INITRD}" ]; then - install -m 0644 ${INITRD} ${BDIR}/initrd + install -m 0644 ${INITRD} ${HDDDIR}/initrd fi - install -m 444 ${STAGING_DIR}/${BUILD_SYS}/share/syslinux/ldlinux.sys \ - ${BDIR}/ldlinux.sys + install -m 444 ${STAGING_DATADIR_NATIVE}/syslinux/ldlinux.sys \ + ${HDDDIR}/ldlinux.sys # Do a little math, bash style - #BLOCKS=`du -s ${BDIR} | cut -f 1` - BLOCKS=`du -bks ${BDIR} | cut -f 1` + #BLOCKS=`du -s ${HDDDIR} | cut -f 1` + BLOCKS=`du -bks ${HDDDIR} | cut -f 1` SIZE=`expr $BLOCKS + ${BOOTIMG_EXTRA_SPACE}` - mkdosfs -F 12 -n ${BOOTIMG_VOLUME_ID} -d ${BDIR} \ - -C ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}-boot.bin $SIZE + install -d ${DEPLOY_DIR_IMAGE} - syslinux ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}-boot.bin + mkdosfs -F 12 -n ${BOOTIMG_VOLUME_ID} -d ${HDDDIR} \ + -C ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.hddimg $SIZE - #Create an ISO if we have an INITRD + syslinux ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.hddimg + chmod 644 ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.hddimg + + # Create an ISO if we have an INITRD if [ -n "${INITRD}" ] && [ -s "${INITRD}" ] && [ "${NOISO}" != "1" ] ; then install -d ${ISODIR} # Install the kernel - install -m 0644 ${STAGING_KERNEL_DIR}/bzImage \ + install -m 0644 ${STAGING_DIR}/${MACHINE}${HOST_VENDOR}-${HOST_OS}/kernel/bzImage \ ${ISODIR}/vmlinuz # Install the configuration files - cp ${BDIR}/syslinux.cfg ${ISODIR}/isolinux.cfg + cp ${HDDDIR}/syslinux.cfg ${ISODIR}/isolinux.cfg if [ -f ${SYSLINUXMENU} ]; then cp ${SYSLINUXMENU} ${ISODIR} @@ -68,21 +79,21 @@ build_boot_bin() { install -m 0644 ${INITRD} ${ISODIR}/initrd # And install the syslinux stuff - cp ${STAGING_DIR}/${BUILD_SYS}/share/syslinux/isolinux.bin \ + cp ${STAGING_DATADIR_NATIVE}/syslinux/isolinux.bin \ ${ISODIR} + ${IMAGE_POSTPROCESS_COMMAND} + mkisofs -V ${BOOTIMG_VOLUME_ID} \ -o ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.iso \ -b isolinux/isolinux.bin -c isolinux/boot.cat -r \ -no-emul-boot -boot-load-size 4 -boot-info-table \ - ${IMAGE_ROOTFS} + ${S}/cd/ fi } python do_bootimg() { - docfg = bb.data.getVar('AUTO_SYSLINUXCFG', d, 1) - if docfg: - bb.build.exec_func('build_syslinux_cfg', d) + bb.build.exec_func('build_syslinux_cfg', d) bb.build.exec_func('build_boot_bin', d) } diff --git a/classes/canadian-cross.bbclass b/classes/canadian-cross.bbclass new file mode 100644 index 0000000000..514aaeb414 --- /dev/null +++ b/classes/canadian-cross.bbclass @@ -0,0 +1,81 @@ +# +# Note this class is deprecated and replaced by cross-canadian.bbclass +# + + +# Canadian cross packages are built indirectly via dependency, +# no need for them to be a direct target of 'world' +EXCLUDE_FROM_WORLD = "1" + +inherit canadian + +PACKAGES = "" + +BASE_PACKAGE_ARCH = "${SDK_ARCH}" +BASEPKG_HOST_SYS = "${SDK_ARCH}${SDK_VENDOR}-${SDK_OS}" +BASEPKG_TARGET_SYS = "${SDK_ARCH}${SDK_VENDOR}-${SDK_OS}" + +HOST_ARCH = "${BUILD_ARCH}" +HOST_VENDOR = "${BUILD_VENDOR}" +HOST_OS = "${BUILD_OS}" +HOST_PREFIX = "${BUILD_PREFIX}" +HOST_CC_ARCH = "${BUILD_CC_ARCH}" +HOST_EXEEXT = "${BUILD_EXEEXT}" + +TARGET_ARCH = "${SDK_ARCH}" +TARGET_VENDOR = "${SDK_VENDOR}" +TARGET_OS = "${SDK_OS}" +TARGET_PREFIX = "${SDK_PREFIX}" +TARGET_CC_ARCH = "${SDK_CC_ARCH}" +TARGET_EXEEXT = "${SDK_EXEEXT}" + +CPPFLAGS = "${BUILD_CPPFLAGS}" +CFLAGS = "${BUILD_CFLAGS}" +CXXFLAGS = "${BUILD_CFLAGS}" +LDFLAGS = "${BUILD_LDFLAGS}" + +TOOLCHAIN_OPTIONS = "" + +# Architecture dependent paths +bindir = "${exec_prefix}/bin" +sbindir = "${exec_prefix}/bin" +libexecdir = "${exec_prefix}/libexec" +libdir = "${exec_prefix}/lib" +includedir = "${exec_prefix}/include" +oldincludedir = "${exec_prefix}/include" + +# Path prefixes +export base_prefix = "${STAGING_DIR_HOST}" +export prefix = "${STAGING_DIR_HOST}/usr" +export exec_prefix = "${STAGING_DIR_HOST}/usr" + +# Base paths +export base_bindir = "${STAGING_DIR_HOST}/bin" +export base_sbindir = "${STAGING_DIR_HOST}/sbin" +export base_libdir = "${STAGING_DIR_HOST}/lib" + +# Architecture independent paths +export datadir = "${STAGING_DIR_HOST}/usr/share" +export sysconfdir = "${STAGING_DIR_HOST}/etc" +export sharedstatedir = "${STAGING_DIR_HOST}/com" +export localstatedir = "${STAGING_DIR_HOST}/var" +export infodir = "${STAGING_DIR_HOST}/usr/info" +export mandir = "${STAGING_DIR_HOST}/usr/man" +export docdir = "${STAGING_DIR_HOST}/usr/doc" +export servicedir = "${STAGING_DIR_HOST}/srv" + +# Architecture dependent paths +export bindir = "${STAGING_DIR_HOST}/usr/bin" +export sbindir = "${STAGING_DIR_HOST}/usr/sbin" +export libexecdir = "${STAGING_DIR_HOST}/usr/libexec" +export libdir = "${STAGING_DIR_HOST}/usr/lib" +export includedir = "${STAGING_DIR_HOST}/usr/include" +export oldincludedir = "${STAGING_DIR_HOST}/usr/include" + +do_stage () { + oe_runmake install +} + +do_install () { + : +} diff --git a/classes/canadian-native.bbclass b/classes/canadian-native.bbclass new file mode 100644 index 0000000000..3cd003cb4b --- /dev/null +++ b/classes/canadian-native.bbclass @@ -0,0 +1,71 @@ +# +# Note this class is deprecated and replaced by nativesdk.bbclass +# + +# Canadian native packages are built indirectly via dependency, +# no need for them to be a direct target of 'world' +EXCLUDE_FROM_WORLD = "1" + +inherit canadian + +PACKAGES = "" + +BASE_PACKAGE_ARCH = "${SDK_ARCH}" +BASEPKG_HOST_SYS = "${SDK_ARCH}${SDK_VENDOR}-${SDK_OS}" +BASEPKG_TARGET_SYS = "${SDK_ARCH}${SDK_VENDOR}-${SDK_OS}" + +HOST_ARCH = "${SDK_ARCH}" +HOST_VENDOR = "${SDK_VENDOR}" +HOST_OS = "${SDK_OS}" +HOST_PREFIX = "${SDK_PREFIX}" +HOST_CC_ARCH = "${SDK_CC_ARCH}" +HOST_EXEEXT = "${SDK_EXEEXT}" + +TARGET_ARCH = "${SDK_ARCH}" +TARGET_VENDOR = "${SDK_VENDOR}" +TARGET_OS = "${SDK_OS}" +TARGET_PREFIX = "${SDK_PREFIX}" +TARGET_CC_ARCH = "${SDK_CC_ARCH}" +TARGET_EXEEXT = "${SDK_EXEEXT}" + +CPPFLAGS = "${SDK_CPPFLAGS}" +CFLAGS = "${SDK_CFLAGS}" +CXXFLAGS = "${SDK_CFLAGS}" +LDFLAGS = "${SDK_LDFLAGS}" + +# set the compiler as well. It could have been set to something else +export CC = "${CCACHE}${SDK_PREFIX}gcc ${HOST_CC_ARCH}" +export CXX = "${CCACHE}${SDK_PREFIX}g++ ${HOST_CC_ARCH}" +export F77 = "${CCACHE}${SDK_PREFIX}g77 ${HOST_CC_ARCH}" +export CPP = "${SDK_PREFIX}gcc -E" +export LD = "${SDK_PREFIX}ld" +#export CCLD = "${CC}" +export AR = "${SDK_PREFIX}ar" +export AS = "${SDK_PREFIX}as" +export RANLIB = "${SDK_PREFIX}ranlib" +export STRIP = "${SDK_PREFIX}strip" + + +# Change to place files in SDKPATH +prefix = "${SDKPATH}" +exec_prefix = "${SDKPATH}" +base_prefix = "${SDKPATH}" + +export PKG_CONFIG_DIR = "${STAGING_DIR_HOST}${libdir}/pkgconfig" +export PKG_CONFIG_SYSROOT_DIR = "${STAGING_DIR_HOST}" + +do_stage () { + if [ "${INHIBIT_NATIVE_STAGE_INSTALL}" != "1" ] + then + if [ "${AUTOTOOLS_NATIVE_STAGE_INSTALL}" != "1" ] + then + oe_runmake install + else + autotools_stage_all + fi + fi +} + +do_install () { + : +} diff --git a/classes/canadian-sdk.bbclass b/classes/canadian-sdk.bbclass new file mode 100644 index 0000000000..94db57796e --- /dev/null +++ b/classes/canadian-sdk.bbclass @@ -0,0 +1,102 @@ +# +# Note this class is deprecated and replaced by crosssdk.bbclass +# + +# Canadian SDK packages are built either explicitly by the user, +# or indirectly via dependency. No need to be in 'world'. +EXCLUDE_FROM_WORLD = "1" + +inherit canadian + +PACKAGE_ARCH = "${SDK_SYS}-sdk-${OLD_PACKAGE_ARCH}" +BASE_PACKAGE_ARCH = "${OLD_BASE_PACKAGE_ARCH}" + +HOST_ARCH = "${SDK_ARCH}" +HOST_VENDOR = "${SDK_VENDOR}" +HOST_OS = "${SDK_OS}" +HOST_PREFIX = "${SDK_PREFIX}" +HOST_CC_ARCH = "${SDK_CC_ARCH}" +HOST_EXEEXT = "${SDK_EXEEXT}" + +CPPFLAGS = "${SDK_CPPFLAGS}" +CFLAGS = "${SDK_CFLAGS}" +CXXFLAGS = "${SDK_CFLAGS}" +LDFLAGS = "${SDK_LDFLAGS}" + +DEPENDS_prepend = "virtual/${HOST_PREFIX}binutils virtual/${HOST_PREFIX}gcc " + +# On mingw systems we want to have the real sysroot default to c:/... and +# assume that the default install will be on the C drive. This can be changed +# by setting SDK_REALPATH_MINGW. +SDK_REALPATH = "${SDK_PATH}" +SDK_REALPATH_MINGW ?= "C:" + +# Path prefixes +prefix = "${SDK_PATH}" +exec_prefix = "${prefix}" +base_prefix = "${prefix}" + +# Base paths +export base_bindir = "${prefix}/bin" +export base_sbindir = "${prefix}/bin" +export base_libdir = "${prefix}/lib" + +# Architecture independent paths +export datadir = "${prefix}/share" +export sysconfdir = "${prefix}/etc" +export sharedstatedir = "${datadir}/com" +export localstatedir = "${prefix}/var" +export infodir = "${datadir}/info" +export mandir = "${datadir}/man" +export docdir = "${datadir}/doc" +export servicedir = "${prefix}/srv" + +# Architecture dependent paths +export bindir = "${prefix}/bin" +export sbindir = "${prefix}/bin" +export libexecdir = "${prefix}/libexec" +export libdir = "${prefix}/lib" +export includedir = "${prefix}/include" +export oldincludedir = "${prefix}/include" + +export dollar = "$" + +canadian_sdk_runconf() { + # modified oe_runconf() + # 1. Override prefix with SDK_REALPATH + # 2. Pass '${prefix}' to configure, to allow for prefix override + # 3. But don't do that for infodir and mandir, as they will + # break gcc makefiles for windows/dos SDK_REALPATH + if [ -x ${S}/configure ] ; then + cfgcmd="${S}/configure \ + --build=${BUILD_SYS} \ + --host=${HOST_SYS} \ + --target=${TARGET_SYS} \ + --prefix=${SDK_REALPATH} \ + --exec-prefix=$dollar{prefix} \ + --bindir=$dollar{prefix}/bin \ + --sbindir=$dollar{prefix}/bin \ + --libexecdir=$dollar{prefix}/libexec \ + --datadir=$dollar{prefix}/share \ + --sysconfdir=$dollar{prefix}/etc \ + --sharedstatedir=$dollar{prefix}/com \ + --localstatedir=$dollar{prefix}/var \ + --libdir=$dollar{prefix}/lib \ + --includedir=$dollar{prefix}/include \ + --oldincludedir=$dollar{prefix}/include \ + --infodir=${prefix}/share/info \ + --mandir=${prefix}/share/man \ + --enable-mainainer-mode \ + ${EXTRA_OECONF} \ + $@" + oenote "Running $cfgcmd..." + $cfgcmd || oefatal "oe_runconf failed" + else + oefatal "no configure script found" + fi +} + +FILES_${PN} = "${prefix}" +FILES_${PN}-dbg += "${prefix}/.debug \ + ${prefix}/bin/.debug \ + " diff --git a/classes/canadian.bbclass b/classes/canadian.bbclass new file mode 100644 index 0000000000..8edce1412c --- /dev/null +++ b/classes/canadian.bbclass @@ -0,0 +1,29 @@ +# +# Note this class is deprecated +# + + +# For Canadian SDKs we need to know what these values start out as, and use +# them as well as the updated ones. +OLD_PACKAGE_ARCH := "${PACKAGE_ARCH}" +OLD_MULTIMACH_ARCH := "${MULTIMACH_ARCH}" +OLD_TARGET_VENDOR := "${TARGET_VENDOR}" +OLD_TARGET_OS := "${TARGET_OS}" +OLD_BASE_PACKAGE_ARCH := "${BASE_PACKAGE_ARCH}" + +OLD_MULTIMACH_TARGET_SYS = "${OLD_MULTIMACH_ARCH}${OLD_TARGET_VENDOR}-${OLD_TARGET_OS}" +OLD_BASEPKG_TARGET_SYS = "${OLD_BASE_PACKAGE_ARCH}${OLD_TARGET_VENDOR}-${OLD_TARGET_OS}" + +# We want to allow for both machine-target_os-sdk_arch-sdk_os and for +# sdk_arch-sdk_os +MULTIMACH_SDK_SYS = "${OLD_MULTIMACH_TARGET_SYS}-${SDK_SYS}" +BASEPKG_SDK_SYS = "${OLD_BASEPKG_TARGET_SYS}-${SDK_SYS}" +STAGING_DIR_SDK = "${STAGING_DIR}/${MULTIMACH_SDK_SYS}" + +# Our host dir isn't the build system here, but the SDK system +STAGING_DIR_HOST = "${STAGING_DIR}/${SDK_SYS}" + +# Overrides for paths +STAGING_BINDIR_CROSS = "${STAGING_BINDIR}" + +PACKAGE_ARCH = "${SDK_ARCH}" diff --git a/classes/ccache.inc b/classes/ccache.inc index 5e9356104b..d830a1b8fe 100644 --- a/classes/ccache.inc +++ b/classes/ccache.inc @@ -5,7 +5,7 @@ CCACHE_DIR_TARGET = "${TMPDIR}/ccache" python () { - if not bb.data.inherits_class('native', d) and not bb.data.inherits_class('cross', d): - bb.data.setVar('CCACHE_DIR', '${CCACHE_DIR_TARGET}', d) - bb.data.setVarFlag('CCACHE_DIR', 'export', '1', d) + if not bb.data.inherits_class('native', d) and not bb.data.inherits_class('cross', d): + bb.data.setVar('CCACHE_DIR', '${CCACHE_DIR_TARGET}', d) + bb.data.setVarFlag('CCACHE_DIR', 'export', '1', d) } diff --git a/classes/ccdv.bbclass b/classes/ccdv.bbclass index edd151ef8c..8c8306cbf1 100644 --- a/classes/ccdv.bbclass +++ b/classes/ccdv.bbclass @@ -1,16 +1,16 @@ python () { - if bb.data.getVar('PN', d, 1) in ['ccdv-native']: - if not bb.data.getVar('INHIBIT_DEFAULT_DEPS', d, 1): - bb.data.setVar("DEPENDS", '%s %s' % ("ccdv-native", bb.data.getVar("DEPENDS", d, 1) or ""), d) - bb.data.setVar("CC", '%s %s' % ("ccdv", bb.data.getVar("CC", d, 1) or ""), d) - bb.data.setVar("BUILD_CC", '%s %s' % ("ccdv", bb.data.getVar("BUILD_CC", d, 1) or ""), d) - bb.data.setVar("CCLD", '%s %s' % ("ccdv", bb.data.getVar("CCLD", d, 1) or ""), d) + if bb.data.getVar('PN', d, 1) in ['ccdv-native']: + if not bb.data.getVar('INHIBIT_DEFAULT_DEPS', d, 1): + bb.data.setVar("DEPENDS", '%s %s' % ("ccdv-native", bb.data.getVar("DEPENDS", d, 1) or ""), d) + bb.data.setVar("CC", '%s %s' % ("ccdv", bb.data.getVar("CC", d, 1) or ""), d) + bb.data.setVar("BUILD_CC", '%s %s' % ("ccdv", bb.data.getVar("BUILD_CC", d, 1) or ""), d) + bb.data.setVar("CCLD", '%s %s' % ("ccdv", bb.data.getVar("CCLD", d, 1) or ""), d) } def quiet_libtool(bb,d): deps = (bb.data.getVar('DEPENDS', d, 1) or "").split() if 'libtool-cross' in deps: - return "'LIBTOOL=${STAGING_BINDIR}/${HOST_SYS}-libtool --silent'" + return "'LIBTOOL=${STAGING_BINDIR_NATIVE}/${HOST_SYS}-libtool --silent'" elif 'libtool-native' in deps: return "'LIBTOOL=${B}/${HOST_SYS}-libtool --silent'" else: diff --git a/classes/chicken.bbclass b/classes/chicken.bbclass new file mode 100644 index 0000000000..5ebe1ff462 --- /dev/null +++ b/classes/chicken.bbclass @@ -0,0 +1,11 @@ +def chicken_arch(bb, d): + import re + arch_pattern = re.compile('^i.*86$') + target_arch = d.getVar("TARGET_ARCH", 1) + if arch_pattern.match(target_arch): + return 'x86' + else: + return target_arch + +CHICKEN_ARCH = "${@chicken_arch(bb, d)}" + diff --git a/classes/clean.bbclass b/classes/clean.bbclass new file mode 100644 index 0000000000..65c1ab5d76 --- /dev/null +++ b/classes/clean.bbclass @@ -0,0 +1,53 @@ +def clean_builddir(d): + from shutil import rmtree + + builddir = d.getVar("B", True) + srcdir = d.getVar("S", True) + if builddir != srcdir: + rmtree(builddir, ignore_errors=True) + +def clean_stamps(d): + from glob import glob + from bb import note + from bb.data import expand + from os import unlink + + note("Removing stamps") + for stamp in glob(expand('${STAMP}.*', d)): + try: + unlink(stamp) + except OSError: + pass + +def clean_workdir(d): + from shutil import rmtree + from bb import note + + workdir = d.getVar("WORKDIR", 1) + note("Removing %s" % workdir) + rmtree(workdir, ignore_errors=True) + +def clean_git(d): + from subprocess import call + + call(["git", "clean", "-d", "-f", "-X"], cwd=d.getVar("S", True)) + +def clean_make(d): + import bb + + bb.note("Running make clean") + try: + bb.build.exec_func("__do_clean_make", d) + except bb.build.FuncFailed: + pass + +__do_clean_make () { + oe_runmake clean +} + +python do_clean () { + clean_stamps(d) + clean_workdir(d) + clean_builddir(d) + clean_make(d) +} diff --git a/classes/cmake.bbclass b/classes/cmake.bbclass new file mode 100644 index 0000000000..f21c4d6545 --- /dev/null +++ b/classes/cmake.bbclass @@ -0,0 +1,46 @@ +DEPENDS += " cmake-native " + +# We want the staging and installing functions from autotools +inherit autotools_stage + +# Use in-tree builds by default but allow this to be changed +# since some packages do not support them (e.g. llvm 2.5). +OECMAKE_SOURCEPATH ?= "." + +# If declaring this, make sure you also set EXTRA_OEMAKE to +# "-C ${OECMAKE_BUILDPATH}". So it will run the right makefiles. +OECMAKE_BUILDPATH ?= "" + +cmake_do_configure() { + if [ ${OECMAKE_BUILDPATH} ] + then + mkdir ${OECMAKE_BUILDPATH} + cd ${OECMAKE_BUILDPATH} + fi + + cmake ${OECMAKE_SOURCEPATH} \ + -DCMAKE_INSTALL_PREFIX:PATH=${prefix} \ + -DCMAKE_FIND_ROOT_PATH:PATH=${STAGING_DIR_HOST} \ + ${EXTRA_OECMAKE} \ + -Wno-dev +} + +cmake_do_compile() { + if [ ${OECMAKE_BUILDPATH} ] + then + cd ${OECMAKE_BUILDPATH} + fi + + base_do_compile +} + +cmake_do_install() { + if [ ${OECMAKE_BUILDPATH} ]; + then + cd ${OECMAKE_BUILDPATH} + fi + + autotools_do_install +} + +EXPORT_FUNCTIONS do_configure do_compile do_install diff --git a/classes/concatenated-image.bbclass b/classes/concatenated-image.bbclass new file mode 100644 index 0000000000..5cf8d33c05 --- /dev/null +++ b/classes/concatenated-image.bbclass @@ -0,0 +1,38 @@ + +# +# define the FLASH_KERNEL_SIZE and FLASH_ROOT_SIZE in your machine.conf, +# and this class builds a simple, padded concatenated image of +# <kernel><padding><rootfs> and performs error checking that either +# kernel or rootfs isn't too large to fit. +# +concat_pack_image() { + # find latest kernel - is there a more general way to do this? + KERNEL=`ls -tr ${DEPLOY_DIR_IMAGE}/${KERNEL_IMAGETYPE}* | tail -n 1` + if [ -z "$KERNEL" ]; then + oefatal "No kernel found in ${DEPLOY_DIR_IMAGE}. Was expecting a ${KERNEL_IMAGETYPE}\* file." + exit 1 + fi + ROOTFS=${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.jffs2 + OUTPUT=${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.flash.img + PADFILE=${DEPLOY_DIR_IMAGE}/padfile.zzz + KERNEL_SIZE_MAX_DEC=`echo ${FLASH_KERNEL_SIZE} | awk --non-decimal-data '{printf "%d\n", $1}' ` + ROOT_SIZE_MAX_DEC=`echo ${FLASH_ROOT_SIZE} | awk --non-decimal-data '{printf "%d\n", $1}' ` + KERNEL_SIZE=`ls -l $KERNEL | awk '{print $5}'` + if [ $KERNEL_SIZE -gt $KERNEL_SIZE_MAX_DEC ]; then + oefatal "Kernel too large at $KERNEL_SIZE bytes. Max is $KERNEL_SIZE_MAX_DEC." + exit 1 + fi + ROOT_SIZE=`ls -l $ROOTFS | awk '{print $5}'` + if [ $ROOT_SIZE -gt $ROOT_SIZE_MAX_DEC ]; then + oefatal "Rootfs is too large at $ROOT_SIZE bytes. Max is $ROOT_SIZE_MAX_DEC." + exit 1 + fi + PAD_SIZE=`echo "$KERNEL_SIZE_MAX_DEC - $KERNEL_SIZE" | bc ` + dd if=/dev/zero of=$PADFILE bs=$PAD_SIZE count=1 2>>/dev/null + cat $KERNEL $PADFILE $ROOTFS > $OUTPUT + rm -f $PADFILE + ls -l $OUTPUT +} + +IMAGE_POSTPROCESS_COMMAND += "concat_pack_image; " + diff --git a/classes/corecdp-mirrors.bbclass b/classes/corecdp-mirrors.bbclass new file mode 100644 index 0000000000..0d1f0b4a7b --- /dev/null +++ b/classes/corecdp-mirrors.bbclass @@ -0,0 +1,4 @@ +MIRRORS_append () { +ftp://.*/.* http://www.multitech.net/corecdp/sources/ +https?$://.*/.* http://www.multitech.net/corecdp/sources/ +} diff --git a/classes/cpan-base.bbclass b/classes/cpan-base.bbclass new file mode 100644 index 0000000000..82fd5b459a --- /dev/null +++ b/classes/cpan-base.bbclass @@ -0,0 +1,53 @@ +# +# cpan-base providers various perl related information needed for building +# cpan modules +# +FILES_${PN} += "${libdir}/perl5 ${datadir}/perl5" + +DEPENDS += "${@["perl", "perl-native"][(bb.data.inherits_class('native', d))]}" +RDEPENDS += "${@["perl", ""][(bb.data.inherits_class('native', d))]}" + +# Determine the staged version of perl from the perl configuration file +def get_perl_version(d): + import re + cfg = bb.data.expand('${STAGING_LIBDIR}/perl/config.sh', d) + try: + f = open(cfg, 'r') + except IOError: + return None + l = f.readlines(); + f.close(); + r = re.compile("version='(\d\.\d\.\d)'") + for s in l: + m = r.match(s) + if m: + return m.group(1) + return None + +# Only 5.8.7 and 5.8.4 existed at the time we moved to the new layout +def is_new_perl(d): + ver = get_perl_version(d) + if ver == "5.8.4" or ver == "5.8.7": + return "no" + return "yes" + +# Determine where the library directories are +def perl_get_libdirs(d): + libdir = bb.data.getVar('libdir', d, 1) + if is_new_perl(d) == "yes": + libdirs = libdir + '/perl5' + else: + libdirs = libdir + '/*/*/perl5' + return libdirs + +def is_target(d): + if not bb.data.inherits_class('native', d): + return "yes" + return "no" + +IS_NEW_PERL = "${@is_new_perl(d)}" +PERLLIBDIRS = "${@perl_get_libdirs(d)}" + +FILES_${PN}-dbg += "${PERLLIBDIRS}/auto/*/.debug \ + ${PERLLIBDIRS}/auto/*/*/.debug \ + ${PERLLIBDIRS}/auto/*/*/*/.debug" diff --git a/classes/cpan.bbclass b/classes/cpan.bbclass index 74bbebf882..66054bc755 100644 --- a/classes/cpan.bbclass +++ b/classes/cpan.bbclass @@ -1,36 +1,67 @@ # # This is for perl modules that use the old Makefile.PL build system # -FILES_${PN} += '${libdir}/perl5' -EXTRA_CPANFLAGS = "" +inherit cpan-base -DEPENDS += "perl-native" -RDEPENDS += "perl" +EXTRA_CPANFLAGS ?= "" + +# Env var which tells perl if it should use host (no) or target (yes) settings +export PERLCONFIGTARGET = "${@is_target(d)}" + +# Env var which tells perl where the perl include files are +export PERL_INC = "${STAGING_LIBDIR}/perl/${@get_perl_version(d)}/CORE" +export PERL_LIB = "${STAGING_DATADIR}/perl/${@get_perl_version(d)}" +export PERL_ARCHLIB = "${STAGING_LIBDIR}/perl/${@get_perl_version(d)}" cpan_do_configure () { - perl Makefile.PL ${EXTRA_CPANFLAGS} + yes '' | perl Makefile.PL ${EXTRA_CPANFLAGS} if [ "${BUILD_SYS}" != "${HOST_SYS}" ]; then - . ${STAGING_DIR}/${TARGET_SYS}/perl/config.sh - sed -i -e "s:\(SITELIBEXP = \).*:\1${sitelibexp}:" \ - -e "s:\(SITEARCHEXP = \).*:\1${sitearchexp}:" \ - -e "s:\(INSTALLVENDORLIB = \).*:\1${D}${libdir}/perl5/site_perl/${version}:" \ - -e "s:\(INSTALLVENDORARCH = \).*:\1${D}${libdir}/perl5/site_perl/${version}:" \ - -e "s:\(LDDLFLAGS.*\)${STAGING_DIR}/${BUILD_SYS}/lib:\1${STAGING_LIBDIR}:" \ - Makefile + . ${STAGING_LIBDIR}/perl/config.sh + if [ "${IS_NEW_PERL}" = "yes" ]; then + sed -i -e "s:\(SITELIBEXP = \).*:\1${sitelibexp}:" \ + -e "s:\(SITEARCHEXP = \).*:\1${sitearchexp}:" \ + -e "s:\(INSTALLVENDORLIB = \).*:\1${D}${datadir}/perl5:" \ + -e "s:\(INSTALLVENDORARCH = \).*:\1${D}${libdir}/perl5:" \ + -e "s:\(LDDLFLAGS.*\)${STAGING_LIBDIR_NATIVE}:\1${STAGING_LIBDIR}:" \ + Makefile + else + sed -i -e "s:\(SITELIBEXP = \).*:\1${sitelibexp}:" \ + -e "s:\(SITEARCHEXP = \).*:\1${sitearchexp}:" \ + -e "s:\(INSTALLVENDORLIB = \).*:\1${D}${libdir}/perl5/site_perl/${version}:" \ + -e "s:\(INSTALLVENDORARCH = \).*:\1${D}${libdir}/perl5/site_perl/${version}:" \ + -e "s:\(LDDLFLAGS.*\)${STAGING_LIBDIR_NATIVE}:\1${STAGING_LIBDIR}:" \ + Makefile + fi fi } cpan_do_compile () { - # You must use gcc to link on sh - OPTIONS="" - if test ${TARGET_ARCH} = "sh3" -o ${TARGET_ARCH} = "sh4"; then - OPTIONS="LD=${TARGET_ARCH}-${TARGET_OS}-gcc" + if [ "${IS_NEW_PERL}" = "yes" ]; then + oe_runmake PASTHRU_INC="${CFLAGS}" CCFLAGS="${CFLAGS}" LD="${CCLD}" + else + # You must use gcc to link on sh + OPTIONS="" + if test ${TARGET_ARCH} = "sh3" -o ${TARGET_ARCH} = "sh4"; then + OPTIONS="LD=${TARGET_ARCH}-${TARGET_OS}-gcc" + fi + if test ${TARGET_ARCH} = "powerpc" ; then + OPTIONS="LD=${TARGET_ARCH}-${TARGET_OS}-gcc" + fi + oe_runmake PASTHRU_INC="${CFLAGS}" CCFLAGS="${CFLAGS}" $OPTIONS fi - oe_runmake PASTHRU_INC="${CFLAGS}" CCFLAGS="${CFLAGS}" $OPTIONS } cpan_do_install () { - oe_runmake install_vendor + if [ ${@is_target(d)} = "yes" ]; then + oe_runmake install_vendor + fi +} + +cpan_do_stage () { + if [ ${@is_target(d)} = "no" ]; then + oe_runmake install_vendor + fi } + -EXPORT_FUNCTIONS do_configure do_compile do_install +EXPORT_FUNCTIONS do_configure do_compile do_install do_stage diff --git a/classes/cpan_build.bbclass b/classes/cpan_build.bbclass index 0660ef9b82..b2ec8255de 100644 --- a/classes/cpan_build.bbclass +++ b/classes/cpan_build.bbclass @@ -1,20 +1,17 @@ # # This is for perl modules that use the new Build.PL build system # -INHIBIT_NATIVE_STAGE_INSTALL = "1" -FILES_${PN} += '${libdir}/perl5' +inherit cpan-base -DEPENDS += "perl-native" -RDEPENDS += "perl" +INHIBIT_NATIVE_STAGE_INSTALL = "1" # # We also need to have built libmodule-build-perl-native for # everything except libmodule-build-perl-native itself (which uses -# this class, but uses itself as the probider of +# this class, but uses itself as the provider of # libmodule-build-perl) # def cpan_build_dep_prepend(d): - import bb; if bb.data.getVar('CPAN_BUILD_DEPS', d, 1): return '' pn = bb.data.getVar('PN', d, 1) @@ -24,24 +21,29 @@ def cpan_build_dep_prepend(d): DEPENDS_prepend = "${@cpan_build_dep_prepend(d)}" -def is_crosscompiling(d): - import bb - if not bb.data.inherits_class('native', d): - return "yes" - return "no" - cpan_build_do_configure () { - if [ ${@is_crosscompiling(d)} == "yes" ]; then + if [ ${@is_target(d)} == "yes" ]; then # build for target - . ${STAGING_DIR}/${TARGET_SYS}/perl/config.sh - perl Build.PL --installdirs vendor \ - --destdir ${D} \ - --install_path lib="${libdir}/perl5/site_perl/${version}" \ - --install_path arch="${libdir}/perl5/site_perl/${version}/${TARGET_SYS}" \ - --install_path script=${bindir} \ - --install_path bin=${bindir} \ - --install_path bindoc=${mandir}/man1 \ - --install_path libdoc=${mandir}/man3 + . ${STAGING_LIBDIR}/perl/config.sh + if [ "${IS_NEW_PERL}" = "yes" ]; then + perl Build.PL --installdirs vendor \ + --destdir ${D} \ + --install_path lib="${datadir}/perl5" \ + --install_path arch="${libdir}/perl5" \ + --install_path script=${bindir} \ + --install_path bin=${bindir} \ + --install_path bindoc=${mandir}/man1 \ + --install_path libdoc=${mandir}/man3 + else + perl Build.PL --installdirs vendor \ + --destdir ${D} \ + --install_path lib="${libdir}/perl5/site_perl/${version}" \ + --install_path arch="${libdir}/perl5/site_perl/${version}/${TARGET_SYS}" \ + --install_path script=${bindir} \ + --install_path bin=${bindir} \ + --install_path bindoc=${mandir}/man1 \ + --install_path libdoc=${mandir}/man3 + fi else # build for host perl Build.PL --installdirs site @@ -53,13 +55,13 @@ cpan_build_do_compile () { } cpan_build_do_install () { - if [ ${@is_crosscompiling(d)} == "yes" ]; then + if [ ${@is_target(d)} == "yes" ]; then perl Build install fi } do_stage_append () { - if [ ${@is_crosscompiling(d)} == "no" ]; then + if [ ${@is_target(d)} == "no" ]; then perl Build install fi } diff --git a/classes/cross-canadian.bbclass b/classes/cross-canadian.bbclass new file mode 100644 index 0000000000..bd738ecd4d --- /dev/null +++ b/classes/cross-canadian.bbclass @@ -0,0 +1,46 @@ +# SDK packages are built either explicitly by the user, +# or indirectly via dependency. No need to be in 'world'. +EXCLUDE_FROM_WORLD = "1" + +# Save MULTIMACH_ARCH +OLD_MULTIMACH_ARCH := "${MULTIMACH_ARCH}" +# Save PACKAGE_ARCH +OLD_PACKAGE_ARCH := ${PACKAGE_ARCH} +PACKAGE_ARCH = "${SDK_ARCH}-${TARGET_ARCH}-canadian" +PACKAGE_ARCHS = "${PACKAGE_ARCH}" +# Also save BASE_PACKAGE_ARCH since HOST_ARCH can influence it +OLD_BASE_PACKAGE_ARCH := "${BASE_PACKAGE_ARCH}" +BASE_PACKAGE_ARCH = "${OLD_BASE_PACKAGE_ARCH}" + +INHIBIT_DEFAULT_DEPS = "1" + +STAGING_DIR_HOST = "${STAGING_DIR}/${HOST_SYS}-nativesdk" +STAGING_DIR_TARGET = "${STAGING_DIR}/${BASEPKG_TARGET_SYS}" + +PATH_append = ":${TMPDIR}/cross/${HOST_ARCH}/${bindir_cross}" +PKGDATA_DIR = "${TMPDIR}/pkgdata/${HOST_ARCH}-nativesdk${HOST_VENDOR}-${HOST_OS}" + +HOST_ARCH = "${SDK_ARCH}" +HOST_VENDOR = "${SDK_VENDOR}" +HOST_OS = "${SDK_OS}" +HOST_PREFIX = "${SDK_PREFIX}" +HOST_CC_ARCH = "${SDK_CC_ARCH}" + +CPPFLAGS = "${BUILDSDK_CPPFLAGS}" +CFLAGS = "${BUILDSDK_CFLAGS}" +CXXFLAGS = "${BUILDSDK_CFLAGS}" +LDFLAGS = "${BUILDSDK_LDFLAGS}" + +# Change to place files in SDKPATH +prefix = "${SDKPATH}" +exec_prefix = "${SDKPATH}" +base_prefix = "${SDKPATH}" + +FILES_${PN} = "${prefix}" +FILES_${PN}-dbg += "${prefix}/.debug \ + ${prefix}/bin/.debug \ + " + +export PKG_CONFIG_DIR = "${STAGING_DIR_HOST}${layout_libdir}/pkgconfig" +export PKG_CONFIG_SYSROOT_DIR = "${STAGING_DIR_HOST}" + diff --git a/classes/cross.bbclass b/classes/cross.bbclass index 09357acbe8..1de157c0f5 100644 --- a/classes/cross.bbclass +++ b/classes/cross.bbclass @@ -2,6 +2,13 @@ # no need for them to be a direct target of 'world' EXCLUDE_FROM_WORLD = "1" +# Save PACKAGE_ARCH before changing HOST_ARCH +OLD_PACKAGE_ARCH := "${PACKAGE_ARCH}" +PACKAGE_ARCH = "${OLD_PACKAGE_ARCH}" +# Also save BASE_PACKAGE_ARCH since HOST_ARCH can influence it +OLD_BASE_PACKAGE_ARCH := "${BASE_PACKAGE_ARCH}" +BASE_PACKAGE_ARCH = "${OLD_BASE_PACKAGE_ARCH}" + PACKAGES = "" HOST_ARCH = "${BUILD_ARCH}" @@ -9,42 +16,23 @@ HOST_VENDOR = "${BUILD_VENDOR}" HOST_OS = "${BUILD_OS}" HOST_PREFIX = "${BUILD_PREFIX}" HOST_CC_ARCH = "${BUILD_CC_ARCH}" +HOST_EXEEXT = "${BUILD_EXEEXT}" +BASEPKG_HOST_SYS = "${HOST_ARCH}${HOST_VENDOR}-${HOST_OS}" CPPFLAGS = "${BUILD_CPPFLAGS}" CFLAGS = "${BUILD_CFLAGS}" CXXFLAGS = "${BUILD_CFLAGS}" LDFLAGS = "${BUILD_LDFLAGS}" -LDFLAGS_build-darwin = "-L${STAGING_DIR}/${BUILD_SYS}/lib " +LDFLAGS_build-darwin = "-L${STAGING_LIBDIR_NATIVE}" -# Overrides for paths +TOOLCHAIN_OPTIONS = "" -# Path prefixes -base_prefix = "${exec_prefix}" +# Overrides for paths prefix = "${CROSS_DIR}" +base_prefix = "${prefix}" exec_prefix = "${prefix}" - -# Base paths -base_bindir = "${base_prefix}/bin" base_sbindir = "${base_prefix}/bin" -base_libdir = "${base_prefix}/lib" - -# Architecture independent paths -datadir = "${prefix}/share" -sysconfdir = "${prefix}/etc" -sharedstatedir = "${prefix}/com" -localstatedir = "${prefix}/var" -infodir = "${datadir}/info" -mandir = "${datadir}/man" -docdir = "${datadir}/doc" -servicedir = "${prefix}/srv" - -# Architecture dependent paths -bindir = "${exec_prefix}/bin" sbindir = "${exec_prefix}/bin" -libexecdir = "${exec_prefix}/libexec" -libdir = "${exec_prefix}/lib" -includedir = "${exec_prefix}/include" -oldincludedir = "${exec_prefix}/include" do_stage () { oe_runmake install diff --git a/classes/crosssdk.bbclass b/classes/crosssdk.bbclass new file mode 100644 index 0000000000..0b1af8fc2f --- /dev/null +++ b/classes/crosssdk.bbclass @@ -0,0 +1,15 @@ +inherit cross + +PACKAGES = "" + +BASE_PACKAGE_ARCH = "${SDK_ARCH}" +PACKAGE_ARCH = "${BASE_PACKAGE_ARCH}" +STAGING_DIR_TARGET = "${STAGING_DIR}/${SDK_ARCH}-nativesdk${SDK_VENDOR}-${SDK_OS}" + +TARGET_ARCH = "${SDK_ARCH}" +TARGET_VENDOR = "${SDK_VENDOR}" +TARGET_OS = "${SDK_OS}" +TARGET_PREFIX = "${SDK_PREFIX}" +TARGET_CC_ARCH = "${SDK_CC_ARCH}" + + diff --git a/classes/debian.bbclass b/classes/debian.bbclass index 698d917b51..8f6e7d88cf 100644 --- a/classes/debian.bbclass +++ b/classes/debian.bbclass @@ -1,19 +1,22 @@ -STAGING_PKGMAPS_DIR = "${STAGING_DIR}/pkgmaps/debian" - -# Debain package renaming only occurs when a package is built +# Debian package renaming only occurs when a package is built # We therefore have to make sure we build all runtime packages # before building the current package to make the packages runtime # depends are correct -BUILD_ALL_DEPS = "1" - +# +# Custom library package names can be defined setting +# DEBIANNAME_ + pkgname to the desired name. +# # Better expressed as ensure all RDEPENDS package before we package # This means we can't have circular RDEPENDS/RRECOMMENDS -do_package[rdeptask] = "do_package" +do_package_write_ipk[rdeptask] = "do_package" +do_package_write_deb[rdeptask] = "do_package" +do_package_write_tar[rdeptask] = "do_package" +do_package_write_rpm[rdeptask] = "do_package" python debian_package_name_hook () { import glob, copy, stat, errno, re - workdir = bb.data.getVar('WORKDIR', d, 1) + pkgdest = bb.data.getVar('PKGDEST', d, 1) packages = bb.data.getVar('PACKAGES', d, 1) def socrunch(s): @@ -42,7 +45,7 @@ python debian_package_name_hook () { sonames = [] has_bins = 0 has_libs = 0 - pkg_dir = os.path.join(workdir, "install", orig_pkg) + pkg_dir = os.path.join(pkgdest, orig_pkg) for root, dirs, files in os.walk(pkg_dir): if bin_re.match(root) and files: has_bins = 1 @@ -88,7 +91,10 @@ python debian_package_name_hook () { for pkg in packages.split(): if (bb.data.getVar('PKG_' + pkg, d) or bb.data.getVar('DEBIAN_NOAUTONAME_' + pkg, d)): continue - if pkg == orig_pkg: + debian_pn = bb.data.getVar('DEBIANNAME_' + pkg, d) + if debian_pn: + newpkg = debian_pn + elif pkg == orig_pkg: newpkg = pkgname else: newpkg = pkg.replace(orig_pkg, devname, 1) @@ -101,5 +107,5 @@ python debian_package_name_hook () { EXPORT_FUNCTIONS package_name_hook -DEBIAN_NAMES = 1 +DEBIAN_NAMES = "1" diff --git a/classes/devshell.bbclass b/classes/devshell.bbclass new file mode 100644 index 0000000000..9327b55d0a --- /dev/null +++ b/classes/devshell.bbclass @@ -0,0 +1,22 @@ +EXTRA_OEMAKE[export] = "1" + +do_devshell[dirs] = "${S}" +do_devshell[nostamp] = "1" + +export DISPLAY +export DBUS_SESSION_BUS_ADDRESS +export XAUTHORITY ?= "${HOME}/.Xauthority" + +devshell_do_devshell() { + export TERMWINDOWTITLE="Bitbake Developer Shell" + ${TERMCMD} + if [ $? -ne 0 ]; then + echo "Fatal: '${TERMCMD}' not found. Check TERMCMD variable." + exit 1 + fi +} +addtask devshell after do_patch + + +EXPORT_FUNCTIONS do_devshell + diff --git a/classes/dietlibc.bbclass b/classes/dietlibc.bbclass new file mode 100644 index 0000000000..2676385197 --- /dev/null +++ b/classes/dietlibc.bbclass @@ -0,0 +1,30 @@ +DEPENDS =+ "dietlibc" + +def dietlibc_after_parse(d): + import bb + # Remove the NLS + cfg = oe_filter_out('--(dis|en)able-nls', bb.data.getVar('EXTRA_OECONF', d, 1) or "", d) + # Remove shared enable static only + cfg += " --disable-nls --disable-shared --enable-static" + bb.data.setVar('EXTRA_OECONF', cfg, d) + cfg = bb.data.getVar('EXTRA_OEMAKE', d, 1) or "" + cfg = oe_filter_out("\'CC=", bb.data.getVar('EXTRA_OEMAKE', d, 1) or "", d) + cfgtmp = "\'CC=\"diet ${CCACHE}\"" + cfgtmp += cfg + bb.data.setVar('EXTRA_OEMAKE', cfgtmp, d) + +#python () { +# dietlibc_after_parse(d) +#} + +set_dietlibc_env () { + export CC="diet ${CC}" +} + +do_compile_prepend() { + set_dietlibc_env +} + +do_configure_prepend() { + set_dietlibc_env +} diff --git a/classes/distutils-base.bbclass b/classes/distutils-base.bbclass index 68d7112166..2e151ded38 100644 --- a/classes/distutils-base.bbclass +++ b/classes/distutils-base.bbclass @@ -1,14 +1,5 @@ -EXTRA_OEMAKE = "" DEPENDS += "${@["python-native python", ""][(bb.data.getVar('PACKAGES', d, 1) == '')]}" RDEPENDS += "python-core" -def python_dir(d): - import os, bb - staging_incdir = bb.data.getVar( "STAGING_INCDIR", d, 1 ) - if os.path.exists( "%s/python2.3" % staging_incdir ): return "python2.3" - if os.path.exists( "%s/python2.4" % staging_incdir ): return "python2.4" - raise "No Python in STAGING_INCDIR. Forgot to build python-native ?" - -PYTHON_DIR = "${@python_dir(d)}" -FILES_${PN} = "${bindir} ${libdir} ${libdir}/${PYTHON_DIR}" +inherit distutils-common-base diff --git a/classes/distutils-common-base.bbclass b/classes/distutils-common-base.bbclass new file mode 100644 index 0000000000..01bf9eaeba --- /dev/null +++ b/classes/distutils-common-base.bbclass @@ -0,0 +1,30 @@ +EXTRA_OEMAKE = "" + +export STAGING_INCDIR +export STAGING_LIBDIR + +def python_dir(d): + import os, bb + staging_incdir = bb.data.getVar( "STAGING_INCDIR", d, 1 ) + for majmin in "2.6 2.5 2.4 2.3".split(): + if os.path.exists( "%s/python%s" % ( staging_incdir, majmin ) ): return "python%s" % majmin + if not "python-native" in bb.data.getVar( "DEPENDS", d, 1 ).split(): + raise "No Python in STAGING_INCDIR. Forgot to build python-native ?" + return "INVALID" + +PYTHON_DIR = "${@python_dir(d)}" + +PACKAGES = "${PN}-dev ${PN}-dbg ${PN}-doc ${PN}" + +FILES_${PN} = "${bindir}/* ${libdir}/* ${libdir}/${PYTHON_DIR}/*" + +FILES_${PN}-dev += "\ + ${datadir}/pkgconfig \ + ${libdir}/pkgconfig \ + ${libdir}/${PYTHON_DIR}/site-packages/*.la \ +" +FILES_${PN}-dbg = "\ + ${libdir}/${PYTHON_DIR}/site-packages/.debug \ + ${libdir}/${PYTHON_DIR}/site-packages/*/.debug \ + ${libdir}/${PYTHON_DIR}/site-packages/*/*/.debug \ +" diff --git a/classes/distutils-native-base.bbclass b/classes/distutils-native-base.bbclass new file mode 100644 index 0000000000..2703fe0740 --- /dev/null +++ b/classes/distutils-native-base.bbclass @@ -0,0 +1,3 @@ +DEPENDS += "${@["python-native", ""][(bb.data.getVar('PACKAGES', d, 1) == '')]}" + +inherit distutils-common-base diff --git a/classes/distutils.bbclass b/classes/distutils.bbclass index a2b0e2b770..4d1fc8c6fc 100644 --- a/classes/distutils.bbclass +++ b/classes/distutils.bbclass @@ -1,15 +1,70 @@ inherit distutils-base +DISTUTILS_BUILD_ARGS ?= "" +DISTUTILS_STAGE_HEADERS_ARGS ?= "--install-dir=${STAGING_INCDIR}/${PYTHON_DIR}" +DISTUTILS_STAGE_ALL_ARGS ?= "--prefix=${STAGING_DIR_HOST}${prefix} \ + --install-data=${STAGING_DATADIR}" +DISTUTILS_INSTALL_ARGS ?= "--prefix=${D}/${prefix} \ + --install-data=${D}/${datadir}" + distutils_do_compile() { - BUILD_SYS=${BUILD_SYS} HOST_SYS=${HOST_SYS} \ - ${STAGING_BINDIR}/python setup.py build || \ - oefatal "python setup.py build execution failed." + STAGING_INCDIR=${STAGING_INCDIR} \ + STAGING_LIBDIR=${STAGING_LIBDIR} \ + BUILD_SYS=${BUILD_SYS} HOST_SYS=${HOST_SYS} \ + ${STAGING_BINDIR_NATIVE}/python setup.py build ${DISTUTILS_BUILD_ARGS} || \ + oefatal "python setup.py build_ext execution failed." +} + +distutils_stage_headers() { + install -d ${STAGING_DIR_HOST}${libdir}/${PYTHON_DIR}/site-packages + BUILD_SYS=${BUILD_SYS} HOST_SYS=${HOST_SYS} \ + ${STAGING_BINDIR_NATIVE}/python setup.py install_headers ${DISTUTILS_STAGE_HEADERS_ARGS} || \ + oefatal "python setup.py install_headers execution failed." +} + +distutils_stage_all() { + STAGING_INCDIR=${STAGING_INCDIR} \ + STAGING_LIBDIR=${STAGING_LIBDIR} \ + install -d ${STAGING_DIR_HOST}${libdir}/${PYTHON_DIR}/site-packages + PYTHONPATH=${STAGING_DIR_HOST}${libdir}/${PYTHON_DIR}/site-packages \ + BUILD_SYS=${BUILD_SYS} HOST_SYS=${HOST_SYS} \ + ${STAGING_BINDIR_NATIVE}/python setup.py install ${DISTUTILS_STAGE_ALL_ARGS} || \ + oefatal "python setup.py install (stage) execution failed." } distutils_do_install() { - BUILD_SYS=${BUILD_SYS} HOST_SYS=${HOST_SYS} \ - ${STAGING_BINDIR}/python setup.py install --prefix=${D}/${prefix} --install-data=${D}/${datadir} || \ - oefatal "python setup.py install execution failed." + install -d ${D}${libdir}/${PYTHON_DIR}/site-packages + STAGING_INCDIR=${STAGING_INCDIR} \ + STAGING_LIBDIR=${STAGING_LIBDIR} \ + PYTHONPATH=${D}/${libdir}/${PYTHON_DIR}/site-packages \ + BUILD_SYS=${BUILD_SYS} HOST_SYS=${HOST_SYS} \ + ${STAGING_BINDIR_NATIVE}/python setup.py install ${DISTUTILS_INSTALL_ARGS} || \ + oefatal "python setup.py install execution failed." + + for i in `find ${D} -name "*.py"` ; do \ + sed -i -e s:${D}::g $i + done + + if test -e ${D}${bindir} ; then + for i in ${D}${bindir}/* ; do \ + sed -i -e s:${STAGING_BINDIR_NATIVE}:${bindir}:g $i + done + fi + + if test -e ${D}${sbindir}; then + for i in ${D}${sbindir}/* ; do \ + sed -i -e s:${STAGING_BINDIR_NATIVE}:${bindir}:g $i + done + fi + + rm -f ${D}${libdir}/${PYTHON_DIR}/site-packages/easy-install.pth + + # + # FIXME: Bandaid against wrong datadir computation + # + if test -e ${D}${datadir}/share; then + mv -f ${D}${datadir}/share/* ${D}${datadir}/ + fi } EXPORT_FUNCTIONS do_compile do_install diff --git a/classes/dsmg600-image.bbclass b/classes/dsmg600-image.bbclass new file mode 100644 index 0000000000..16c6b6eeb0 --- /dev/null +++ b/classes/dsmg600-image.bbclass @@ -0,0 +1,19 @@ +dsmg600_pack_image () { + install -d ${DEPLOY_DIR_IMAGE}/firmupgrade + install -m 0755 ${DEPLOY_DIR_IMAGE}/zImage-nslu2${SITEINFO_ENDIANESS}.bin \ + ${DEPLOY_DIR_IMAGE}/firmupgrade/ip-ramdisk + install -m 0644 ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.jffs2 \ + ${DEPLOY_DIR_IMAGE}/firmupgrade/rootfs.gz + touch ${DEPLOY_DIR_IMAGE}/firmupgrade/usr.cramfs + chmod 0644 ${DEPLOY_DIR_IMAGE}/firmupgrade/usr.cramfs + echo "hwid=1.0.1" >${DEPLOY_DIR_IMAGE}/firmupgrade/version.msg + echo "model=dsm-g600" >>${DEPLOY_DIR_IMAGE}/firmupgrade/version.msg + echo "vendor=dlink" >>${DEPLOY_DIR_IMAGE}/firmupgrade/version.msg + echo "" >>${DEPLOY_DIR_IMAGE}/firmupgrade/version.msg + chmod 0744 ${DEPLOY_DIR_IMAGE}/firmupgrade/version.msg + tar -c -f ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}-dsmg600.bin \ + -C ${DEPLOY_DIR_IMAGE} firmupgrade + rm -rf ${DEPLOY_DIR_IMAGE}/firmupgrade +} + +IMAGE_POSTPROCESS_COMMAND += "dsmg600_pack_image; " diff --git a/classes/e.bbclass b/classes/e.bbclass index 008e3f2dc1..fca9aa0010 100644 --- a/classes/e.bbclass +++ b/classes/e.bbclass @@ -1,36 +1,29 @@ HOMEPAGE = "http://www.enlightenment.org" SECTION = "e/apps" +SRCNAME ?= "${PN}" + +SRC_URI = "svn://svn.enlightenment.org/svn/e/trunk;module=${SRCNAME};proto=http" +S = "${WORKDIR}/${SRCNAME}" + +ARM_INSTRUCTION_SET = "arm" inherit autotools pkgconfig binconfig do_prepsources () { make clean distclean || true } -addtask prepsources after do_fetch before do_unpack - -def binconfig_suffix(d): - import bb - return ["","-native"][bb.data.inherits_class('native', d)] +addtask prepsources after do_patch before do_configure -export CURL_CONFIG = "${STAGING_BINDIR}/curl-config${@binconfig_suffix(d)}" -export EDB_CONFIG = "${STAGING_BINDIR}/edb-config${@binconfig_suffix(d)}" -export EET_CONFIG = "${STAGING_BINDIR}/eet-config${@binconfig_suffix(d)}" -export EVAS_CONFIG = "${STAGING_BINDIR}/evas-config${@binconfig_suffix(d)}" -export ECORE_CONFIG = "${STAGING_BINDIR}/ecore-config${@binconfig_suffix(d)}" -export EMBRYO_CONFIG = "${STAGING_BINDIR}/embryo-config${@binconfig_suffix(d)}" -export ENGRAVE_CONFIG = "${STAGING_BINDIR}/engrave-config${@binconfig_suffix(d)}" -export ENLIGHTENMENT_CONFIG = "${STAGING_BINDIR}/enlightenment-config${@binconfig_suffix(d)}" -export EPSILON_CONFIG = "${STAGING_BINDIR}/epsilon-config${@binconfig_suffix(d)}" -export EPEG_CONFIG = "${STAGING_BINDIR}/epeg-config${@binconfig_suffix(d)}" -export ESMART_CONFIG = "${STAGING_BINDIR}/esmart-config${@binconfig_suffix(d)}" -export FREETYPE_CONFIG = "${STAGING_BINDIR}/freetype-config${@binconfig_suffix(d)}" -export IMLIB2_CONFIG = "${STAGING_BINDIR}/imlib2-config${@binconfig_suffix(d)}" - -do_compile_prepend() { - find ${S} -name Makefile | xargs sed -i 's:/usr/include:${STAGING_INCDIR}:' - find ${S} -name Makefile | xargs sed -i 's:/usr/X11R6/include:${STAGING_INCDIR}:' +do_configure_append() { + find ${S} -name Makefile | xargs sed -i s:'-I$(includedir)':'-I.':g } -PACKAGES = "${PN} ${PN}-themes" -FILES_${PN} = "${libdir}/lib*.so*" +export CURL_CONFIG = "${STAGING_BINDIR_CROSS}/curl-config" +export FREETYPE_CONFIG = "${STAGING_BINDIR_CROSS}/freetype-config" + +# This construction is stupid, someone with more E knowledge should change it to =+ or something +# And it's in efl.bbclass as well.... +PACKAGES = "${PN}-dbg ${PN}-themes ${PN} ${PN}-dev ${PN}-doc ${PN}-lib ${PN}-static" +FILES_${PN}-lib = "${libdir}/lib*.so.*" FILES_${PN}-themes = "${datadir}/${PN}/themes ${datadir}/${PN}/data ${datadir}/${PN}/fonts ${datadir}/${PN}/pointers ${datadir}/${PN}/images ${datadir}/${PN}/users ${datadir}/${PN}/images ${datadir}/${PN}/styles" +FILES_${PN}-dev += "${includedir} ${libdir}/lib*.so" diff --git a/classes/efl.bbclass b/classes/efl.bbclass index c258758d30..900d9c7f0d 100644 --- a/classes/efl.bbclass +++ b/classes/efl.bbclass @@ -1,49 +1,60 @@ -inherit e - SECTION = "e/libs" - +HOMEPAGE = "http://www.enlightenment.org" +LICENSE = "MIT BSD" SRCNAME = "${@bb.data.getVar('PN', d, 1).replace('-native', '')}" -SRC_URI = "${E_URI}/${SRCNAME}-${PV}.tar.gz" -S = "${WORKDIR}/${SRCNAME}-${PV}" +SRC_URI = "svn://svn.enlightenment.org/svn/e/trunk;module=${SRCNAME};proto=http" +S = "${WORKDIR}/${SRCNAME}" +DEPENDS += "pkgconfig-native" -INHIBIT_AUTO_STAGE_INCLUDES = "1" -INHIBIT_NATIVE_STAGE_INSTALL = "1" +# revision 0d93ec84b30bc1bee2caaee72d667f87bc468a70 made SRCDATE and hence PV go backwards, so we need to up PE to unbreak builds and feeds :( +PE = "2" -libdirectory = "src/lib" -libraries = "lib${SRCNAME}" -headers = "${@bb.data.getVar('SRCNAME',d,1).capitalize()}.h" +ARM_INSTRUCTION_SET = "arm" -do_stage_append () { - for i in ${libraries} - do - oe_libinstall -C ${libdirectory} $i ${STAGING_LIBDIR} - done - for i in ${headers} - do - install -m 0644 ${libdirectory}/$i ${STAGING_INCDIR} - done +inherit autotools - # Install binaries automatically for native builds - if [ "${@binconfig_suffix(d)}" = "-native" ] - then - - # Most EFL binaries start with the package name - for i in src/bin/${SRCNAME}* - do - if [ -x $i -a -f $i ] - then - - # Don't install anything with an extension (.so, etc) - if echo $i | grep -v \\. - then - ${HOST_SYS}-libtool --mode=install install -m 0755 $i ${STAGING_BINDIR} - fi - fi - done - fi +# evas-native looks at this var, so keep it +AUTOTOOLS_STAGE_PKGCONFIG = "1" + +do_configure_prepend() { + touch config.rpath +} + +do_install_prepend () { + for i in `find ${S}/ -name "*.pc" -type f` ; do \ + sed -i -e 's:-L${STAGING_LIBDIR}::g' -e 's:-I${STAGING_INCDIR}::g' $i + done } -PACKAGES = "${PN} ${PN}-themes ${PN}-dev ${PN}-examples" -FILES_${PN}-dev = "${bindir}/${PN}-config ${libdir}/pkgconfig ${libdir}/lib*.?a ${libdir}/lib*.a ${includedir}" -FILES_${PN}-examples = "${bindir} ${datadir}" +# This construction is stupid, someone with more E knowledge should change it to =+ or something +PACKAGES = "${PN}-dbg ${PN} ${PN}-themes ${PN}-dev ${PN}-doc ${PN}-tests ${PN}-static" + +FILES_${PN} = "${libdir}/*.so.*" + +FILES_${PN}-themes = "${datadir}/${PN}/themes \ + ${datadir}/${PN}/data \ + ${datadir}/${PN}/fonts \ + ${datadir}/${PN}/pointers \ + ${datadir}/${PN}/images \ + ${datadir}/${PN}/users \ + ${datadir}/${PN}/images \ + ${datadir}/${PN}/styles" + +FILES_${PN}-dev += "${bindir}/${PN}-config \ + ${libdir}/pkgconfig/* \ + ${libdir}/lib*.la \ + ${libdir}/*.so \ + ${libdir}/${PN}/*.la \ + ${libdir}/${PN}/*/*.la" + +FILES_${PN}-static += "${libdir}/${PN}/*.a \ + ${libdir}/${PN}/*/*.a \ +" + +FILES_${PN}-dbg += "${libdir}/${PN}/.debug \ + ${libdir}/${PN}/*/.debug" + +FILES_${PN}-tests = "${bindir}/${PN} \ + ${bindir}/*_* \ + ${datadir}" diff --git a/classes/failure-cleanup.bbclass b/classes/failure-cleanup.bbclass new file mode 100644 index 0000000000..3870c756c8 --- /dev/null +++ b/classes/failure-cleanup.bbclass @@ -0,0 +1,18 @@ +# This class clean a package on failure, a nice way to keep diskspace usage down and force rebuilds + +# we want to be an event handler +addhandler failure_eventhandler +python failure_eventhandler() { + from bb import build, event, note, error, data + from bb.event import NotHandled, getName + + if e.data is None or getName(e) == "MsgNote": + return NotHandled + + name = getName(e) + if name == "PkgFailed": + bb.note("Exectuting -c clean on failed build") + build.exec_func('do_clean', e.data) + + return NotHandled +} diff --git a/classes/flow-lossage.bbclass b/classes/flow-lossage.bbclass index 3e841e3cae..00e6bf0257 100644 --- a/classes/flow-lossage.bbclass +++ b/classes/flow-lossage.bbclass @@ -1,5 +1,5 @@ # gcc-3.4 blows up in gtktext with -frename-registers on arm-linux python () { - cflags = (bb.data.getVar('CFLAGS', d, 1) or '').replace('-frename-registers', '') - bb.data.setVar('CFLAGS', cflags, d) + cflags = (bb.data.getVar('CFLAGS', d, 1) or '').replace('-frename-registers', '') + bb.data.setVar('CFLAGS', cflags, d) } diff --git a/classes/fso-plugin.bbclass b/classes/fso-plugin.bbclass new file mode 100644 index 0000000000..d050540ef6 --- /dev/null +++ b/classes/fso-plugin.bbclass @@ -0,0 +1,4 @@ +FILES_${PN} += "${libdir}/cornucopia/modules/*/*.so" +FILES_${PN}-dev += "${libdir}/cornucopia/modules/*/*.la" +FILES_${PN}-dbg += "${libdir}/cornucopia/modules/*/.debug" + diff --git a/classes/gconf.bbclass b/classes/gconf.bbclass index 686f8e6596..f55ae2c2ae 100644 --- a/classes/gconf.bbclass +++ b/classes/gconf.bbclass @@ -1,4 +1,4 @@ -DEPENDS += "gconf" +DEPENDS += "gconf gconf-native" gconf_postinst() { if [ "$1" = configure ]; then @@ -32,10 +32,10 @@ fi python populate_packages_append () { import os.path, re packages = bb.data.getVar('PACKAGES', d, 1).split() - workdir = bb.data.getVar('WORKDIR', d, 1) + pkgdest = bb.data.getVar('PKGDEST', d, 1) for pkg in packages: - schema_dir = '%s/install/%s/etc/gconf/schemas' % (workdir, pkg) + schema_dir = '%s/%s/etc/gconf/schemas' % (pkgdest, pkg) schemas = [] schema_re = re.compile(".*\.schemas$") if os.path.exists(schema_dir): @@ -45,9 +45,10 @@ python populate_packages_append () { if schemas != []: bb.note("adding gconf postinst and prerm scripts to %s" % pkg) bb.data.setVar('SCHEMA_FILES', " ".join(schemas), d) - postinst = bb.data.getVar('pkg_postinst_%s' % pkg, d, 1) or bb.data.getVar('pkg_postinst', d, 1) - if not postinst: - postinst = '#!/bin/sh\n' + postinst = '#!/bin/sh\n' + pkgpostinst = bb.data.getVar('pkg_postinst_%s' % pkg, d, 1) or bb.data.getVar('pkg_postinst', d, 1) + if pkgpostinst: + postinst += pkgpostinst postinst += bb.data.getVar('gconf_postinst', d, 1) bb.data.setVar('pkg_postinst_%s' % pkg, postinst, d) prerm = bb.data.getVar('pkg_prerm_%s' % pkg, d, 1) or bb.data.getVar('pkg_prerm', d, 1) diff --git a/classes/gettext.bbclass b/classes/gettext.bbclass index 3785f5acd3..b2ff2849fa 100644 --- a/classes/gettext.bbclass +++ b/classes/gettext.bbclass @@ -1,11 +1,15 @@ +DEPENDS =+ "gettext-native" +def gettext_after_parse(d): + # Remove the NLS bits if USE_NLS is no. + if bb.data.getVar('USE_NLS', d, 1) == 'no': + cfg = oe_filter_out('^--(dis|en)able-nls$', bb.data.getVar('EXTRA_OECONF', d, 1) or "", d) + cfg += " --disable-nls" + depends = bb.data.getVar('DEPENDS', d, 1) or "" + bb.data.setVar('DEPENDS', oe_filter_out('^(virtual/libiconv|virtual/libintl)$', depends, d), d) + bb.data.setVar('EXTRA_OECONF', cfg, d) + python () { - # Remove the NLS bits if USE_NLS is no. - if bb.data.getVar('USE_NLS', d, 1) == 'no': - cfg = oe_filter_out('^--(dis|en)able-nls$', bb.data.getVar('EXTRA_OECONF', d, 1) or "", d) - cfg += " --disable-nls" - depends = bb.data.getVar('DEPENDS', d, 1) or "" - bb.data.setVar('DEPENDS', oe_filter_out('^(virtual/libiconv|virtual/libintl)$', depends, d), d) - bb.data.setVar('EXTRA_OECONF', cfg, d) + gettext_after_parse(d) } DEPENDS =+ "gettext-native" diff --git a/classes/gitver.bbclass b/classes/gitver.bbclass new file mode 100644 index 0000000000..5b4ba8d1e1 --- /dev/null +++ b/classes/gitver.bbclass @@ -0,0 +1,64 @@ +# Copyright (C) 2009 Chris Larson <clarson@kergoth.com> +# Released under the MIT license (see COPYING.MIT for the terms) +# +# gitver.bbclass provides a GITVER variable which is a (fairly) sane version, +# for use in ${PV}, extracted from the ${S} git checkout, assuming it is one. +# This is most useful in concert with srctree.bbclass. + + +GITVER = "${@get_git_pv('${S}', d)}" + +def get_git_pv(path, d, tagadjust=None): + from subprocess import Popen, PIPE + import os + from bb import error + from bb.parse import mark_dependency + + gitdir = os.path.abspath(os.path.join(d.getVar("S", True), ".git")) + env = { "GIT_DIR": gitdir } + + def popen(cmd, **kwargs): + kwargs["stderr"] = PIPE + kwargs["stdout"] = PIPE + kwargs["env"] = env + try: + pipe = Popen(cmd, **kwargs) + except OSError, e: + #error("Execution of %s failed: %s" % (cmd, e)) + return + + (stdout, stderr) = pipe.communicate(None) + if pipe.returncode != 0: + #error("Execution of %s failed: %s" % (cmd, stderr)) + return + return stdout.rstrip() + + # Force the recipe to be reparsed so the version gets bumped + # if the active branch is switched, or if the branch changes. + mark_dependency(d, os.path.join(gitdir, "HEAD")) + + ref = popen(["git", "symbolic-ref", "HEAD"]) + reffile = os.path.join(gitdir, ref) + if ref and os.path.exists(reffile): + mark_dependency(d, reffile) + else: + # The ref might be hidden in packed-refs. Force a reparse if anything + # in the working copy changes. + mark_dependency(d, os.path.join(gitdir, "index")) + + # Catch new tags. + tagdir = os.path.join(gitdir, "refs", "tags") + if os.path.exists(tagdir): + mark_dependency(d, tagdir) + + ver = popen(["git", "describe", "--tags"], cwd=path) + if not ver: + ver = popen(["git", "rev-parse", "--short", "HEAD"], cwd=path) + if ver: + return "0.0-%s" % ver + else: + return "0.0" + else: + if tagadjust: + ver = tagadjust(ver) + return ver diff --git a/classes/glibc-package.bbclass b/classes/glibc-package.bbclass new file mode 100644 index 0000000000..90b9bfd584 --- /dev/null +++ b/classes/glibc-package.bbclass @@ -0,0 +1,305 @@ +# +# This class knows how to package up glibc. Its shared since prebuild binary toolchains +# may need packaging and its pointless to duplicate this code. +# +# Caller should set GLIBC_INTERNAL_USE_BINARY_LOCALE to one of: +# "compile" - Use QEMU to generate the binary locale files +# "precompiled" - The binary locale files are pregenerated and already present +# "ondevice" - The device will build the locale files upon first boot through the postinst + +inherit qemu + +GLIBC_INTERNAL_USE_BINARY_LOCALE ?= "ondevice" + +PACKAGES = "glibc-dbg glibc catchsegv sln nscd ldd localedef glibc-utils glibc-dev glibc-static glibc-doc glibc-locale libcidn libmemusage libsegfault glibc-extra-nss glibc-thread-db glibc-pcprofile" +PACKAGES_DYNAMIC = "glibc-gconv-* glibc-charmap-* glibc-localedata-* locale-base-* glibc-binary-localedata-*" + +INSANE_SKIP_glibc-dbg = True + +libc_baselibs = "${base_libdir}/libcrypt*.so.* ${base_libdir}/libcrypt-*.so ${base_libdir}/libc*.so.* ${base_libdir}/libc-*.so ${base_libdir}/libm*.so.* ${base_libdir}/libm-*.so ${base_libdir}/ld*.so.* ${base_libdir}/ld-*.so ${base_libdir}/libpthread*.so.* ${base_libdir}/libpthread-*.so ${base_libdir}/libresolv*.so.* ${base_libdir}/libresolv-*.so ${base_libdir}/librt*.so.* ${base_libdir}/librt-*.so ${base_libdir}/libutil*.so.* ${base_libdir}/libutil-*.so ${base_libdir}/libnsl*.so.* ${base_libdir}/libnsl-*.so ${base_libdir}/libnss_files*.so.* ${base_libdir}/libnss_files-*.so ${base_libdir}/libnss_compat*.so.* ${base_libdir}/libnss_compat-*.so ${base_libdir}/libnss_dns*.so.* ${base_libdir}/libnss_dns-*.so ${base_libdir}/libdl*.so.* ${base_libdir}/libdl-*.so ${base_libdir}/libanl*.so.* ${base_libdir}/libanl-*.so ${base_libdir}/libBrokenLocale*.so.* ${base_libdir}/libBrokenLocale-*.so" + +# The problem is that if PN = "glibc", FILES_${PN} will overwrite FILES_glibc +# Solution: Make them both the same thing, then it doesn't matter + +glibcfiles = "${libc_baselibs} ${libexecdir}/* ${datadir}/zoneinfo ${@base_conditional('USE_LDCONFIG', '1', '${base_sbindir}/ldconfig', '', d)}" +glibcdbgfiles = "${bindir}/.debug ${sbindir}/.debug ${libdir}/.debug \ + ${base_bindir}/.debug ${base_sbindir}/.debug ${base_libdir}/.debug \ + ${libdir}/gconv/.debug ${libexecdir}/*/.debug" +glibcdevfiles = "${bindir}/rpcgen ${includedir} ${libdir}/lib*${SOLIBSDEV} ${libdir}/*.la \ + ${libdir}/*.a ${libdir}/*.o ${libdir}/pkgconfig ${libdir}/*nonshared.a \ + ${base_libdir}/*.a ${base_libdir}/*.o ${datadir}/aclocal" + +FILES_glibc = "${glibcfiles}" +FILES_${PN} = "${glibcfiles}" +FILES_ldd = "${bindir}/ldd" +FILES_libsegfault = "${base_libdir}/libSegFault*" +FILES_libcidn = "${base_libdir}/libcidn*.so" +FILES_libmemusage = "${base_libdir}/libmemusage.so" +FILES_glibc-extra-nss = "${base_libdir}/libnss*" +FILES_sln = "${base_sbindir}/sln" +FILES_glibc-dev = "${glibcdevfiles}" +FILES_${PN}-dev = "${glibcdevfiles}" +FILES_glibc-dbg = "${glibcdbgfiles}" +FILES_${PN}-dbg = "${glibcdbgfiles}" +FILES_nscd = "${sbindir}/nscd* ${sysconfdir}/nscd* ${sysconfdir}/init.d/nscd*" +FILES_glibc-utils = "${bindir}/* ${sbindir}/*" +FILES_glibc-gconv = "${libdir}/gconv/*" +FILES_catchsegv = "${bindir}/catchsegv" +RDEPENDS_catchsegv = "libsegfault" +FILES_glibc-pcprofile = "${base_libdir}/libpcprofile.so" +FILES_glibc-thread-db = "${base_libdir}/libthread_db*" +FILES_localedef = "${bindir}/localedef" +RPROVIDES_glibc-dev += "libc-dev" + +DESCRIPTION_sln = "glibc: create symbolic links between files" +DESCRIPTION_nscd = "glibc: name service cache daemon for passwd, group, and hosts" +DESCRIPTION_glibc-extra-nss = "glibc: nis, nisplus and hesiod search services" +DESCRIPTION_ldd = "glibc: print shared library dependencies" +DESCRIPTION_localedef = "glibc: compile locale definition files" +DESCRIPTION_glibc-utils = "glibc: misc utilities like iconf, local, gencat, tzselect, rpcinfo, ..." + +TMP_LOCALE="/tmp/locale${libdir}/locale" + +locale_base_postinst() { +#!/bin/sh + +if [ "x$D" != "x" ]; then + exit 1 +fi + +rm -rf ${TMP_LOCALE} +mkdir -p ${TMP_LOCALE} +if [ -f ${libdir}/locale/locale-archive ]; then + cp ${libdir}/locale/locale-archive ${TMP_LOCALE}/ +fi +localedef --inputfile=${datadir}/i18n/locales/%s --charmap=%s --prefix=/tmp/locale %s +mkdir -p ${libdir}/locale/ +mv ${TMP_LOCALE}/locale-archive ${libdir}/locale/ +rm -rf ${TMP_LOCALE} +} + +locale_base_postrm() { +#!/bin/sh + +rm -rf ${TMP_LOCALE} +mkdir -p ${TMP_LOCALE} +if [ -f ${libdir}/locale/locale-archive ]; then + cp ${libdir}/locale/locale-archive ${TMP_LOCALE}/ +fi +localedef --delete-from-archive --inputfile=${datadir}/locales/%s --charmap=%s --prefix=/tmp/locale %s +mv ${TMP_LOCALE}/locale-archive ${libdir}/locale/ +rm -rf ${TMP_LOCALE} +} + +do_prep_locale_tree() { + treedir=${WORKDIR}/locale-tree + rm -rf $treedir + mkdir -p $treedir/bin $treedir/lib $treedir/${datadir} $treedir/${libdir}/locale + cp -pPR ${PKGD}${datadir}/i18n $treedir/${datadir}/i18n + # unzip to avoid parsing errors + for i in $treedir/${datadir}/i18n/charmaps/*gz; do + gunzip $i + done + ls -d ${PKGD}${base_libdir}/* | xargs -iBLAH cp -pPR BLAH $treedir/lib + if [ -f ${CROSS_DIR}/${TARGET_SYS}/lib/libgcc_s.so ]; then + cp -pPR ${CROSS_DIR}/${TARGET_SYS}/lib/libgcc_s.so $treedir/lib + fi + if [ -f ${CROSS_DIR}/${TARGET_SYS}/lib/libgcc_s.so.* ]; then + cp -pPR ${CROSS_DIR}/${TARGET_SYS}/lib/libgcc_s.so.* $treedir/lib + fi + install -m 0755 ${PKGD}${bindir}/localedef $treedir/bin +} + +do_collect_bins_from_locale_tree() { + treedir=${WORKDIR}/locale-tree + + mkdir -p ${PKGD}${libdir} + cp -pPR $treedir/${libdir}/locale ${PKGD}${libdir} +} + +python package_do_split_gconvs () { + import os, re + if (bb.data.getVar('PACKAGE_NO_GCONV', d, 1) == '1'): + bb.note("package requested not splitting gconvs") + return + + if not bb.data.getVar('PACKAGES', d, 1): + return + + libdir = bb.data.getVar('libdir', d, 1) + if not libdir: + bb.error("libdir not defined") + return + datadir = bb.data.getVar('datadir', d, 1) + if not datadir: + bb.error("datadir not defined") + return + + gconv_libdir = base_path_join(libdir, "gconv") + charmap_dir = base_path_join(datadir, "i18n", "charmaps") + locales_dir = base_path_join(datadir, "i18n", "locales") + binary_locales_dir = base_path_join(libdir, "locale") + + do_split_packages(d, gconv_libdir, file_regex='^(.*)\.so$', output_pattern='glibc-gconv-%s', description='gconv module for character set %s', extra_depends='glibc-gconv') + + do_split_packages(d, charmap_dir, file_regex='^(.*)\.gz$', output_pattern='glibc-charmap-%s', description='character map for %s encoding', extra_depends='') + + def calc_locale_deps(fn, pkg, file_regex, output_pattern, group): + deps = [] + f = open(fn, "r") + c_re = re.compile('^copy "(.*)"') + i_re = re.compile('^include "(\w+)".*') + for l in f.readlines(): + m = c_re.match(l) or i_re.match(l) + if m: + dp = legitimize_package_name('glibc-localedata-%s' % m.group(1)) + if not dp in deps: + deps.append(dp) + f.close() + if deps != []: + bb.data.setVar('RDEPENDS_%s' % pkg, " ".join(deps), d) + + do_split_packages(d, locales_dir, file_regex='(.*)', output_pattern='glibc-localedata-%s', description='locale definition for %s', hook=calc_locale_deps, extra_depends='') + bb.data.setVar('PACKAGES', bb.data.getVar('PACKAGES', d) + ' glibc-gconv', d) + + use_bin = bb.data.getVar("GLIBC_INTERNAL_USE_BINARY_LOCALE", d, 1) + + dot_re = re.compile("(.*)\.(.*)") + + if use_bin != "precompiled": + supported = bb.data.getVar('GLIBC_GENERATE_LOCALES', d, 1) + if not supported or supported == "all": + f = open(base_path_join(bb.data.getVar('WORKDIR', d, 1), "SUPPORTED"), "r") + supported = f.readlines() + f.close() + else: + supported = supported.split() + supported = map(lambda s:s.replace(".", " ") + "\n", supported) + else: + supported = [] + full_bin_path = bb.data.getVar('PKGD', d, True) + binary_locales_dir + for dir in os.listdir(full_bin_path): + dbase = dir.split(".") + d2 = " " + if len(dbase) > 1: + d2 = "." + dbase[1].upper() + " " + supported.append(dbase[0] + d2) + + # Collate the locales by base and encoding + utf8_only = int(bb.data.getVar('LOCALE_UTF8_ONLY', d, 1) or 0) + encodings = {} + for l in supported: + l = l[:-1] + (locale, charset) = l.split(" ") + if utf8_only and charset != 'UTF-8': + continue + m = dot_re.match(locale) + if m: + locale = m.group(1) + if not encodings.has_key(locale): + encodings[locale] = [] + encodings[locale].append(charset) + + def output_locale_source(name, pkgname, locale, encoding): + bb.data.setVar('RDEPENDS_%s' % pkgname, 'localedef glibc-localedata-%s glibc-charmap-%s' % (legitimize_package_name(locale), legitimize_package_name(encoding)), d) + bb.data.setVar('pkg_postinst_%s' % pkgname, bb.data.getVar('locale_base_postinst', d, 1) % (locale, encoding, locale), d) + bb.data.setVar('pkg_postrm_%s' % pkgname, bb.data.getVar('locale_base_postrm', d, 1) % (locale, encoding, locale), d) + + def output_locale_binary_rdepends(name, pkgname, locale, encoding): + m = re.match("(.*)\.(.*)", name) + if m: + glibc_name = "%s.%s" % (m.group(1), m.group(2).lower().replace("-","")) + else: + glibc_name = name + bb.data.setVar('RDEPENDS_%s' % pkgname, legitimize_package_name('glibc-binary-localedata-%s' % glibc_name), d) + + def output_locale_binary(name, pkgname, locale, encoding): + # This is a hack till linux-libc-headers gets patched for the missing arm syscalls and all arm device kernels as well + if bb.data.getVar("DISTRO_NAME", d, 1) == "Angstrom": + kernel_ver = "2.6.24" + elif bb.data.getVar("DISTRO_NAME", d, 1) == "KaeilOS": + kernel_ver = "2.6.24" + else: + kernel_ver = bb.data.getVar("OLDEST_KERNEL", d, 1) + + qemu = qemu_target_binary(d) + " -s 1048576" + if kernel_ver: + qemu += " -r %s" % (kernel_ver) + pkgname = 'locale-base-' + legitimize_package_name(name) + + treedir = base_path_join(bb.data.getVar("WORKDIR", d, 1), "locale-tree") + ldlibdir = "%s/lib" % treedir + path = bb.data.getVar("PATH", d, 1) + i18npath = base_path_join(treedir, datadir, "i18n") + + localedef_opts = "--force --old-style --no-archive --prefix=%s --inputfile=%s/i18n/locales/%s --charmap=%s %s" % (treedir, datadir, locale, encoding, name) + + qemu_options = bb.data.getVar("QEMU_OPTIONS_%s" % bb.data.getVar('PACKAGE_ARCH', d, 1), d, 1) + if not qemu_options: + qemu_options = bb.data.getVar('QEMU_OPTIONS', d, 1) + + cmd = "PATH=\"%s\" I18NPATH=\"%s\" %s -L %s -E LD_LIBRARY_PATH=%s %s %s/bin/localedef %s" % (path, i18npath, qemu, treedir, ldlibdir, qemu_options, treedir, localedef_opts) + bb.note("generating locale %s (%s)" % (locale, encoding)) + if os.system(cmd): + raise bb.build.FuncFailed("localedef returned an error (command was %s)." % cmd) + + def output_locale(name, locale, encoding): + pkgname = 'locale-base-' + legitimize_package_name(name) + bb.data.setVar('ALLOW_EMPTY_%s' % pkgname, '1', d) + bb.data.setVar('PACKAGES', '%s %s' % (pkgname, bb.data.getVar('PACKAGES', d, 1)), d) + rprovides = 'virtual-locale-%s' % legitimize_package_name(name) + m = re.match("(.*)_(.*)", name) + if m: + rprovides += ' virtual-locale-%s' % m.group(1) + bb.data.setVar('RPROVIDES_%s' % pkgname, rprovides, d) + if use_bin == "compile": + output_locale_binary_rdepends(name, pkgname, locale, encoding) + output_locale_binary(name, pkgname, locale, encoding) + elif use_bin == "precompiled": + output_locale_binary_rdepends(name, pkgname, locale, encoding) + else: + output_locale_source(name, pkgname, locale, encoding) + + if use_bin == "compile": + bb.note("preparing tree for binary locale generation") + bb.build.exec_func("do_prep_locale_tree", d) + + # Reshuffle names so that UTF-8 is preferred over other encodings + non_utf8 = [] + for l in encodings.keys(): + if len(encodings[l]) == 1: + output_locale(l, l, encodings[l][0]) + if encodings[l][0] != "UTF-8": + non_utf8.append(l) + else: + if "UTF-8" in encodings[l]: + output_locale(l, l, "UTF-8") + encodings[l].remove("UTF-8") + else: + non_utf8.append(l) + for e in encodings[l]: + output_locale('%s.%s' % (l, e), l, e) + + if non_utf8 != [] and use_bin != "precompiled": + bb.note("the following locales are supported only in legacy encodings:") + bb.note(" " + " ".join(non_utf8)) + + if use_bin == "compile": + bb.note("collecting binary locales from locale tree") + bb.build.exec_func("do_collect_bins_from_locale_tree", d) + do_split_packages(d, binary_locales_dir, file_regex='(.*)', output_pattern='glibc-binary-localedata-%s', description='binary locale definition for %s', extra_depends='', allow_dirs=True) + elif use_bin == "precompiled": + do_split_packages(d, binary_locales_dir, file_regex='(.*)', output_pattern='glibc-binary-localedata-%s', description='binary locale definition for %s', extra_depends='', allow_dirs=True) + else: + bb.note("generation of binary locales disabled. this may break i18n!") + +} + +# We want to do this indirection so that we can safely 'return' +# from the called function even though we're prepending +python populate_packages_prepend () { + if bb.data.getVar('DEBIAN_NAMES', d, 1): + bb.data.setVar('PKG_glibc', 'libc6', d) + bb.data.setVar('PKG_glibc-dev', 'libc6-dev', d) + bb.build.exec_func('package_do_split_gconvs', d) +} diff --git a/classes/glx-use-tls.bbclass b/classes/glx-use-tls.bbclass new file mode 100644 index 0000000000..7530872fa4 --- /dev/null +++ b/classes/glx-use-tls.bbclass @@ -0,0 +1,7 @@ +def get_tls_setting(bb, d): + # until we have no prober TLS support in uclibc disable it + if bb.data.getVar('TARGET_OS', d, 1).find('uclibc') >= 0 : + return "" + return "--enable-glx-tls" + +EXTRA_OECONF += "${@get_tls_setting(bb, d)}" diff --git a/classes/gnome.bbclass b/classes/gnome.bbclass index 8643989b73..cb03650b48 100644 --- a/classes/gnome.bbclass +++ b/classes/gnome.bbclass @@ -1,6 +1,6 @@ def gnome_verdir(v): import re - m = re.match("([0-9]+)\.([0-9]+)\..*", v) + m = re.match("^([0-9]+)\.([0-9]+)", v) return "%s.%s" % (m.group(1), m.group(2)) SECTION ?= "x11/gnome" @@ -8,13 +8,23 @@ SRC_URI = "${GNOME_MIRROR}/${PN}/${@gnome_verdir("${PV}")}/${PN}-${PV}.tar.bz2" DEPENDS += "gnome-common" -FILES_${PN} += "${datadir}/application-registry ${datadir}/mime-info \ +FILES_${PN} += "${datadir}/application-registry \ + ${datadir}/mime-info \ + ${datadir}/mime/packages \ + ${datadir}/mime/application \ ${datadir}/gnome-2.0" -inherit autotools pkgconfig gconf +inherit autotools gtk-icon-cache pkgconfig gconf mime -EXTRA_AUTORECONF += "-I ${STAGING_DIR}/${HOST_SYS}/share/aclocal/gnome2-macros" +AUTOTOOLS_STAGE_PKGCONFIG = "1" gnome_stage_includes() { autotools_stage_includes } + +do_install_append() { + rm -rf ${D}${localstatedir}/lib/scrollkeeper/* + rm -rf ${D}${localstatedir}/scrollkeeper/* + rm -f ${D}${datadir}/applications/*.cache +} + diff --git a/classes/gpephone.bbclass b/classes/gpephone.bbclass new file mode 100644 index 0000000000..57867b5d4b --- /dev/null +++ b/classes/gpephone.bbclass @@ -0,0 +1,7 @@ +DEPENDS_prepend = "coreutils-native virtual/libintl intltool-native " +GPE_TARBALL_SUFFIX ?= "gz" +SRC_URI = "${GPEPHONE_MIRROR}/${PN}-${PV}/${PN}-${PV}.tar.${GPE_TARBALL_SUFFIX}" +FILES_${PN} += "${datadir}/gpe ${datadir}/application-registry" +SECTION ?= "gpe" + +inherit gettext autotools diff --git a/classes/gtk-binver.bbclass b/classes/gtk-binver.bbclass new file mode 100644 index 0000000000..52082492e7 --- /dev/null +++ b/classes/gtk-binver.bbclass @@ -0,0 +1,9 @@ +def gtkbinver_find(d): + import bb + try: + for line in file( "%s/gtk+-2.0.pc" % bb.data.getVar('PKG_CONFIG_DIR', d, 1) ).readlines(): + if line.startswith( "gtk_binary_version" ): + # bb.note( "gtk_binary_version = '%s'" % line.split("=")[1].strip() ) + return line.split("=")[1].strip() + except OSError: + return "0.0.0" diff --git a/classes/gtk-doc.bbclass b/classes/gtk-doc.bbclass new file mode 100644 index 0000000000..58daaf39e2 --- /dev/null +++ b/classes/gtk-doc.bbclass @@ -0,0 +1,4 @@ +# We don't have gtk-doc so disable it +do_configure_prepend() { + echo "EXTRA_DIST=">> ${S}/gtk-doc.make +} diff --git a/classes/gtk-icon-cache.bbclass b/classes/gtk-icon-cache.bbclass index 0f68e6812b..524c2f0c46 100644 --- a/classes/gtk-icon-cache.bbclass +++ b/classes/gtk-icon-cache.bbclass @@ -1,23 +1,37 @@ FILES_${PN} += "${datadir}/icons/hicolor" +RDEPENDS += "hicolor-icon-theme" -gtk-icon-cache_postinst() { +# This could run on the host as icon cache files are architecture independent, +# but there is no gtk-update-icon-cache built natively. +gtk_icon_cache_postinst() { if [ "x$D" != "x" ]; then exit 1 fi -gtk-update-icon-cache -q /usr/share/icons/hicolor + +# Update the pixbuf loaders in case they haven't been registered yet +gdk-pixbuf-query-loaders > /etc/gtk-2.0/gdk-pixbuf.loaders + +for icondir in /usr/share/icons/* ; do + if [ -d $icondir ] ; then + gtk-update-icon-cache -qt $icondir + fi +done } -gtk-icon-cache_postrm() { -gtk-update-icon-cache -q /usr/share/icons/hicolor +gtk_icon_cache_postrm() { +for icondir in /usr/share/icons/* ; do + if [ -d $icondir ] ; then + gtk-update-icon-cache -qt $icondir + fi +done } python populate_packages_append () { - import os.path packages = bb.data.getVar('PACKAGES', d, 1).split() - workdir = bb.data.getVar('WORKDIR', d, 1) + pkgdest = bb.data.getVar('PKGDEST', d, 1) for pkg in packages: - icon_dir = '%s/install/%s/%s/icons/hicolor' % (workdir, pkg, bb.data.getVar('datadir', d, 1)) + icon_dir = '%s/%s/%s/icons' % (pkgdest, pkg, bb.data.getVar('datadir', d, 1)) if not os.path.exists(icon_dir): continue @@ -26,13 +40,13 @@ python populate_packages_append () { postinst = bb.data.getVar('pkg_postinst_%s' % pkg, d, 1) or bb.data.getVar('pkg_postinst', d, 1) if not postinst: postinst = '#!/bin/sh\n' - postinst += bb.data.getVar('gtk-icon-cache_postinst', d, 1) + postinst += bb.data.getVar('gtk_icon_cache_postinst', d, 1) bb.data.setVar('pkg_postinst_%s' % pkg, postinst, d) postrm = bb.data.getVar('pkg_postrm_%s' % pkg, d, 1) or bb.data.getVar('pkg_postrm', d, 1) if not postrm: postrm = '#!/bin/sh\n' - postrm += bb.data.getVar('gtk-icon-cache_postrm', d, 1) + postrm += bb.data.getVar('gtk_icon_cache_postrm', d, 1) bb.data.setVar('pkg_postrm_%s' % pkg, postrm, d) } diff --git a/classes/icecc.bbclass b/classes/icecc.bbclass index 2f34d408d2..0a22f70001 100644 --- a/classes/icecc.bbclass +++ b/classes/icecc.bbclass @@ -1,8 +1,31 @@ # IceCream distributed compiling support # -# We need to create a tar.bz2 of our toolchain and set -# ICECC_VERSION, ICECC_CXX and ICEC_CC +# Stages directories with symlinks from gcc/g++ to icecc, for both +# native and cross compilers. Depending on each configure or compile, +# the directories are added at the head of the PATH list and ICECC_CXX +# and ICEC_CC are set. # +# For the cross compiler, creates a tar.gz of our toolchain and sets +# ICECC_VERSION accordingly. +# +#The class now handles all 3 different compile 'stages' (i.e native ,cross-kernel and target) creating the +#necessary enviroment tar.gz file to be used by the remote machines. +#It also supports meta-toolchain generation +# +#If ICECC_PATH is not set in local.conf then the class will try to locate it using 'which' +#but nothing is sure ;) +# +#If ICECC_ENV_EXEC is set in local.conf should point to the icecc-create-env script provided by the user +#or the default one provided by icecc-create-env.bb will be used +#(NOTE that this is a modified version of the script need it and *not the one that comes with icecc* +# +#User can specify if specific packages or packages belonging to class should not use icecc to distribute +#compile jobs to remote machines, but handled localy, by defining ICECC_USER_CLASS_BL and ICECC_PACKAGE_BL +#with the appropriate values in local.conf +######################################################################################### +#Error checking is kept to minimum so double check any parameters you pass to the class +########################################################################################### + def icc_determine_gcc_version(gcc): """ @@ -12,97 +35,183 @@ def icc_determine_gcc_version(gcc): """ return os.popen("%s --version" % gcc ).readline().split()[2] -def create_env(bb,d): +def create_cross_env(bb,d): """ - Create a tar.bz of the current toolchain + Create a tar.bz2 of the current toolchain """ - # Constin native-native compilation no environment needed if # host prefix is empty (let us duplicate the query for ease) prefix = bb.data.expand('${HOST_PREFIX}', d) if len(prefix) == 0: return "" - import tarfile - import socket - import time - import os + import tarfile, socket, time ice_dir = bb.data.expand('${CROSS_DIR}', d) prefix = bb.data.expand('${HOST_PREFIX}' , d) distro = bb.data.expand('${DISTRO}', d) target_sys = bb.data.expand('${TARGET_SYS}', d) - float = bb.data.getVar('${TARGET_FPU}', d) or "hard" + target_prefix = bb.data.expand('${TARGET_PREFIX}', d) + float = bb.data.getVar('TARGET_FPU', d) or "hard" name = socket.gethostname() # Stupid check to determine if we have built a libc and a cross # compiler. try: - os.stat(os.path.join(ice_dir, target_sys, 'lib', 'ld-linux.so.2')) + os.stat(os.path.join(ice_dir, target_sys, 'lib', 'libstdc++.so')) os.stat(os.path.join(ice_dir, target_sys, 'bin', 'g++')) - except: + except: # no cross compiler built yet + bb.error('no cross compiler built yet?') return "" VERSION = icc_determine_gcc_version( os.path.join(ice_dir,target_sys,"bin","g++") ) - cross_name = prefix + distro + target_sys + float +VERSION+ name - tar_file = os.path.join(ice_dir, 'ice', cross_name + '.tar.bz2') + cross_name = prefix + distro + "-" + target_sys + "-" + float + "-" + VERSION + "-" + name + tar_file = os.path.join(ice_dir, 'ice', cross_name + '.tar.gz') try: os.stat(tar_file) + # tar file already exists return tar_file - except: + except: try: os.makedirs(os.path.join(ice_dir,'ice')) except: + # directory already exists, continue pass - # FIXME find out the version of the compiler - # Consider using -print-prog-name={cc1,cc1plus} - # and -print-file-name=specs - - # We will use the GCC to tell us which tools to use - # What we need is: - # -gcc - # -g++ - # -as - # -cc1 - # -cc1plus - # and we add them to /usr/bin - - tar = tarfile.open(tar_file, 'w:bz2') - - # Now add the required files - tar.add(os.path.join(ice_dir,target_sys,'bin','gcc'), - os.path.join("usr","bin","gcc") ) - tar.add(os.path.join(ice_dir,target_sys,'bin','g++'), - os.path.join("usr","bin","g++") ) - tar.add(os.path.join(ice_dir,target_sys,'bin','as'), - os.path.join("usr","bin","as") ) - - # Now let us find cc1 and cc1plus - cc1 = os.popen("%s -print-prog-name=cc1" % data.getVar('CC', d, True)).read()[:-1] - cc1plus = os.popen("%s -print-prog-name=cc1plus" % data.getVar('CC', d, True)).read()[:-1] - spec = os.popen("%s -print-file-name=specs" % data.getVar('CC', d, True)).read()[:-1] - - # CC1 and CC1PLUS should be there... - tar.add(cc1, os.path.join('usr', 'bin', 'cc1')) - tar.add(cc1plus, os.path.join('usr', 'bin', 'cc1plus')) - - # spec - if it exists - if os.path.exists(spec): - tar.add(spec) - - tar.close() + + #check if user has specified a specific icecc-create-env script + #if not use the OE provided one + cr_env_script = bb.data.expand('${ICECC_ENV_EXEC}', d) + if cr_env_script == "${ICECC_ENV_EXEC}": + cr_env_script = bb.data.expand('${STAGING_DIR}', d)+"/ice/icecc-create-env" + #call the modified create-env script + result=os.popen("%s %s %s %s %s %s" %(cr_env_script, + "--silent", + os.path.join(ice_dir, 'bin', "%s-gcc" % target_sys), + os.path.join(ice_dir, 'bin', "%s-g++" % target_sys), + os.path.join(ice_dir, 'bin', "%s-as" % target_sys), + os.path.join(ice_dir,"ice",cross_name) ) ) return tar_file +def create_native_env(bb,d): + import tarfile, socket, time + ice_dir = bb.data.expand('${CROSS_DIR}', d) + prefix = bb.data.expand('${HOST_PREFIX}' , d) + distro = bb.data.expand('${DISTRO}', d) + target_sys = bb.data.expand('${TARGET_SYS}', d) + target_prefix = bb.data.expand('${TARGET_PREFIX}', d) + float = bb.data.getVar('TARGET_FPU', d) or "hard" + name = socket.gethostname() + + archive_name = "local-host-env" + "-" + name + tar_file = os.path.join(ice_dir, 'ice', archive_name + '.tar.gz') + + try: + os.stat(tar_file) + # tar file already exists + return tar_file + except: + try: + #os.makedirs(os.path.join(ice_dir)) + os.makedirs(os.path.join(ice_dir,'ice')) + except: + # directory already exists, continue + pass + + #check if user has specified a specific icecc-create-env script + #if not use the OE provided one + cr_env_script = bb.data.expand('${ICECC_ENV_EXEC}', d) + if cr_env_script == "${ICECC_ENV_EXEC}": + cr_env_script = bb.data.expand('${STAGING_DIR}', d)+"/ice/icecc-create-env" + result=os.popen("%s %s %s %s %s %s" %(cr_env_script, + "--silent", + os.popen("%s gcc" % "which").read()[:-1], + os.popen("%s g++" % "which").read()[:-1], + os.popen("%s as" % "which").read()[:-1], + os.path.join(ice_dir,"ice",archive_name) ) ) + return tar_file + + +def get_cross_kernel_cc(bb,d): + kernel_cc = bb.data.expand('${KERNEL_CC}', d) + kernel_cc = kernel_cc.replace('ccache', '').strip() + kernel_cc = kernel_cc.split(' ')[0] + kernel_cc = kernel_cc.strip() + return kernel_cc + + +def create_cross_kernel_env(bb,d): + import tarfile, socket, time + ice_dir = bb.data.expand('${CROSS_DIR}', d) + prefix = bb.data.expand('${HOST_PREFIX}' , d) + distro = bb.data.expand('${DISTRO}', d) + target_sys = bb.data.expand('${TARGET_SYS}', d) + target_prefix = bb.data.expand('${TARGET_PREFIX}', d) + float = bb.data.getVar('TARGET_FPU', d) or "hard" + name = socket.gethostname() + kernel_cc = get_cross_kernel_cc(bb, d) + + # Stupid check to determine if we have built a libc and a cross + # compiler. + try: + os.stat(os.path.join(ice_dir, 'bin', kernel_cc)) + except: # no cross compiler built yet + bb.error('no kernel cross compiler built yet') + return "" + + VERSION = icc_determine_gcc_version( os.path.join(ice_dir,"bin",kernel_cc) ) + cross_name = prefix + distro + "-" + target_sys + "-" + float + "-" + VERSION + "-" + name + tar_file = os.path.join(ice_dir, 'ice', cross_name + '.tar.gz') + + try: + os.stat(tar_file) + # tar file already exists + return tar_file + except: + try: + os.makedirs(os.path.join(ice_dir,'ice')) + except: + # directory already exists, continue + pass + + + #check if user has specified a specific icecc-create-env script + #if not use the OE provided one + cr_env_script = bb.data.getVar('ICECC_ENV_EXEC', d) or bb.data.expand('${STAGING_DIR}', d)+"/ice/icecc-create-env" + result=os.popen("%s %s %s %s %s %s" %(cr_env_script, + "--silent", + os.path.join(ice_dir, 'bin', kernel_cc), + os.path.join(ice_dir, 'bin', "%s-g++" % target_sys), + os.path.join(ice_dir, 'bin', "%s-as" % target_sys), + os.path.join(ice_dir, "ice", cross_name) ) ) + return tar_file + + +def create_env(bb,d): + + #return create_cross_kernel_env(bb,d) + + if bb.data.inherits_class("native", d): + return create_native_env(bb,d) + elif bb.data.inherits_class("kernel", d): + return create_cross_kernel_env(bb,d) + elif bb.data.inherits_class("cross", d): + return create_native_env(bb,d) + elif bb.data.inherits_class("sdk", d): + return create_native_env(bb,d) + else: + return create_cross_env(bb,d) + + def create_path(compilers, type, bb, d): """ Create Symlinks for the icecc in the staging directory """ - import os - staging = os.path.join(bb.data.expand('${STAGING_DIR}', d), "ice", type) - icecc = bb.data.getVar('ICECC_PATH', d) + + #check if the icecc path is set by the user + icecc = bb.data.getVar('ICECC_PATH', d) or os.popen("%s icecc" % "which").read()[:-1] # Create the dir if necessary try: @@ -110,7 +219,6 @@ def create_path(compilers, type, bb, d): except: os.makedirs(staging) - for compiler in compilers: gcc_path = os.path.join(staging, compiler) try: @@ -122,57 +230,93 @@ def create_path(compilers, type, bb, d): def use_icc_version(bb,d): - # Constin native native - prefix = bb.data.expand('${HOST_PREFIX}', d) - if len(prefix) == 0: - return "no" + icecc_ver = "yes" + system_class_blacklist = [ "none" ] + for black in system_class_blacklist: + if bb.data.inherits_class(black, d): + icecc_ver = "no" - blacklist = [ "cross", "native" ] + user_class_blacklist = bb.data.getVar('ICECC_USER_CLASS_BL', d) or "none" + user_class_blacklist = user_class_blacklist.split() - for black in blacklist: - if bb.data.inherits_class(black, d): - return "no" + for black in user_class_blacklist: + if bb.data.inherits_class(black, d): + icecc_ver = "no" - return "yes" + return icecc_ver -def icc_path(bb,d,compile): - native = bb.data.expand('${PN}', d) - blacklist = [ "ulibc", "glibc", "ncurses" ] - for black in blacklist: - if black in native: - return "" - blacklist = [ "cross", "native" ] - for black in blacklist: - if bb.data.inherits_class(black, d): - compile = False +def icc_path(bb,d): + package_tmp = bb.data.expand('${PN}', d) + + #"system" package blacklist contains a list of packages that can not distribute compile tasks + #for one reason or the other + system_package_blacklist = [ "uclibc", "glibc", "gcc", "bind", "u-boot", "dhcp-forwarder", "enchant", "connman" ] + user_package_blacklist = (bb.data.getVar('ICECC_USER_PACKAGE_BL', d) or "").split() + package_blacklist = system_package_blacklist + user_package_blacklist + + for black in package_blacklist: + if black in package_tmp: + bb.note(package_tmp, ' found in blacklist, disable icecc') + bb.data.setVar("PARALLEL_MAKE" , "", d) + return "" prefix = bb.data.expand('${HOST_PREFIX}', d) - if compile and len(prefix) != 0: - return create_path( [prefix+"gcc", prefix+"g++"], "cross", bb, d ) - elif not compile or len(prefix) == 0: + + if bb.data.inherits_class("cross", d): + return create_path( ["gcc", "g++"], "native", bb, d) + + elif bb.data.inherits_class("native", d): return create_path( ["gcc", "g++"], "native", bb, d) + elif bb.data.inherits_class("kernel", d): + return create_path( [get_cross_kernel_cc(bb,d), ], "cross-kernel", bb, d) + + elif len(prefix) == 0: + return create_path( ["gcc", "g++"], "native", bb, d) + + else: + return create_path( [prefix+"gcc", prefix+"g++"], "cross", bb, d) + def icc_version(bb,d): return create_env(bb,d) -# -# set the IceCream environment variables +def check_for_kernel(bb,d): + if bb.data.inherits_class("kernel", d): + return "yes" + return "no" + + +set_icecc_env() { + ICE_PATH=${@icc_path(bb,d)} + if test x${ICE_PATH} != x; then + export PATH=${ICE_PATH}$PATH + export CCACHE_PATH=$PATH + #check if we are building a kernel and select gcc-cross-kernel + if [ "${@check_for_kernel(bb,d)}" = "yes" ]; then + export ICECC_CC="${@get_cross_kernel_cc(bb,d)}" + export ICECC_CXX="${HOST_PREFIX}g++" + else + export ICECC_CC="${HOST_PREFIX}gcc" + export ICECC_CXX="${HOST_PREFIX}g++" + fi + + if [ "${@use_icc_version(bb,d)}" = "yes" ]; then + export ICECC_VERSION="${@icc_version(bb,d)}" + else + export -n ICECC_VERSION + fi + oenote "set the icecream environment variables: PATH=$PATH, CCACHE_PATH=$CCACHE_PATH, ICECC_CC=$ICECC_CC, ICECC_CXX=$ICECC_CXX, ICECC_VERSION=$ICECC_VERSION" + fi +} + do_configure_prepend() { - export PATH=${@icc_path(bb,d,False)}$PATH - export ICECC_CC="gcc" - export ICECC_CXX="g++" + set_icecc_env } do_compile_prepend() { - export PATH=${@icc_path(bb,d,True)}$PATH - export ICECC_CC="${HOST_PREFIX}gcc" - export ICECC_CXX="${HOST_PREFIX}g++" - - if [ "${@use_icc_version(bb,d)}" = "yes" ]; then - export ICECC_VERSION="${@icc_version(bb,d)}" - fi + set_icecc_env } diff --git a/classes/image.bbclass b/classes/image.bbclass new file mode 100644 index 0000000000..9dce609733 --- /dev/null +++ b/classes/image.bbclass @@ -0,0 +1,280 @@ +inherit rootfs_${IMAGE_PKGTYPE} + +LICENSE = "MIT" +PACKAGES = "" + +# +# udev, devfsd, busybox-mdev (from busybox) or none +# +IMAGE_DEV_MANAGER ?= "${@base_contains("MACHINE_FEATURES", "kernel26", "udev","",d)} " +# +# sysvinit, upstart +# +IMAGE_INIT_MANAGER ?= "sysvinit sysvinit-pidof" +IMAGE_INITSCRIPTS ?= "initscripts" +# +# tinylogin, getty +# +IMAGE_LOGIN_MANAGER ?= "tinylogin" + +# set sane default for the SPLASH variable +SPLASH ?= "" + +IMAGE_KEEPROOTFS ?= "" +IMAGE_KEEPROOTFS[doc] = "Set to non-empty to keep ${IMAGE_ROOTFS} around after image creation." + +IMAGE_BOOT ?= "${IMAGE_INITSCRIPTS} \ +${IMAGE_DEV_MANAGER} \ +${IMAGE_INIT_MANAGER} \ +${IMAGE_LOGIN_MANAGER} " + +RDEPENDS += "${IMAGE_INSTALL} ${IMAGE_BOOT}" + +# "export IMAGE_BASENAME" not supported at this time +IMAGE_BASENAME[export] = "1" +export PACKAGE_INSTALL ?= "${IMAGE_INSTALL} ${IMAGE_BOOT}" + +# We need to recursively follow RDEPENDS and RRECOMMENDS for images +do_rootfs[recrdeptask] += "do_deploy do_populate_staging" + +# Images are generally built explicitly, do not need to be part of world. +EXCLUDE_FROM_WORLD = "1" + +USE_DEVFS ?= "0" + +PID = "${@os.getpid()}" + +PACKAGE_ARCH = "${MACHINE_ARCH}" + +do_rootfs[depends] += "makedevs-native:do_populate_staging fakeroot-native:do_populate_staging" + +python () { + import bb + + deps = bb.data.getVarFlag('do_rootfs', 'depends', d) or "" + for type in (bb.data.getVar('IMAGE_FSTYPES', d, True) or "").split(): + for dep in ((bb.data.getVar('IMAGE_DEPENDS_%s' % type, d) or "").split() or []): + deps += " %s:do_populate_staging" % dep + for dep in (bb.data.getVar('EXTRA_IMAGEDEPENDS', d, True) or "").split(): + deps += " %s:do_populate_staging" % dep + bb.data.setVarFlag('do_rootfs', 'depends', deps, d) + + runtime_mapping_rename("PACKAGE_INSTALL", d) +} + +# +# Get a list of files containing tables of devices to be created. +# * IMAGE_DEVICE_TABLE is the old name to an absolute path to a device table file +# * IMAGE_DEVICE_TABLES is a new name for a file, or list of files, searched +# for in the BBPATH +# If neither are specified then the default name of files/device_table-minimal.txt +# is searched for in the BBPATH (same as the old version.) +# +def get_devtable_list(d): + import bb + devtable = bb.data.getVar('IMAGE_DEVICE_TABLE', d, 1) + if devtable != None: + return devtable + devtables = bb.data.getVar('IMAGE_DEVICE_TABLES', d, 1) + if devtables == None: + devtables = 'files/device_table-minimal.txt' + return " ".join([ bb.which(bb.data.getVar('BBPATH', d, 1), devtable) + for devtable in devtables.split() ]) + +def get_imagecmds(d): + import bb + cmds = "\n" + old_overrides = bb.data.getVar('OVERRIDES', d, 0) + for type in bb.data.getVar('IMAGE_FSTYPES', d, True).split(): + localdata = bb.data.createCopy(d) + bb.data.setVar('OVERRIDES', '%s:%s' % (type, old_overrides), localdata) + bb.data.update_data(localdata) + cmd = "\t#Code for image type " + type + "\n" + cmd += "\t${IMAGE_CMD_" + type + "}\n" + cmd += "\tcd ${DEPLOY_DIR_IMAGE}/\n" + cmd += "\trm -f ${DEPLOY_DIR_IMAGE}/${IMAGE_LINK_NAME}." + type + "\n" + cmd += "\tln -s ${IMAGE_NAME}.rootfs." + type + " ${DEPLOY_DIR_IMAGE}/${IMAGE_LINK_NAME}." + type + "\n\n" + cmds += bb.data.expand(cmd, localdata) + return cmds + +IMAGE_POSTPROCESS_COMMAND ?= "" +MACHINE_POSTPROCESS_COMMAND ?= "" +ROOTFS_POSTPROCESS_COMMAND ?= "" + +# some default locales +IMAGE_LINGUAS ?= "de-de fr-fr en-gb" + +LINGUAS_INSTALL = "${@" ".join(map(lambda s: "locale-base-%s" % s, bb.data.getVar('IMAGE_LINGUAS', d, 1).split()))}" + +do_rootfs[nostamp] = "1" +do_rootfs[dirs] = "${TOPDIR}" +do_build[nostamp] = "1" + +# Must call real_do_rootfs() from inside here, rather than as a separate +# task, so that we have a single fakeroot context for the whole process. +fakeroot do_rootfs () { + set -x + rm -rf ${IMAGE_ROOTFS} + mkdir -p ${IMAGE_ROOTFS} + mkdir -p ${DEPLOY_DIR_IMAGE} + + if [ "${USE_DEVFS}" != "1" ]; then + for devtable in ${@get_devtable_list(d)}; do + makedevs -r ${IMAGE_ROOTFS} -D $devtable + done + fi + + rootfs_${IMAGE_PKGTYPE}_do_rootfs + + insert_feed_uris + + ${IMAGE_PREPROCESS_COMMAND} + + ROOTFS_SIZE=`du -ks ${IMAGE_ROOTFS}|awk '{size = ${IMAGE_EXTRA_SPACE} + $1; print (size > ${IMAGE_ROOTFS_SIZE} ? size : ${IMAGE_ROOTFS_SIZE}) }'` + ${@get_imagecmds(d)} + + ${IMAGE_POSTPROCESS_COMMAND} + + ${MACHINE_POSTPROCESS_COMMAND} + ${@['rm -rf ${IMAGE_ROOTFS}', ''][bool(d.getVar("IMAGE_KEEPROOTFS", 1))]} +} + +do_deploy_to[nostamp] = "1" +do_deploy_to () { + # A standalone task to deploy built image to the location specified + # by DEPLOY_TO variable (likely passed via environment). + # Assumes ${IMAGE_FSTYPES} is a single value! + cp "${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.${IMAGE_FSTYPES}" ${DEPLOY_TO} +} + +insert_feed_uris () { + + echo "Building feeds for [${DISTRO}].." + + for line in ${FEED_URIS} + do + # strip leading and trailing spaces/tabs, then split into name and uri + line_clean="`echo "$line"|sed 's/^[ \t]*//;s/[ \t]*$//'`" + feed_name="`echo "$line_clean" | sed -n 's/\(.*\)##\(.*\)/\1/p'`" + feed_uri="`echo "$line_clean" | sed -n 's/\(.*\)##\(.*\)/\2/p'`" + + echo "Added $feed_name feed with URL $feed_uri" + + # insert new feed-sources + echo "src/gz $feed_name $feed_uri" >> ${IMAGE_ROOTFS}/etc/opkg/${feed_name}-feed.conf + done + + # Allow to use package deploy directory contents as quick devel-testing + # feed. This creates individual feed configs for each arch subdir of those + # specified as compatible for the current machine. + # NOTE: Development-helper feature, NOT a full-fledged feed. + if [ -n "${FEED_DEPLOYDIR_BASE_URI}" ]; then + for arch in ${PACKAGE_ARCHS} + do + echo "src/gz local-$arch ${FEED_DEPLOYDIR_BASE_URI}/$arch" >> ${IMAGE_ROOTFS}/etc/opkg/local-$arch-feed.conf + done + fi +} + +log_check() { + set +x + for target in $* + do + lf_path="${WORKDIR}/temp/log.do_$target.${PID}" + + echo "log_check: Using $lf_path as logfile" + + if test -e "$lf_path" + then + rootfs_${IMAGE_PKGTYPE}_log_check $target $lf_path + else + echo "Cannot find logfile [$lf_path]" + fi + echo "Logfile is clean" + done + + set -x +} + +# set '*' as the rootpassword so the images +# can decide if they want it or not + +zap_root_password () { + sed 's%^root:[^:]*:%root:*:%' < ${IMAGE_ROOTFS}/etc/passwd >${IMAGE_ROOTFS}/etc/passwd.new + mv ${IMAGE_ROOTFS}/etc/passwd.new ${IMAGE_ROOTFS}/etc/passwd +} + +create_etc_timestamp() { + date +%2m%2d%2H%2M%Y >${IMAGE_ROOTFS}/etc/timestamp +} + +# Turn any symbolic /sbin/init link into a file +remove_init_link () { + if [ -h ${IMAGE_ROOTFS}/sbin/init ]; then + LINKFILE=${IMAGE_ROOTFS}`readlink ${IMAGE_ROOTFS}/sbin/init` + rm ${IMAGE_ROOTFS}/sbin/init + cp $LINKFILE ${IMAGE_ROOTFS}/sbin/init + fi +} + +make_zimage_symlink_relative () { + if [ -L ${IMAGE_ROOTFS}/boot/zImage ]; then + (cd ${IMAGE_ROOTFS}/boot/ && for i in `ls zImage-* | sort`; do ln -sf $i zImage; done) + fi +} + +# Make login manager(s) enable automatic login. +# Useful for devices where we do not want to log in at all (e.g. phones) +set_image_autologin () { + sed -i 's%^AUTOLOGIN=\"false"%AUTOLOGIN="true"%g' ${IMAGE_ROOTFS}/etc/sysconfig/gpelogin +} + +# Can be use to create /etc/timestamp during image construction to give a reasonably +# sane default time setting +rootfs_update_timestamp () { + date "+%m%d%H%M%Y" >${IMAGE_ROOTFS}/etc/timestamp +} + +# Install locales into image for every entry in IMAGE_LINGUAS +install_linguas() { +if [ -e ${IMAGE_ROOTFS}/usr/bin/opkg-cl ] ; then + OPKG="opkg-cl ${IPKG_ARGS}" + + ${OPKG} update || true + ${OPKG} list_installed | awk '{print $1}' |sort | uniq > /tmp/installed-packages + + for i in $(cat /tmp/installed-packages | grep -v locale) ; do + for translation in ${IMAGE_LINGUAS}; do + translation_split=$(echo ${translation} | awk -F '-' '{print $1}') + echo ${i}-locale-${translation} + echo ${i}-locale-${translation_split} + done + done | sort | uniq > /tmp/wanted-locale-packages + + ${OPKG} list | awk '{print $1}' |grep locale |sort | uniq > /tmp/available-locale-packages + + cat /tmp/wanted-locale-packages /tmp/available-locale-packages | sort | uniq -d > /tmp/pending-locale-packages + + cat /tmp/pending-locale-packages | xargs ${OPKG} -nodeps install + rm -f ${IMAGE_ROOTFS}${libdir}/opkg/lists/* + + for i in ${IMAGE_ROOTFS}${libdir}/opkg/info/*.preinst; do + if [ -f $i ] && ! sh $i; then + opkg-cl ${IPKG_ARGS} flag unpacked `basename $i .preinst` + fi + done + + for i in ${IMAGE_ROOTFS}${libdir}/opkg/info/*.postinst; do + if [ -f $i ] && ! sh $i configure; then + opkg-cl ${IPKG_ARGS} flag unpacked `basename $i .postinst` + fi + done + +fi +} + +# export the zap_root_password, create_etc_timestamp and remote_init_link +EXPORT_FUNCTIONS zap_root_password create_etc_timestamp remove_init_link do_rootfs make_zimage_symlink_relative set_image_autologin rootfs_update_timestamp install_linguas + +addtask rootfs before do_build after do_install +addtask deploy_to after do_rootfs diff --git a/classes/image_ipk.bbclass b/classes/image_ipk.bbclass deleted file mode 100644 index 83e9acf315..0000000000 --- a/classes/image_ipk.bbclass +++ /dev/null @@ -1,99 +0,0 @@ -inherit rootfs_ipk - -# We need to recursively follow RDEPENDS and RRECOMMENDS for images -BUILD_ALL_DEPS = "1" -do_rootfs[recrdeptask] = "do_package" - -# Images are generally built explicitly, do not need to be part of world. -EXCLUDE_FROM_WORLD = "1" - -USE_DEVFS ?= "0" - -DEPENDS += "makedevs-native" -PACKAGE_ARCH = "${MACHINE_ARCH}" - -def get_image_deps(d): - import bb - str = "" - for type in (bb.data.getVar('IMAGE_FSTYPES', d, 1) or "").split(): - deps = bb.data.getVar('IMAGE_DEPENDS_%s' % type, d) or "" - if deps: - str += " %s" % deps - return str - -DEPENDS += "${@get_image_deps(d)}" - -# -# Get a list of files containing device tables to create. -# * IMAGE_DEVICE_TABLE is the old name to an absolute path to a device table file -# * IMAGE_DEVICE_TABLES is a new name for a file, or list of files, seached -# for in the BBPATH -# If neither are specified then the default name of files/device_table-minimal.txt -# is searched for in the BBPATH (same as the old version.) -# -def get_devtable_list(d): - import bb - devtable = bb.data.getVar('IMAGE_DEVICE_TABLE', d, 1) - if devtable != None: - return devtable - str = "" - devtables = bb.data.getVar('IMAGE_DEVICE_TABLES', d, 1) - if devtables == None: - devtables = 'files/device_table-minimal.txt' - for devtable in devtables.split(): - str += " %s" % bb.which(bb.data.getVar('BBPATH', d, 1), devtable) - return str - -IMAGE_POSTPROCESS_COMMAND ?= "" - -# Must call real_do_rootfs() from inside here, rather than as a separate -# task, so that we have a single fakeroot context for the whole process. -fakeroot do_rootfs () { - set -x - rm -rf ${IMAGE_ROOTFS} - - if [ "${USE_DEVFS}" != "1" ]; then - mkdir -p ${IMAGE_ROOTFS}/dev - for devtable in ${@get_devtable_list(d)}; do - makedevs -r ${IMAGE_ROOTFS} -D $devtable - done - fi - - real_do_rootfs - - insert_feed_uris - - rm -f ${IMAGE_ROOTFS}${libdir}/ipkg/lists/oe - - ${IMAGE_PREPROCESS_COMMAND} - - export TOPDIR=${TOPDIR} - - for type in ${IMAGE_FSTYPES}; do - if test -z "$FAKEROOTKEY"; then - fakeroot -i ${TMPDIR}/fakedb.image bbimage -t $type -e ${FILE} - else - bbimage -n "${IMAGE_NAME}" -t "$type" -e "${FILE}" - fi - done - - ${IMAGE_POSTPROCESS_COMMAND} -} - -insert_feed_uris () { - - echo "Building feeds for [${DISTRO}].." - - for line in ${FEED_URIS} - do - # strip leading and trailing spaces/tabs, then split into name and uri - line_clean="`echo "$line"|sed 's/^[ \t]*//;s/[ \t]*$//'`" - feed_name="`echo "$line_clean" | sed -n 's/\(.*\)##\(.*\)/\1/p'`" - feed_uri="`echo "$line_clean" | sed -n 's/\(.*\)##\(.*\)/\2/p'`" - - echo "Added $feed_name feed with URL $feed_uri" - - # insert new feed-sources - echo "src/gz $feed_name $feed_uri" >> ${IMAGE_ROOTFS}/etc/ipkg/${feed_name}-feed.conf - done -} diff --git a/classes/insane.bbclass b/classes/insane.bbclass index ead718db7f..804caf06ee 100644 --- a/classes/insane.bbclass +++ b/classes/insane.bbclass @@ -8,109 +8,539 @@ # -Check the RUNTIME path for the $TMPDIR # -Check if .la files wrongly point to workdir # -Check if .pc files wrongly point to workdir -# -Check if packages contains .dbg or .so files where they should be in -dev or -dbg -# +# -Check if packages contains .debug directories or .so files +# where they should be in -dev or -dbg +# -Check if config.log contains traces to broken autoconf tests # # We need to have the scanelf utility as soon as -# possible and this is contained within the pax-utils-native +# possible and this is contained within the pax-utils-native. +# The package.bbclass can help us here. # - -# We play a special package function inherit package -PACKAGE_DEPENDS += "pax-utils-native" +PACKAGE_DEPENDS += "pax-utils-native desktop-file-utils-native" PACKAGEFUNCS += " do_package_qa " -def package_qa_check_rpath(file,name,d): + +# +# dictionary for elf headers +# +# feel free to add and correct. +# +# TARGET_OS TARGET_ARCH MACHINE, OSABI, ABIVERSION, Little Endian, 32bit? +def package_qa_get_machine_dict(): + return { + "darwin9" : { + "arm" : (40, 0, 0, True, True), + }, + "linux" : { + "arm" : (40, 97, 0, True, True), + "armeb": (40, 97, 0, False, True), + "powerpc": (20, 0, 0, False, True), + "i386": ( 3, 0, 0, True, True), + "i486": ( 3, 0, 0, True, True), + "i586": ( 3, 0, 0, True, True), + "i686": ( 3, 0, 0, True, True), + "x86_64": (62, 0, 0, True, False), + "ia64": (50, 0, 0, True, False), + "alpha": (36902, 0, 0, True, False), + "hppa": (15, 3, 0, False, True), + "m68k": ( 4, 0, 0, False, True), + "mips": ( 8, 0, 0, False, True), + "mipsel": ( 8, 0, 0, True, True), + "s390": (22, 0, 0, False, True), + "sh4": (42, 0, 0, True, True), + "sparc": ( 2, 0, 0, False, True), + }, + "linux-uclibc" : { + "arm" : ( 40, 97, 0, True, True), + "armeb": ( 40, 97, 0, False, True), + "powerpc": ( 20, 0, 0, False, True), + "i386": ( 3, 0, 0, True, True), + "i486": ( 3, 0, 0, True, True), + "i586": ( 3, 0, 0, True, True), + "i686": ( 3, 0, 0, True, True), + "mips": ( 8, 0, 0, False, True), + "mipsel": ( 8, 0, 0, True, True), + "avr32": (6317, 0, 0, False, True), + "sh4": (42, 0, 0, True, True), + + }, + "uclinux-uclibc" : { + "bfin": ( 106, 0, 0, True, True), + }, + "linux-gnueabi" : { + "arm" : (40, 0, 0, True, True), + "armeb" : (40, 0, 0, False, True), + }, + "linux-uclibceabi" : { + "arm" : (40, 0, 0, True, True), + "armeb" : (40, 0, 0, False, True), + }, + "linux-gnuspe" : { + "powerpc": (20, 0, 0, False, True), + }, + "linux-uclibcspe" : { + "powerpc": (20, 0, 0, False, True), + }, + + } + +# factory for a class, embedded in a method +def package_qa_get_elf(path, bits32): + class ELFFile: + EI_NIDENT = 16 + + EI_CLASS = 4 + EI_DATA = 5 + EI_VERSION = 6 + EI_OSABI = 7 + EI_ABIVERSION = 8 + + # possible values for EI_CLASS + ELFCLASSNONE = 0 + ELFCLASS32 = 1 + ELFCLASS64 = 2 + + # possible value for EI_VERSION + EV_CURRENT = 1 + + # possible values for EI_DATA + ELFDATANONE = 0 + ELFDATA2LSB = 1 + ELFDATA2MSB = 2 + + def my_assert(self, expectation, result): + if not expectation == result: + #print "'%x','%x' %s" % (ord(expectation), ord(result), self.name) + raise Exception("This does not work as expected") + + def __init__(self, name): + self.name = name + + def open(self): + self.file = file(self.name, "r") + self.data = self.file.read(ELFFile.EI_NIDENT+4) + + self.my_assert(len(self.data), ELFFile.EI_NIDENT+4) + self.my_assert(self.data[0], chr(0x7f) ) + self.my_assert(self.data[1], 'E') + self.my_assert(self.data[2], 'L') + self.my_assert(self.data[3], 'F') + if bits32 : + self.my_assert(self.data[ELFFile.EI_CLASS], chr(ELFFile.ELFCLASS32)) + else: + self.my_assert(self.data[ELFFile.EI_CLASS], chr(ELFFile.ELFCLASS64)) + self.my_assert(self.data[ELFFile.EI_VERSION], chr(ELFFile.EV_CURRENT) ) + + self.sex = self.data[ELFFile.EI_DATA] + if self.sex == chr(ELFFile.ELFDATANONE): + raise Exception("self.sex == ELFDATANONE") + elif self.sex == chr(ELFFile.ELFDATA2LSB): + self.sex = "<" + elif self.sex == chr(ELFFile.ELFDATA2MSB): + self.sex = ">" + else: + raise Exception("Unknown self.sex") + + def osAbi(self): + return ord(self.data[ELFFile.EI_OSABI]) + + def abiVersion(self): + return ord(self.data[ELFFile.EI_ABIVERSION]) + + def isLittleEndian(self): + return self.sex == "<" + + def isBigEngian(self): + return self.sex == ">" + + def machine(self): + """ + We know the sex stored in self.sex and we + know the position + """ + import struct + (a,) = struct.unpack(self.sex+"H", self.data[18:20]) + return a + + return ELFFile(path) + + +# Known Error classes +# 0 - non dev contains .so +# 1 - package contains a dangerous RPATH +# 2 - package depends on debug package +# 3 - non dbg contains .so +# 4 - wrong architecture +# 5 - .la contains installed=yes or reference to the workdir +# 6 - .pc contains reference to /usr/include or workdir +# 7 - the desktop file is not valid +# 8 - .la contains reference to the workdir +# 9 - LDFLAGS ignored + +def package_qa_clean_path(path,d): + """ Remove the common prefix from the path. In this case it is the TMPDIR""" + return path.replace(bb.data.getVar('TMPDIR',d,True),"") + +def package_qa_make_fatal_error(error_class, name, path,d): + """ + decide if an error is fatal + + TODO: Load a whitelist of known errors + """ + return not error_class in [0, 5, 7] + +def package_qa_write_error(error_class, name, path, d): + """ + Log the error + """ + if not bb.data.getVar('QA_LOG', d): + bb.note("a QA error occured but will not be logged because QA_LOG is not set") + return + + ERROR_NAMES =[ + "non dev contains .so", + "package contains RPATH", + "package depends on debug package", + "non dbg contains .debug", + "wrong architecture", + "evil hides inside the .la", + "evil hides inside the .pc", + "the desktop file is not valid", + ".la contains reference to the workdir", + "LDFLAGS ignored", + ] + + log_path = os.path.join( bb.data.getVar('T', d, True), "log.qa_package" ) + f = file( log_path, "a+") + print >> f, "%s, %s, %s" % \ + (ERROR_NAMES[error_class], name, package_qa_clean_path(path,d)) + f.close() + +def package_qa_handle_error(error_class, error_msg, name, path, d): + bb.error("QA Issue with %s: %s" % (name, error_msg)) + package_qa_write_error(error_class, name, path, d) + return not package_qa_make_fatal_error(error_class, name, path, d) + +def package_qa_check_rpath(file,name,d, elf): """ Check for dangerous RPATHs """ + if not elf: + return True + import bb, os - scanelf = os.path.join(bb.data.getVar('STAGING_BINDIR',d,True),'scanelf') + sane = True + scanelf = os.path.join(bb.data.getVar('STAGING_BINDIR_NATIVE',d,True),'scanelf') bad_dir = bb.data.getVar('TMPDIR', d, True) + "/work" + bad_dir_test = bb.data.getVar('TMPDIR', d, True) if not os.path.exists(scanelf): - bb.note("Can not check RPATH scanelf not found") + bb.fatal("Can not check RPATH, scanelf (part of pax-utils-native) not found") + if not bad_dir in bb.data.getVar('WORKDIR', d, True): - bb.error("This class assumed that WORKDIR is ${TMPDIR}/work... Not doing any check") + bb.fatal("This class assumed that WORKDIR is ${TMPDIR}/work... Not doing any check") - output = os.popen("%s -Byr %s" % (scanelf,file)) - txt = output.readline().rsplit() - if bad_dir in txt: - bb.error("QA Issue package %s contains bad RPATH %s in file %s" % (name, txt, file)) + output = os.popen("%s -B -F%%r#F '%s'" % (scanelf,file)) + txt = output.readline().split() + for line in txt: + if bad_dir in line: + error_msg = "package %s contains bad RPATH %s in file %s" % (name, line, file) + sane = package_qa_handle_error(1, error_msg, name, file, d) - pass + return sane -def package_qa_check_devdbg(path, name,d): +def package_qa_check_dev(path, name,d, elf): """ - Check for debug remains inside the binary or - non dev packages containing + Check for ".so" library symlinks in non-dev packages """ - import bb + sane = True + + # SDK packages are special. + for s in ['sdk', 'canadian-sdk']: + if bb.data.inherits_class(s, d): + return True + if not "-dev" in name: - if path[-3:] == ".so": - bb.error("QA Issue: non dev package contains .so") + if path[-3:] == ".so" and os.path.islink(path): + error_msg = "non -dev package contains symlink .so: %s path '%s'" % \ + (name, package_qa_clean_path(path,d)) + sane = package_qa_handle_error(0, error_msg, name, path, d) + + return sane + +def package_qa_check_dbg(path, name,d, elf): + """ + Check for ".debug" files or directories outside of the dbg package + """ + + sane = True if not "-dbg" in name: - if path[-4:] == ".dbg": - bb.error("QA Issue: non debug package contains .dbg file") + if '.debug' in path: + error_msg = "non debug package contains .debug directory: %s path %s" % \ + (name, package_qa_clean_path(path,d)) + sane = package_qa_handle_error(3, error_msg, name, path, d) + + return sane -def package_qa_check_perm(path,name,d): +def package_qa_check_perm(path,name,d, elf): """ Check the permission of files """ - pass + sane = True + return sane -def package_qa_check_arch(path,name,d): +def package_qa_check_arch(path,name,d, elf): """ Check if archs are compatible """ - pass + if not elf: + return True + + sane = True + target_os = bb.data.getVar('TARGET_OS', d, True) + target_arch = bb.data.getVar('TARGET_ARCH', d, True) + + # FIXME: Cross package confuse this check, so just skip them + for s in ['cross', 'sdk', 'canadian-cross', 'canadian-sdk']: + if bb.data.inherits_class(s, d): + return True + + # avoid following links to /usr/bin (e.g. on udev builds) + # we will check the files pointed to anyway... + if os.path.islink(path): + return True + + #if this will throw an exception, then fix the dict above + (machine, osabi, abiversion, littleendian, bits32) \ + = package_qa_get_machine_dict()[target_os][target_arch] + + # Check the architecture and endiannes of the binary + if not machine == elf.machine(): + error_msg = "Architecture did not match (%d to %d) on %s" % \ + (machine, elf.machine(), package_qa_clean_path(path,d)) + sane = package_qa_handle_error(4, error_msg, name, path, d) + elif not littleendian == elf.isLittleEndian(): + error_msg = "Endiannes did not match (%d to %d) on %s" % \ + (littleendian, elf.isLittleEndian(), package_qa_clean_path(path,d)) + sane = package_qa_handle_error(4, error_msg, name, path, d) + + return sane + +def package_qa_check_desktop(path, name, d, elf): + """ + Run all desktop files through desktop-file-validate. + """ + sane = True + if path.endswith(".desktop"): + output = os.popen("desktop-file-validate %s" % path) + # This only produces output on errors + for l in output: + sane = package_qa_handle_error(7, l.strip(), name, path, d) -def package_qa_check_pcla(path,name,d): + return sane + +def package_qa_hash_style(path, name, d, elf): """ - .pc and .la files should not point + Check if the binary has the right hash style... """ + if not elf: + return True + + if os.path.islink(path): + return True + + gnu_hash = "--hash-style=gnu" in bb.data.getVar('LDFLAGS', d, True) + if not gnu_hash: + gnu_hash = "--hash-style=both" in bb.data.getVar('LDFLAGS', d, True) + if not gnu_hash: + return True + + objdump = bb.data.getVar('OBJDUMP', d, True) + env_path = bb.data.getVar('PATH', d, True) + + sane = True + elf = False + # A bit hacky. We do not know if path is an elf binary or not + # we will search for 'NEEDED' or 'INIT' as this should be printed... + # and come before the HASH section (guess!!!) and works on split out + # debug symbols too + for line in os.popen("LC_ALL=C PATH=%s %s -p '%s' 2> /dev/null" % (env_path, objdump, path), "r"): + if "NEEDED" in line or "INIT" in line: + sane = False + elf = True + if "GNU_HASH" in line: + sane = True + if "[mips32]" in line or "[mips64]" in line: + sane = True + + if elf and not sane: + error_msg = "No GNU_HASH in the elf binary: '%s'" % path + return package_qa_handle_error(9, error_msg, name, path, d) + + return True + def package_qa_check_staged(path,d): """ Check staged la and pc files for sanity -e.g. installed being false + + As this is run after every stage we should be able + to find the one responsible for the errors easily even + if we look at every .pc and .la file """ - pass + + sane = True + tmpdir = bb.data.getVar('TMPDIR', d, True) + workdir = os.path.join(tmpdir, "work") + + installed = "installed=yes" + iscrossnative = False + pkgconfigcheck = tmpdir + for s in ['cross', 'native', 'canadian-cross', 'canadian-native']: + if bb.data.inherits_class(s, d): + pkgconfigcheck = workdir + iscrossnative = True + + # find all .la and .pc files + # read the content + # and check for stuff that looks wrong + for root, dirs, files in os.walk(path): + for file in files: + path = os.path.join(root,file) + if file[-2:] == "la": + file_content = open(path).read() + # Don't check installed status for native/cross packages + if not iscrossnative: + if installed in file_content: + error_msg = "%s failed sanity test (installed) in path %s" % (file,root) + sane = package_qa_handle_error(5, error_msg, "staging", path, d) + if workdir in file_content: + error_msg = "%s failed sanity test (workdir) in path %s" % (file,root) + sane = package_qa_handle_error(8, error_msg, "staging", path, d) + elif file[-2:] == "pc": + file_content = open(path).read() + if pkgconfigcheck in file_content: + error_msg = "%s failed sanity test (tmpdir) in path %s" % (file,root) + sane = package_qa_handle_error(6, error_msg, "staging", path, d) + + return sane # Walk over all files in a directory and call func def package_qa_walk(path, funcs, package,d): - import os + sane = True + + #if this will throw an exception, then fix the dict above + target_os = bb.data.getVar('TARGET_OS', d, True) + target_arch = bb.data.getVar('TARGET_ARCH', d, True) + (machine, osabi, abiversion, littleendian, bits32) \ + = package_qa_get_machine_dict()[target_os][target_arch] + for root, dirs, files in os.walk(path): for file in files: path = os.path.join(root,file) + elf = package_qa_get_elf(path, bits32) + try: + elf.open() + except: + elf = None for func in funcs: - func(path, package,d) + if not func(path, package,d, elf): + sane = False + + return sane +def package_qa_check_rdepends(pkg, pkgdest, d): + sane = True + if not "-dbg" in pkg and not "task-" in pkg and not "-image" in pkg: + # Copied from package_ipk.bbclass + # boiler plate to update the data + localdata = bb.data.createCopy(d) + root = "%s/%s" % (pkgdest, pkg) + + bb.data.setVar('ROOT', '', localdata) + bb.data.setVar('ROOT_%s' % pkg, root, localdata) + pkgname = bb.data.getVar('PKG_%s' % pkg, localdata, True) + if not pkgname: + pkgname = pkg + bb.data.setVar('PKG', pkgname, localdata) + + overrides = bb.data.getVar('OVERRIDES', localdata) + if not overrides: + raise bb.build.FuncFailed('OVERRIDES not defined') + overrides = bb.data.expand(overrides, localdata) + bb.data.setVar('OVERRIDES', overrides + ':' + pkg, localdata) + + bb.data.update_data(localdata) + + # Now check the RDEPENDS + rdepends = explode_deps(bb.data.getVar('RDEPENDS', localdata, True) or "") + + + # Now do the sanity check!!! + for rdepend in rdepends: + if "-dbg" in rdepend: + error_msg = "%s rdepends on %s" % (pkgname,rdepend) + sane = package_qa_handle_error(2, error_msg, pkgname, rdepend, d) + + return sane # The PACKAGE FUNC to scan each package python do_package_qa () { - bb.note("DO PACKAGE QA") - workdir = bb.data.getVar('WORKDIR', d, True) + bb.debug(2, "DO PACKAGE QA") + pkgdest = bb.data.getVar('PKGDEST', d, True) packages = bb.data.getVar('PACKAGES',d, True) # no packages should be scanned if not packages: return + checks = [package_qa_check_rpath, package_qa_check_dev, + package_qa_check_perm, package_qa_check_arch, + package_qa_check_desktop, package_qa_hash_style, + package_qa_check_dbg] + walk_sane = True + rdepends_sane = True for package in packages.split(): - bb.note("Package: %s" % package) - path = "%s/install/%s" % (workdir, package) - package_qa_walk(path, [package_qa_check_rpath, package_qa_check_devdbg, package_qa_check_perm, package_qa_check_arch], package, d) + if bb.data.getVar('INSANE_SKIP_' + package, d, True): + bb.note("package %s skipped" % package) + continue + + bb.debug(1, "Checking Package: %s" % package) + path = "%s/%s" % (pkgdest, package) + if not package_qa_walk(path, checks, package, d): + walk_sane = False + if not package_qa_check_rdepends(package, pkgdest, d): + rdepends_sane = False + + if not walk_sane or not rdepends_sane: + bb.fatal("QA run found fatal errors. Please consider fixing them.") + bb.debug(2, "DONE with PACKAGE QA") } # The Staging Func, to check all staging addtask qa_staging after do_populate_staging before do_build python do_qa_staging() { - bb.note("Staged!") + bb.debug(2, "QA checking staging") + + if not package_qa_check_staged(bb.data.getVar('STAGING_LIBDIR',d,True), d): + bb.fatal("QA staging was broken by the package built above") +} - package_qa_check_staged(bb.data.getVar('STAGING_DIR',d,True), d) +# Check broken config.log files +addtask qa_configure after do_configure before do_compile +python do_qa_configure() { + bb.debug(1, "Checking sanity of the config.log file") + for root, dirs, files in os.walk(bb.data.getVar('WORKDIR', d, True)): + statement = "grep 'CROSS COMPILE Badness:' %s > /dev/null" % \ + os.path.join(root,"config.log") + if "config.log" in files: + if os.system(statement) == 0: + bb.fatal("""This autoconf log indicates errors, it looked at host includes. +Rerun configure task after fixing this. The path was '%s'""" % root) } diff --git a/classes/java-library.bbclass b/classes/java-library.bbclass new file mode 100644 index 0000000000..06c3170544 --- /dev/null +++ b/classes/java-library.bbclass @@ -0,0 +1,70 @@ +# Inherit this bbclass for each java recipe that builds a Java library (jar file[s]). +# +# It automatically adds important build dependencies, defines JPN (Java Package Name) +# a package named ${JPN} whose contents are those of ${datadir}/java (the jar location). +# +# The JPN is basically lib${PN}-java but takes care of the fact that ${PN} already +# starts with "lib" and/or ends with "-java". In case the "lib" prefix is part of +# your package's normal name (e.g. liberator) the guessing is wrong and you have +# to set JPN manually! + +inherit java + +# use java_stage for native packages +JAVA_NATIVE_STAGE_INSTALL = "1" + +def java_package_name(d): + import bb; + + pre="" + post="" + + pn = bb.data.getVar('PN', d, 1) + if not pn.startswith("lib"): + pre='lib' + + if not pn.endswith("-java"): + post='-java' + + return pre + pn + post + +JPN ?= "${@java_package_name(d)}" + +DEPENDS_prepend = "virtual/javac-native fastjar-native " + +PACKAGES = "${JPN}" + +PACKAGE_ARCH_${JPN} = "all" + +FILES_${JPN} = "${datadir_java}" + +# File name of the libraries' main Jar file +JARFILENAME = "${BP}.jar" + +# Space-separated list of alternative file names. +ALTJARFILENAMES = "${BPN}.jar" + +# Java "source" distributions often contain precompiled things +# we want to delete first. +do_removebinaries() { + find ${WORKDIR} -name "*.jar" -exec rm {} \; + find ${WORKDIR} -name "*.class" -exec rm {} \; +} + +addtask removebinaries after do_unpack before do_patch + +java_install() { + oe_jarinstall ${JARFILENAME} ${ALTJARFILENAMES} +} + +do_install() { + java_install +} + +java_stage() { + oe_jarinstall -s ${JARFILENAME} ${ALTJARFILENAMES} +} + +do_stage() { + java_stage +} diff --git a/classes/java-native.bbclass b/classes/java-native.bbclass new file mode 100644 index 0000000000..7b67c6041c --- /dev/null +++ b/classes/java-native.bbclass @@ -0,0 +1,11 @@ +# This is to be used by recipes which rely on java-library.bbclass +# infrastructure and are a *-native recipe which needs to install +# jar files into staging. +# +# This class has nothing to do with Java's JNI. + +inherit native + +do_stage () { + java_stage +} diff --git a/classes/java.bbclass b/classes/java.bbclass new file mode 100644 index 0000000000..d4cf5aa954 --- /dev/null +++ b/classes/java.bbclass @@ -0,0 +1,195 @@ +# Defines the commonly used target directories and provides a convenience +# function to install jar files. +# +# All the default directory locations herein resemble locations chosen in +# the Debian distribution. + +# Jar location on target +datadir_java ?= ${datadir}/java + +# JNI library location on target +libdir_jni ?= ${libdir}/jni + +# JVM bundle location on target +libdir_jvm ?= ${libdir}/jvm + +STAGING_DATADIR_JAVA ?= ${STAGING_DIR_JAVA} +STAGING_LIBDIR_JNI ?= ${STAGING_LIBDIR}/jni +STAGING_LIBDIR_JVM ?= ${STAGING_LIBDIR}/jvm + +STAGING_DATADIR_JAVA_NATIVE ?= ${STAGING_DATADIR_NATIVE}/java +STAGING_LIBDIR_JNI_NATIVE ?= ${STAGING_LIBDIR_NATIVE}/jni +STAGING_LIBDIR_JVM_NATIVE ?= ${STAGING_LIBDIR_NATIVE}/jvm + +oe_jarinstall() { + # Purpose: Install a jar file and create all the given symlinks to it. + # Example: + # oe_jarinstall foo-1.3.jar foo.jar + # Installs foo-1.3.jar and creates symlink foo.jar. + # + # oe_jarinstall -s foo-1.3.jar foo.jar + # Installs foo-1.3.jar to staging and creates symlink foo.jar. + # + # oe_jarinstall -r foo-1.3.jar foo_1_3.jar foo.jar + # Installs foo_1_3.jar as foo-1.3.jar and creates a symlink to this. + # + dir=${D}${datadir_java} + destname="" + while [ "$#" -gt 0 ]; do + case "$1" in + -s) + # put jar files to native staging if this is a -native recipe + if [ ${PACKAGE_ARCH} = ${BUILD_ARCH} ]; then + dir=${STAGING_DATADIR_JAVA_NATIVE} + else + dir=${STAGING_DATADIR_JAVA} + fi + ;; + -r) + shift + destname=$1 + ;; + -*) + oefatal "oe_jarinstall: unknown option: $1" + ;; + *) + break; + ;; + esac + shift + done + + jarname=$1 + destname=${destname:-`basename $jarname`} + shift + + install -d $dir + install -m 0644 $jarname $dir/$destname + + # Creates symlinks out of the remaining arguments. + while [ "$#" -gt 0 ]; do + if [ -e $dir/$1 -o -h $dir/$1 ]; then + oewarn "file was in the way. removing:" $dir/$1 + rm $dir/$1 + fi + ln -s $destname $dir/$1 + shift + done +} + +oe_makeclasspath() { + # Purpose: Generate a classpath variable from the given Jar file names + # where the ".jar" has been omitted. The string is stored in the script + # variable whose name is given in the first argument to this function. + # + # oe_makeclasspath cp foo baz bar + # Stores ${datadir_java}/foo.jar:${datadir_java}/baz.jar:${datadir_java}/bar.jar + # in variable "cp". + # + # oe_makeclasspath bootcp -s foo baz bar + # Stores ${STAGING_DATADIR_JAVA}/foo.jar:${STAGING_DATADIR_JAVA}/baz.jar:${STAGING_DATADIR_JAVA}/bar.jar + # in variable "bootcp". + # + # Provide the -s at the beginning otherwise strange things happen. + # If -s is given the function checks whether the requested jar file exists + # and exits with an error message if it cannot be found. + # + # Note: In order to encourage usage of the DEPENDS variable, the function + # can accept recipe names. If a recipe has no corresponding Jar file it + # is ignored. Be careful with recipes where the recipe name is different + # from the the Jar file name! + dir=${datadir_java} + classpath= + delimiter= + retval=$1 + + shift + + while [ "$#" -gt 0 ]; do + case "$1" in + -s) + # take jar files from native staging if this is a -native recipe + if [ ${PACKAGE_ARCH} = ${BUILD_ARCH} ]; then + dir=${STAGING_DATADIR_JAVA_NATIVE} + else + dir=${STAGING_DATADIR_JAVA} + fi + ;; + -*) + oefatal "oe_makeclasspath: unknown option: $1" + ;; + *) + file=$dir/$1.jar + + if [ -e $file ]; then + classpath=$classpath$delimiter$file + delimiter=":" + fi + + ;; + esac + shift + done + + eval $retval="$classpath" +} + +# Creates a simple wrapper script for your Java program. +# The script is written to ${PN} by default. +# +# Parameters are as follows: +# [options] <output file> <main class> [jar files ...] +# +# Options are +# -o <name> where name is the output file name +# +# It can only take jar files from ${datadir_java}! +oe_java_simple_wrapper() { + delimiter= + mainclass= + classpath= + output=${PN} + + while [ "$#" -gt 0 ]; do + case "$1" in + -o) + shift + output=$1 + ;; + -*) + oefatal "oe_java_simple_wrapper: unknown option: $1" + ;; + *) + if [ $mainclass ] + then + classpath=$classpath$delimiter${datadir_java}/$1 + delimiter=":" + else + mainclass=$1 + fi + ;; + esac + shift + done + + oenote "Creating simple Java wrapper script" + oenote "Output File: $output" + oenote "Main Class: $mainclass" + oenote "Classpath: $classpath" + + echo "#!/bin/sh" > $output + echo "# This file is autogenerated by the oe_java_simple_wrapper function of OpenEmbedded" >> $output + echo >> $output + echo "# You can provide additional VM arguments by setting the VMARGS environment variable." >> $output + echo "CLASSPATH_ARG=\"-cp $classpath\"" >> $output + echo >> $output + echo "MAIN_CLASS=$mainclass" >> $output + echo >> $output + echo "# Allows overriding the VM by setting the JAVA environment variable." >> $output + echo "if [ x\${JAVA} = x ]" >> $output + echo "then" >> $output + echo " JAVA=java" >> $output + echo "fi" >> $output + echo >> $output + echo "exec \${JAVA} \${VMARGS} \${CLASSPATH_ARG} \${MAIN_CLASS} \${@}" >> $output +} diff --git a/classes/kernel-arch.bbclass b/classes/kernel-arch.bbclass index b331d25614..8894fa554c 100644 --- a/classes/kernel-arch.bbclass +++ b/classes/kernel-arch.bbclass @@ -4,24 +4,39 @@ # in the kernel source "arch" directory # -valid_archs = "alpha cris ia64 m68knommu ppc sh \ - sparc64 x86_64 arm h8300 m32r mips \ - ppc64 sh64 um arm26 i386 m68k \ - parisc s390 sparc v850" +valid_archs = "alpha cris ia64 \ + x86_64 i386 x86 \ + m68knommu m68k ppc powerpc ppc64 \ + sparc sparc64 \ + arm arm26 \ + m32r mips \ + sh sh64 um h8300 \ + parisc s390 v850 \ + avr32 blackfin" def map_kernel_arch(a, d): - import bb, re + import re valid_archs = bb.data.getVar('valid_archs', d, 1).split() if re.match('(i.86|athlon)$', a): return 'i386' elif re.match('arm26$', a): return 'arm26' elif re.match('armeb$', a): return 'arm' - elif re.match('powerpc$', a): return 'ppc' elif re.match('mipsel$', a): return 'mips' elif re.match('sh(3|4)$', a): return 'sh' - elif a in valid_archs: return a + elif re.match('bfin', a): return 'blackfin' + elif a in valid_archs: return a else: bb.error("cannot map '%s' to a linux kernel architecture" % a) export ARCH = "${@map_kernel_arch(bb.data.getVar('TARGET_ARCH', d, 1), d)}" + +def map_uboot_arch(a, d): + import re + + if re.match('powerpc$', a): return 'ppc' + elif re.match('i.86$', a): return 'x86' + return a + +export UBOOT_ARCH = "${@map_uboot_arch(bb.data.getVar('ARCH', d, 1), d)}" + diff --git a/classes/kernel.bbclass b/classes/kernel.bbclass index 3a7fd5b499..83530b5a5e 100644 --- a/classes/kernel.bbclass +++ b/classes/kernel.bbclass @@ -3,23 +3,42 @@ inherit linux-kernel-base module_strip PROVIDES += "virtual/kernel" DEPENDS += "virtual/${TARGET_PREFIX}depmod-${@get_kernelmajorversion('${PV}')} virtual/${TARGET_PREFIX}gcc${KERNEL_CCSUFFIX} update-modules" +KERNEL_IMAGETYPE ?= "zImage" + +# Add dependency on mkimage for kernels that build a uImage + +python __anonymous () { + kerneltype = bb.data.getVar('KERNEL_IMAGETYPE', d, 1) or '' + if kerneltype == 'uImage': + depends = bb.data.getVar("DEPENDS", d, 1) + depends = "%s u-boot-mkimage-openmoko-native" % depends + bb.data.setVar("DEPENDS", depends, d) + + image = bb.data.getVar('INITRAMFS_IMAGE', d, True) + if image != '' and image is not None: + bb.data.setVar('INITRAMFS_TASK', '${INITRAMFS_IMAGE}:do_rootfs', d) + + machine_kernel_pr = bb.data.getVar('MACHINE_KERNEL_PR', d, True) + + if machine_kernel_pr: + bb.data.setVar('PR', machine_kernel_pr, d) +} + +INITRAMFS_IMAGE ?= "" +INITRAMFS_TASK ?= "" + inherit kernel-arch PACKAGES_DYNAMIC += "kernel-module-*" PACKAGES_DYNAMIC += "kernel-image-*" +PACKAGES_DYNAMIC += "kernel-firmware-*" export OS = "${TARGET_OS}" export CROSS_COMPILE = "${TARGET_PREFIX}" -KERNEL_IMAGETYPE ?= "zImage" KERNEL_PRIORITY = "${@bb.data.getVar('PV',d,1).split('-')[0].split('.')[-1]}" -# [jbowler 20051109] ${PV}${KERNEL_LOCALVERSION} is used throughout this -# .bbclass to (apparently) find the full 'uname -r' kernel version, this -# should be the same as UTS_RELEASE or (in this file) KERNEL_VERSION: -# KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)$(LOCALVERSION) -# but since this is not certain this overridable setting is used here: -KERNEL_RELEASE ?= "${PV}${KERNEL_LOCALVERSION}" +KERNEL_RELEASE ?= "${KERNEL_VERSION}" KERNEL_CCSUFFIX ?= "" KERNEL_LDSUFFIX ?= "" @@ -35,7 +54,8 @@ HOST_LD_KERNEL_ARCH ?= "${TARGET_LD_KERNEL_ARCH}" KERNEL_CC = "${CCACHE}${HOST_PREFIX}gcc${KERNEL_CCSUFFIX} ${HOST_CC_KERNEL_ARCH}" KERNEL_LD = "${LD}${KERNEL_LDSUFFIX} ${HOST_LD_KERNEL_ARCH}" -KERNEL_OUTPUT = "arch/${ARCH}/boot/${KERNEL_IMAGETYPE}" +# Where built kernel lies in the kernel tree +KERNEL_OUTPUT ?= "arch/${ARCH}/boot/${KERNEL_IMAGETYPE}" KERNEL_IMAGEDEST = "boot" # @@ -51,8 +71,16 @@ KERNEL_LOCALVERSION ?= "" # kernels are generally machine specific PACKAGE_ARCH = "${MACHINE_ARCH}" +# U-Boot support +UBOOT_ENTRYPOINT ?= "20008000" +UBOOT_LOADADDRESS ?= "${UBOOT_ENTRYPOINT}" + +# For the kernel, we don't want the '-e MAKEFLAGS=' in EXTRA_OEMAKE. +# We don't want to override kernel Makefile variables from the environment +EXTRA_OEMAKE = "" + kernel_do_compile() { - unset CFLAGS CPPFLAGS CXXFLAGS LDFLAGS + unset CFLAGS CPPFLAGS CXXFLAGS LDFLAGS MACHINE oe_runmake include/linux/version.h CC="${KERNEL_CC}" LD="${KERNEL_LD}" if [ "${KERNEL_MAJOR_VERSION}" != "2.6" ]; then oe_runmake dep CC="${KERNEL_CC}" LD="${KERNEL_LD}" @@ -64,14 +92,35 @@ kernel_do_compile() { oenote "no modules to compile" fi } +kernel_do_compile[depends] = "${INITRAMFS_TASK}" kernel_do_stage() { - ASMDIR=`readlink include/asm` + if [ -e include/asm ] ; then + # This link is generated only in kernel before 2.6.33-rc1, don't stage it for newer kernels + ASMDIR=`readlink include/asm` - mkdir -p ${STAGING_KERNEL_DIR}/include/$ASMDIR - cp -fR include/$ASMDIR/* ${STAGING_KERNEL_DIR}/include/$ASMDIR/ - rm -f $ASMDIR ${STAGING_KERNEL_DIR}/include/asm - ln -sf $ASMDIR ${STAGING_KERNEL_DIR}/include/asm + mkdir -p ${STAGING_KERNEL_DIR}/include/$ASMDIR + cp -fR include/$ASMDIR/* ${STAGING_KERNEL_DIR}/include/$ASMDIR/ + fi + # Kernel 2.6.27 moved headers from includes/asm-${ARCH} to arch/${ARCH}/include/asm + if [ -e arch/${ARCH}/include/asm/ ] ; then + if [ -e include/asm ] ; then + cp -fR arch/${ARCH}/include/asm/* ${STAGING_KERNEL_DIR}/include/$ASMDIR/ + fi + install -d ${STAGING_KERNEL_DIR}/arch/${ARCH}/include + cp -fR arch/${ARCH}/* ${STAGING_KERNEL_DIR}/arch/${ARCH}/ + + # Check for arch/x86 on i386 + elif [ -d arch/x86/include/asm/ ]; then + cp -fR arch/x86/include/asm/* ${STAGING_KERNEL_DIR}/include/asm-x86/ + install -d ${STAGING_KERNEL_DIR}/arch/x86/include + cp -fR arch/x86/* ${STAGING_KERNEL_DIR}/arch/x86/ + fi + + if [ -e include/asm ] ; then + rm -f ${STAGING_KERNEL_DIR}/include/asm + ln -sf $ASMDIR ${STAGING_KERNEL_DIR}/include/asm + fi mkdir -p ${STAGING_KERNEL_DIR}/include/asm-generic cp -fR include/asm-generic/* ${STAGING_KERNEL_DIR}/include/asm-generic/ @@ -85,25 +134,12 @@ kernel_do_stage() { mkdir -p ${STAGING_KERNEL_DIR}/include/pcmcia cp -fR include/pcmcia/* ${STAGING_KERNEL_DIR}/include/pcmcia/ - if [ -d drivers/crypto ]; then - mkdir -p ${STAGING_KERNEL_DIR}/drivers/crypto - cp -fR drivers/crypto/* ${STAGING_KERNEL_DIR}/drivers/crypto/ - fi - - if [ -d include/media ]; then - mkdir -p ${STAGING_KERNEL_DIR}/include/media - cp -fR include/media/* ${STAGING_KERNEL_DIR}/include/media/ - fi - - if [ -d include/acpi ]; then - mkdir -p ${STAGING_KERNEL_DIR}/include/acpi - cp -fR include/acpi/* ${STAGING_KERNEL_DIR}/include/acpi/ - fi - - if [ -d include/sound ]; then - mkdir -p ${STAGING_KERNEL_DIR}/include/sound - cp -fR include/sound/* ${STAGING_KERNEL_DIR}/include/sound/ - fi + for entry in drivers/crypto drivers/media include/media include/acpi include/sound include/video include/scsi include/trace; do + if [ -d $entry ]; then + mkdir -p ${STAGING_KERNEL_DIR}/$entry + cp -fR $entry/* ${STAGING_KERNEL_DIR}/$entry/ + fi + done if [ -d drivers/sound ]; then # 2.4 alsa needs some headers from this directory @@ -111,9 +147,9 @@ kernel_do_stage() { cp -fR drivers/sound/*.h ${STAGING_KERNEL_DIR}/include/drivers/sound/ fi - install -m 0644 .config ${STAGING_KERNEL_DIR}/config-${KERNEL_RELEASE} - ln -sf config-${KERNEL_RELEASE} ${STAGING_KERNEL_DIR}/.config - ln -sf config-${KERNEL_RELEASE} ${STAGING_KERNEL_DIR}/kernel-config + install -m 0644 .config ${STAGING_KERNEL_DIR}/config-${KERNEL_VERSION} + ln -sf config-${KERNEL_VERSION} ${STAGING_KERNEL_DIR}/.config + ln -sf config-${KERNEL_VERSION} ${STAGING_KERNEL_DIR}/kernel-config echo "${KERNEL_VERSION}" >${STAGING_KERNEL_DIR}/kernel-abiversion echo "${S}" >${STAGING_KERNEL_DIR}/kernel-source echo "${KERNEL_CCSUFFIX}" >${STAGING_KERNEL_DIR}/kernel-ccsuffix @@ -125,17 +161,23 @@ kernel_do_stage() { if [ -e arch/${ARCH}/Makefile ]; then install -d ${STAGING_KERNEL_DIR}/arch/${ARCH} install -m 0644 arch/${ARCH}/Makefile* ${STAGING_KERNEL_DIR}/arch/${ARCH} + # Otherwise check arch/x86/Makefile for i386 and x86_64 on kernels >= 2.6.24 + elif [ -e arch/x86/Makefile ]; then + install -d ${STAGING_KERNEL_DIR}/arch/x86 + install -m 0644 arch/x86/Makefile* ${STAGING_KERNEL_DIR}/arch/x86 fi cp -fR include/config* ${STAGING_KERNEL_DIR}/include/ + # Install kernel images and system.map to staging + [ -e vmlinux ] && install -m 0644 vmlinux ${STAGING_KERNEL_DIR}/ install -m 0644 ${KERNEL_OUTPUT} ${STAGING_KERNEL_DIR}/${KERNEL_IMAGETYPE} - install -m 0644 System.map ${STAGING_KERNEL_DIR}/System.map-${KERNEL_RELEASE} + install -m 0644 System.map ${STAGING_KERNEL_DIR}/System.map-${KERNEL_VERSION} [ -e Module.symvers ] && install -m 0644 Module.symvers ${STAGING_KERNEL_DIR}/ cp -fR scripts ${STAGING_KERNEL_DIR}/ } kernel_do_install() { - unset CFLAGS CPPFLAGS CXXFLAGS LDFLAGS + unset CFLAGS CPPFLAGS CXXFLAGS LDFLAGS MACHINE if (grep -q -i -e '^CONFIG_MODULES=y$' .config); then oe_runmake DEPMOD=echo INSTALL_MOD_PATH="${D}" modules_install else @@ -144,11 +186,16 @@ kernel_do_install() { install -d ${D}/${KERNEL_IMAGEDEST} install -d ${D}/boot - install -m 0644 ${KERNEL_OUTPUT} ${D}/${KERNEL_IMAGEDEST}/${KERNEL_IMAGETYPE}-${KERNEL_RELEASE} - install -m 0644 System.map ${D}/boot/System.map-${KERNEL_RELEASE} - install -m 0644 .config ${D}/boot/config-${KERNEL_RELEASE} + install -m 0644 ${KERNEL_OUTPUT} ${D}/${KERNEL_IMAGEDEST}/${KERNEL_IMAGETYPE}-${KERNEL_VERSION} + install -m 0644 System.map ${D}/boot/System.map-${KERNEL_VERSION} + install -m 0644 .config ${D}/boot/config-${KERNEL_VERSION} + install -m 0644 vmlinux ${D}/boot/vmlinux-${KERNEL_VERSION} + [ -e Module.symvers ] && install -m 0644 Module.symvers ${D}/boot/Module.symvers-${KERNEL_VERSION} install -d ${D}/etc/modutils - + if [ "${KERNEL_MAJOR_VERSION}" = "2.6" ]; then + install -d ${D}/etc/modprobe.d + fi + # Check if scripts/genksyms exists and if so, build it if [ -e scripts/genksyms/ ]; then oe_runmake SUBDIRS="scripts/genksyms" @@ -159,36 +206,73 @@ kernel_do_install() { } kernel_do_configure() { - yes '' | oe_runmake oldconfig + yes '' | oe_runmake oldconfig + if [ ! -z "${INITRAMFS_IMAGE}" ]; then + for img in cpio.gz cpio.lzo cpio.lzma; do + if [ -e "${DEPLOY_DIR_IMAGE}/${INITRAMFS_IMAGE}-${MACHINE}.$img" ]; then + cp "${DEPLOY_DIR_IMAGE}/${INITRAMFS_IMAGE}-${MACHINE}.$img" initramfs.$img + fi + done + fi +} + +do_menuconfig() { + export TERMWINDOWTITLE="${PN} Kernel Configuration" + export SHELLCMDS="make menuconfig" + ${TERMCMDRUN} + if [ $? -ne 0 ]; then + echo "Fatal: '${TERMCMD}' not found. Check TERMCMD variable." + exit 1 + fi } +do_menuconfig[nostamp] = "1" +addtask menuconfig after do_configure pkg_postinst_kernel () { - update-alternatives --install /${KERNEL_IMAGEDEST}/${KERNEL_IMAGETYPE} ${KERNEL_IMAGETYPE} /${KERNEL_IMAGEDEST}/${KERNEL_IMAGETYPE}-${KERNEL_RELEASE} ${KERNEL_PRIORITY} || true + cd /${KERNEL_IMAGEDEST}; update-alternatives --install /${KERNEL_IMAGEDEST}/${KERNEL_IMAGETYPE} ${KERNEL_IMAGETYPE} ${KERNEL_IMAGETYPE}-${KERNEL_VERSION} ${KERNEL_PRIORITY} || true } pkg_postrm_kernel () { - update-alternatives --remove ${KERNEL_IMAGETYPE} /${KERNEL_IMAGEDEST}/${KERNEL_IMAGETYPE}-${KERNEL_RELEASE} || true + cd /${KERNEL_IMAGEDEST}; update-alternatives --remove ${KERNEL_IMAGETYPE} ${KERNEL_IMAGETYPE}-${KERNEL_VERSION} || true } inherit cml1 EXPORT_FUNCTIONS do_compile do_install do_stage do_configure -PACKAGES = "kernel kernel-image kernel-dev" +# kernel-base becomes kernel-${KERNEL_VERSION} +# kernel-image becomes kernel-image-${KERNEL_VERISON} +PACKAGES = "kernel kernel-base kernel-image kernel-dev kernel-vmlinux" FILES = "" FILES_kernel-image = "/boot/${KERNEL_IMAGETYPE}*" -FILES_kernel-dev = "/boot/System.map* /boot/config*" -RDEPENDS_kernel = "kernel-image-${KERNEL_VERSION}" +FILES_kernel-dev = "/boot/System.map* /boot/Module.symvers* /boot/config*" +FILES_kernel-vmlinux = "/boot/vmlinux*" +RDEPENDS_kernel = "kernel-base" +RRECOMMENDS_kernel-module-hostap-cs += '${@base_version_less_or_equal("KERNEL_VERSION", "2.6.17", "", "apm-wifi-suspendfix", d)}' +RRECOMMENDS_kernel-module-orinoco-cs += '${@base_version_less_or_equal("KERNEL_VERSION", "2.6.17", "", "apm-wifi-suspendfix", d)}' +# Allow machines to override this dependency if kernel image files are +# not wanted in images as standard +RDEPENDS_kernel-base ?= "kernel-image" PKG_kernel-image = "kernel-image-${KERNEL_VERSION}" +PKG_kernel-base = "kernel-${KERNEL_VERSION}" ALLOW_EMPTY_kernel = "1" +ALLOW_EMPTY_kernel-base = "1" ALLOW_EMPTY_kernel-image = "1" +# Userspace workarounds for kernel modules issues +# This is shame, fix the kernel instead! +DEPENDS_kernel-module-dtl1-cs = "bluez-dtl1-workaround" +RDEPENDS_kernel-module-dtl1-cs = "bluez-dtl1-workaround" + +# renamed modules +RPROVIDES_kernel-module-aes-generic = "kernel-module-aes" + pkg_postinst_kernel-image () { -if [ ! -e "$D/lib/modules/${KERNEL_RELEASE}" ]; then - mkdir -p $D/lib/modules/${KERNEL_RELEASE} +if [ ! -e "$D/lib/modules/${KERNEL_VERSION}" ]; then + mkdir -p $D/lib/modules/${KERNEL_VERSION} fi if [ -n "$D" ]; then - ${HOST_PREFIX}depmod-${KERNEL_MAJOR_VERSION} -A -b $D -F ${STAGING_KERNEL_DIR}/System.map-${KERNEL_RELEASE} ${KERNEL_VERSION} + ${HOST_PREFIX}depmod-${KERNEL_MAJOR_VERSION} -A -b $D -F ${STAGING_KERNEL_DIR}/System.map-${KERNEL_VERSION} ${KERNEL_VERSION} else depmod -a fi @@ -196,7 +280,7 @@ fi pkg_postinst_modules () { if [ -n "$D" ]; then - ${HOST_PREFIX}depmod-${KERNEL_MAJOR_VERSION} -A -b $D -F ${STAGING_KERNEL_DIR}/System.map-${KERNEL_RELEASE} ${KERNEL_VERSION} + ${HOST_PREFIX}depmod-${KERNEL_MAJOR_VERSION} -A -b $D -F ${STAGING_KERNEL_DIR}/System.map-${KERNEL_VERSION} ${KERNEL_VERSION} else depmod -a update-modules || true @@ -220,6 +304,8 @@ module_autoload_ipsec = "ipsec" module_autoload_ircomm-tty = "ircomm-tty" module_autoload_rfcomm = "rfcomm" module_autoload_sa1100-rtc = "sa1100-rtc" +# sa1100-rtc was renamed in 2.6.23 onwards +module_autoload_rtc-sa1100 = "rtc-sa1100" # alias defaults (alphabetically sorted) module_conf_af_packet = "alias net-pf-17 af_packet" @@ -231,14 +317,18 @@ module_conf_sco = "alias bt-proto-2 sco" module_conf_rfcomm = "alias bt-proto-3 rfcomm" python populate_packages_prepend () { + import os def extract_modinfo(file): - import os, re - tmpfile = os.tmpnam() + import tempfile, re + tempfile.tempdir = bb.data.getVar("WORKDIR", d, 1) + tf = tempfile.mkstemp() + tmpfile = tf[1] cmd = "PATH=\"%s\" %sobjcopy -j .modinfo -O binary %s %s" % (bb.data.getVar("PATH", d, 1), bb.data.getVar("HOST_PREFIX", d, 1) or "", file, tmpfile) os.system(cmd) f = open(tmpfile) l = f.read().split("\000") f.close() + os.close(tf[0]) os.unlink(tmpfile) exp = re.compile("([^=]+)=(.*)") vals = {} @@ -250,14 +340,14 @@ python populate_packages_prepend () { return vals def parse_depmod(): - import os, re + import re - dvar = bb.data.getVar('D', d, 1) + dvar = bb.data.getVar('PKGD', d, 1) if not dvar: bb.error("D not defined") return - kernelver = bb.data.getVar('KERNEL_RELEASE', d, 1) + kernelver = bb.data.getVar('KERNEL_VERSION', d, 1) kernelver_stripped = kernelver m = re.match('^(.*-hh.*)[\.\+].*$', kernelver) if m: @@ -301,10 +391,10 @@ python populate_packages_prepend () { return deps def get_dependencies(file, pattern, format): - file = file.replace(bb.data.getVar('D', d, 1) or '', '', 1) + file = file.replace(bb.data.getVar('PKGD', d, 1) or '', '', 1) if module_deps.has_key(file): - import os.path, re + import re dependencies = [] for i in module_deps[file]: m = re.match(pattern, os.path.basename(i)) @@ -312,10 +402,6 @@ python populate_packages_prepend () { continue on = legitimize_package_name(m.group(1)) dependency_pkg = format % on - v = bb.data.getVar("PARALLEL_INSTALL_MODULES", d, 1) or "0" - if v == "1": - kv = bb.data.getVar("KERNEL_MAJOR_VERSION", d, 1) - dependency_pkg = "%s-%s" % (dependency_pkg, kv) dependencies.append(dependency_pkg) return dependencies return [] @@ -324,11 +410,14 @@ python populate_packages_prepend () { import re vals = extract_modinfo(file) - dvar = bb.data.getVar('D', d, 1) + dvar = bb.data.getVar('PKGD', d, 1) # If autoloading is requested, output /etc/modutils/<name> and append # appropriate modprobe commands to the postinst autoload = bb.data.getVar('module_autoload_%s' % basename, d, 1) + if not autoload: + # Also, try canonical name with dashes + autoload = bb.data.getVar('module_autoload_%s' % basename.replace('_', '-'), d, 1) if autoload: name = '%s/etc/modutils/%s' % (dvar, basename) f = open(name, 'w') @@ -344,13 +433,16 @@ python populate_packages_prepend () { # Write out any modconf fragment modconf = bb.data.getVar('module_conf_%s' % basename, d, 1) if modconf: - name = '%s/etc/modutils/%s.conf' % (dvar, basename) + if bb.data.getVar("KERNEL_MAJOR_VERSION", d, 1) == "2.6": + name = '%s/etc/modprobe.d/%s.conf' % (dvar, basename) + else: + name = '%s/etc/modutils/%s.conf' % (dvar, basename) f = open(name, 'w') f.write("%s\n" % modconf) f.close() files = bb.data.getVar('FILES_%s' % pkg, d, 1) - files = "%s /etc/modutils/%s /etc/modutils/%s.conf" % (files, basename, basename) + files = "%s /etc/modutils/%s /etc/modutils/%s.conf /etc/modprobe.d/%s.conf" % (files, basename, basename, basename) bb.data.setVar('FILES_%s' % pkg, files, d) if vals.has_key("description"): @@ -371,13 +463,20 @@ python populate_packages_prepend () { postinst = bb.data.getVar('pkg_postinst_modules', d, 1) postrm = bb.data.getVar('pkg_postrm_modules', d, 1) - do_split_packages(d, root='/lib/modules', file_regex=module_regex, output_pattern=module_pattern, description='%s kernel module', postinst=postinst, postrm=postrm, recursive=True, hook=frob_metadata, extra_depends='update-modules kernel-image-%s' % bb.data.getVar("KERNEL_VERSION", d, 1)) - import re, os + maybe_update_modules = "update-modules " + if bb.data.getVar("ONLINE_PACKAGE_MANAGEMENT", d) == "none": + maybe_update_modules = "" + + do_split_packages(d, root='/lib/firmware', file_regex='^(.*)\.bin$', output_pattern='kernel-firmware-%s', description='Firmware for %s', recursive=True, extra_depends='') + do_split_packages(d, root='/lib/firmware', file_regex='^(.*)\.fw$', output_pattern='kernel-firmware-%s', description='Firmware for %s', recursive=True, extra_depends='') + do_split_packages(d, root='/lib/modules', file_regex=module_regex, output_pattern=module_pattern, description='%s kernel module', postinst=postinst, postrm=postrm, recursive=True, hook=frob_metadata, extra_depends='%skernel-%s' % (maybe_update_modules, bb.data.getVar("KERNEL_VERSION", d, 1))) + + import re metapkg = "kernel-modules" bb.data.setVar('ALLOW_EMPTY_' + metapkg, "1", d) bb.data.setVar('FILES_' + metapkg, "", d) - blacklist = [ 'kernel-dev', 'kernel-image' ] + blacklist = [ 'kernel-dev', 'kernel-image', 'kernel-base', 'kernel-vmlinux' ] for l in module_deps.values(): for i in l: pkg = module_pattern % legitimize_package_name(re.match(module_regex, os.path.basename(i)).group(1)) @@ -391,36 +490,65 @@ python populate_packages_prepend () { bb.data.setVar('DESCRIPTION_' + metapkg, 'Kernel modules meta package', d) packages.append(metapkg) bb.data.setVar('PACKAGES', ' '.join(packages), d) +} - v = bb.data.getVar("PARALLEL_INSTALL_MODULES", d, 1) or "0" - if v == "1": - kv = bb.data.getVar("KERNEL_MAJOR_VERSION", d, 1) - packages = bb.data.getVar("PACKAGES", d, 1).split() - module_re = re.compile("^kernel-module-") +# Support checking the kernel size since some kernels need to reside in partitions +# with a fixed length or there is a limit in transferring the kernel to memory +do_sizecheck() { + if [ ! -z "${KERNEL_IMAGE_MAXSIZE}" -a -z "${DONT_CHECK_KERNELSIZE}" ]; then + size=`ls -l ${KERNEL_OUTPUT} | awk '{ print $5}'` + if [ $size -ge ${KERNEL_IMAGE_MAXSIZE} ]; then + rm ${KERNEL_OUTPUT} + die "This kernel (size=$size > ${KERNEL_IMAGE_MAXSIZE}) is too big for your device. Please reduce the size of the kernel by making more of it modular." + fi + fi +} - newmetapkg = "kernel-modules-%s" % kv - bb.data.setVar('ALLOW_EMPTY_' + newmetapkg, "1", d) - bb.data.setVar('FILES_' + newmetapkg, "", d) +addtask sizecheck before do_install after do_compile - newmetapkg_rdepends = [] +do_uboot_mkimage() { + if test "x${KERNEL_IMAGETYPE}" = "xuImage" ; then + ENTRYPOINT=${UBOOT_ENTRYPOINT} + if test -n "${UBOOT_ENTRYSYMBOL}"; then + ENTRYPOINT=`${HOST_PREFIX}nm ${S}/vmlinux | \ + awk '$3=="${UBOOT_ENTRYSYMBOL}" {print $1}'` + fi + if test -e arch/${ARCH}/boot/compressed/vmlinux ; then + ${OBJCOPY} -O binary -R .note -R .comment -S arch/${ARCH}/boot/compressed/vmlinux linux.bin + uboot-mkimage -A ${UBOOT_ARCH} -O linux -T kernel -C none -a ${UBOOT_LOADADDRESS} -e $ENTRYPOINT -n "${DISTRO_NAME}/${PV}/${MACHINE}" -d linux.bin arch/${ARCH}/boot/uImage + rm -f linux.bin + else + ${OBJCOPY} -O binary -R .note -R .comment -S vmlinux linux.bin + rm -f linux.bin.gz + gzip -9 linux.bin + uboot-mkimage -A ${UBOOT_ARCH} -O linux -T kernel -C gzip -a ${UBOOT_LOADADDRESS} -e $ENTRYPOINT -n "${DISTRO_NAME}/${PV}/${MACHINE}" -d linux.bin.gz arch/${ARCH}/boot/uImage + rm -f linux.bin.gz + fi + fi +} - for p in packages: - if not module_re.match(p): - continue - pkg = bb.data.getVar("PKG_%s" % p, d, 1) or p - newpkg = "%s-%s" % (pkg, kv) - bb.data.setVar("PKG_%s" % p, newpkg, d) - rprovides = bb.data.getVar("RPROVIDES_%s" % p, d, 1) - if rprovides: - rprovides = "%s %s" % (rprovides, pkg) - else: - rprovides = pkg - bb.data.setVar("RPROVIDES_%s" % p, rprovides, d) - newmetapkg_rdepends.append(newpkg) +addtask uboot_mkimage before do_install after do_compile + +KERNEL_IMAGE_BASE_NAME ?= "${KERNEL_IMAGETYPE}-${PV}-${PR}-${MACHINE}" +KERNEL_IMAGE_SYMLINK_NAME ?= "${KERNEL_IMAGETYPE}-${MACHINE}" +MODULES_IMAGE_BASE_NAME ?= modules-${PV}-${PR}-${MACHINE} + +do_deploy() { + install -d ${DEPLOY_DIR_IMAGE} + install -m 0644 ${KERNEL_OUTPUT} ${DEPLOY_DIR_IMAGE}/${KERNEL_IMAGE_BASE_NAME}.bin + package_stagefile_shell ${DEPLOY_DIR_IMAGE}/${KERNEL_IMAGE_BASE_NAME}.bin - bb.data.setVar('RDEPENDS_' + newmetapkg, ' '.join(newmetapkg_rdepends), d) - bb.data.setVar('DESCRIPTION_' + newmetapkg, 'Kernel modules meta package', d) - packages.append(newmetapkg) - bb.data.setVar('PACKAGES', ' '.join(packages), d) + if [ -d "${PKGD}/lib" ]; then + fakeroot tar -cvzf ${DEPLOY_DIR_IMAGE}/${MODULES_IMAGE_BASE_NAME}.tgz -C ${PKGD} lib + fi + cd ${DEPLOY_DIR_IMAGE} + rm -f ${KERNEL_IMAGE_SYMLINK_NAME}.bin + ln -sf ${KERNEL_IMAGE_BASE_NAME}.bin ${KERNEL_IMAGE_SYMLINK_NAME}.bin + package_stagefile_shell ${DEPLOY_DIR_IMAGE}/${KERNEL_IMAGE_SYMLINK_NAME}.bin } + +do_deploy[dirs] = "${S}" +do_deploy[depends] += "fakeroot-native:do_populate_staging" + +addtask deploy before do_build after do_package diff --git a/classes/lib_package.bbclass b/classes/lib_package.bbclass index e29d2659b0..82c93707ea 100644 --- a/classes/lib_package.bbclass +++ b/classes/lib_package.bbclass @@ -1,9 +1,10 @@ -PACKAGES = "${PN} ${PN}-dev ${PN}-doc ${PN}-bin" +PACKAGES += "${PN}-bin" -FILES_${PN} = "${libexecdir} ${libdir}/lib*.so.* \ +FILES_${PN} = "${libexecdir} ${libdir}/lib*${SOLIBS} \ ${sysconfdir} ${sharedstatedir} ${localstatedir} \ - /lib/*.so* ${datadir}/${PN} ${libdir}/${PN}" -FILES_${PN}-dev = "${includedir} ${libdir}/lib*.so ${libdir}/*.la \ + ${base_libdir}/*${SOLIBS} \ + ${datadir}/${PN} ${libdir}/${PN}" +FILES_${PN}-dev = "${includedir} ${libdir}/lib*${SOLIBSDEV} ${libdir}/*.la \ ${libdir}/*.a ${libdir}/pkgconfig /lib/*.a /lib/*.o \ ${datadir}/aclocal ${bindir}/*-config" -FILES_${PN}-bin = "${bindir} ${sbindir} /bin /sbin" +FILES_${PN}-bin = "${bindir}/* ${sbindir}/* /bin/* /sbin/*" diff --git a/classes/linux-kernel-base.bbclass b/classes/linux-kernel-base.bbclass index e58c228080..510951a620 100644 --- a/classes/linux-kernel-base.bbclass +++ b/classes/linux-kernel-base.bbclass @@ -1,9 +1,12 @@ # parse kernel ABI version out of <linux/version.h> def get_kernelversion(p): - import re, os + import re fn = p + '/include/linux/utsrelease.h' if not os.path.isfile(fn): + # after 2.6.33-rc1 + fn = p + '/include/generated/utsrelease.h' + if not os.path.isfile(fn): fn = p + '/include/linux/version.h' import re @@ -30,12 +33,7 @@ def get_kernelmajorversion(p): return None def linux_module_packages(s, d): - import bb, os.path suffix = "" - if (bb.data.getVar("PARALLEL_INSTALL_MODULES", d, 1) == "1"): - file = bb.data.expand('${STAGING_KERNEL_DIR}/kernel-abiversion', d) - if (os.path.exists(file)): - suffix = "-%s" % (get_kernelmajorversion(base_read_file(file))) return " ".join(map(lambda s: "kernel-module-%s%s" % (s.lower().replace('_', '-').replace('@', '+'), suffix), s.split())) # that's all diff --git a/classes/lockdown.bbclass b/classes/lockdown.bbclass new file mode 100644 index 0000000000..45b9761b9c --- /dev/null +++ b/classes/lockdown.bbclass @@ -0,0 +1,41 @@ +addtask show_versions before do_build +do_show_versions[nostamp] = "1" +python do_show_versions() { + import sys + + localdata = bb.data.createCopy(d) + bb.data.update_data(localdata) + + src_uri = bb.data.getVar('SRC_URI', localdata, 1) + if not src_uri: + return 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) + + + src_uri = bb.data.getVar("SRC_URI", d, False) + pn = bb.data.getVar("PN", d, True) + src_revs = open("%s/src_revs.inc" % bb.data.getVar("TMPDIR", d, 1), "a") + src_dates = open("%s/src_dates.inc" % bb.data.getVar("TMPDIR", d, 1), "a") + pref_versions = open("%s/preferred_versions.inc" % bb.data.getVar("TMPDIR", d, 1), "a") + if "SRCREV" in bb.data.getVar("PV", d, False): + print >> src_revs, 'SRCREV_pn-%(pn)s ?= "%(rev)s"' % { 'pn' : pn, 'rev' : bb.data.getVar("SRCREV", d, True) } + elif "cvs://" in src_uri or "svn://" in src_uri or "git://" in src_uri: + print >> src_dates, 'SRCDATE_pn-%(pn)s ?= "%(date)s"' % { 'pn' : pn, 'date' : bb.data.getVar("SRCDATE", d, True) } + + print >> pref_versions, 'PREFERRED_VERSION_%(pn)s = "%(version)s"' % { "pn" : pn, 'version' : bb.data.getVar("PV", d, True) } + src_revs.close() + src_dates.close() + pref_versions.close() +} + +addtask lockdown +do_lockdown[nostamp] = "1" +do_lockdown[recrdeptask] = "do_show_versions" +python do_lockdown() { +} + diff --git a/classes/magicbox-image.bbclass b/classes/magicbox-image.bbclass new file mode 100644 index 0000000000..c75e69cac2 --- /dev/null +++ b/classes/magicbox-image.bbclass @@ -0,0 +1,37 @@ +magicbox_gen_images() { + # find latest kernel + KERNEL=`ls -tr ${DEPLOY_DIR_IMAGE}/uImage* | tail -n 1` + if [ -z "$KERNEL" ]; then + oefatal "No kernel found in ${DEPLOY_DIR_IMAGE}. Exiting !" + exit 1 + fi + + #squashfs + #We need to prep the image so that u-boot recognizes it + mv ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.squashfs ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.squashfs.bin + ${STAGING_BINDIR_NATIVE}/mkimage -A ppc -O linux -T ramdisk -C none -n "OPLinux-uclibc-squashfs" \ + -d ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.squashfs.bin ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.squashfs + rm -f ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.squashfs.bin + + + #squashfs-lzma + #same as squashfs + mv ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.squashfs-lzma ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.squashfs-lzma.bin + ${STAGING_BINDIR_NATIVE}/mkimage -A ppc -O linux -T ramdisk -C none -n "OPLinux-uclibc-squashfs-lzma" \ + -d ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.squashfs-lzma.bin ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.squashfs-lzma + rm -f ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.squashfs-lzma.bin + + #kernel+jffs2 in a single image + #Add jffs2 marker at the end of the rootfs file + echo -ne '\xde\xad\xc0\xde' >> ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.jffs2 + + + ( dd if=$KERNEL bs=65536 conv=sync; \ + dd if=${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.jffs2 bs=65536 conv=sync; \ + ) > ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.jffs2.flash.bin + +} + + + +IMAGE_POSTPROCESS_COMMAND += "magicbox_gen_images; " diff --git a/classes/manifest.bbclass b/classes/manifest.bbclass index 687f4b756e..8d714d3bbc 100644 --- a/classes/manifest.bbclass +++ b/classes/manifest.bbclass @@ -1,6 +1,6 @@ python read_manifest () { - import sys, bb.manifest + import sys mfn = bb.data.getVar("MANIFEST", d, 1) if os.access(mfn, os.R_OK): # we have a manifest, so emit do_stage and do_populate_pkgs, diff --git a/classes/meta.bbclass b/classes/meta.bbclass new file mode 100644 index 0000000000..d35c40bccd --- /dev/null +++ b/classes/meta.bbclass @@ -0,0 +1,4 @@ + +PACKAGES = "" + +do_build[recrdeptask] = "do_build"
\ No newline at end of file diff --git a/classes/mime.bbclass b/classes/mime.bbclass new file mode 100644 index 0000000000..2416c1466f --- /dev/null +++ b/classes/mime.bbclass @@ -0,0 +1,56 @@ +DEPENDS += "shared-mime-info-native shared-mime-info" + +mime_postinst() { +if [ "$1" = configure ]; then + if [ -x ${bindir}/update-mime-database ] ; then + echo "Updating MIME database... this may take a while." + update-mime-database $D${datadir}/mime + else + echo "Missing ${bindir}/update-mime-database, update of mime database failed!" + exit 1 + fi +fi +} + +mime_postrm() { +if [ "$1" = remove ] || [ "$1" = upgrade ]; then + if [ -x ${bindir}/update-mime-database ] ; then + echo "Updating MIME database... this may take a while." + update-mime-database $D${datadir}/mime + else + echo "Missing ${bindir}/update-mime-database, update of mime database failed!" + exit 1 + fi +fi +} + +python populate_packages_append () { + import os.path, re + packages = bb.data.getVar('PACKAGES', d, 1).split() + pkgdest = bb.data.getVar('PKGDEST', d, 1) + + for pkg in packages: + mime_dir = '%s/%s/usr/share/mime/packages' % (pkgdest, pkg) + mimes = [] + mime_re = re.compile(".*\.xml$") + if os.path.exists(mime_dir): + for f in os.listdir(mime_dir): + if mime_re.match(f): + mimes.append(f) + if mimes != []: + bb.note("adding mime postinst and postrm scripts to %s" % pkg) + postinst = bb.data.getVar('pkg_postinst_%s' % pkg, d, 1) or bb.data.getVar('pkg_postinst', d, 1) + if not postinst: + postinst = '#!/bin/sh\n' + postinst += bb.data.getVar('mime_postinst', d, 1) + bb.data.setVar('pkg_postinst_%s' % pkg, postinst, d) + postrm = bb.data.getVar('pkg_postrm_%s' % pkg, d, 1) or bb.data.getVar('pkg_postrm', d, 1) + if not postrm: + postrm = '#!/bin/sh\n' + postrm += bb.data.getVar('mime_postrm', d, 1) + bb.data.setVar('pkg_postrm_%s' % pkg, postrm, d) + bb.note("adding freedesktop-mime-info dependency to %s" % pkg) + rdepends = explode_deps(bb.data.getVar('RDEPENDS_' + pkg, d, 0) or bb.data.getVar('RDEPENDS', d, 0) or "") + rdepends.append("freedesktop-mime-info") + bb.data.setVar('RDEPENDS_' + pkg, " " + " ".join(rdepends), d) +} diff --git a/classes/module-base.bbclass b/classes/module-base.bbclass index da5bd01dae..bc53e1bad5 100644 --- a/classes/module-base.bbclass +++ b/classes/module-base.bbclass @@ -5,11 +5,16 @@ inherit kernel-arch export OS = "${TARGET_OS}" export CROSS_COMPILE = "${TARGET_PREFIX}" +# A machine.conf or local.conf can increase MACHINE_KERNEL_PR to force +# rebuilds for kernel and external modules +PR = "${MACHINE_KERNEL_PR}" + export KERNEL_VERSION = "${@base_read_file('${STAGING_KERNEL_DIR}/kernel-abiversion')}" export KERNEL_SOURCE = "${@base_read_file('${STAGING_KERNEL_DIR}/kernel-source')}" KERNEL_OBJECT_SUFFIX = "${@[".o", ".ko"][base_read_file('${STAGING_KERNEL_DIR}/kernel-abiversion') > "2.6.0"]}" KERNEL_CCSUFFIX = "${@base_read_file('${STAGING_KERNEL_DIR}/kernel-ccsuffix')}" KERNEL_LDSUFFIX = "${@base_read_file('${STAGING_KERNEL_DIR}/kernel-ldsuffix')}" +KERNEL_ARSUFFIX = "${@base_read_file('${STAGING_KERNEL_DIR}/kernel-arsuffix')}" # Set TARGET_??_KERNEL_ARCH in the machine .conf to set architecture # specific options necessary for building the kernel and modules. @@ -17,9 +22,12 @@ TARGET_CC_KERNEL_ARCH ?= "" HOST_CC_KERNEL_ARCH ?= "${TARGET_CC_KERNEL_ARCH}" TARGET_LD_KERNEL_ARCH ?= "" HOST_LD_KERNEL_ARCH ?= "${TARGET_LD_KERNEL_ARCH}" +TARGET_AR_KERNEL_ARCH ?= "" +HOST_AR_KERNEL_ARCH ?= "${TARGET_AR_KERNEL_ARCH}" KERNEL_CC = "${CCACHE}${HOST_PREFIX}gcc${KERNEL_CCSUFFIX} ${HOST_CC_KERNEL_ARCH}" KERNEL_LD = "${LD}${KERNEL_LDSUFFIX} ${HOST_LD_KERNEL_ARCH}" +KERNEL_AR = "${AR}${KERNEL_ARSUFFIX} ${HOST_AR_KERNEL_ARCH}" # kernel modules are generally machine specific PACKAGE_ARCH = "${MACHINE_ARCH}" diff --git a/classes/module.bbclass b/classes/module.bbclass index 6089f90462..eef98292a7 100644 --- a/classes/module.bbclass +++ b/classes/module.bbclass @@ -1,37 +1,26 @@ -RDEPENDS += "kernel (${KERNEL_VERSION})" +RDEPENDS += "kernel (${KERNEL_VERSION}) update-modules" DEPENDS += "virtual/kernel" inherit module-base -python populate_packages_prepend() { - v = bb.data.getVar("PARALLEL_INSTALL_MODULES", d, 1) or "0" - if v == "1": - kv = bb.data.getVar("KERNEL_VERSION", d, 1) - packages = bb.data.getVar("PACKAGES", d, 1) - for p in packages.split(): - pkg = bb.data.getVar("PKG_%s" % p, d, 1) or p - newpkg = "%s-%s" % (pkg, kv) - bb.data.setVar("PKG_%s" % p, newpkg, d) - rprovides = bb.data.getVar("RPROVIDES_%s" % p, d, 1) - if rprovides: - rprovides = "%s %s" % (rprovides, pkg) - else: - rprovides = pkg - bb.data.setVar("RPROVIDES_%s" % p, rprovides, d) -} +MODULE_MAKE_FLAGS = '\ + KERNEL_PATH=${STAGING_KERNEL_DIR}\ + KERNEL_SRC=${STAGING_KERNEL_DIR}\ + KDIR=${STAGING_KERNEL_DIR}\ + KERNELDIR=${STAGING_KERNEL_DIR}\ + KERNEL_VERSION=${KERNEL_VERSION}\ + CC="${KERNEL_CC}" LD="${KERNEL_LD}"\ + AR="${KERNEL_AR}"\ + ' module_do_compile() { unset CFLAGS CPPFLAGS CXXFLAGS LDFLAGS - oe_runmake KERNEL_PATH=${STAGING_KERNEL_DIR} \ - KERNEL_SRC=${STAGING_KERNEL_DIR} \ - KERNEL_VERSION=${KERNEL_VERSION} \ - CC="${KERNEL_CC}" LD="${KERNEL_LD}" \ - ${MAKE_TARGETS} + oe_runmake ${MODULE_MAKE_FLAGS} ${MAKE_TARGETS} } module_do_install() { unset CFLAGS CPPFLAGS CXXFLAGS LDFLAGS - oe_runmake DEPMOD=echo INSTALL_MOD_PATH="${D}" CC="${KERNEL_CC}" LD="${KERNEL_LD}" modules_install + oe_runmake DEPMOD=echo INSTALL_MOD_PATH="${D}" ${MODULE_MAKE_FLAGS} modules_install } pkg_postinst_append () { diff --git a/classes/module_strip.bbclass b/classes/module_strip.bbclass index 116e8b902f..2650f71d50 100644 --- a/classes/module_strip.bbclass +++ b/classes/module_strip.bbclass @@ -1,18 +1,20 @@ -#DEPENDS_append = " module-strip" +PACKAGESTRIPFUNCS += "do_strip_modules" do_strip_modules () { - for p in ${PACKAGES}; do - if test -e ${WORKDIR}/install/$p/lib/modules; then - modules="`find ${WORKDIR}/install/$p/lib/modules -name \*${KERNEL_OBJECT_SUFFIX}`" - if [ -n "$modules" ]; then - ${STRIP} -v -g $modules -# NM="${CROSS_DIR}/bin/${HOST_PREFIX}nm" OBJCOPY="${CROSS_DIR}/bin/${HOST_PREFIX}objcopy" strip_module $modules - fi + if test -e ${PKGD}/lib/modules; then + if [ "${KERNEL_MAJOR_VERSION}" == "2.6" ]; then + modules="`find ${PKGD}/lib/modules -name \*.ko`" + else + modules="`find ${PKGD}/lib/modules -name \*.o`" fi - done + if [ -n "$modules" ]; then + for module in $modules ; do + if ! [ -d "$module" ] ; then + ${STRIP} -v -g $module + fi + done + fi + fi } -python do_package_append () { - if (bb.data.getVar('INHIBIT_PACKAGE_STRIP', d, 1) != '1'): - bb.build.exec_func('do_strip_modules', d) -} + diff --git a/classes/mono.bbclass b/classes/mono.bbclass new file mode 100644 index 0000000000..cf8dd15bdf --- /dev/null +++ b/classes/mono.bbclass @@ -0,0 +1,174 @@ +def mono_find_provides_and_requires(files, d): + provides = [] + requires = [] + + import bb, os, commands + + pathprefix = "export PATH=%s; export LANG=; export LC_ALL=; " % bb.data.getVar('PATH', d, 1) + for filename in files: + if not filename.endswith(".dll") and not filename.endswith(".exe"): + continue + if not os.path.isfile(filename) or os.path.islink(filename): + continue + + ## Provides + name, version = None, None + + ret, result = commands.getstatusoutput("%smonodis --assembly '%s'" % (pathprefix, filename)) + if ret: + bb.error("raw_provides_and_requires: monodis --assembly '%s' failed, dependency information will be inaccurate" % filename) + continue + for line in result.splitlines(): + if not ":" in line: continue + key, value = line.split(":", 1) + if key.strip() == "Name": + name = value.strip() + elif key.strip() == "Version": + version = value.strip() + if name is not None and version is not None: + if (name, version) not in provides: + provides.append( (name, version) ) + + ## Requires + name, version = None, None + ret, result = commands.getstatusoutput("%smonodis --assemblyref '%s'" % (pathprefix, filename)) + if ret: + bb.error("raw_provides_and_requires: monodis --assemblyref '%s' failed, dependency information will be inaccurate" % filename) + continue + for line in result.splitlines(): + if not "=" in line: continue + key, value = line.split("=", 1) + if ":" in key and key.split(":",1)[1].strip() == "Version": + version = value.strip() + elif key.strip() == "Name": + name = value.strip() + if name is not None and version is not None: + if (name, version) not in requires: + requires.append( (name, version) ) + name, version = None, None + + # Remove everything from requires that's already in provides as it's not actually required + # to be provided externally + requires = [e for e in requires if not e in provides] + return provides, requires + +CLILIBSDIR = "${STAGING_DIR_HOST}/clilibs" + +python mono_do_clilibs() { + import bb, os, re, os.path + + exclude_clilibs = bb.data.getVar('EXCLUDE_FROM_CLILIBS', d, 0) + if exclude_clilibs: + bb.note("not generating clilibs") + return + + lib_re = re.compile("^lib.*\.so") + libdir_re = re.compile(".*/lib$") + + packages = bb.data.getVar('PACKAGES', d, 1) + + workdir = bb.data.getVar('WORKDIR', d, 1) + if not workdir: + bb.error("WORKDIR not defined") + return + + pkgdest = bb.data.getVar('PKGDEST', d, 1) + + clilibs_dir = bb.data.getVar('CLILIBSDIR', d, 1) + bb.mkdirhier(clilibs_dir) + + provides, requires = {}, {} + private_libs = bb.data.getVar('PRIVATE_CLILIBS', d, 1) + for pkg in packages.split(): + bb.debug(2, "calculating clilib provides for %s" % pkg) + + files_to_check = [] + top = os.path.join(pkgdest, pkg) + for root, dirs, files in os.walk(top): + for file in files: + path = os.path.join(root, file) + if file.endswith(".exe") or file.endswith(".dll"): + files_to_check.append( path ) + provides[pkg], requires[pkg] = mono_find_provides_and_requires(files_to_check, d) + clilibs_file = os.path.join(clilibs_dir, pkg + ".list") + if os.path.exists(clilibs_file): + os.remove(clilibs_file) + if len(provides[pkg]) > 0: + fd = open(clilibs_file, 'w') + for s in provides[pkg]: + fd.write(" ".join(s) + '\n') + fd.close() + + clilib_provider = {} + list_re = re.compile('^(.*)\.list$') + for file in os.listdir(clilibs_dir): + m = list_re.match(file) + if m: + dep_pkg = m.group(1) + fd = open(os.path.join(clilibs_dir, file)) + lines = fd.readlines() + fd.close() + for l in lines: + clilib_provider[tuple(l.rstrip().split())] = dep_pkg + + for pkg in packages.split(): + bb.debug(2, "calculating clilib requirements for %s" % pkg) + + deps = [] + for n in requires[pkg]: + if n in clilib_provider.keys(): + dep_pkg = clilib_provider[n] + + if dep_pkg == pkg: + continue + + if not dep_pkg in deps: + deps.append(dep_pkg) + else: + bb.note("Couldn't find CLI library provider for %s" % (n,)) + + deps_file = os.path.join(pkgdest, pkg + ".clilibdeps") + if os.path.exists(deps_file): + os.remove(deps_file) + if len(deps) > 0: + fd = open(deps_file, 'w') + for dep in deps: + fd.write(dep + '\n') + fd.close() +} + +do_mono_stage() { + if [ "${INHIBIT_MONO_STAGE}" = "1" ] + then + return + fi + + for package in ${PACKAGES}; do + if [ -d "${PKGDEST}/${package}/${libdir}" ]; then + cd "${PKGDEST}/${package}/${libdir}" + for file in `find . -iname "*.dll"`; do + cp --parent -fpPR "${file}" "${STAGING_LIBDIR}/" + done + fi + done +} +addtask mono_stage after do_package before do_populate_staging + +def mono_after_parse(d): + import bb + # Insert mono_do_clilibs into PACKAGEFUNCS + # Needs to be called after populate_packages, but before read_shlibdeps + PACKAGEFUNCS = bb.data.getVar("PACKAGEFUNCS", d, 1) + if PACKAGEFUNCS: + PACKAGEFUNCS = PACKAGEFUNCS.split() + if "read_shlibdeps" in PACKAGEFUNCS: + i = PACKAGEFUNCS.index("read_shlibdeps") + PACKAGEFUNCS.insert(i, "mono_do_clilibs") + elif "populate_packages" in PACKAGEFUNCS: + i = PACKAGEFUNCS.index("populate_packages") + PACKAGEFUNCS.insert(i+1, "mono_do_clilibs") + bb.data.setVar("PACKAGEFUNCS", " ".join(PACKAGEFUNCS), d) + +python () { + mono_after_parse(d) +} diff --git a/classes/mozilla.bbclass b/classes/mozilla.bbclass index 629f2531da..c9a3966709 100644 --- a/classes/mozilla.bbclass +++ b/classes/mozilla.bbclass @@ -4,7 +4,7 @@ DEPENDS += "gnu-config-native virtual/libintl xt libxi \ LICENSE = "MPL NPL" SRC_URI += "file://mozconfig" -inherit gettext +inherit gettext pkgconfig EXTRA_OECONF = "--target=${TARGET_SYS} --host=${BUILD_SYS} \ --build=${BUILD_SYS} --prefix=${prefix}" @@ -19,7 +19,7 @@ export MOZ_OBJDIR = "${S}" export CONFIGURE_ARGS = "${EXTRA_OECONF}" export HOST_LIBIDL_CFLAGS = "`${HOST_LIBIDL_CONFIG} --cflags`" export HOST_LIBIDL_LIBS = "`${HOST_LIBIDL_CONFIG} --libs`" -export HOST_LIBIDL_CONFIG = "PKG_CONFIG_PATH=${STAGING_BINDIR}/../share/pkgconfig pkg-config libIDL-2.0" +export HOST_LIBIDL_CONFIG = "PKG_CONFIG_PATH=${STAGING_LIBDIR_NATIVE}/pkgconfig pkg-config libIDL-2.0" export HOST_CC = "${BUILD_CC}" export HOST_CXX = "${BUILD_CXX}" export HOST_CFLAGS = "${BUILD_CFLAGS}" @@ -33,13 +33,15 @@ mozilla_do_configure() { set -e for cg in `find ${S} -name config.guess`; do install -m 0755 \ - ${STAGING_BINDIR}/../share/gnu-config/config.guess \ - ${STAGING_BINDIR}/../share/gnu-config/config.sub \ + ${STAGING_DATADIR_NATIVE}/gnu-config/config.guess \ + ${STAGING_DATADIR_NATIVE}/gnu-config/config.sub \ `dirname $cg`/ done ) - oe_runmake -f client.mk ${MOZ_OBJDIR}/Makefile \ - ${MOZ_OBJDIR}/config.status + if [ -e ${MOZ_OBJDIR}/Makefile ] ; then + oe_runmake -f client.mk ${MOZ_OBJDIR}/Makefile \ + ${MOZ_OBJDIR}/config.status + fi } mozilla_do_compile() { diff --git a/classes/multimachine.bbclass b/classes/multimachine.bbclass deleted file mode 100644 index 30a285e5f3..0000000000 --- a/classes/multimachine.bbclass +++ /dev/null @@ -1,22 +0,0 @@ -STAMP = "${TMPDIR}/stamps/${MULTIMACH_ARCH}${TARGET_VENDOR}-${TARGET_OS}/${PF}" -WORKDIR = "${TMPDIR}/work/${MULTIMACH_ARCH}${TARGET_VENDOR}-${TARGET_OS}/${PF}" -STAGING_KERNEL_DIR = "${STAGING_DIR}/${MULTIMACH_ARCH}${TARGET_VENDOR}-${TARGET_OS}/kernel" - -# Find any machine specific sub packages and if present, mark the -# whole package as machine specific for multimachine purposes. -python __anonymous () { - packages = bb.data.getVar('PACKAGES', d, 1).split() - macharch = bb.data.getVar('MACHINE_ARCH', d, 1) - multiarch = bb.data.getVar('PACKAGE_ARCH', d, 1) - - for pkg in packages: - pkgarch = bb.data.getVar("PACKAGE_ARCH_%s" % pkg, d, 1) - - # We could look for != PACKAGE_ARCH here but how to choose - # if multiple differences are present? - # Look through IPKG_ARCHS for the priority order? - if pkgarch and pkgarch == macharch: - multiarch = macharch - - bb.data.setVar('MULTIMACH_ARCH', multiarch, d) -} diff --git a/classes/n2100-image.bbclass b/classes/n2100-image.bbclass new file mode 100644 index 0000000000..b74e74c48a --- /dev/null +++ b/classes/n2100-image.bbclass @@ -0,0 +1,32 @@ +n2100_pack_image() { + # find latest kernel + KERNEL=`ls -tr ${DEPLOY_DIR_IMAGE}/zImage* | tail -n 1` + if [ -z "$KERNEL" ]; then + oefatal "No kernel found in ${DEPLOY_DIR_IMAGE}. Bitbake linux to create one." + exit 1 + fi + ROOTFS=${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.jffs2 + OUTPUT=${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.flash.img + PADFILE=${DEPLOY_DIR_IMAGE}/padfile.zzz + HEX_MAX_KERN_SIZE=1C0000 + DEC_MAX_KERN_SIZE=`echo "ibase=16; $HEX_MAX_KERN_SIZE" | bc ` + HEX_MAX_ROOT_SIZE=DC0000 + DEC_MAX_ROOT_SIZE=`echo "ibase=16; $HEX_MAX_ROOT_SIZE" | bc ` + KERNEL_SIZE=`ls -l $KERNEL | awk '{print $5}'` + if [ $KERNEL_SIZE -gt $DEC_MAX_KERN_SIZE ]; then + oefatal "Kernel too large at $KERNEL_SIZE bytes. Max is $DEC_MAX_KERN_SIZE." + exit 1 + fi + ROOT_SIZE=`ls -l $ROOTFS | awk '{print $5}'` + if [ $ROOT_SIZE -gt $DEC_MAX_ROOT_SIZE ]; then + oefatal "Rootfs is too large at $ROOT_SIZE bytes. Max is $DEC_MAX_ROOT_SIZE." + exit 1 + fi + PAD_SIZE=`echo "$DEC_MAX_KERN_SIZE - $KERNEL_SIZE" | bc ` + dd if=/dev/zero of=$PADFILE bs=$PAD_SIZE count=1 2>>/dev/null + cat $KERNEL $PADFILE $ROOTFS > $OUTPUT + rm -f $PADFILE + ls -l $OUTPUT +} + +IMAGE_POSTPROCESS_COMMAND += "n2100_pack_image; " diff --git a/classes/nas100d-image.bbclass b/classes/nas100d-image.bbclass new file mode 100644 index 0000000000..0877b4f84d --- /dev/null +++ b/classes/nas100d-image.bbclass @@ -0,0 +1,19 @@ +nas100d_pack_image () { + install -d ${DEPLOY_DIR_IMAGE}/firmupgrade + install -m 0755 ${DEPLOY_DIR_IMAGE}/zImage-nslu2${SITEINFO_ENDIANESS}.bin \ + ${DEPLOY_DIR_IMAGE}/firmupgrade/ip-ramdisk + install -m 0644 ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.jffs2 \ + ${DEPLOY_DIR_IMAGE}/firmupgrade/rootfs.gz + touch ${DEPLOY_DIR_IMAGE}/firmupgrade/usr.cramfs + chmod 0644 ${DEPLOY_DIR_IMAGE}/firmupgrade/usr.cramfs + echo "hwid=1.0.1" >${DEPLOY_DIR_IMAGE}/firmupgrade/version.msg + echo "model=koala" >>${DEPLOY_DIR_IMAGE}/firmupgrade/version.msg + echo "vendor=iomega" >>${DEPLOY_DIR_IMAGE}/firmupgrade/version.msg + echo "" >>${DEPLOY_DIR_IMAGE}/firmupgrade/version.msg + chmod 0744 ${DEPLOY_DIR_IMAGE}/firmupgrade/version.msg + tar -c -f ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}-nas100d.bin \ + -C ${DEPLOY_DIR_IMAGE} firmupgrade + rm -rf ${DEPLOY_DIR_IMAGE}/firmupgrade +} + +IMAGE_POSTPROCESS_COMMAND += "nas100d_pack_image; " diff --git a/classes/native.bbclass b/classes/native.bbclass index 04ff7d92d1..6698b61cfc 100644 --- a/classes/native.bbclass +++ b/classes/native.bbclass @@ -1,5 +1,3 @@ -inherit base - # Native packages are built indirectly via dependency, # no need for them to be a direct target of 'world' EXCLUDE_FROM_WORLD = "1" @@ -7,35 +5,41 @@ EXCLUDE_FROM_WORLD = "1" PACKAGES = "" PACKAGE_ARCH = "${BUILD_ARCH}" +BASE_PACKAGE_ARCH = "${BUILD_ARCH}" +BASEPKG_HOST_SYS = "${BUILD_ARCH}${BUILD_VENDOR}-${BUILD_OS}" +BASEPKG_TARGET_SYS = "${BUILD_ARCH}${BUILD_VENDOR}-${BUILD_OS}" + # When this class has packaging enabled, setting # RPROVIDES becomes unnecessary. RPROVIDES = "${PN}" -# Need to resolve package RDEPENDS as well as DEPENDS -BUILD_ALL_DEPS = "1" - -# Break the circular dependency as a result of DEPENDS -# in package.bbclass -PACKAGE_DEPENDS = "" - TARGET_ARCH = "${BUILD_ARCH}" TARGET_OS = "${BUILD_OS}" TARGET_VENDOR = "${BUILD_VENDOR}" TARGET_PREFIX = "${BUILD_PREFIX}" TARGET_CC_ARCH = "${BUILD_CC_ARCH}" +TARGET_EXEEXT = "${BUILD_EXEEXT}" HOST_ARCH = "${BUILD_ARCH}" HOST_OS = "${BUILD_OS}" HOST_VENDOR = "${BUILD_VENDOR}" HOST_PREFIX = "${BUILD_PREFIX}" HOST_CC_ARCH = "${BUILD_CC_ARCH}" +HOST_EXEEXT = "${BUILD_EXEEXT}" CPPFLAGS = "${BUILD_CPPFLAGS}" CFLAGS = "${BUILD_CFLAGS}" CXXFLAGS = "${BUILD_CFLAGS}" LDFLAGS = "${BUILD_LDFLAGS}" -LDFLAGS_build-darwin = "-L${STAGING_DIR}/${BUILD_SYS}/lib " +LDFLAGS_build-darwin = "-L${STAGING_LIBDIR_NATIVE} " +STAGING_BINDIR = "${STAGING_BINDIR_NATIVE}" +STAGING_BINDIR_CROSS = "${STAGING_BINDIR_NATIVE}" + +STAGING_DIR_JAVA = "${STAGING_DATADIR_JAVA_NATIVE}" + +# Don't use site files for native builds +export CONFIG_SITE = "" # set the compiler as well. It could have been set to something else export CC = "${CCACHE}${HOST_PREFIX}gcc ${HOST_CC_ARCH}" @@ -49,47 +53,72 @@ export AS = "${HOST_PREFIX}as" export RANLIB = "${HOST_PREFIX}ranlib" export STRIP = "${HOST_PREFIX}strip" - # Path prefixes -base_prefix = "${exec_prefix}" -prefix = "${STAGING_DIR}" -exec_prefix = "${STAGING_DIR}/${BUILD_ARCH}-${BUILD_OS}" - -# Base paths -base_bindir = "${base_prefix}/bin" -base_sbindir = "${base_prefix}/bin" -base_libdir = "${base_prefix}/lib" - -# Architecture independent paths -sysconfdir = "${prefix}/etc" -sharedstatedir = "${prefix}/com" -localstatedir = "${prefix}/var" -infodir = "${datadir}/info" -mandir = "${datadir}/man" -docdir = "${datadir}/doc" -servicedir = "${prefix}/srv" - -# Architecture dependent paths -bindir = "${exec_prefix}/bin" -sbindir = "${exec_prefix}/bin" -libexecdir = "${exec_prefix}/libexec" -libdir = "${exec_prefix}/lib" -includedir = "${exec_prefix}/include" -oldincludedir = "${exec_prefix}/include" - -# Datadir is made arch dependent here, primarily -# for autoconf macros, and other things that -# may be manipulated to handle crosscompilation -# issues. -datadir = "${exec_prefix}/share" - -do_stage () { - if [ "${INHIBIT_NATIVE_STAGE_INSTALL}" != "1" ] +base_prefix = "${STAGING_DIR_NATIVE}" +prefix = "${STAGING_DIR_NATIVE}${prefix_native}" +exec_prefix = "${STAGING_DIR_NATIVE}${prefix_native}" + +# Since we actually install these into situ there is no staging prefix +STAGING_DIR_HOST = "" +STAGING_DIR_TARGET = "" +SHLIBSDIR = "${STAGING_DIR_NATIVE}/shlibs" +PKG_CONFIG_DIR = "${libdir}/pkgconfig" + +do_stage_native () { + # If autotools is active, use the autotools staging function, else + # use our "make install" equivalent + if [ "${AUTOTOOLS_NATIVE_STAGE_INSTALL}" == "1" ] then + autotools_stage_all + else oe_runmake install fi } -do_install () { - true +do_stage () { + do_stage_native +} + +PKG_CONFIG_PATH .= "${EXTRA_NATIVE_PKGCONFIG_PATH}" +PKG_CONFIG_SYSROOT_DIR = "" + +ORIG_DEPENDS := "${DEPENDS}" + +DEPENDS_virtclass-native ?= "${ORIG_DEPENDS}" + +python __anonymous () { + # If we've a legacy native do_stage, we need to neuter do_install + stagefunc = bb.data.getVar('do_stage', d, True) + + # For now, force legacy mode for native packages using autotools_stage_all + if (stagefunc.strip() == "autotools_stage_all"): + bb.debug(1, "Forcing legacy staging mode for %s" % bb.data.getVar('FILE', d, 1)) + bb.data.setVar('FORCE_LEGACY_STAGING', "1", d) + elif (stagefunc.strip() != "do_stage_native" and stagefunc.strip() != "autotools_stage_all") and bb.data.getVar('AUTOTOOLS_NATIVE_STAGE_INSTALL', d, 1) == "1": + bb.data.setVar("do_install", " :", d) + + if "native" in (bb.data.getVar('BBCLASSEXTEND', d, True) or ""): + pn = bb.data.getVar("PN", d, True) + depends = bb.data.getVar("DEPENDS_virtclass-native", d, True) + deps = bb.utils.explode_deps(depends) + newdeps = [] + for dep in deps: + if dep.endswith("-cross"): + newdeps.append(dep.replace("-cross", "-native")) + elif not dep.endswith("-native"): + + newdeps.append(dep + "-native") + else: + newdeps.append(dep) + bb.data.setVar("DEPENDS_virtclass-native", " ".join(newdeps), d) + provides = bb.data.getVar("PROVIDES", d, True) + for prov in provides.split(): + if prov.find(pn) != -1: + continue + if not prov.endswith("-native"): + + provides = provides.replace(prov, prov + "-native") + bb.data.setVar("PROVIDES", provides, d) + bb.data.setVar("OVERRIDES", bb.data.getVar("OVERRIDES", d, False) + ":virtclass-native", d) } + diff --git a/classes/nativesdk.bbclass b/classes/nativesdk.bbclass new file mode 100644 index 0000000000..080adc5d77 --- /dev/null +++ b/classes/nativesdk.bbclass @@ -0,0 +1,78 @@ +# SDK packages are built either explicitly by the user, +# or indirectly via dependency. No need to be in 'world'. +EXCLUDE_FROM_WORLD = "1" + +# +# Update BASE_PACKAGE_ARCH and PACKAGE_ARCHS +# +OLD_PACKAGE_ARCH := ${BASE_PACKAGE_ARCH} +BASE_PACKAGE_ARCH = "${SDK_ARCH}-nativesdk" +python () { + archs = bb.data.getVar('PACKAGE_ARCHS', d, True).split() + sdkarchs = [] + for arch in archs: + sdkarchs.append(arch + '-nativesdk') + bb.data.setVar('PACKAGE_ARCHS', " ".join(sdkarchs), d) +} + +#STAGING_DIR_HOST = "${STAGING_DIR}/${HOST_SYS}-nativesdk" +#STAGING_DIR_TARGET = "${STAGING_DIR}/${BASEPKG_TARGET_SYS}-nativesdk" + +CROSS_DIR = "${TMPDIR}/cross/${HOST_ARCH}" + +HOST_ARCH = "${SDK_ARCH}" +HOST_VENDOR = "${SDK_VENDOR}" +HOST_OS = "${SDK_OS}" +HOST_PREFIX = "${SDK_PREFIX}" +HOST_CC_ARCH = "${SDK_CC_ARCH}" +#HOST_SYS = "${HOST_ARCH}${TARGET_VENDOR}-${HOST_OS}" + +TARGET_ARCH = "${SDK_ARCH}" +TARGET_VENDOR = "${SDK_VENDOR}" +TARGET_OS = "${SDK_OS}" +TARGET_PREFIX = "${SDK_PREFIX}" +TARGET_CC_ARCH = "${SDK_CC_ARCH}" + +CPPFLAGS = "${BUILDSDK_CPPFLAGS}" +CFLAGS = "${BUILDSDK_CFLAGS}" +CXXFLAGS = "${BUILDSDK_CFLAGS}" +LDFLAGS = "${BUILDSDK_LDFLAGS}" + +# Change to place files in SDKPATH +prefix = "${SDKPATH}" +exec_prefix = "${SDKPATH}" +base_prefix = "${SDKPATH}" + +FILES_${PN} += "${prefix}" +FILES_${PN}-dbg += "${prefix}/.debug \ + ${prefix}/bin/.debug \ + " + +export PKG_CONFIG_DIR = "${STAGING_DIR_HOST}${libdir}/pkgconfig" +export PKG_CONFIG_SYSROOT_DIR = "${STAGING_DIR_HOST}" + +python __anonymous () { + pn = bb.data.getVar("PN", d, True) + depends = bb.data.getVar("DEPENDS", d, True) + deps = bb.utils.explode_deps(depends) + newdeps = [] + for dep in deps: + if dep.endswith("-native") or dep.endswith("-cross"): + newdeps.append(dep) + elif dep.endswith("-gcc-intermediate") or dep.endswith("-gcc-initial") or dep.endswith("-gcc"): + newdeps.append(dep + "-crosssdk") + elif not dep.endswith("-nativesdk"): + newdeps.append(dep + "-nativesdk") + else: + newdeps.append(dep) + bb.data.setVar("DEPENDS", " ".join(newdeps), d) + provides = bb.data.getVar("PROVIDES", d, True) + for prov in provides.split(): + if prov.find(pn) != -1: + continue + if not prov.endswith("-nativesdk"): + provides = provides.replace(prov, prov + "-nativesdk") + bb.data.setVar("PROVIDES", provides, d) +} + + diff --git a/classes/nslu2-image.bbclass b/classes/nslu2-image.bbclass new file mode 100644 index 0000000000..8be1fa762f --- /dev/null +++ b/classes/nslu2-image.bbclass @@ -0,0 +1,23 @@ +nslu2_pack_image () { + slugimage -p \ + -b ${STAGING_LIBDIR}/nslu2-binaries/RedBoot \ + -s ${STAGING_LIBDIR}/nslu2-binaries/SysConf \ + -k ${DEPLOY_DIR_IMAGE}/zImage-${MACHINE}.bin \ + -L ${STAGING_LOADER_DIR}/apex-nslu2.bin \ + -r Flashdisk:${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.jffs2 \ + -m ${STAGING_FIRMWARE_DIR}/NPE-B \ + -t ${STAGING_LIBDIR}/nslu2-binaries/Trailer \ + -o ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}-nslu2.bin + slugimage -F -p \ + -b ${STAGING_LIBDIR}/nslu2-binaries/RedBoot \ + -s ${STAGING_LIBDIR}/nslu2-binaries/SysConf \ + -k ${DEPLOY_DIR_IMAGE}/zImage-${MACHINE}.bin \ + -L ${STAGING_LOADER_DIR}/apex-nslu2-16mb.bin \ + -r Flashdisk:${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.jffs2 \ + -m ${STAGING_FIRMWARE_DIR}/NPE-B \ + -t ${STAGING_LIBDIR}/nslu2-binaries/Trailer \ + -o ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}-nslu2-16mb.bin +} + +EXTRA_IMAGEDEPENDS += 'slugimage-native nslu2-linksys-firmware ixp4xx-npe apex-nslu2 apex-nslu2-16mb' +IMAGE_POSTPROCESS_COMMAND += "nslu2_pack_image; " diff --git a/classes/nslu2-jffs2-image.bbclass b/classes/nslu2-jffs2-image.bbclass deleted file mode 100644 index 56ad0f0659..0000000000 --- a/classes/nslu2-jffs2-image.bbclass +++ /dev/null @@ -1,18 +0,0 @@ -NSLU2_SLUGIMAGE_ARGS ?= "" - -nslu2_pack_image () { - install -d ${DEPLOY_DIR_IMAGE}/slug - install -m 0644 ${STAGING_LIBDIR}/nslu2-binaries/RedBoot \ - ${STAGING_LIBDIR}/nslu2-binaries/Trailer \ - ${STAGING_LIBDIR}/nslu2-binaries/SysConf \ - ${DEPLOY_DIR_IMAGE}/slug/ - install -m 0644 ${DEPLOY_DIR_IMAGE}/zImage-${IMAGE_BASENAME} ${DEPLOY_DIR_IMAGE}/slug/vmlinuz - install -m 0644 ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.jffs2 ${DEPLOY_DIR_IMAGE}/slug/flashdisk.jffs2 - cd ${DEPLOY_DIR_IMAGE}/slug - slugimage -p -b RedBoot -s SysConf -r Ramdisk:1,Flashdisk:flashdisk.jffs2 -t Trailer \ - -o ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.flashdisk.img ${NSLU2_SLUGIMAGE_ARGS} - rm -rf ${DEPLOY_DIR_IMAGE}/slug -} - -EXTRA_IMAGEDEPENDS += 'slugimage-native nslu2-linksys-firmware' -IMAGE_POSTPROCESS_COMMAND += "nslu2_pack_image; " diff --git a/classes/nslu2-mirrors.bbclass b/classes/nslu2-mirrors.bbclass index 1181edc716..b5ad01adea 100644 --- a/classes/nslu2-mirrors.bbclass +++ b/classes/nslu2-mirrors.bbclass @@ -1,4 +1,4 @@ MIRRORS_append () { -ftp://.*/.*/ http://sources.nslu2-linux.org/sources/ -http://.*/.*/ http://sources.nslu2-linux.org/sources/ +ftp://.*/.* http://sources.nslu2-linux.org/sources/ +https?://.*/.* http://sources.nslu2-linux.org/sources/ } diff --git a/classes/nslu2-ramdisk-image.bbclass b/classes/nslu2-ramdisk-image.bbclass deleted file mode 100644 index 0b545854fd..0000000000 --- a/classes/nslu2-ramdisk-image.bbclass +++ /dev/null @@ -1,18 +0,0 @@ -NSLU2_SLUGIMAGE_ARGS ?= "" - -nslu2_pack_image () { - install -d ${DEPLOY_DIR_IMAGE}/slug - install -m 0644 ${STAGING_LIBDIR}/nslu2-binaries/RedBoot \ - ${STAGING_LIBDIR}/nslu2-binaries/Trailer \ - ${STAGING_LIBDIR}/nslu2-binaries/SysConf \ - ${DEPLOY_DIR_IMAGE}/slug/ - install -m 0644 ${DEPLOY_DIR_IMAGE}/zImage-${IMAGE_BASENAME} ${DEPLOY_DIR_IMAGE}/slug/vmlinuz - install -m 0644 ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.ext2.gz ${DEPLOY_DIR_IMAGE}/slug/ramdisk.ext2.gz - cd ${DEPLOY_DIR_IMAGE}/slug - slugimage -p -b RedBoot -s SysConf -r Ramdisk:ramdisk.ext2.gz -t Trailer \ - -o ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.ramdisk.img ${NSLU2_SLUGIMAGE_ARGS} - rm -rf ${DEPLOY_DIR_IMAGE}/slug -} - -EXTRA_IMAGEDEPENDS += 'slugimage-native nslu2-linksys-firmware' -IMAGE_POSTPROCESS_COMMAND += "nslu2_pack_image; " diff --git a/classes/nylon-image.bbclass b/classes/nylon-image.bbclass index 8517c033e9..e973bf7cf5 100644 --- a/classes/nylon-image.bbclass +++ b/classes/nylon-image.bbclass @@ -1,5 +1,5 @@ # we dont need the kernel in the image -ROOTFS_POSTPROCESS_COMMAND = "rm -f ${IMAGE_ROOTFS}/tmp/zImage*" +ROOTFS_POSTPROCESS_COMMAND = "rm -f ${IMAGE_ROOTFS}/tmp/*Image*" # create a tar.gz (.imgz) file containing the filesystem and the kernel nylon_create_imgz() { @@ -7,10 +7,19 @@ nylon_create_imgz() { rm -f ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.imgz install -d ${DEPLOY_DIR_IMAGE}/tmp - cp ${DEPLOY_DIR_IMAGE}/${KERNEL_IMAGE_NAME}.flash.bin ${DEPLOY_DIR_IMAGE}/tmp/zImage.flash - cp ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.${type} ${DEPLOY_DIR_IMAGE}/tmp/rootfs.${type} + # copy the kernel (for mips on flash) into tmp + FLASH_BIN=${DEPLOY_DIR_IMAGE}/${KERNEL_IMAGE_NAME}.flash.bin + cp ${FLASH_BIN} ${DEPLOY_DIR_IMAGE}/tmp/zImage.flash + + # copy rootfs.jffs (or so) into tmp + cp ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.jffs2 ${DEPLOY_DIR_IMAGE}/tmp/rootfs.jffs2 + + # make an imgz out of tmp ( cd ${DEPLOY_DIR_IMAGE}/tmp; tar cvzf ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.imgz * ) rm -r ${DEPLOY_DIR_IMAGE}/tmp } -IMAGE_POSTPROCESS_COMMAND += "nylon_create_imgz;" +IMAGE_POSTPROCESS_COMMAND += "kldsköa" +IMAGE_POSTPROCESS_COMMAND_mtx-1 += "nylon_create_imgz;" +IMAGE_POSTPROCESS_COMMAND_mtx-2 += "nylon_create_imgz;" +IMAGE_POSTPROCESS_COMMAND_mtx-3a += "nylon_create_initrd_uimage;" diff --git a/classes/nylon-mirrors.bbclass b/classes/nylon-mirrors.bbclass index 2986bd8f80..11cc45ca0c 100644 --- a/classes/nylon-mirrors.bbclass +++ b/classes/nylon-mirrors.bbclass @@ -1,6 +1,6 @@ MIRRORS_append () { -ftp://.*/.*/ http://meshcube.org/nylon/stable/sources/ -http://.*/.*/ http://meshcube.org/nylon/stable/sources/ -ftp://.*/.*/ http://meshcube.org/nylon/unstable/sources/ -http://.*/.*/ http://meshcube.org/nylon/unstable/sources/ +ftp://.*/.*/ http://download.berlin.freifunk.net/meshcube.org/nylon/stable/sources/ +http://.*/.*/ http://download.berlin.freifunk.net/meshcube.org/nylon/stable/sources/ +ftp://.*/.*/ http://download.berlin.freifunk.net/meshcube.org/nylon/unstable/sources/ +http://.*/.*/ http://download.berlin.freifunk.net/meshcube.org/nylon/unstable/sources/ }
\ No newline at end of file diff --git a/classes/oelint.bbclass b/classes/oelint.bbclass index c9e39d13fb..f2e7540dcf 100644 --- a/classes/oelint.bbclass +++ b/classes/oelint.bbclass @@ -1,5 +1,5 @@ addtask lint before do_fetch -do_lint[nostamp] = 1 +do_lint[nostamp] = "1" python do_lint() { def testVar(var, explain=None): try: diff --git a/classes/oestats-client.bbclass b/classes/oestats-client.bbclass new file mode 100644 index 0000000000..e4e6206ac4 --- /dev/null +++ b/classes/oestats-client.bbclass @@ -0,0 +1,202 @@ +# Integration with the oestats build statistics server, see: +# +# http://opensource.bolloretelecom.eu/projects/oestats +# +# To make use of this class, add to your local.conf: +# +# INHERIT += "oestats-client" +# OESTATS_SERVER = "http://some.server.org" +# OESTATS_BUILDER = "some_nickname" +# + +def oestats_setid(d, val): + import bb + f = file(bb.data.getVar('TMPDIR', d, True) + '/oestats.id', 'w') + f.write(val) + +def oestats_getid(d): + import bb + f = file(bb.data.getVar('TMPDIR', d, True) + '/oestats.id', 'r') + return f.read() + +def oestats_send(d, server, action, vars = {}, files = {}): + import bb + import urllib2 + + # build body + output = [] + bound = '----------ThIs_Is_tHe_bouNdaRY_$' + for key in vars: + assert vars[key] + output.append('--' + bound) + output.append('Content-Disposition: form-data; name="%s"' % key) + output.append('') + output.append(vars[key]) + for key in files: + assert files[key] + output.append('--' + bound) + output.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (key, files[key]['filename'])) + output.append('Content-Type: %s' % files[key]['content-type']) + + output.append('') + output.append(files[key]['content']) + output.append('--' + bound + '--') + output.append('') + body = "\r\n".join(output) + + # build headers + headers = { + "User-agent": "oestats-client/0.5", + "Content-type": "multipart/form-data; boundary=%s" % bound, + "Content-length": str(len(body))} + + proxy = bb.data.getVar('HTTP_PROXY', d, True ) + if (proxy): + phl = urllib2.ProxyHandler({'http' : proxy}) + opener = urllib2.build_opener(phl) + urllib2.install_opener(opener) + + actionURL = "%s%s" %(server, action) + req = urllib2.Request(actionURL, body, headers); + response = urllib2.urlopen(req) + data = response.read() + + return data + +def oestats_start(server, builder, d): + import bb + import os.path + import re + + # send report + id = "" + try: + data = oestats_send(d, server, "/builds/", { + 'builder': builder, + 'build_arch': bb.data.getVar('BUILD_ARCH', d, True), + 'metadata_branch': bb.data.getVar('METADATA_BRANCH', d, True), + 'metadata_revision': bb.data.getVar('METADATA_REVISION', d, True), + 'machine': bb.data.getVar('MACHINE', d, True), + 'distro': bb.data.getVar('DISTRO', d, True), + }) + if re.match("^\d+$", data): id=data + except: + pass + + # save the build id + if id: + bb.note("oestats: build %s" % id) + else: + bb.note("oestats: error starting build, disabling stats") + oestats_setid(d, id) + +def oestats_stop(server, d, failures): + import bb + + # retrieve build id + id = oestats_getid(d) + if not id: return + + # send report + if failures > 0: + status = "Failed" + else: + status = "Succeeded" + + try: + response = oestats_send(d, server, "/builds/%s/" % id, { + 'status': status, + }) + if status == 'Failed': + bb.note("oestats: build failed, see %s%s" % (server, response)) + except: + bb.note("oestats: error stopping build") + +def oestats_task(server, d, task, status): + import bb + import glob + import os.path + import time + + # retrieve build id + id = oestats_getid(d) + if not id: return + + # calculate build time + try: + elapsed = time.time() - float(bb.data.getVar('OESTATS_STAMP', d, True)) + except: + elapsed = 0 + + # prepare files + files = {} + if status == 'Failed': + logs = glob.glob("%s/log.%s.*" % (bb.data.getVar('T', d, True), task)) + if len(logs) > 0: + log = logs[0] + files['log'] = { + 'filename': 'log.txt', + 'content': file(log).read(), + 'content-type': 'text/plain'} + if task == 'do_package': + qalog = "%s/log.qa_package" % bb.data.getVar('T', d, True) + if os.path.exists(qalog): + files['qalog'] = { + 'filename': 'qalog.txt', + 'content': file(qalog).read(), + 'content-type': 'text/plain'} + + # prepare report + vars = { + 'build': id, + 'package': bb.data.getVar('PN', d, True), + 'version': bb.data.getVar('PV', d, True), + 'revision': bb.data.getVar('PR', d, True), + 'depends': bb.data.getVar('DEPENDS', d, True), + 'task': task, + 'status': status, + 'time': str(elapsed)} + bug_number = bb.data.getVar('OESTATS_BUG_NUMBER', d, True) + bug_tracker = bb.data.getVar('OESTATS_BUG_TRACKER', d, True) + if bug_number and bug_tracker: + vars['bug_number'] = bug_number + vars['bug_tracker'] = bug_tracker + + # send report + try: + response = oestats_send(d, server, "/tasks/", vars, files) + if status == 'Failed': + bb.note("oestats: task failed, see %s%s" % (server, response)) + except: + bb.note("oestats: error sending task, disabling stats") + oestats_setid(d, "") + +addhandler oestats_eventhandler +python oestats_eventhandler () { + from bb.event import getName + import bb + import time + + if e.data is None or getName(e) == "MsgNote": + return NotHandled + + server = bb.data.getVar('OESTATS_SERVER', e.data, True) + if not server.startswith('http://') and not server.startswith('https://'): + server = "http://%s" %(server) + builder = bb.data.getVar('OESTATS_BUILDER', e.data, True) + if not server or not builder: + return NotHandled + + if getName(e) == 'BuildStarted': + oestats_start(server, builder, e.data) + elif getName(e) == 'BuildCompleted': + oestats_stop(server, e.data, e.getFailures()) + elif getName(e) == 'TaskStarted': + bb.data.setVar('OESTATS_STAMP', repr(time.time()), e.data) + elif getName(e) == 'TaskSucceeded': + oestats_task(server, e.data, e.task, 'Succeeded') + elif getName(e) == 'TaskFailed': + oestats_task(server, e.data, e.task, 'Failed') + + return NotHandled +} diff --git a/classes/openmoko-base.bbclass b/classes/openmoko-base.bbclass new file mode 100644 index 0000000000..8cbf7df884 --- /dev/null +++ b/classes/openmoko-base.bbclass @@ -0,0 +1,19 @@ +HOMEPAGE = "http://www.openmoko.org" +LICENSE ?= "GPL" +OPENMOKO_RELEASE ?= "OM-2007.2" +OPENMOKO_MIRROR ?= "svn://svn.openmoko.org/trunk" + +def openmoko_base_get_subdir(d): + openmoko, section = bb.data.getVar('SECTION', d, 1).split("/") + if section == 'base' or section == 'libs': return "" + elif section in 'apps tools pim'.split(): return "applications" + elif section == "panel-plugin": return "panel-plugins" + elif section == "inputmethods": return "inputmethods" + else: return section + +SUBDIR = "${@openmoko_base_get_subdir(d)}" + +SRC_URI := "${OPENMOKO_MIRROR}/src/target/${OPENMOKO_RELEASE}/${SUBDIR};module=${PN};proto=http" +S = "${WORKDIR}/${PN}" + +FILES_${PN} += "${datadir}/icons" diff --git a/classes/openmoko-panel-plugin.bbclass b/classes/openmoko-panel-plugin.bbclass new file mode 100644 index 0000000000..6a22a92ac8 --- /dev/null +++ b/classes/openmoko-panel-plugin.bbclass @@ -0,0 +1,6 @@ +SECTION = "openmoko/panel-plugin" +DEPENDS += "matchbox-panel-2 libmokopanelui2" + +inherit openmoko2 + +FILES_${PN} = "${libdir}/matchbox-panel/lib*.so* ${datadir}" diff --git a/classes/openmoko.bbclass b/classes/openmoko.bbclass new file mode 100644 index 0000000000..808ab8fcb6 --- /dev/null +++ b/classes/openmoko.bbclass @@ -0,0 +1,3 @@ +inherit openmoko-base autotools pkgconfig + +DEPENDS_prepend = "${@["openmoko-libs ", ""][(bb.data.getVar('PN', d, 1) == 'openmoko-libs')]}" diff --git a/classes/openmoko2.bbclass b/classes/openmoko2.bbclass new file mode 100644 index 0000000000..233c721ff7 --- /dev/null +++ b/classes/openmoko2.bbclass @@ -0,0 +1,31 @@ +inherit autotools pkgconfig + +HOMEPAGE = "http://www.openmoko.org" +OPENMOKO_RELEASE ?= "OM-2007.2" +OPENMOKO_MIRROR ?= "svn://svn.openmoko.org/trunk" + +def openmoko_two_get_license(d): + openmoko, section = bb.data.getVar('SECTION', d, 1).split("/") + return "LGPL GPL".split()[section != "libs"] + +def openmoko_two_get_subdir(d): + openmoko, section = bb.data.getVar('SECTION', d, 1).split("/") + if section == 'base': return "" + elif section == 'libs': return "libraries" + elif section in 'apps tools pim'.split(): return "applications" + elif section == "panel-plugin": return "panel-plugins" + elif section == "inputmethods": return "inputmethods" + elif section == "daemons": return "daemons" + elif section == "misc": return "misc" + else: return section + +LICENSE = "${@openmoko_two_get_license(d)}" +SUBDIR = "${@openmoko_two_get_subdir(d)}" + +SRC_URI := "${OPENMOKO_MIRROR}/src/target/${OPENMOKO_RELEASE}/${SUBDIR};module=${PN};proto=http" +S = "${WORKDIR}/${PN}" + +FILES_${PN} += "${datadir}/icons" + +SVNREV = "r${SRCREV}" +#SVNREV = "${SRCDATE}" diff --git a/classes/opie.bbclass b/classes/opie.bbclass index 922cb9435a..bd1bbaf578 100644 --- a/classes/opie.bbclass +++ b/classes/opie.bbclass @@ -15,16 +15,13 @@ inherit palmtop -# Note that when CVS changes to 1.2.2, the dash -# should be removed from OPIE_CVS_PV to convert -# to the standardised version format -OPIE_CVS_PV = "1.2.2+cvs-${SRCDATE}" +OPIE_CVS_PV ?= "1.2.2+cvs${SRCDATE}" DEPENDS_prepend = "${@["libopie2 ", ""][(bb.data.getVar('PN', d, 1) == 'libopie2')]}" # to be consistent, put all targets into workdir # NOTE: leave one space at the end, other files are expecting that -EXTRA_QMAKEVARS_POST += "DESTDIR=${S} " +EXTRA_QMAKEVARS_POST += " DESTDIR=${S} " # Opie standard TAG value TAG = "${@'v' + bb.data.getVar('PV',d,1).replace('.', '_')}" @@ -82,7 +79,8 @@ python opie_do_opie_install() { S = bb.data.getVar( "S", d, 1 ) D = "%s/image" % bb.data.getVar( "WORKDIR", d, True ) WORKDIR = bb.data.getVar( "WORKDIR", d, True ) - palmtopdir = bb.data.getVar( "palmtopdir", d ) + palmtopdir = bb.data.getVar( "palmtopdir", d, True ) + gnubindir = bb.data.getVar( "bindir", d, True ) APPDESKTOP = bb.data.getVar( "APPDESKTOP", d, True ) or "%s/%s" % ( WORKDIR, desktopdir ) if desktopdir is not None: @@ -92,11 +90,12 @@ python opie_do_opie_install() { os.system( "install -d %s%s%s/" % ( D, palmtopdir, bindir ) ) if APPTYPE == "binary": - os.system( "install -m 0755 %s/%s %s%s%s/" % ( S, APPNAME, D, palmtopdir, bindir ) ) + os.system( "install -d %s%s/" % ( D, gnubindir ) ) + os.system( "install -m 0755 %s/%s %s%s/" % ( S, APPNAME, D, gnubindir ) ) elif APPTYPE == "quicklaunch": os.system( "install -m 0755 %s/lib%s.so %s%s%s/" % ( S, APPNAME, D, palmtopdir, bindir ) ) - os.system( "install -d %s%s/bin/" % ( D, palmtopdir ) ) - os.system( "ln -sf %s/bin/quicklauncher %s%s/bin/%s" % ( palmtopdir, D, palmtopdir, APPNAME ) ) + os.system( "install -d %s%s/" % ( D, gnubindir ) ) + os.system( "ln -sf %s/quicklauncher %s%s/%s" % ( gnubindir, D, gnubindir, APPNAME ) ) elif APPTYPE == "plugin": os.system( "install -m 0755 %s/lib%s.so %s%s%s/" % ( S, APPNAME, D, palmtopdir, bindir ) ) } diff --git a/classes/opie_i18n.bbclass b/classes/opie_i18n.bbclass index cb3d07de75..107d090451 100644 --- a/classes/opie_i18n.bbclass +++ b/classes/opie_i18n.bbclass @@ -13,7 +13,7 @@ SRC_URI += "${HANDHELDS_CVS};module=opie/i18n" DEPENDS += "opie-i18n" die () { - echo -e "opie_18n: ERROR: $1" + printf "opie_18n: ERROR: $1\n" exit 1 } @@ -60,21 +60,21 @@ do_build_opie_i18n () { package_name2="`echo "${PN}"| sed "s/^opie\-//;s/\-//"`" test "$package_name" != "$package_name2" && I18N_FILES="${package_name}.ts lib${package_name}.ts opie-${package_name}.ts ${package_name2}.ts lib${package_name2}.ts opie-${package_name2}.ts" test "$package_name" = "$package_name2" && I18N_FILES="${package_name}.ts lib${package_name}.ts opie-${package_name}.ts" - echo -e "I18N Datafiles: ${I18N_FILES} (auto-detected)\nYou can overide the auto-detection by setting I18N_FILES in your .oe file" + printf "I18N Datafiles: ${I18N_FILES} (auto-detected)\nYou can overide the auto-detection by setting I18N_FILES in your .oe file\n" else echo "I18N Datafiles: ${I18N_FILES} (provided by .bb)" fi rm -f "${WORKDIR}/FILES.tmp" "${WORKDIR}/PACKAGES.tmp" - echo -e "\nFILES is set to [${FILES}]\n" + printf "\nFILES is set to [${FILES}]\n\n" for file in ${I18N_FILES} do echo "Working on [$file]" for ts_file in `ls -1 */*.ts | egrep "/$file"` do - echo -e "\tCompiling [$ts_file]" + printf "\tCompiling [$ts_file]\n" cd "${WORKDIR}/i18n/`dirname $ts_file`" || die "[${WORKDIR}/i18n/`dirname $ts_file`] not found" opie-lrelease "`basename $ts_file`" || die "lrelease failed! Make sure that <inherit opie_i18n> or <inherit opie> is *below* <DEPENDS =>!" @@ -82,7 +82,7 @@ do_build_opie_i18n () { # to allow packaging as "_" is not allowed in a package name lang="`echo "$ts_file" | sed -n "s#\(.*\)/\(.*\)#\1#p"`" lang_sane="`echo "$ts_file" | sed -n "s#\(.*\)/\(.*\)#\1#p"|sed s/\_/\-/`" - echo -e "\tPackaging [`basename $ts_file`] for language [$lang]" + printf "\tPackaging [`basename $ts_file`] for language [$lang]\n" install -d ${D}${palmtopdir}/i18n/$lang install -m 0644 ${WORKDIR}/i18n/$lang/.directory ${D}${palmtopdir}/i18n/$lang/ @@ -93,14 +93,14 @@ do_build_opie_i18n () { # function do_build_opie_i18n_data() which sets the variables FILES_* and # PACKAGES as needed. echo -n "${PN}-${lang_sane} " >> "${WORKDIR}/PACKAGES.tmp" - echo -e "${PN}-${lang_sane}#${palmtopdir}/i18n/$lang" >> "${WORKDIR}/FILES.tmp" + printf "${PN}-${lang_sane}#${palmtopdir}/i18n/$lang" >> "${WORKDIR}/FILES.tmp\n" ts_found_something=1 done if test "$ts_found_something" != 1 then - echo -e "\tNo translations found" + printf "\tNo translations found\n" else ts_found_something="" ts_found="$ts_found $file" @@ -109,7 +109,7 @@ do_build_opie_i18n () { # Only used for debugging purposes test "${I18N_STATS}" = 1 && cd "${WORKDIR}/i18n" - echo -e "Completed [$file]\n\n" + printf "Completed [$file]\n\n\n" done qt_dirs="apps bin etc lib pics plugins share sounds" @@ -125,7 +125,7 @@ do_build_opie_i18n () { if (echo "${FILES}" | egrep "${palmtopdir}/? |${palmtopdir}/?$") &>/dev/null then echo "NOTE: FILES was set to ${palmtopdir} which would include the i18n directory" - echo -e "\n\nI'll remove ${palmtopdir} from FILES and replace it with all directories" + printf "\n\nI'll remove ${palmtopdir} from FILES and replace it with all directories\n" echo "below QtPalmtop, except i18n ($qt_dirs). See classes/opie_i18n.oeclass for details" # Removes /opt/QtPalmtop from FILES but keeps /opt/QtPalmtop/$some_dir @@ -138,7 +138,7 @@ do_build_opie_i18n () { if test -z "${FILES}" then echo "NOTE:" - echo -e "Since FILES is empty, i'll add all directories below ${palmtopdir} to it,\nexcluding i18n: ( $qt_dirs )" + printf "Since FILES is empty, i'll add all directories below ${palmtopdir} to it,\nexcluding i18n: ( $qt_dirs )\n" echo "${PN}#$FILES $dir_" >> "${WORKDIR}/FILES.tmp" fi diff --git a/classes/oplinux-mirrors.bbclass b/classes/oplinux-mirrors.bbclass new file mode 100644 index 0000000000..59c199485c --- /dev/null +++ b/classes/oplinux-mirrors.bbclass @@ -0,0 +1,14 @@ +# Copyright (C) 2007, Stelios Koroneos - Digital OPSiS, All Rights Reserved +# Released under the MIT license (see packages/COPYING) + +MIRRORS_append () { +ftp://.*/.* http://digital-opsis.com/oplinux/stable/sources/ +https?://.*/.* http://digital-opsis.com/oplinux/stable/sources/ +ftp://.*/.* http://digital-opsis.com/oplinux/unstable/sources/ +https?://.*/.* http://digital-opsis.com/oplinux/unstable/sources/ + +ftp://.*/.* http://digital-opsis.com/oplinux-uclibc/stable/sources/ +https?://.*/.* http://digital-opsis.com/oplinux-uclibc/stable/sources/ +ftp://.*/.* http://digital-opsis.com/oplinux-uclibc/unstable/sources/ +https?://.*/.* http://digital-opsis.com/oplinux-uclibc/unstable/sources/ +} diff --git a/classes/own-mirrors.bbclass b/classes/own-mirrors.bbclass new file mode 100644 index 0000000000..e8a0f481d7 --- /dev/null +++ b/classes/own-mirrors.bbclass @@ -0,0 +1,4 @@ +PREMIRRORS() { +https?://.*/.* ${SOURCE_MIRROR_URL} +ftp://.*/.* ${SOURCE_MIRROR_URL} +} diff --git a/classes/package.bbclass b/classes/package.bbclass index 27d5a3a685..062f782129 100644 --- a/classes/package.bbclass +++ b/classes/package.bbclass @@ -1,4 +1,20 @@ +# +# General packaging help functions +# + +PKGD = "${WORKDIR}/package" +PKGDEST = "${WORKDIR}/packages-split" + +PKGV ?= "${PV}" +PKGR ?= "${PR}${DISTRO_PR}" + +EXTENDPKGEVER = "${@['','${PKGE\x7d:'][bb.data.getVar('PKGE',d,1) > 0]}" +EXTENDPKGV ?= "${EXTENDPKGEVER}${PKGV}-${PKGR}" + def legitimize_package_name(s): + """ + Make sure package names are legitimate strings + """ import re def fixutf(m): @@ -12,85 +28,15 @@ def legitimize_package_name(s): # Remaining package name validity fixes return s.lower().replace('_', '-').replace('@', '+').replace(',', '+').replace('/', '-') -STAGING_PKGMAPS_DIR ?= "${STAGING_DIR}/pkgmaps" - -def add_package_mapping (pkg, new_name, d): - import bb, os - - def encode(str): - import codecs - c = codecs.getencoder("string_escape") - return c(str)[0] - - pmap_dir = bb.data.getVar('STAGING_PKGMAPS_DIR', d, 1) - - bb.mkdirhier(pmap_dir) - - data_file = os.path.join(pmap_dir, pkg) - - f = open(data_file, 'w') - f.write("%s\n" % encode(new_name)) - f.close() - -def get_package_mapping (pkg, d): - import bb, os - - def decode(str): - import codecs - c = codecs.getdecoder("string_escape") - return c(str)[0] - - data_file = bb.data.expand("${STAGING_PKGMAPS_DIR}/%s" % pkg, d) - - if os.access(data_file, os.R_OK): - f = file(data_file, 'r') - lines = f.readlines() - f.close() - for l in lines: - return decode(l).strip() - return pkg - -def runtime_mapping_rename (varname, d): - import bb, os - - #bb.note("%s before: %s" % (varname, bb.data.getVar(varname, d, 1))) - - new_depends = [] - for depend in explode_deps(bb.data.getVar(varname, d, 1) or ""): - # Have to be careful with any version component of the depend - split_depend = depend.split(' (') - new_depend = get_package_mapping(split_depend[0].strip(), d) - if len(split_depend) > 1: - new_depends.append("%s (%s" % (new_depend, split_depend[1])) - else: - new_depends.append(new_depend) - - bb.data.setVar(varname, " ".join(new_depends) or None, d) - - #bb.note("%s after: %s" % (varname, bb.data.getVar(varname, d, 1))) - -python package_mapping_rename_hook () { - runtime_mapping_rename("RDEPENDS", d) - runtime_mapping_rename("RRECOMMENDS", d) - runtime_mapping_rename("RSUGGESTS", d) - runtime_mapping_rename("RPROVIDES", d) - runtime_mapping_rename("RREPLACES", d) - runtime_mapping_rename("RCONFLICTS", d) -} - +def do_split_packages(d, root, file_regex, output_pattern, description, postinst=None, recursive=False, hook=None, extra_depends=None, aux_files_pattern=None, postrm=None, allow_dirs=False, prepend=False, match_path=False, aux_files_pattern_verbatim=None, allow_links=False): + """ + Used in .bb files to split up dynamically generated subpackages of a + given package, usually plugins or modules. + """ -def do_split_packages(d, root, file_regex, output_pattern, description, postinst=None, recursive=False, hook=None, extra_depends=None, aux_files_pattern=None, postrm=None, allow_dirs=False, prepend=False, match_path=False, aux_files_pattern_verbatim=None): - import os, os.path, bb + dvar = bb.data.getVar('PKGD', d, True) - dvar = bb.data.getVar('D', d, 1) - if not dvar: - bb.error("D not defined") - return - - packages = bb.data.getVar('PACKAGES', d, 1).split() - if not packages: - # nothing to do - return + packages = bb.data.getVar('PACKAGES', d, True).split() if postinst: postinst = '#!/bin/sh\n' + postinst + '\n' @@ -107,7 +53,14 @@ def do_split_packages(d, root, file_regex, output_pattern, description, postinst objs.append(relpath) if extra_depends == None: - extra_depends = packages[0] + # This is *really* broken + mainpkg = packages[0] + # At least try and patch it up I guess... + if mainpkg.find('-dbg'): + mainpkg = mainpkg.replace('-dbg', '') + if mainpkg.find('-dev'): + mainpkg = mainpkg.replace('-dev', '') + extra_depends = mainpkg for o in objs: import re, stat @@ -120,7 +73,7 @@ def do_split_packages(d, root, file_regex, output_pattern, description, postinst continue f = os.path.join(dvar + root, o) mode = os.lstat(f).st_mode - if not (stat.S_ISREG(mode) or (allow_dirs and stat.S_ISDIR(mode))): + if not (stat.S_ISREG(mode) or (allow_links and stat.S_ISLNK(mode)) or (allow_dirs and stat.S_ISDIR(mode))): continue on = legitimize_package_name(m.group(1)) pkg = output_pattern % on @@ -144,7 +97,7 @@ def do_split_packages(d, root, file_regex, output_pattern, description, postinst the_files.append(aux_files_pattern_verbatim % m.group(1)) bb.data.setVar('FILES_' + pkg, " ".join(the_files), d) if extra_depends != '': - the_depends = bb.data.getVar('RDEPENDS_' + pkg, d, 1) + the_depends = bb.data.getVar('RDEPENDS_' + pkg, d, True) if the_depends: the_depends = '%s %s' % (the_depends, extra_depends) else: @@ -156,7 +109,7 @@ def do_split_packages(d, root, file_regex, output_pattern, description, postinst if postrm: bb.data.setVar('pkg_postrm_' + pkg, postrm, d) else: - oldfiles = bb.data.getVar('FILES_' + pkg, d, 1) + oldfiles = bb.data.getVar('FILES_' + pkg, d, True) if not oldfiles: bb.fatal("Package '%s' exists but has no files" % pkg) bb.data.setVar('FILES_' + pkg, oldfiles + " " + os.path.join(root, o), d) @@ -165,92 +118,100 @@ def do_split_packages(d, root, file_regex, output_pattern, description, postinst bb.data.setVar('PACKAGES', ' '.join(packages), d) -# Function to strip a single file, called from RUNSTRIP below -# A working 'file' (one which works on the target architecture) -# is necessary for this stuff to work. -PACKAGE_DEPENDS ?= "file-native" -DEPENDS_prepend =+ "${PACKAGE_DEPENDS} " -# file(1) output to match to consider a file an unstripped executable -FILE_UNSTRIPPED_MATCH ?= "not stripped" -#FIXME: this should be "" when any errors are gone! -IGNORE_STRIP_ERRORS ?= "1" - -runstrip() { - local ro st - st=0 - if { file "$1" || { - oewarn "file $1: failed (forced strip)" >&2 - echo '${FILE_UNSTRIPPED_MATCH}' - } - } | grep -q '${FILE_UNSTRIPPED_MATCH}' - then - oenote "${STRIP} $1" - ro= - test -w "$1" || { - ro=1 - chmod +w "$1" - } - mkdir -p $(dirname "$1")/.debug - debugfile="$(dirname "$1")/.debug/$(basename "$1")" - '${OBJCOPY}' --only-keep-debug "$1" "$debugfile" - '${STRIP}' "$1" - st=$? - '${OBJCOPY}' --add-gnu-debuglink="$debugfile" "$1" - test -n "$ro" && chmod -w "$1" - if test $st -ne 0 - then - oewarn "runstrip: ${STRIP} $1: strip failed" >&2 - if [ x${IGNORE_STRIP_ERRORS} == x1 ] - then - #FIXME: remove this, it's for error detection - if file "$1" 2>/dev/null >&2 - then - (oefatal "${STRIP} $1: command failed" >/dev/tty) - else - (oefatal "file $1: command failed" >/dev/tty) - fi - st=0 - fi - fi - else - oenote "runstrip: skip $1" - fi - return $st +PACKAGE_DEPENDS += "file-native" + +def package_stash_hook(func, name, d): + import bb, os.path + body = bb.data.getVar(func, d, True) + pn = bb.data.getVar('PN', d, True) + staging = bb.data.getVar('PKGDATA_DIR', d, True) + dirname = os.path.join(staging, 'hooks', name) + bb.mkdirhier(dirname) + fn = os.path.join(dirname, pn) + f = open(fn, 'w') + f.write("python () {\n"); + f.write(body); + f.write("}\n"); + f.close() + +python () { + if bb.data.getVar('PACKAGES', d, True) != '': + deps = bb.data.getVarFlag('do_package', 'depends', d) or "" + for dep in (bb.data.getVar('PACKAGE_DEPENDS', d, True) or "").split(): + deps += " %s:do_populate_staging" % dep + bb.data.setVarFlag('do_package', 'depends', deps, d) + + deps = (bb.data.getVarFlag('do_package', 'deptask', d) or "").split() + # shlibs requires any DEPENDS to have already packaged for the *.list files + deps.append("do_package") + bb.data.setVarFlag('do_package', 'deptask', " ".join(deps), d) } -python populate_packages () { - import glob, stat, errno, re +def runstrip(file, d): + # Function to strip a single file, called from populate_packages below + # A working 'file' (one which works on the target architecture) + # is necessary for this stuff to work, hence the addition to do_package[depends] - workdir = bb.data.getVar('WORKDIR', d, 1) - if not workdir: - bb.error("WORKDIR not defined, unable to package") - return + import commands, stat - import os # path manipulations - outdir = bb.data.getVar('DEPLOY_DIR', d, 1) - if not outdir: - bb.error("DEPLOY_DIR not defined, unable to package") - return - bb.mkdirhier(outdir) + pathprefix = "export PATH=%s; " % bb.data.getVar('PATH', d, True) - dvar = bb.data.getVar('D', d, 1) - if not dvar: - bb.error("D not defined, unable to package") - return - bb.mkdirhier(dvar) + ret, result = commands.getstatusoutput("%sfile '%s'" % (pathprefix, file)) - packages = bb.data.getVar('PACKAGES', d, 1) - if not packages: - bb.debug(1, "PACKAGES not defined, nothing to package") - return + if ret: + bb.error("runstrip: 'file %s' failed (forced strip)" % file) - pn = bb.data.getVar('PN', d, 1) - if not pn: - bb.error("PN not defined") - return + if "not stripped" not in result: + bb.debug(1, "runstrip: skip %s" % file) + return 0 - os.chdir(dvar) + # If the file is in a .debug directory it was already stripped, + # don't do it again... + if os.path.dirname(file).endswith(".debug"): + bb.debug(2, "Already ran strip on %s" % file) + return 0 + + strip = bb.data.getVar("STRIP", d, True) + objcopy = bb.data.getVar("OBJCOPY", d, True) + + newmode = None + if not os.access(file, os.W_OK): + origmode = os.stat(file)[stat.ST_MODE] + newmode = origmode | stat.S_IWRITE + os.chmod(file, newmode) + + extraflags = "" + if ".so" in file and "shared" in result: + extraflags = "--remove-section=.comment --remove-section=.note --strip-unneeded" + elif "shared" in result or "executable" in result: + extraflags = "--remove-section=.comment --remove-section=.note" + elif file.endswith(".a"): + extraflags = "--remove-section=.comment --strip-debug" + + + bb.mkdirhier(os.path.join(os.path.dirname(file), ".debug")) + debugfile=os.path.join(os.path.dirname(file), ".debug", os.path.basename(file)) + + stripcmd = "'%s' %s '%s'" % (strip, extraflags, file) + bb.debug(1, "runstrip: %s" % stripcmd) + + os.system("%s'%s' --only-keep-debug '%s' '%s'" % (pathprefix, objcopy, file, debugfile)) + ret = os.system("%s%s" % (pathprefix, stripcmd)) + os.system("%s'%s' --add-gnu-debuglink='%s' '%s'" % (pathprefix, objcopy, debugfile, file)) + + if newmode: + os.chmod(file, origmode) + + if ret: + bb.error("runstrip: '%s' strip command failed" % stripcmd) + + return 1 + +PACKAGESTRIPFUNCS += "do_runstrip" +python do_runstrip() { + import stat + dvar = bb.data.getVar('PKGD', d, True) def isexec(path): try: s = os.stat(path) @@ -258,53 +219,200 @@ python populate_packages () { return 0 return (s[stat.ST_MODE] & stat.S_IEXEC) + for root, dirs, files in os.walk(dvar): + for f in files: + file = os.path.join(root, f) + if not os.path.islink(file) and not os.path.isdir(file) and isexec(file): + runstrip(file, d) +} + + +def write_package_md5sums (root, outfile, ignorepaths): + # For each regular file under root, writes an md5sum to outfile. + # With thanks to patch.bbclass. + import bb, os + + try: + # Python 2.5+ + import hashlib + ctor = hashlib.md5 + except ImportError: + import md5 + ctor = md5.new + + outf = file(outfile, 'w') + + # Each output line looks like: "<hex...> <filename without leading slash>" + striplen = len(root) + if not root.endswith('/'): + striplen += 1 + + for walkroot, dirs, files in os.walk(root): + # Skip e.g. the DEBIAN directory + if walkroot[striplen:] in ignorepaths: + dirs[:] = [] + continue + + for name in files: + fullpath = os.path.join(walkroot, name) + if os.path.islink(fullpath) or (not os.path.isfile(fullpath)): + continue + + m = ctor() + f = file(fullpath, 'rb') + while True: + d = f.read(8192) + if not d: + break + m.update(d) + f.close() + + print >> outf, "%s %s" % (m.hexdigest(), fullpath[striplen:]) + + outf.close() + + +# +# Package data handling routines +# + +def get_package_mapping (pkg, d): + data = read_subpkgdata(pkg, d) + key = "PKG_%s" % pkg + + if key in data: + return data[key] + + return pkg + +def runtime_mapping_rename (varname, d): + #bb.note("%s before: %s" % (varname, bb.data.getVar(varname, d, True))) + + new_depends = [] + for depend in explode_deps(bb.data.getVar(varname, d, True) or ""): + # Have to be careful with any version component of the depend + split_depend = depend.split(' (') + new_depend = get_package_mapping(split_depend[0].strip(), d) + if len(split_depend) > 1: + new_depends.append("%s (%s" % (new_depend, split_depend[1])) + else: + new_depends.append(new_depend) + + bb.data.setVar(varname, " ".join(new_depends) or None, d) + + #bb.note("%s after: %s" % (varname, bb.data.getVar(varname, d, True))) + +# +# Package functions suitable for inclusion in PACKAGEFUNCS +# + +python package_do_split_locales() { + if (bb.data.getVar('PACKAGE_NO_LOCALE', d, True) == '1'): + bb.debug(1, "package requested not splitting locales") + return + + packages = (bb.data.getVar('PACKAGES', d, True) or "").split() + + datadir = bb.data.getVar('datadir', d, True) + if not datadir: + bb.note("datadir not defined") + return + + dvar = bb.data.getVar('PKGD', d, True) + pn = bb.data.getVar('PN', d, True) + + if pn + '-locale' in packages: + packages.remove(pn + '-locale') + + localedir = os.path.join(dvar + datadir, 'locale') + + if not os.path.isdir(localedir): + bb.debug(1, "No locale files in this package") + return + + locales = os.listdir(localedir) + + # This is *really* broken + mainpkg = packages[0] + # At least try and patch it up I guess... + if mainpkg.find('-dbg'): + mainpkg = mainpkg.replace('-dbg', '') + if mainpkg.find('-dev'): + mainpkg = mainpkg.replace('-dev', '') + + for l in locales: + ln = legitimize_package_name(l) + pkg = pn + '-locale-' + ln + packages.append(pkg) + bb.data.setVar('FILES_' + pkg, os.path.join(datadir, 'locale', l), d) + bb.data.setVar('RDEPENDS_' + pkg, '%s virtual-locale-%s' % (mainpkg, ln), d) + bb.data.setVar('RPROVIDES_' + pkg, '%s-locale %s-translation' % (pn, ln), d) + bb.data.setVar('DESCRIPTION_' + pkg, '%s translation for %s' % (l, pn), d) + + bb.data.setVar('PACKAGES', ' '.join(packages), d) +} + +python perform_packagecopy () { + dest = bb.data.getVar('D', d, True) + dvar = bb.data.getVar('PKGD', d, True) + + bb.mkdirhier(dvar) + + # Start by package population by taking a copy of the installed + # files to operate on + os.system('rm -rf %s/*' % (dvar)) + os.system('cp -pPR %s/* %s/' % (dest, dvar)) +} + +python populate_packages () { + import glob, errno, re,os + + workdir = bb.data.getVar('WORKDIR', d, True) + outdir = bb.data.getVar('DEPLOY_DIR', d, True) + dvar = bb.data.getVar('PKGD', d, True) + packages = bb.data.getVar('PACKAGES', d, True) + pn = bb.data.getVar('PN', d, True) + + bb.mkdirhier(outdir) + os.chdir(dvar) + # Sanity check PACKAGES for duplicates - should be moved to # sanity.bbclass once we have the infrastucture package_list = [] for pkg in packages.split(): if pkg in package_list: bb.error("-------------------") - bb.error("%s is listed in PACKAGES mutliple times, this leads to packaging errors." % pkg) + bb.error("%s is listed in PACKAGES multiple times, this leads to packaging errors." % pkg) bb.error("Please fix the metadata/report this as bug to OE bugtracker.") bb.error("-------------------") else: package_list.append(pkg) - if (bb.data.getVar('INHIBIT_PACKAGE_STRIP', d, 1) != '1'): - stripfunc = "" - for root, dirs, files in os.walk(dvar): - for f in files: - file = os.path.join(root, f) - if not os.path.islink(file) and isexec(file): - stripfunc += "\trunstrip %s || st=1\n" % (file) - if not stripfunc == "": - from bb import build - localdata = bb.data.createCopy(d) - # strip - bb.data.setVar('RUNSTRIP', '\tlocal st\n\tst=0\n%s\treturn $st' % stripfunc, localdata) - bb.data.setVarFlag('RUNSTRIP', 'func', 1, localdata) - bb.build.exec_func('RUNSTRIP', localdata) + + if (bb.data.getVar('INHIBIT_PACKAGE_STRIP', d, True) != '1'): + for f in (bb.data.getVar('PACKAGESTRIPFUNCS', d, True) or '').split(): + bb.build.exec_func(f, d) + + pkgdest = bb.data.getVar('PKGDEST', d, True) + os.system('rm -rf %s' % pkgdest) + + seen = [] + main_is_empty = 1 + main_pkg = bb.data.getVar('PN', d, True) for pkg in package_list: localdata = bb.data.createCopy(d) - root = os.path.join(workdir, "install", pkg) - - os.system('rm -rf %s' % root) + root = os.path.join(pkgdest, pkg) + bb.mkdirhier(root) - bb.data.setVar('ROOT', '', localdata) - bb.data.setVar('ROOT_%s' % pkg, root, localdata) bb.data.setVar('PKG', pkg, localdata) - - overrides = bb.data.getVar('OVERRIDES', localdata, 1) + overrides = bb.data.getVar('OVERRIDES', localdata, True) if not overrides: raise bb.build.FuncFailed('OVERRIDES not defined') - bb.data.setVar('OVERRIDES', overrides+':'+pkg, localdata) - + bb.data.setVar('OVERRIDES', overrides + ':' + pkg, localdata) bb.data.update_data(localdata) - root = bb.data.getVar('ROOT', localdata, 1) - bb.mkdirhier(root) - filesvar = bb.data.getVar('FILES', localdata, 1) or "" + filesvar = bb.data.getVar('FILES', localdata, True) or "" files = filesvar.split() for file in files: if os.path.isabs(file): @@ -318,16 +426,29 @@ python populate_packages () { globbed = glob.glob(file) if globbed: if [ file ] != globbed: - files += globbed - continue + if not file in globbed: + files += globbed + continue + else: + globbed.remove(file) + files += globbed if (not os.path.islink(file)) and (not os.path.exists(file)): continue + if file in seen: + continue + seen.append(file) + if os.path.isdir(file) and not os.path.islink(file): + bb.mkdirhier(os.path.join(root,file)) + os.chmod(os.path.join(root,file), os.stat(file).st_mode) + continue fpath = os.path.join(root,file) dpath = os.path.dirname(fpath) bb.mkdirhier(dpath) - ret = bb.movefile(file,fpath) - if ret is None or ret == 0: - raise bb.build.FuncFailed("File population failed") + ret = bb.copyfile(file, fpath) + if ret is False: + raise bb.build.FuncFailed("File population failed when copying %s to %s" % (file, fpath)) + if pkg == main_pkg and main_is_empty: + main_is_empty = 0 del localdata os.chdir(workdir) @@ -335,7 +456,8 @@ python populate_packages () { for root, dirs, files in os.walk(dvar): for f in files: path = os.path.join(root[len(dvar):], f) - unshipped.append(path) + if ('.' + path) not in seen: + unshipped.append(path) if unshipped != []: bb.note("the following files were installed but not shipped in any package:") @@ -345,18 +467,16 @@ python populate_packages () { bb.build.exec_func("package_name_hook", d) for pkg in package_list: - pkgname = bb.data.getVar('PKG_%s' % pkg, d, 1) + pkgname = bb.data.getVar('PKG_%s' % pkg, d, True) if pkgname is None: bb.data.setVar('PKG_%s' % pkg, pkg, d) - else: - add_package_mapping(pkg, pkgname, d) dangling_links = {} pkg_files = {} for pkg in package_list: dangling_links[pkg] = [] pkg_files[pkg] = [] - inst_root = os.path.join(workdir, "install", pkg) + inst_root = os.path.join(pkgdest, pkg) for root, dirs, files in os.walk(inst_root): for f in files: path = os.path.join(root, f) @@ -373,7 +493,11 @@ python populate_packages () { dangling_links[pkg].append(os.path.normpath(target)) for pkg in package_list: - rdepends = explode_deps(bb.data.getVar('RDEPENDS_' + pkg, d, 1) or bb.data.getVar('RDEPENDS', d, 1) or "") + rdepends = explode_deps(bb.data.getVar('RDEPENDS_' + pkg, d, 0) or bb.data.getVar('RDEPENDS', d, 0) or "") + + remstr = "${PN} (= ${EXTENDPKGV})" + if main_is_empty and remstr in rdepends: + rdepends.remove(remstr) for l in dangling_links[pkg]: found = False bb.debug(1, "%s contains dangling link %s" % (pkg, l)) @@ -390,6 +514,11 @@ python populate_packages () { if found == False: bb.note("%s contains dangling symlink to %s" % (pkg, l)) bb.data.setVar('RDEPENDS_' + pkg, " " + " ".join(rdepends), d) +} +populate_packages[dirs] = "${D}" + +python emit_pkgdata() { + from glob import glob def write_if_exists(f, pkg, var): def encode(str): @@ -397,21 +526,46 @@ python populate_packages () { c = codecs.getencoder("string_escape") return c(str)[0] - val = bb.data.getVar('%s_%s' % (var, pkg), d, 1) + val = bb.data.getVar('%s_%s' % (var, pkg), d, True) if val: f.write('%s_%s: %s\n' % (var, pkg, encode(val))) + return + val = bb.data.getVar('%s' % (var), d, True) + if val: + f.write('%s: %s\n' % (var, encode(val))) + return + + packages = bb.data.getVar('PACKAGES', d, True) + pkgdest = bb.data.getVar('PKGDEST', d, 1) + pkgdatadir = bb.data.getVar('PKGDATA_DIR', d, True) - data_file = bb.data.expand("${STAGING_DIR}/pkgdata/${PN}", d) + pstageactive = bb.data.getVar('PSTAGING_ACTIVE', d, True) + if pstageactive == "1": + lf = bb.utils.lockfile(bb.data.expand("${STAGING_DIR}/staging.lock", d)) + + data_file = pkgdatadir + bb.data.expand("/${PN}" , d) f = open(data_file, 'w') f.write("PACKAGES: %s\n" % packages) f.close() + package_stagefile(data_file, d) - for pkg in package_list: - subdata_file = bb.data.expand("${STAGING_DIR}/pkgdata/runtime/%s" % pkg, d) + workdir = bb.data.getVar('WORKDIR', d, True) + + for pkg in packages.split(): + subdata_file = pkgdatadir + "/runtime/%s" % pkg sf = open(subdata_file, 'w') + write_if_exists(sf, pkg, 'PN') + write_if_exists(sf, pkg, 'PV') + write_if_exists(sf, pkg, 'PR') + write_if_exists(sf, pkg, 'PKGV') + write_if_exists(sf, pkg, 'PKGR') write_if_exists(sf, pkg, 'DESCRIPTION') write_if_exists(sf, pkg, 'RDEPENDS') write_if_exists(sf, pkg, 'RPROVIDES') + write_if_exists(sf, pkg, 'RRECOMMENDS') + write_if_exists(sf, pkg, 'RSUGGESTS') + write_if_exists(sf, pkg, 'RREPLACES') + write_if_exists(sf, pkg, 'RCONFLICTS') write_if_exists(sf, pkg, 'PKG') write_if_exists(sf, pkg, 'ALLOW_EMPTY') write_if_exists(sf, pkg, 'FILES') @@ -420,121 +574,98 @@ python populate_packages () { write_if_exists(sf, pkg, 'pkg_preinst') write_if_exists(sf, pkg, 'pkg_prerm') sf.close() - bb.build.exec_func("read_subpackage_metadata", d) + + package_stagefile(subdata_file, d) + #if pkgdatadir2: + # bb.copyfile(subdata_file, pkgdatadir2 + "/runtime/%s" % pkg) + + allow_empty = bb.data.getVar('ALLOW_EMPTY_%s' % pkg, d, True) + if not allow_empty: + allow_empty = bb.data.getVar('ALLOW_EMPTY', d, True) + root = "%s/%s" % (pkgdest, pkg) + os.chdir(root) + g = glob('*') + glob('.[!.]*') + if g or allow_empty == "1": + packagedfile = pkgdatadir + '/runtime/%s.packaged' % pkg + file(packagedfile, 'w').close() + package_stagefile(packagedfile, d) + if pstageactive == "1": + bb.utils.unlockfile(lf) } +emit_pkgdata[dirs] = "${PKGDATA_DIR}/runtime" ldconfig_postinst_fragment() { if [ x"$D" = "x" ]; then - ldconfig + if [ -e /etc/ld.so.conf ] ; then + [ -x /sbin/ldconfig ] && /sbin/ldconfig + fi fi } -python package_depchains() { - """ - For a given set of prefix and postfix modifiers, make those packages - RRECOMMENDS on the corresponding packages for its DEPENDS. - - Example: If package A depends upon package B, and A's .bb emits an - A-dev package, this would make A-dev Recommends: B-dev. - """ - - packages = bb.data.getVar('PACKAGES', d, 1) - postfixes = (bb.data.getVar('DEPCHAIN_POST', d, 1) or '').split() - prefixes = (bb.data.getVar('DEPCHAIN_PRE', d, 1) or '').split() - - def pkg_addrrecs(pkg, base, func, d): - rdepends = explode_deps(bb.data.getVar('RDEPENDS_' + base, d, 1) or bb.data.getVar('RDEPENDS', d, 1) or "") - # bb.note('rdepends for %s is %s' % (base, rdepends)) - rreclist = [] - - for depend in rdepends: - split_depend = depend.split(' (') - name = split_depend[0].strip() - func(rreclist, name) - - oldrrec = bb.data.getVar('RRECOMMENDS_%s', d) or '' - bb.data.setVar('RRECOMMENDS_%s' % pkg, oldrrec + ' '.join(rreclist), d) - - def packaged(pkg, d): - return os.access(bb.data.expand('${STAGING_DIR}/pkgdata/runtime/%s.packaged' % pkg, d), os.R_OK) - - for pkg in packages.split(): - for postfix in postfixes: - def func(list, name): - pkg = '%s%s' % (name, postfix) - if packaged(pkg, d): - list.append(pkg) - - base = pkg[:-len(postfix)] - if pkg.endswith(postfix): - pkg_addrrecs(pkg, base, func, d) - continue - - for prefix in prefixes: - def func(list, name): - pkg = '%s%s' % (prefix, name) - if packaged(pkg, d): - list.append(pkg) - - base = pkg[len(prefix):] - if pkg.startswith(prefix): - pkg_addrrecs(pkg, base, func, d) -} +SHLIBSDIR = "${STAGING_DIR_HOST}/shlibs" python package_do_shlibs() { - import os, re, os.path + import re exclude_shlibs = bb.data.getVar('EXCLUDE_FROM_SHLIBS', d, 0) if exclude_shlibs: - bb.note("not generating shlibs") + bb.debug(1, "not generating shlibs") return lib_re = re.compile("^lib.*\.so") libdir_re = re.compile(".*/lib$") - packages = bb.data.getVar('PACKAGES', d, 1) - if not packages: - bb.debug(1, "no packages to build; not calculating shlibs") - return - - workdir = bb.data.getVar('WORKDIR', d, 1) - if not workdir: - bb.error("WORKDIR not defined") - return + packages = bb.data.getVar('PACKAGES', d, True) - staging = bb.data.getVar('STAGING_DIR', d, 1) - if not staging: - bb.error("STAGING_DIR not defined") - return + workdir = bb.data.getVar('WORKDIR', d, True) - ver = bb.data.getVar('PV', d, 1) + ver = bb.data.getVar('PKGV', d, True) if not ver: - bb.error("PV not defined") + bb.error("PKGV not defined") return - target_sys = bb.data.getVar('TARGET_SYS', d, 1) - if not target_sys: - bb.error("TARGET_SYS not defined") - return + pkgdest = bb.data.getVar('PKGDEST', d, True) - shlibs_dir = os.path.join(staging, target_sys, "shlibs") - old_shlibs_dir = os.path.join(staging, "shlibs") + shlibs_dir = bb.data.getVar('SHLIBSDIR', d, True) bb.mkdirhier(shlibs_dir) + pstageactive = bb.data.getVar('PSTAGING_ACTIVE', d, True) + if pstageactive == "1": + lf = bb.utils.lockfile(bb.data.expand("${STAGING_DIR}/staging.lock", d)) + + if bb.data.getVar('PACKAGE_SNAP_LIB_SYMLINKS', d, True) == "1": + snap_symlinks = True + else: + snap_symlinks = False + + if (bb.data.getVar('USE_LDCONFIG', d, True) or "1") == "1": + use_ldconfig = True + else: + use_ldconfig = False + needed = {} + private_libs = bb.data.getVar('PRIVATE_LIBS', d, True) for pkg in packages.split(): needs_ldconfig = False bb.debug(2, "calculating shlib provides for %s" % pkg) + pkgver = bb.data.getVar('PKGV_' + pkg, d, True) + if not pkgver: + pkgver = bb.data.getVar('PV_' + pkg, d, True) + if not pkgver: + pkgver = ver + needed[pkg] = [] sonames = list() - top = os.path.join(workdir, "install", pkg) + top = os.path.join(pkgdest, pkg) + renames = [] for root, dirs, files in os.walk(top): for file in files: soname = None path = os.path.join(root, file) - if os.access(path, os.X_OK) or lib_re.match(file): - cmd = (bb.data.getVar('BUILD_PREFIX', d, 1) or "") + "objdump -p " + path + " 2>/dev/null" + if (os.access(path, os.X_OK) or lib_re.match(file)) and not os.path.islink(path): + cmd = bb.data.getVar('OBJDUMP', d, True) + " -p " + path + " 2>/dev/null" + cmd = "PATH=\"%s\" %s" % (bb.data.getVar('PATH', d, True), cmd) fd = os.popen(cmd) lines = fd.readlines() fd.close() @@ -543,10 +674,18 @@ python package_do_shlibs() { if m: needed[pkg].append(m.group(1)) m = re.match("\s+SONAME\s+([^\s]*)", l) - if m and not m.group(1) in sonames: - sonames.append(m.group(1)) - if m and libdir_re.match(root): - needs_ldconfig = True + if m: + this_soname = m.group(1) + if not this_soname in sonames: + # if library is private (only used by package) then do not build shlib for it + if not private_libs or -1 == private_libs.find(this_soname): + sonames.append(this_soname) + if libdir_re.match(root): + needs_ldconfig = True + if snap_symlinks and (file != soname): + renames.append((path, os.path.join(root, this_soname))) + for (old, new) in renames: + os.rename(old, new) shlibs_file = os.path.join(shlibs_dir, pkg + ".list") if os.path.exists(shlibs_file): os.remove(shlibs_file) @@ -558,20 +697,25 @@ python package_do_shlibs() { for s in sonames: fd.write(s + '\n') fd.close() + package_stagefile(shlibs_file, d) fd = open(shver_file, 'w') - fd.write(ver + '\n') + fd.write(pkgver + '\n') fd.close() - if needs_ldconfig: + package_stagefile(shver_file, d) + if needs_ldconfig and use_ldconfig: bb.debug(1, 'adding ldconfig call to postinst for %s' % pkg) - postinst = bb.data.getVar('pkg_postinst_%s' % pkg, d, 1) or bb.data.getVar('pkg_postinst', d, 1) + postinst = bb.data.getVar('pkg_postinst_%s' % pkg, d, True) or bb.data.getVar('pkg_postinst', d, True) if not postinst: postinst = '#!/bin/sh\n' - postinst += bb.data.getVar('ldconfig_postinst_fragment', d, 1) + postinst += bb.data.getVar('ldconfig_postinst_fragment', d, True) bb.data.setVar('pkg_postinst_%s' % pkg, postinst, d) + if pstageactive == "1": + bb.utils.unlockfile(lf) + shlib_provider = {} list_re = re.compile('^(.*)\.list$') - for dir in [old_shlibs_dir, shlibs_dir]: + for dir in [shlibs_dir]: if not os.path.exists(dir): continue for file in os.listdir(dir): @@ -590,7 +734,18 @@ python package_do_shlibs() { for l in lines: shlib_provider[l.rstrip()] = (dep_pkg, lib_ver) - + assumed_libs = bb.data.getVar('ASSUME_SHLIBS', d, True) + if assumed_libs: + for e in assumed_libs.split(): + l, dep_pkg = e.split(":") + lib_ver = None + dep_pkg = dep_pkg.rsplit("_", 1) + if len(dep_pkg) == 2: + lib_ver = dep_pkg[1] + dep_pkg = dep_pkg[0] + shlib_provider[l] = (dep_pkg, lib_ver) + + dep_packages = [] for pkg in packages.split(): bb.debug(2, "calculating shlib requirements for %s" % pkg) @@ -608,10 +763,13 @@ python package_do_shlibs() { dep = dep_pkg if not dep in deps: deps.append(dep) + if not dep_pkg in dep_packages: + dep_packages.append(dep_pkg) + else: bb.note("Couldn't find shared library provider for %s" % n) - deps_file = os.path.join(workdir, "install", pkg + ".shlibdeps") + deps_file = os.path.join(pkgdest, pkg + ".shlibdeps") if os.path.exists(deps_file): os.remove(deps_file) if len(deps): @@ -622,30 +780,13 @@ python package_do_shlibs() { } python package_do_pkgconfig () { - import re, os - - packages = bb.data.getVar('PACKAGES', d, 1) - if not packages: - bb.debug(1, "no packages to build; not calculating pkgconfig dependencies") - return - - workdir = bb.data.getVar('WORKDIR', d, 1) - if not workdir: - bb.error("WORKDIR not defined") - return - - staging = bb.data.getVar('STAGING_DIR', d, 1) - if not staging: - bb.error("STAGING_DIR not defined") - return + import re - target_sys = bb.data.getVar('TARGET_SYS', d, 1) - if not target_sys: - bb.error("TARGET_SYS not defined") - return + packages = bb.data.getVar('PACKAGES', d, True) + workdir = bb.data.getVar('WORKDIR', d, True) + pkgdest = bb.data.getVar('PKGDEST', d, True) - shlibs_dir = os.path.join(staging, target_sys, "shlibs") - old_shlibs_dir = os.path.join(staging, "shlibs") + shlibs_dir = bb.data.getVar('SHLIBSDIR', d, True) bb.mkdirhier(shlibs_dir) pc_re = re.compile('(.*)\.pc$') @@ -657,7 +798,7 @@ python package_do_pkgconfig () { for pkg in packages.split(): pkgconfig_provided[pkg] = [] pkgconfig_needed[pkg] = [] - top = os.path.join(workdir, "install", pkg) + top = os.path.join(pkgdest, pkg) for root, dirs, files in os.walk(top): for file in files: m = pc_re.match(file) @@ -685,6 +826,10 @@ python package_do_pkgconfig () { if hdr == 'Requires': pkgconfig_needed[pkg] += exp.replace(',', ' ').split() + pstageactive = bb.data.getVar('PSTAGING_ACTIVE', d, True) + if pstageactive == "1": + lf = bb.utils.lockfile(bb.data.expand("${STAGING_DIR}/staging.lock", d)) + for pkg in packages.split(): pkgs_file = os.path.join(shlibs_dir, pkg + ".pclist") if os.path.exists(pkgs_file): @@ -694,8 +839,9 @@ python package_do_pkgconfig () { for p in pkgconfig_provided[pkg]: f.write('%s\n' % p) f.close() + package_stagefile(pkgs_file, d) - for dir in [old_shlibs_dir, shlibs_dir]: + for dir in [shlibs_dir]: if not os.path.exists(dir): continue for file in os.listdir(dir): @@ -720,7 +866,7 @@ python package_do_pkgconfig () { found = True if found == False: bb.note("couldn't find pkgconfig module '%s' in any package" % n) - deps_file = os.path.join(workdir, "install", pkg + ".pcdeps") + deps_file = os.path.join(pkgdest, pkg + ".pcdeps") if os.path.exists(deps_file): os.remove(deps_file) if len(deps): @@ -728,76 +874,224 @@ python package_do_pkgconfig () { for dep in deps: fd.write(dep + '\n') fd.close() + package_stagefile(deps_file, d) + + if pstageactive == "1": + bb.utils.unlockfile(lf) } -python package_do_split_locales() { - import os +python read_shlibdeps () { + packages = bb.data.getVar('PACKAGES', d, True).split() + for pkg in packages: + rdepends = explode_deps(bb.data.getVar('RDEPENDS_' + pkg, d, 0) or bb.data.getVar('RDEPENDS', d, 0) or "") + for extension in ".shlibdeps", ".pcdeps", ".clilibdeps": + depsfile = bb.data.expand("${PKGDEST}/" + pkg + extension, d) + if os.access(depsfile, os.R_OK): + fd = file(depsfile) + lines = fd.readlines() + fd.close() + for l in lines: + rdepends.append(l.rstrip()) + bb.data.setVar('RDEPENDS_' + pkg, " " + " ".join(rdepends), d) +} - if (bb.data.getVar('PACKAGE_NO_LOCALE', d, 1) == '1'): - bb.debug(1, "package requested not splitting locales") - return +python package_depchains() { + """ + For a given set of prefix and postfix modifiers, make those packages + RRECOMMENDS on the corresponding packages for its RDEPENDS. - packages = (bb.data.getVar('PACKAGES', d, 1) or "").split() - if not packages: - bb.debug(1, "no packages to build; not splitting locales") - return + Example: If package A depends upon package B, and A's .bb emits an + A-dev package, this would make A-dev Recommends: B-dev. - datadir = bb.data.getVar('datadir', d, 1) - if not datadir: - bb.note("datadir not defined") - return + If only one of a given suffix is specified, it will take the RRECOMMENDS + based on the RDEPENDS of *all* other packages. If more than one of a given + suffix is specified, its will only use the RDEPENDS of the single parent + package. + """ - dvar = bb.data.getVar('D', d, 1) - if not dvar: - bb.error("D not defined") - return + packages = bb.data.getVar('PACKAGES', d, True) + postfixes = (bb.data.getVar('DEPCHAIN_POST', d, True) or '').split() + prefixes = (bb.data.getVar('DEPCHAIN_PRE', d, True) or '').split() - pn = bb.data.getVar('PN', d, 1) - if not pn: - bb.error("PN not defined") - return + def pkg_adddeprrecs(pkg, base, suffix, getname, depends, d): - if pn + '-locale' in packages: - packages.remove(pn + '-locale') + #bb.note('depends for %s is %s' % (base, depends)) + rreclist = explode_deps(bb.data.getVar('RRECOMMENDS_' + pkg, d, True) or bb.data.getVar('RRECOMMENDS', d, True) or "") - localedir = os.path.join(dvar + datadir, 'locale') + for depend in depends: + if depend.find('-native') != -1 or depend.find('-cross') != -1 or depend.startswith('virtual/'): + #bb.note("Skipping %s" % depend) + continue + if depend.endswith('-dev'): + depend = depend.replace('-dev', '') + if depend.endswith('-dbg'): + depend = depend.replace('-dbg', '') + pkgname = getname(depend, suffix) + #bb.note("Adding %s for %s" % (pkgname, depend)) + if not pkgname in rreclist: + rreclist.append(pkgname) - if not os.path.isdir(localedir): - bb.debug(1, "No locale files in this package") - return + #bb.note('setting: RRECOMMENDS_%s=%s' % (pkg, ' '.join(rreclist))) + bb.data.setVar('RRECOMMENDS_%s' % pkg, ' '.join(rreclist), d) - locales = os.listdir(localedir) + def pkg_addrrecs(pkg, base, suffix, getname, rdepends, d): - mainpkg = packages[0] + #bb.note('rdepends for %s is %s' % (base, rdepends)) + rreclist = explode_deps(bb.data.getVar('RRECOMMENDS_' + pkg, d, True) or bb.data.getVar('RRECOMMENDS', d, True) or "") - for l in locales: - ln = legitimize_package_name(l) - pkg = pn + '-locale-' + ln - packages.append(pkg) - bb.data.setVar('FILES_' + pkg, os.path.join(datadir, 'locale', l), d) - bb.data.setVar('RDEPENDS_' + pkg, '%s virtual-locale-%s' % (mainpkg, ln), d) - bb.data.setVar('RPROVIDES_' + pkg, '%s-locale %s-translation' % (pn, ln), d) - bb.data.setVar('DESCRIPTION_' + pkg, '%s translation for %s' % (l, pn), d) + for depend in rdepends: + if depend.endswith('-dev'): + depend = depend.replace('-dev', '') + if depend.endswith('-dbg'): + depend = depend.replace('-dbg', '') + pkgname = getname(depend, suffix) + if not pkgname in rreclist: + rreclist.append(pkgname) + + #bb.note('setting: RRECOMMENDS_%s=%s' % (pkg, ' '.join(rreclist))) + bb.data.setVar('RRECOMMENDS_%s' % pkg, ' '.join(rreclist), d) + + def add_dep(list, dep): + dep = dep.split(' (')[0].strip() + if dep not in list: + list.append(dep) + + depends = [] + for dep in explode_deps(bb.data.getVar('DEPENDS', d, True) or ""): + add_dep(depends, dep) + + rdepends = [] + for dep in explode_deps(bb.data.getVar('RDEPENDS', d, True) or ""): + add_dep(rdepends, dep) - bb.data.setVar('PACKAGES', ' '.join(packages), d) + for pkg in packages.split(): + for dep in explode_deps(bb.data.getVar('RDEPENDS_' + pkg, d, True) or ""): + add_dep(rdepends, dep) - rdep = (bb.data.getVar('RDEPENDS_%s' % mainpkg, d, 1) or bb.data.getVar('RDEPENDS', d, 1) or "").split() - rdep.append('%s-locale*' % pn) - bb.data.setVar('RDEPENDS_%s' % mainpkg, ' '.join(rdep), d) + #bb.note('rdepends is %s' % rdepends) + + def post_getname(name, suffix): + return '%s%s' % (name, suffix) + def pre_getname(name, suffix): + return '%s%s' % (suffix, name) + + pkgs = {} + for pkg in packages.split(): + for postfix in postfixes: + if pkg.endswith(postfix): + if not postfix in pkgs: + pkgs[postfix] = {} + pkgs[postfix][pkg] = (pkg[:-len(postfix)], post_getname) + + for prefix in prefixes: + if pkg.startswith(prefix): + if not prefix in pkgs: + pkgs[prefix] = {} + pkgs[prefix][pkg] = (pkg[:-len(prefix)], pre_getname) + + for suffix in pkgs: + for pkg in pkgs[suffix]: + (base, func) = pkgs[suffix][pkg] + if suffix == "-dev" and not pkg.startswith("kernel-module-"): + pkg_adddeprrecs(pkg, base, suffix, func, depends, d) + if len(pkgs[suffix]) == 1: + pkg_addrrecs(pkg, base, suffix, func, rdepends, d) + else: + rdeps = [] + for dep in explode_deps(bb.data.getVar('RDEPENDS_' + base, d, True) or bb.data.getVar('RDEPENDS', d, True) or ""): + add_dep(rdeps, dep) + pkg_addrrecs(pkg, base, suffix, func, rdeps, d) } -PACKAGEFUNCS ?= "package_do_split_locales \ - populate_packages package_do_shlibs \ - package_do_pkgconfig read_shlibdeps \ - package_depchains" +PACKAGE_PREPROCESS_FUNCS ?= "" +PACKAGEFUNCS ?= "perform_packagecopy \ + ${PACKAGE_PREPROCESS_FUNCS} \ + package_do_split_locales \ + populate_packages \ + package_do_shlibs \ + package_do_pkgconfig \ + read_shlibdeps \ + package_depchains \ + emit_pkgdata" + +def package_run_hooks(f, d): + import bb, os + staging = bb.data.getVar('PKGDATA_DIR', d, True) + dn = os.path.join(staging, 'hooks', f) + if os.access(dn, os.R_OK): + for f in os.listdir(dn): + fn = os.path.join(dn, f) + fp = open(fn, 'r') + line = 0 + for l in fp.readlines(): + l = l.rstrip() + bb.parse.parse_py.BBHandler.feeder(line, l, fn, os.path.basename(fn), d) + line += 1 + fp.close() + anonqueue = bb.data.getVar("__anonqueue", d, True) or [] + body = [x['content'] for x in anonqueue] + flag = { 'python' : 1, 'func' : 1 } + bb.data.setVar("__anonfunc", "\n".join(body), d) + bb.data.setVarFlags("__anonfunc", flag, d) + try: + t = bb.data.getVar('T', d) + bb.data.setVar('T', '${TMPDIR}/', d) + bb.build.exec_func("__anonfunc", d) + bb.data.delVar('T', d) + if t: + bb.data.setVar('T', t, d) + except Exception, e: + bb.msg.debug(1, bb.msg.domain.Parsing, "Exception when executing anonymous function: %s" % e) + raise + bb.data.delVar("__anonqueue", d) + bb.data.delVar("__anonfunc", d) + python package_do_package () { - for f in (bb.data.getVar('PACKAGEFUNCS', d, 1) or '').split(): + packages = (bb.data.getVar('PACKAGES', d, True) or "").split() + if len(packages) < 1: + bb.debug(1, "No packages to build, skipping do_package") + return + + workdir = bb.data.getVar('WORKDIR', d, True) + outdir = bb.data.getVar('DEPLOY_DIR', d, True) + dest = bb.data.getVar('D', d, True) + dvar = bb.data.getVar('PKGD', d, True) + pn = bb.data.getVar('PN', d, True) + + if not workdir or not outdir or not dest or not dvar or not pn or not packages: + bb.error("WORKDIR, DEPLOY_DIR, D, PN and PKGD all must be defined, unable to package") + return + + for f in (bb.data.getVar('PACKAGEFUNCS', d, True) or '').split(): bb.build.exec_func(f, d) + package_run_hooks(f, d) } - do_package[dirs] = "${D}" -# shlibs requires any DEPENDS to have already packaged for the *.list files -do_package[deptask] = "do_package" -populate_packages[dirs] = "${STAGING_DIR}/pkgdata/runtime ${D}" -EXPORT_FUNCTIONS do_package do_shlibs do_split_locales mapping_rename_hook addtask package before do_build after do_install + +# Dummy task to mark when all packaging is complete +do_package_write () { + : +} +addtask package_write before do_build after do_package + +EXPORT_FUNCTIONS do_package do_package_write + +# +# Helper functions for the package writing classes +# + +python package_mapping_rename_hook () { + """ + Rewrite variables to account for package renaming in things + like debian.bbclass or manual PKG variable name changes + """ + runtime_mapping_rename("RDEPENDS", d) + runtime_mapping_rename("RRECOMMENDS", d) + runtime_mapping_rename("RSUGGESTS", d) + runtime_mapping_rename("RPROVIDES", d) + runtime_mapping_rename("RREPLACES", d) + runtime_mapping_rename("RCONFLICTS", d) +} + +EXPORT_FUNCTIONS mapping_rename_hook diff --git a/classes/package_dbg.bbclass b/classes/package_dbg.bbclass new file mode 100644 index 0000000000..39dceaf9b3 --- /dev/null +++ b/classes/package_dbg.bbclass @@ -0,0 +1,125 @@ +# package_dbg.bbclass: populate -dbg versions for each package in PACKAGES +# +# Copyright (c) 2009 MontaVista Software, Inc. All rights reserved. +# +# Released under the MIT license (see LICENSE.MIT for the terms) + + +inherit package + + +PACKAGE_DBG_DIRS = "${bindir} ${sbindir} \ + ${libexecdir} ${libdir} \ + ${base_bindir} ${base_sbindir} \ + ${base_libdir}" +PACKAGE_DBG_DESC = "Debugging files for %s" +PACKAGE_DBG_EXCLUDE = "${PN}-locale* ${PN}-doc ${PN}-dev *-dbg" + + +def __find(dir): + """ Given a directory, recurses into that directory, + returning all files. """ + + from os import walk + from os.path import join + + for root, dirs, files in walk(dir): + for file in files: + yield join(root, file) + +def __package_get_files(pkg, d): + """ Obtains a list of files to be included in a package. + + Starting from the FILES_<pkg> variable, it expands any globs in the list, + which removes missing files, and traverses any directories in the list. + + It does *not* remove files which are also in other packages, it's left + to the user's discretion whether to allow overlap. """ + + from glob import glob + from os.path import join, isdir, islink + + installdir = d.getVar("D", True) + installdirlen = len(installdir) + + files = (d.getVar("FILES_%s" % pkg, True) or "").split() + for globbed in (glob(join(installdir, file[1:])) for file in files): + for path in globbed: + if isdir(path) and not islink(path): + for file in __find(path): + yield file[installdirlen:] + else: + yield path[installdirlen:] + +def add_dbg_packages(d): + from fnmatch import fnmatch + + packages = d.getVar("PACKAGES", True).split() + excludes = d.getVar("PACKAGE_DBG_EXCLUDE", True).split() + + for pkg in tuple(packages): + if any(fnmatch(pkg, excluded) for excluded in excludes): + continue + + dbgpkg = "%s-dbg" % pkg + if not dbgpkg in packages: + packages.insert(0, dbgpkg) + + d.setVar("PACKAGES", " ".join(packages)) + + +# Add the -dbg packages to PACKAGES +python () { + from bb.data import inherits_class as inherits + + # Task handles its own -dbg versions of its packages at the moment + if not inherits("task", d): + dynpkgs = d.getVar("PACKAGES_DYNAMIC", True).split() + dynpkgs += ["%s-dbg" % dyn for dyn in dynpkgs] + d.setVar("PACKAGES_DYNAMIC", " ".join(dynpkgs)) + + add_dbg_packages(d) +} + +python populate_packages_prepend () { + from bb.data import inherits_class as inherits + + if not inherits("task", d): + bb.build.exec_func("package_do_dbg", d) +} + +# Populate the -dbg subpackage metadata +python package_do_dbg() { + """ Populate the -dbg subpackage metadata. """ + + from os.path import join, basename, dirname + + def setVar(key, val): + if d.getVar(key, val) is None: + d.setVar(key, val) + + add_dbg_packages(d) + packages = d.getVar("PACKAGES", True).split() + desc = d.getVar("PACKAGE_DBG_DESC", True) + debug_dirs = d.getVar("PACKAGE_DBG_DIRS", True).split() + + done = [] + for pkgname in tuple(packages): + files = tuple(__package_get_files(pkgname, d)) + dbg = [join(dirname(file), ".debug", basename(file)) + for file in files + if not file in done and + any(file.startswith(dir) for dir in debug_dirs)] + done.extend(files) + + if dbg: + setVar("FILES_%s-dbg" % pkgname, " ".join(dbg)) + setVar("DESCRIPTION_%s-dbg" % pkgname, desc % pkgname) + setVar("RDEPENDS_%s-dbg" % pkgname, pkgname) + else: + try: + packages.remove("%s-dbg" % pkgname) + except ValueError: + pass + d.setVar("PACKAGES", " ".join(packages)) +} diff --git a/classes/package_deb.bbclass b/classes/package_deb.bbclass new file mode 100644 index 0000000000..2a9bf76a79 --- /dev/null +++ b/classes/package_deb.bbclass @@ -0,0 +1,276 @@ +# +# Copyright 2006-2008 OpenedHand Ltd. +# + +inherit package + +BOOTSTRAP_EXTRA_RDEPENDS += "dpkg" +DISTRO_EXTRA_RDEPENDS += "dpkg" +IMAGE_PKGTYPE ?= "deb" + +# Map TARGET_ARCH to Debian's ideas about architectures +DPKG_ARCH ?= "${TARGET_ARCH}" +DPKG_ARCH_x86 ?= "i386" +DPKG_ARCH_i486 ?= "i386" +DPKG_ARCH_i586 ?= "i386" +DPKG_ARCH_i686 ?= "i386" +DPKG_ARCH_pentium ?= "i386" + +python package_deb_fn () { + bb.data.setVar('PKGFN', bb.data.getVar('PKG',d), d) +} + +addtask package_deb_install +python do_package_deb_install () { + pkg = bb.data.getVar('PKG', d, 1) + pkgfn = bb.data.getVar('PKGFN', d, 1) + rootfs = bb.data.getVar('IMAGE_ROOTFS', d, 1) + debdir = bb.data.getVar('DEPLOY_DIR_DEB', d, 1) + apt_config = bb.data.expand('${STAGING_ETCDIR_NATIVE}/apt/apt.conf', d) + stagingbindir = bb.data.getVar('STAGING_BINDIR_NATIVE', d, 1) + tmpdir = bb.data.getVar('TMPDIR', d, 1) + + if None in (pkg,pkgfn,rootfs): + raise bb.build.FuncFailed("missing variables (one or more of PKG, PKGFN, IMAGE_ROOTFS)") + try: + if not os.exists(rootfs): + os.makedirs(rootfs) + os.chdir(rootfs) + except OSError: + import sys + raise bb.build.FuncFailed(str(sys.exc_value)) + + # update packages file + (exitstatus, output) = commands.getstatusoutput('dpkg-scanpackages %s > %s/Packages' % (debdir, debdir)) + if (exitstatus != 0 ): + raise bb.build.FuncFailed(output) + + f = open(os.path.join(tmpdir, "stamps", "DEB_PACKAGE_INDEX_CLEAN"), "w") + f.close() + + # NOTE: this env stuff is racy at best, we need something more capable + # than 'commands' for command execution, which includes manipulating the + # env of the fork+execve'd processs + + # Set up environment + apt_config_backup = os.getenv('APT_CONFIG') + os.putenv('APT_CONFIG', apt_config) + path = os.getenv('PATH') + os.putenv('PATH', '%s:%s' % (stagingbindir, os.getenv('PATH'))) + + # install package + commands.getstatusoutput('apt-get update') + commands.getstatusoutput('apt-get install -y %s' % pkgfn) + + # revert environment + os.putenv('APT_CONFIG', apt_config_backup) + os.putenv('PATH', path) +} + +python do_package_deb () { + import re, copy + + workdir = bb.data.getVar('WORKDIR', d, 1) + if not workdir: + bb.error("WORKDIR not defined, unable to package") + return + + outdir = bb.data.getVar('DEPLOY_DIR_DEB', d, 1) + if not outdir: + bb.error("DEPLOY_DIR_DEB not defined, unable to package") + return + + dvar = bb.data.getVar('D', d, 1) + if not dvar: + bb.error("D not defined, unable to package") + return + bb.mkdirhier(dvar) + + packages = bb.data.getVar('PACKAGES', d, 1) + if not packages: + bb.debug(1, "PACKAGES not defined, nothing to package") + return + + tmpdir = bb.data.getVar('TMPDIR', d, 1) + + if os.access(os.path.join(tmpdir, "stamps", "DEB_PACKAGE_INDEX_CLEAN"),os.R_OK): + os.unlink(os.path.join(tmpdir, "stamps", "DEB_PACKAGE_INDEX_CLEAN")) + + if packages == []: + bb.debug(1, "No packages; nothing to do") + return + + for pkg in packages.split(): + localdata = bb.data.createCopy(d) + pkgdest = bb.data.getVar('PKGDEST', d, 1) + root = "%s/%s" % (pkgdest, pkg) + + lf = bb.utils.lockfile(root + ".lock") + + bb.data.setVar('ROOT', '', localdata) + bb.data.setVar('ROOT_%s' % pkg, root, localdata) + pkgname = bb.data.getVar('PKG_%s' % pkg, localdata, 1) + if not pkgname: + pkgname = pkg + bb.data.setVar('PKG', pkgname, localdata) + + overrides = bb.data.getVar('OVERRIDES', localdata) + if not overrides: + raise bb.build.FuncFailed('OVERRIDES not defined') + overrides = bb.data.expand(overrides, localdata) + bb.data.setVar('OVERRIDES', overrides + ':' + pkg, localdata) + + bb.data.update_data(localdata) + basedir = os.path.join(os.path.dirname(root)) + + pkgoutdir = os.path.join(outdir, bb.data.getVar('PACKAGE_ARCH', localdata, 1)) + bb.mkdirhier(pkgoutdir) + + os.chdir(root) + from glob import glob + g = glob('*') + glob('.[!.]*') + try: + del g[g.index('DEBIAN')] + del g[g.index('./DEBIAN')] + except ValueError: + pass + if not g and bb.data.getVar('ALLOW_EMPTY', localdata) != "1": + from bb import note + note("Not creating empty archive for %s-%s" % (pkg, bb.data.expand('${PV}-${PR}${DISTRO_PR}', localdata, True))) + bb.utils.unlockfile(lf) + continue + + controldir = os.path.join(root, 'DEBIAN') + bb.mkdirhier(controldir) + os.chmod(controldir, 0755) + try: + ctrlfile = file(os.path.join(controldir, 'control'), 'wb') + # import codecs + # ctrlfile = codecs.open("someFile", "w", "utf-8") + except OSError: + bb.utils.unlockfile(lf) + raise bb.build.FuncFailed("unable to open control file for writing.") + + fields = [] + pe = bb.data.getVar('PE', d, 1) + if pe and int(pe) > 0: + fields.append(["Version: %s:%s-%s%s\n", ['PE', 'PV', 'PR', 'DISTRO_PR']]) + else: + fields.append(["Version: %s-%s%s\n", ['PV', 'PR', 'DISTRO_PR']]) + fields.append(["Description: %s\n", ['DESCRIPTION']]) + fields.append(["Section: %s\n", ['SECTION']]) + fields.append(["Priority: %s\n", ['PRIORITY']]) + fields.append(["Maintainer: %s\n", ['MAINTAINER']]) + fields.append(["Architecture: %s\n", ['DPKG_ARCH']]) + fields.append(["OE: %s\n", ['PN']]) + fields.append(["Homepage: %s\n", ['HOMEPAGE']]) + +# Package, Version, Maintainer, Description - mandatory +# Section, Priority, Essential, Architecture, Source, Depends, Pre-Depends, Recommends, Suggests, Conflicts, Replaces, Provides - Optional + + + def pullData(l, d): + l2 = [] + for i in l: + data = bb.data.getVar(i, d, 1) + if data is None: + raise KeyError(f) + if i == 'DPKG_ARCH' and bb.data.getVar('PACKAGE_ARCH', d, 1) == 'all': + data = 'all' + l2.append(data) + return l2 + + ctrlfile.write("Package: %s\n" % pkgname) + # check for required fields + try: + for (c, fs) in fields: + ctrlfile.write(unicode(c % tuple(pullData(fs, localdata)))) + except KeyError: + import sys + (type, value, traceback) = sys.exc_info() + bb.utils.unlockfile(lf) + ctrlfile.close() + raise bb.build.FuncFailed("Missing field for deb generation: %s" % value) + # more fields + + bb.build.exec_func("mapping_rename_hook", localdata) + + rdepends = explode_deps(unicode(bb.data.getVar("RDEPENDS", localdata, 1) or "")) + rdepends = [dep for dep in rdepends if not '*' in dep] + rrecommends = explode_deps(unicode(bb.data.getVar("RRECOMMENDS", localdata, 1) or "")) + rrecommends = [rec for rec in rrecommends if not '*' in rec] + rsuggests = (unicode(bb.data.getVar("RSUGGESTS", localdata, 1) or "")).split() + rprovides = (unicode(bb.data.getVar("RPROVIDES", localdata, 1) or "")).split() + rreplaces = (unicode(bb.data.getVar("RREPLACES", localdata, 1) or "")).split() + rconflicts = (unicode(bb.data.getVar("RCONFLICTS", localdata, 1) or "")).split() + if rdepends: + ctrlfile.write(u"Depends: %s\n" % ", ".join(rdepends)) + if rsuggests: + ctrlfile.write(u"Suggests: %s\n" % ", ".join(rsuggests)) + if rrecommends: + ctrlfile.write(u"Recommends: %s\n" % ", ".join(rrecommends)) + if rprovides: + ctrlfile.write(u"Provides: %s\n" % ", ".join(rprovides)) + if rreplaces: + ctrlfile.write(u"Replaces: %s\n" % ", ".join(rreplaces)) + if rconflicts: + ctrlfile.write(u"Conflicts: %s\n" % ", ".join(rconflicts)) + ctrlfile.close() + + for script in ["preinst", "postinst", "prerm", "postrm"]: + scriptvar = bb.data.getVar('pkg_%s' % script, localdata, 1) + if not scriptvar: + continue + try: + scriptfile = file(os.path.join(controldir, script), 'w') + except OSError: + bb.utils.unlockfile(lf) + raise bb.build.FuncFailed("unable to open %s script file for writing." % script) + scriptfile.write("#!/bin/sh\n") + scriptfile.write(scriptvar) + scriptfile.close() + os.chmod(os.path.join(controldir, script), 0755) + + conffiles_str = bb.data.getVar("CONFFILES", localdata, 1) + if conffiles_str: + try: + conffiles = file(os.path.join(controldir, 'conffiles'), 'w') + except OSError: + bb.utils.unlockfile(lf) + raise bb.build.FuncFailed("unable to open conffiles for writing.") + for f in conffiles_str.split(): + conffiles.write('%s\n' % f) + conffiles.close() + + try: + write_package_md5sums(root, os.path.join(controldir, 'md5sums'), + ['DEBIAN']) + except: + bb.utils.unlockfile(lf) + raise + + os.chdir(basedir) + ret = os.system("PATH=\"%s\" fakeroot dpkg-deb -b %s %s" % (bb.data.getVar("PATH", localdata, 1), root, pkgoutdir)) + if ret != 0: + bb.utils.unlockfile(lf) + raise bb.build.FuncFailed("dpkg-deb execution failed") + + bb.utils.prunedir(controldir) + bb.utils.unlockfile(lf) +} + +python () { + if bb.data.getVar('PACKAGES', d, True) != '': + deps = (bb.data.getVarFlag('do_package_write_deb', 'depends', d) or "").split() + deps.append('dpkg-native:do_populate_staging') + deps.append('fakeroot-native:do_populate_staging') + bb.data.setVarFlag('do_package_write_deb', 'depends', " ".join(deps), d) +} + +python do_package_write_deb () { + bb.build.exec_func("read_subpackage_metadata", d) + bb.build.exec_func("do_package_deb", d) +} +do_package_write_deb[dirs] = "${D}" +addtask package_write_deb before do_package_write after do_package + diff --git a/classes/package_ipk.bbclass b/classes/package_ipk.bbclass index 0cb5128e17..420c892f10 100644 --- a/classes/package_ipk.bbclass +++ b/classes/package_ipk.bbclass @@ -1,15 +1,22 @@ inherit package -DEPENDS_prepend="${@["ipkg-utils-native ", ""][(bb.data.getVar('PACKAGES', d, 1) == '')]}" -BOOTSTRAP_EXTRA_RDEPENDS += "ipkg-collateral ipkg ipkg-link" -PACKAGEFUNCS += "do_package_ipk" + +BOOTSTRAP_EXTRA_RDEPENDS += "opkg-collateral opkg" +IMAGE_PKGTYPE ?= "ipk" + +IPKGCONF_TARGET = "${STAGING_ETCDIR_NATIVE}/opkg.conf" +IPKGCONF_SDK = "${STAGING_ETCDIR_NATIVE}/opkg-sdk.conf" +IPKGCONF_CANSDK = "${STAGING_ETCDIR_NATIVE}/opkg-canadian-sdk.conf" python package_ipk_fn () { from bb import data bb.data.setVar('PKGFN', bb.data.getVar('PKG',d), d) } -python package_ipk_install () { - import os, sys +python package_ipk_install () { + # + # Warning - this function is not multimachine safe (see stagingdir reference)! + # + pkg = bb.data.getVar('PKG', d, 1) pkgfn = bb.data.getVar('PKGFN', d, 1) rootfs = bb.data.getVar('IMAGE_ROOTFS', d, 1) @@ -23,16 +30,17 @@ python package_ipk_install () { bb.mkdirhier(rootfs) os.chdir(rootfs) except OSError: + import sys (type, value, traceback) = sys.exc_info() print value raise bb.build.FuncFailed # Generate ipk.conf if it or the stamp doesnt exist - conffile = os.path.join(stagingdir,"ipkg.conf") - if not os.access(conffile, os.R_OK): - ipkg_archs = bb.data.getVar('IPKG_ARCHS',d) + conffile = os.path.join(stagingdir,"opkg.conf") + if not os.access(conffile, os.R_OK): + ipkg_archs = bb.data.getVar('PACKAGE_ARCHS',d) if ipkg_archs is None: - bb.error("IPKG_ARCHS missing") + bb.error("PACKAGE_ARCHS missing") raise FuncFailed ipkg_archs = ipkg_archs.split() arch_priority = 1 @@ -46,35 +54,99 @@ python package_ipk_install () { if (not os.access(os.path.join(ipkdir,"Packages"), os.R_OK) or - not os.access(os.path.join(os.path.join(tmpdir, "stamps"),"do_packages"),os.R_OK)): + not os.access(os.path.join(tmpdir, "stamps", "IPK_PACKAGE_INDEX_CLEAN"),os.R_OK): ret = os.system('ipkg-make-index -p %s %s ' % (os.path.join(ipkdir, "Packages"), ipkdir)) if (ret != 0 ): raise bb.build.FuncFailed - f=open(os.path.join(os.path.join(tmpdir, "stamps"),"do_packages"),"w") + f = open(os.path.join(tmpdir, "stamps", "IPK_PACKAGE_INDEX_CLEAN"),"w") f.close() - ret = os.system('ipkg-cl -o %s -f %s update' % (rootfs, conffile)) - ret = os.system('ipkg-cl -o %s -f %s install %s' % (rootfs, conffile, pkgfn)) + ret = os.system('opkg-cl -o %s -f %s update' % (rootfs, conffile)) + ret = os.system('opkg-cl -o %s -f %s install %s' % (rootfs, conffile, pkgfn)) if (ret != 0 ): raise bb.build.FuncFailed } +do_package_update_index_ipk[lockfiles] = "${DEPLOY_DIR_IPK}.lock" +do_package_update_index_ipk[nostamp] = "1" +do_package_update_index_ipk[recrdeptask] += "do_package_write_ipk" +do_package_update_index_ipk[recrdeptask] += "do_package_write_ipk" +do_package_update_index_ipk[depends] += "ipkg-utils-native:do_populate_staging" + +# +# Update the Packages index files in ${DEPLOY_DIR_IPK} +# +do_package_update_index_ipk () { + set -x + + ipkgarchs="${PACKAGE_ARCHS}" + + if [ ! -z "${DEPLOY_KEEP_PACKAGES}" ]; then + return + fi + + mkdir -p ${DEPLOY_DIR_IPK} + touch ${DEPLOY_DIR_IPK}/Packages + ipkg-make-index -r ${DEPLOY_DIR_IPK}/Packages -p ${DEPLOY_DIR_IPK}/Packages -l ${DEPLOY_DIR_IPK}/Packages.filelist -m ${DEPLOY_DIR_IPK} + + for arch in $ipkgarchs; do + if [ -e ${DEPLOY_DIR_IPK}/$arch/ ] ; then + touch ${DEPLOY_DIR_IPK}/$arch/Packages + ipkg-make-index -r ${DEPLOY_DIR_IPK}/$arch/Packages -p ${DEPLOY_DIR_IPK}/$arch/Packages -l ${DEPLOY_DIR_IPK}/$arch/Packages.filelist -m ${DEPLOY_DIR_IPK}/$arch/ + fi + if [ -e ${DEPLOY_DIR_IPK}/${BUILD_ARCH}-$arch-sdk/ ] ; then + touch ${DEPLOY_DIR_IPK}/${BUILD_ARCH}-$arch-sdk/Packages + ipkg-make-index -r ${DEPLOY_DIR_IPK}/${BUILD_ARCH}-$arch-sdk/Packages -p ${DEPLOY_DIR_IPK}/${BUILD_ARCH}-$arch-sdk/Packages -l ${DEPLOY_DIR_IPK}/${BUILD_ARCH}-$arch-sdk/Packages.filelist -m ${DEPLOY_DIR_IPK}/${BUILD_ARCH}-$arch-sdk/ + fi + if [ -e ${DEPLOY_DIR_IPK}/${SDK_SYS}-sdk-$arch/ ] ; then + touch ${DEPLOY_DIR_IPK}/${SDK_SYS}-sdk-$arch/Packages + ipkg-make-index -r ${DEPLOY_DIR_IPK}/${SDK_SYS}-sdk-$arch/Packages -p ${DEPLOY_DIR_IPK}/${SDK_SYS}-sdk-$arch/Packages -l ${DEPLOY_DIR_IPK}/${SDK_SYS}-sdk-$arch/Packages.filelist -m ${DEPLOY_DIR_IPK}/${SDK_SYS}-sdk-$arch/ + fi + done +} + +# +# Generate an ipkg conf file ${IPKGCONF_TARGET} suitable for use against +# the target system and an ipkg conf file ${IPKGCONF_SDK} suitable for +# use against the host system in sdk builds +# +package_generate_ipkg_conf () { + mkdir -p ${STAGING_ETCDIR_NATIVE}/ + echo "src oe file:${DEPLOY_DIR_IPK}" > ${IPKGCONF_TARGET} + echo "src oe file:${DEPLOY_DIR_IPK}" > ${IPKGCONF_SDK} + echo "src oe file:${DEPLOY_DIR_IPK}" > ${IPKGCONF_CANSDK} + ipkgarchs="${PACKAGE_ARCHS}" + priority=1 + for arch in $ipkgarchs; do + echo "arch $arch $priority" >> ${IPKGCONF_TARGET} + echo "arch ${BUILD_ARCH}-$arch-sdk $priority" >> ${IPKGCONF_SDK} + echo "arch ${SDK_SYS}-sdk-$arch $priority" >> ${IPKGCONF_CANSDK} + priority=$(expr $priority + 5) + if [ -e ${DEPLOY_DIR_IPK}/$arch/Packages ] ; then + echo "src oe-$arch file:${DEPLOY_DIR_IPK}/$arch" >> ${IPKGCONF_TARGET} + fi + if [ -e ${DEPLOY_DIR_IPK}/${BUILD_ARCH}-$arch-sdk/Packages ] ; then + echo "src oe-${BUILD_ARCH}-$arch-sdk file:${DEPLOY_DIR_IPK}/${BUILD_ARCH}-$arch-sdk" >> ${IPKGCONF_SDK} + fi + if [ -e ${DEPLOY_DIR_IPK}/${SDK_SYS}-sdk-$arch/Packages ] ; then + echo "src oe-${SDK_SYS}-sdk-$arch file:${DEPLOY_DIR_IPK}/${SDK_SYS}-sdk-$arch" >> ${IPKGCONF_CANSDK} + fi + done +} + python do_package_ipk () { - import copy # to back up env data - import sys - import re + import re, copy workdir = bb.data.getVar('WORKDIR', d, 1) if not workdir: bb.error("WORKDIR not defined, unable to package") return - import os # path manipulations + outdir = bb.data.getVar('DEPLOY_DIR_IPK', d, 1) if not outdir: bb.error("DEPLOY_DIR_IPK not defined, unable to package") return - bb.mkdirhier(outdir) dvar = bb.data.getVar('D', d, 1) if not dvar: @@ -82,23 +154,18 @@ python do_package_ipk () { return bb.mkdirhier(dvar) - packages = bb.data.getVar('PACKAGES', d, 1) - if not packages: - bb.debug(1, "PACKAGES not defined, nothing to package") - return - tmpdir = bb.data.getVar('TMPDIR', d, 1) - # Invalidate the packages file - if os.access(os.path.join(os.path.join(tmpdir, "stamps"),"do_packages"),os.R_OK): - os.unlink(os.path.join(os.path.join(tmpdir, "stamps"),"do_packages")) - if packages == []: - bb.debug(1, "No packages; nothing to do") - return + if os.access(os.path.join(tmpdir, "stamps", "IPK_PACKAGE_INDEX_CLEAN"), os.R_OK): + os.unlink(os.path.join(tmpdir, "stamps", "IPK_PACKAGE_INDEX_CLEAN")) + packages = bb.data.getVar('PACKAGES', d, True) for pkg in packages.split(): localdata = bb.data.createCopy(d) - root = "%s/install/%s" % (workdir, pkg) + pkgdest = bb.data.getVar('PKGDEST', d, 1) + root = "%s/%s" % (pkgdest, pkg) + + lf = bb.utils.lockfile(root + ".lock") bb.data.setVar('ROOT', '', localdata) bb.data.setVar('ROOT_%s' % pkg, root, localdata) @@ -107,27 +174,27 @@ python do_package_ipk () { pkgname = pkg bb.data.setVar('PKG', pkgname, localdata) - overrides = bb.data.getVar('OVERRIDES', localdata) + overrides = bb.data.getVar('OVERRIDES', localdata, True) if not overrides: raise bb.build.FuncFailed('OVERRIDES not defined') - overrides = bb.data.expand(overrides, localdata) bb.data.setVar('OVERRIDES', overrides + ':' + pkg, localdata) bb.data.update_data(localdata) basedir = os.path.join(os.path.dirname(root)) - pkgoutdir = outdir + arch = bb.data.getVar('PACKAGE_ARCH', localdata, 1) + pkgoutdir = "%s/%s" % (outdir, arch) bb.mkdirhier(pkgoutdir) os.chdir(root) from glob import glob - g = glob('*') + g = glob('*') + glob('.[!.]*') try: del g[g.index('CONTROL')] del g[g.index('./CONTROL')] except ValueError: pass - if not g and not bb.data.getVar('ALLOW_EMPTY', localdata): - from bb import note - note("Not creating empty archive for %s-%s-%s" % (pkg, bb.data.getVar('PV', localdata, 1), bb.data.getVar('PR', localdata, 1))) + if not g and bb.data.getVar('ALLOW_EMPTY', localdata) != "1": + bb.note("Not creating empty archive for %s-%s" % (pkg, bb.data.expand('${PV}-${PR}${DISTRO_PR}', localdata, True))) + bb.utils.unlockfile(lf) continue controldir = os.path.join(root, 'CONTROL') @@ -135,16 +202,22 @@ python do_package_ipk () { try: ctrlfile = file(os.path.join(controldir, 'control'), 'w') except OSError: + bb.utils.unlockfile(lf) raise bb.build.FuncFailed("unable to open control file for writing.") fields = [] - fields.append(["Version: %s-%s\n", ['PV', 'PR']]) + pe = bb.data.getVar('PE', d, 1) + if pe and int(pe) > 0: + fields.append(["Version: %s:%s-%s\n", ['PE', 'PKGV', 'PKGR']]) + else: + fields.append(["Version: %s-%s\n", ['PKGV', 'PKGR']]) fields.append(["Description: %s\n", ['DESCRIPTION']]) fields.append(["Section: %s\n", ['SECTION']]) fields.append(["Priority: %s\n", ['PRIORITY']]) fields.append(["Maintainer: %s\n", ['MAINTAINER']]) + fields.append(["License: %s\n", ['LICENSE']]) fields.append(["Architecture: %s\n", ['PACKAGE_ARCH']]) - fields.append(["OE: %s\n", ['P']]) + fields.append(["OE: %s\n", ['PN']]) fields.append(["Homepage: %s\n", ['HOMEPAGE']]) def pullData(l, d): @@ -162,8 +235,10 @@ python do_package_ipk () { raise KeyError(f) ctrlfile.write(c % tuple(pullData(fs, localdata))) except KeyError: + import sys (type, value, traceback) = sys.exc_info() ctrlfile.close() + bb.utils.unlockfile(lf) raise bb.build.FuncFailed("Missing field for ipk generation: %s" % value) # more fields @@ -175,6 +250,10 @@ python do_package_ipk () { rprovides = (bb.data.getVar("RPROVIDES", localdata, 1) or "").split() rreplaces = (bb.data.getVar("RREPLACES", localdata, 1) or "").split() rconflicts = (bb.data.getVar("RCONFLICTS", localdata, 1) or "").split() + + if not '-locale-' and not '-dbg' and not '-dev' in pkgname: + rdepends.append('%s-locale*' % pkgname) + if rdepends: ctrlfile.write("Depends: %s\n" % ", ".join(rdepends)) if rsuggests: @@ -187,10 +266,9 @@ python do_package_ipk () { ctrlfile.write("Replaces: %s\n" % ", ".join(rreplaces)) if rconflicts: ctrlfile.write("Conflicts: %s\n" % ", ".join(rconflicts)) - src_uri = bb.data.getVar("SRC_URI", localdata, 1) - if src_uri: - src_uri = re.sub("\s+", " ", src_uri) - ctrlfile.write("Source: %s\n" % " ".join(src_uri.split())) + src_uri = bb.data.getVar("SRC_URI", localdata, 1) or d.getVar("FILE", True) + src_uri = re.sub("\s+", " ", src_uri) + ctrlfile.write("Source: %s\n" % " ".join(src_uri.split())) ctrlfile.close() for script in ["preinst", "postinst", "prerm", "postrm"]: @@ -200,6 +278,7 @@ python do_package_ipk () { try: scriptfile = file(os.path.join(controldir, script), 'w') except OSError: + bb.utils.unlockfile(lf) raise bb.build.FuncFailed("unable to open %s script file for writing." % script) scriptfile.write(scriptvar) scriptfile.close() @@ -210,6 +289,7 @@ python do_package_ipk () { try: conffiles = file(os.path.join(controldir, 'conffiles'), 'w') except OSError: + bb.utils.unlockfile(lf) raise bb.build.FuncFailed("unable to open conffiles for writing.") for f in conffiles_str.split(): conffiles.write('%s\n' % f) @@ -219,19 +299,30 @@ python do_package_ipk () { ret = os.system("PATH=\"%s\" %s %s %s" % (bb.data.getVar("PATH", localdata, 1), bb.data.getVar("IPKGBUILDCMD",d,1), pkg, pkgoutdir)) if ret != 0: + bb.utils.unlockfile(lf) raise bb.build.FuncFailed("ipkg-build execution failed") - file(bb.data.expand('${STAGING_DIR}/pkgdata/runtime/%s.packaged' % pkg, d), 'w').close() + bb.utils.prunedir(controldir) + bb.utils.unlockfile(lf) +} - for script in ["preinst", "postinst", "prerm", "postrm", "control" ]: - scriptfile = os.path.join(controldir, script) - try: - os.remove(scriptfile) - except OSError: - pass - try: - os.rmdir(controldir) - except OSError: - pass - del localdata +python () { + if bb.data.getVar('PACKAGES', d, True) != '': + deps = (bb.data.getVarFlag('do_package_write_ipk', 'depends', d) or "").split() + deps.append('ipkg-utils-native:do_populate_staging') + deps.append('fakeroot-native:do_populate_staging') + bb.data.setVarFlag('do_package_write_ipk', 'depends', " ".join(deps), d) +} + +python do_package_write_ipk () { + packages = bb.data.getVar('PACKAGES', d, True) + if not packages: + bb.debug(1, "No PACKAGES defined, nothing to package") + return + + bb.build.exec_func("read_subpackage_metadata", d) + bb.build.exec_func("do_package_ipk", d) } +do_package_write_ipk[dirs] = "${D}" +addtask package_write_ipk before do_package_write after do_package +addtask package_update_index_ipk before do_rootfs diff --git a/classes/package_rpm.bbclass b/classes/package_rpm.bbclass index c29ab5f423..ab09bb24d3 100644 --- a/classes/package_rpm.bbclass +++ b/classes/package_rpm.bbclass @@ -1,20 +1,28 @@ inherit package -inherit rpm_core RPMBUILD="rpmbuild --short-circuit ${RPMOPTS}" -PACKAGEFUNCS += "do_package_rpm" +IMAGE_PKGTYPE ?= "rpm" + +RPMBUILDPATH="${WORKDIR}/rpm" + +RPMOPTS="--rcfile=${WORKDIR}/rpmrc" +RPMOPTS="--rcfile=${WORKDIR}/rpmrc --target ${TARGET_SYS}" +RPM="rpm ${RPMOPTS}" python write_specfile() { - from bb import data, build - import sys + version = bb.data.getVar('PV', d, 1) + version = version.replace('-', '+') + bb.data.setVar('RPMPV', version, d) + out_vartranslate = { "PKG": "Name", - "PV": "Version", - "PR": "Release", + "RPMPV": "Version", "DESCRIPTION": "%description", "ROOT": "BuildRoot", "LICENSE": "License", "SECTION": "Group", + "pkg_postinst": "%post", + "pkg_preinst": "%pre", } root = bb.data.getVar('ROOT', d) @@ -39,9 +47,9 @@ python write_specfile() { del files[files.index(r)] except ValueError: pass - if not files: - from bb import note - note("Not creating empty archive for %s-%s-%s" % (bb.data.getVar('PKG',d, 1), bb.data.getVar('PV', d, 1), bb.data.getVar('PR', d, 1))) + + if not files and bb.data.getVar('ALLOW_EMPTY', d) != "1": + bb.note("Not creating empty archive for %s" % (bb.data.expand('${PKG}-${PV}-${PR}${DISTRO_PR}', d, True))) return # output .spec using this metadata store @@ -53,22 +61,65 @@ python write_specfile() { except OSError: raise bb.build.FuncFailed("unable to open spec file for writing.") -# fd = sys.__stdout__ fd = specfile for var in out_vartranslate.keys(): if out_vartranslate[var][0] == "%": continue - fd.write("%s\t: %s\n" % (out_vartranslate[var], bb.data.getVar(var, d))) + val = bb.data.getVar(var, d, 1) + if val: + fd.write("%s\t: %s\n" % (out_vartranslate[var], val)) + + fd.write("AutoReqProv: no\n") + + def fix_dep_versions(varname): + depends = bb.utils.explode_dep_versions(bb.data.getVar(varname, d, True) or "") + newdeps = [] + for dep in depends: + ver = depends[dep] + if dep and ver: + if '-' in ver: + subd = read_subpkgdata_dict(dep, d) + pv = subd['PV'] + reppv = pv.replace('-', '+') + ver = ver.replace(pv, reppv) + newdeps.append("%s (%s)" % (dep, ver)) + elif dep: + newdeps.append(dep) + bb.data.setVar(varname, " ".join(newdeps), d) + + fix_dep_versions('RDEPENDS') + fix_dep_versions('RRECOMMENDS') + + bb.build.exec_func("mapping_rename_hook", d) + + def write_dep_field(varname, outstring): + depends = bb.utils.explode_dep_versions(bb.data.getVar(varname, d, True) or "") + for dep in depends: + ver = depends[dep] + if dep and ver: + fd.write("%s: %s %s\n" % (outstring, dep, ver)) + elif dep: + fd.write("%s: %s\n" % (outstring, dep)) + + write_dep_field('RDEPENDS', 'Requires') + write_dep_field('RRECOMMENDS', 'Recommends') + write_dep_field('RPROVIDES', 'Provides') + + fd.write("Release\t: %s\n" % bb.data.expand('${PR}${DISTRO_PR}', d, True)) fd.write("Summary\t: .\n") for var in out_vartranslate.keys(): if out_vartranslate[var][0] != "%": continue - fd.write(out_vartranslate[var] + "\n") - fd.write(bb.data.getVar(var, d) + "\n\n") + val = bb.data.getVar(var, d) + if val: + fd.write(out_vartranslate[var] + "\n") + fd.write(val + "\n\n") fd.write("%files\n") for file in files: + if file[0] != '/': + fd.write('/') fd.write("%s\n" % file) fd.close() @@ -80,54 +131,96 @@ python write_specfile() { bb.build.exec_func('BUILDSPEC', d) # move the rpm into the pkgoutdir - rpm = bb.data.expand('${RPMBUILDPATH}/RPMS/${TARGET_ARCH}/${PKG}-${PV}-${PR}.${TARGET_ARCH}.rpm', d) - outrpm = bb.data.expand('${DEPLOY_DIR_RPM}/${PKG}-${PV}-${PR}.${TARGET_ARCH}.rpm', d) + rpm = bb.data.expand('${RPMBUILDPATH}/RPMS/${TARGET_ARCH}/${PKG}-${RPMPV}-${PR}${DISTRO_PR}.${TARGET_ARCH}.rpm', d) + outrpm = bb.data.expand('${DEPLOY_DIR_RPM}/${PACKAGE_ARCH}/${PKG}-${RPMPV}-${PR}.${TARGET_ARCH}.rpm', d) bb.movefile(rpm, outrpm) } +rpm_prep() { + if [ ! -e ${WORKDIR}/rpmrc ]; then + mkdir -p ${RPMBUILDPATH}/{SPECS,RPMS/{i386,i586,i686,noarch,ppc,mips,mipsel,arm},SRPMS,SOURCES,BUILD} + echo 'macrofiles:${STAGING_DIR_NATIVE}/usr/lib/rpm/macros:${WORKDIR}/macros' > ${WORKDIR}/rpmrc + echo '%_topdir ${RPMBUILDPATH}' > ${WORKDIR}/macros + echo '%_repackage_dir ${WORKDIR}' >> ${WORKDIR}/macros + fi +} + python do_package_rpm () { - workdir = bb.data.getVar('WORKDIR', d) + workdir = bb.data.getVar('WORKDIR', d, 1) if not workdir: - raise bb.build.FuncFailed("WORKDIR not defined") - workdir = bb.data.expand(workdir, d) + bb.error("WORKDIR not defined, unable to package") + return - import os # path manipulations - outdir = bb.data.getVar('DEPLOY_DIR_RPM', d) + outdir = bb.data.getVar('DEPLOY_DIR_RPM', d, 1) if not outdir: - raise bb.build.FuncFailed("DEPLOY_DIR_RPM not defined") - outdir = bb.data.expand(outdir, d) + bb.error("DEPLOY_DIR_RPM not defined, unable to package") + return bb.mkdirhier(outdir) - packages = bb.data.getVar('PACKAGES', d) + packages = bb.data.getVar('PACKAGES', d, 1) if not packages: - packages = "${PN}" - bb.data.setVar('FILES', '', d) - ddir = bb.data.expand(bb.data.getVar('D', d), d) - bb.mkdirhier(ddir) - bb.data.setVar(bb.data.expand('FILES_${PN}', d), ''.join([ "./%s" % x for x in os.listdir(ddir)]), d) - packages = bb.data.expand(packages, d) + bb.debug(1, "PACKAGES not defined, nothing to package") + return + + if packages == []: + bb.debug(1, "No packages; nothing to do") + return + + # If "rpm" comes into overrides the presence of this function causes problems. + # Since we don't need it, remove it for now - hacky. + bb.data.delVar("do_package_write_rpm", d) for pkg in packages.split(): localdata = bb.data.createCopy(d) - root = "%s/install/%s" % (workdir, pkg) + pkgdest = bb.data.getVar('PKGDEST', d, 1) + root = "%s/%s" % (pkgdest, pkg) + + lf = bb.utils.lockfile(root + ".lock") bb.data.setVar('ROOT', '', localdata) bb.data.setVar('ROOT_%s' % pkg, root, localdata) - bb.data.setVar('PKG', pkg, localdata) + pkgname = bb.data.getVar('PKG_%s' % pkg, localdata, 1) + if not pkgname: + pkgname = pkg + bb.data.setVar('PKG', pkgname, localdata) overrides = bb.data.getVar('OVERRIDES', localdata) if not overrides: raise bb.build.FuncFailed('OVERRIDES not defined') overrides = bb.data.expand(overrides, localdata) - bb.data.setVar('OVERRIDES', '%s:%s' % (overrides, pkg), localdata) + bb.data.setVar('OVERRIDES', overrides + ':' + pkg, localdata) bb.data.update_data(localdata) -# stuff - root = bb.data.getVar('ROOT', localdata) - basedir = os.path.dirname(root) - pkgoutdir = outdir + + basedir = os.path.join(os.path.dirname(root)) + pkgoutdir = os.path.join(outdir, bb.data.getVar('PACKAGE_ARCH', localdata, 1)) bb.mkdirhier(pkgoutdir) bb.data.setVar('OUTSPECFILE', os.path.join(workdir, "%s.spec" % pkg), localdata) + # Save the value of RPMBUILD expanded into the new dictonary so any + # changes in the compoents that make up workdir don't break packaging + bb.data.setVar('RPMBUILD', bb.data.getVar("RPMBUILD", d, True), localdata) + bb.data.setVar('RPMBUILDPATH', bb.data.getVar("RPMBUILDPATH", d, True), localdata) bb.build.exec_func('write_specfile', localdata) - del localdata + bb.utils.unlockfile(lf) +} + +python () { + if bb.data.getVar('PACKAGES', d, True) != '' and \ + not bb.data.inherits_class('native', d) and \ + not bb.data.inherits_class('cross', d): + deps = (bb.data.getVarFlag('do_package_write_rpm', 'depends', d) or "").split() + deps.append('rpm-native:do_populate_staging') + deps.append('fakeroot-native:do_populate_staging') + bb.data.setVarFlag('do_package_write_rpm', 'depends', " ".join(deps), d) } + + +python do_package_write_rpm () { + bb.build.exec_func("read_subpackage_metadata", d) + bb.build.exec_func("rpm_prep", d) + bb.build.exec_func("do_package_rpm", d) +} + +do_package_write_rpm[dirs] = "${D}" +addtask package_write_rpm before do_package_write after do_package + diff --git a/classes/package_tar.bbclass b/classes/package_tar.bbclass index 63e82f7f39..b905e170f4 100644 --- a/classes/package_tar.bbclass +++ b/classes/package_tar.bbclass @@ -1,17 +1,11 @@ inherit package -PACKAGEFUNCS += "do_package_tar" - python package_tar_fn () { - import os - from bb import data - fn = os.path.join(bb.data.getVar('DEPLOY_DIR_TAR', d), "%s-%s-%s.tar.gz" % (bb.data.getVar('PKG', d), bb.data.getVar('PV', d), bb.data.getVar('PR', d))) - fn = bb.data.expand(fn, d) + fn = os.path.join(bb.data.getVar('DEPLOY_DIR_TAR', d, True), bb.data.expand('${PKG}-${PV}-${PR}${DISTRO_PR}.tar.gz', d, True)) bb.data.setVar('PKGFN', fn, d) } python package_tar_install () { - import os, sys pkg = bb.data.getVar('PKG', d, 1) pkgfn = bb.data.getVar('PKGFN', d, 1) rootfs = bb.data.getVar('IMAGE_ROOTFS', d, 1) @@ -23,6 +17,7 @@ python package_tar_install () { bb.mkdirhier(rootfs) os.chdir(rootfs) except OSError: + import sys (type, value, traceback) = sys.exc_info() print value raise bb.build.FuncFailed @@ -42,7 +37,6 @@ python do_package_tar () { bb.error("WORKDIR not defined, unable to package") return - import os # path manipulations outdir = bb.data.getVar('DEPLOY_DIR_TAR', d, 1) if not outdir: bb.error("DEPLOY_DIR_TAR not defined, unable to package") @@ -62,7 +56,8 @@ python do_package_tar () { for pkg in packages.split(): localdata = bb.data.createCopy(d) - root = "%s/install/%s" % (workdir, pkg) + pkgdest = bb.data.getVar('PKGDEST', d, 1) + root = "%s/%s" % (pkgdest, pkg) bb.data.setVar('ROOT', '', localdata) bb.data.setVar('ROOT_%s' % pkg, root, localdata) @@ -75,7 +70,7 @@ python do_package_tar () { bb.data.setVar('OVERRIDES', '%s:%s' % (overrides, pkg), localdata) bb.data.update_data(localdata) -# stuff + root = bb.data.getVar('ROOT', localdata) bb.mkdirhier(root) basedir = os.path.dirname(root) @@ -83,20 +78,28 @@ python do_package_tar () { bb.mkdirhier(pkgoutdir) bb.build.exec_func('package_tar_fn', localdata) tarfn = bb.data.getVar('PKGFN', localdata, 1) -# if os.path.exists(tarfn): -# del localdata -# continue os.chdir(root) from glob import glob - if not glob('*'): - bb.note("Not creating empty archive for %s-%s-%s" % (pkg, bb.data.getVar('PV', localdata, 1), bb.data.getVar('PR', localdata, 1))) + if not glob('*') + glob('.[!.]*'): + bb.note("Not creating empty archive for %s-%s" % (pkg, bb.data.expand('${PV}-${PR}${DISTRO_PR}', d, True))) continue - ret = os.system("tar -czvf %s %s" % (tarfn, '.')) + ret = os.system("tar -czf %s %s" % (tarfn, '.')) if ret != 0: bb.error("Creation of tar %s failed." % tarfn) +} + +python () { + if bb.data.getVar('PACKAGES', d, True) != '': + deps = (bb.data.getVarFlag('do_package_write_tar', 'depends', d) or "").split() + deps.append('tar-native:do_populate_staging') + deps.append('fakeroot-native:do_populate_staging') + bb.data.setVarFlag('do_package_write_tar', 'depends', " ".join(deps), d) +} - file(bb.data.expand('${STAGING_DIR}/pkgdata/runtime/%s.packaged' % pkg, d), 'w').close() -# end stuff - del localdata +python do_package_write_tar () { + bb.build.exec_func("read_subpackage_metadata", d) + bb.build.exec_func("do_package_tar", d) } +do_package_write_tar[dirs] = "${D}" +addtask package_write_tar before do_build after do_package diff --git a/classes/packaged-staging.bbclass b/classes/packaged-staging.bbclass index 8a2a03ca17..1c5c4cd531 100644 --- a/classes/packaged-staging.bbclass +++ b/classes/packaged-staging.bbclass @@ -1,226 +1,437 @@ # -# Populated ${STAGING} using packages +# Populate builds using prebuilt packages where possible to speed up builds +# and allow staging to be reconstructed. # # To use it add that line to conf/local.conf: # # INHERIT += "packaged-staging" # -# You also need ipkg-cl and ipkg-make-index installed on your host -# put stage-manager and ipkg-build from org.openembedded.packaged-staging/contrib/ in your $PATH - -# BUGS: -# * does not distinguish between -native, -cross and other packages - -# TODO: -# * also build a feed for native and cross packages -# * make package detection a bit smarter (search for compatible archs) -# * make do_clean clean staging as well - -# Summary: -# This class will have two modes of operation: -# PSTAGE_MODE = 'repopulate': repopulated staging from scratch for each packages -# PSTAGE_MODE = 'append': append each package to staging (current behaviour) - -inherit package - -DEPLOY_DIR_PSTAGE = "${DEPLOY_DIR}/pstage" - -PSTAGE_BUILD_CMD = "${IPKGBUILDCMD}" -PSTAGE_INSTALL_CMD = "ipkg-cl install -force-depends -f ${DEPLOY_DIR_PSTAGE}/ipkg.conf -o " -PSTAGE_UPDATE_CMD = "ipkg-cl update -f ${DEPLOY_DIR_PSTAGE}/ipkg.conf -o " -PSTAGE_LIST_CMD = "ipkg-cl list_installed -f ${DEPLOY_DIR_PSTAGE}/ipkg.conf -o " -PSTAGE_PKGNAME = "staging-${PN}_${PV}-${PR}_${PACKAGE_ARCH}.ipk" -PCROSS_PKGNAME = "cross-${PN}_${PV}-${PR}_${BUILD_ARCH}.ipk" - -SPAWNFILE = "${STAGING_DIR}/pkgmaps/${P}-${PR}.spawn" -SPAWNIPK = ${spawn} - -PSTAGE_TMPDIR_STAGE = ${TMPDIR}/tmp-staging -PSTAGE_TMPDIR_CROSS = ${TMPDIR}/tmp-cross - -STAGING_BASEDIR = "${STAGING_LIBDIR}/.." - -PACKAGEFUNCS += "do_write_ipk_list" - -python do_write_ipk_list () { - import os, sys - ipkdir = bb.data.getVar('DEPLOY_DIR_IPK', d, 1) - stagingdir = bb.data.getVar('STAGING_DIR', d, 1) - tmpdir = bb.data.getVar('TMPDIR', d, 1) - p = bb.data.getVar('P', d, 1) - pr = bb.data.getVar('PR', d, 1) - - packages = bb.data.getVar('PACKAGES', d, 1) - if not packages: - bb.debug(1, "PACKAGES not defined, nothing to package") - return - - if packages == []: - bb.debug(1, "No packages; nothing to do") - return - - # Generate ipk.conf if it or the stamp doesnt exist - listfile = os.path.join(stagingdir,"pkgmaps","%s-%s.spawn" % ( p , pr )) - os.system('mkdir -p ' + stagingdir + '/pkgmaps') - if not os.access(listfile, os.R_OK): - os.system('rm -f ' + listfile) - f = open(listfile,"w") - for spawn in packages.split(): - #check if the packagename has changed due to debian shlib renaming - localdata = bb.data.createCopy(d) - pkgname = bb.data.getVar('PKG_%s' % spawn, localdata, 1) - if not pkgname: - pkgname = spawn - f.write("%s\n" % pkgname) - f.close() -} -do_clean_append() { - """clear the build and temp directories""" - stagepkg = bb.data.expand("${DEPLOY_DIR_PSTAGE}/${PSTAGE_PKGNAME}", d) - if stagepkg == '//': raise bb.build.FuncFailed("wrong DATADIR") - bb.note("removing " + stagepkg) - os.system('rm -rf ' + stagepkg) +# +# bitbake.conf set PSTAGING_ACTIVE = "0", this class sets to "1" if we're active +# +PSTAGE_PKGVERSION = "${PV}-${PR}" +PSTAGE_PKGARCH = "${BUILD_SYS}" +PSTAGE_EXTRAPATH ?= "/${OELAYOUT_ABI}/${DISTRO_PR}/" +PSTAGE_PKGPATH = "${DISTRO}${PSTAGE_EXTRAPATH}" +PSTAGE_PKGPN = "${@bb.data.expand('staging-${PN}-${MULTIMACH_ARCH}${TARGET_VENDOR}-${TARGET_OS}', d).replace('_', '-')}" +PSTAGE_PKGNAME = "${PSTAGE_PKGPN}_${PSTAGE_PKGVERSION}_${PSTAGE_PKGARCH}.ipk" +PSTAGE_PKG ?= "${DEPLOY_DIR_PSTAGE}/${PSTAGE_PKGPATH}/${PSTAGE_PKGNAME}" + +PSTAGE_NATIVEDEPENDS = "\ + shasum-native \ + stagemanager-native \ + " + +BB_STAMP_WHITELIST = "${PSTAGE_NATIVEDEPENDS}" + +python () { + pstage_allowed = True + + # These classes encode staging paths into the binary data so can only be + # reused if the path doesn't change/ + if bb.data.inherits_class('native', d) or bb.data.inherits_class('cross', d) or bb.data.inherits_class('sdk', d): + path = bb.data.getVar('PSTAGE_PKGPATH', d, 1) + path = path + bb.data.getVar('TMPDIR', d, 1).replace('/', '-') + bb.data.setVar('PSTAGE_PKGPATH', path, d) + + # PSTAGE_NATIVEDEPENDS lists the packages we need before we can use packaged + # staging. There will always be some packages we depend on. + if bb.data.inherits_class('native', d): + pn = bb.data.getVar('PN', d, True) + nativedeps = bb.data.getVar('PSTAGE_NATIVEDEPENDS', d, True).split() + if pn in nativedeps: + pstage_allowed = False + + # Images aren't of interest to us + if bb.data.inherits_class('image', d): + pstage_allowed = False + + if bb.data.getVar('PSTAGING_DISABLED', d, True) == "1": + pstage_allowed = False + + # Add task dependencies if we're active, otherwise mark packaged staging + # as inactive. + if pstage_allowed: + deps = bb.data.getVarFlag('do_setscene', 'depends', d) or "" + deps += " stagemanager-native:do_populate_staging" + bb.data.setVarFlag('do_setscene', 'depends', deps, d) + + policy = bb.data.getVar("BB_STAMP_POLICY", d, True) + if policy == "whitelist" or policy == "full": + deps = bb.data.getVarFlag('do_setscene', 'recrdeptask', d) or "" + deps += " do_setscene" + bb.data.setVarFlag('do_setscene', 'recrdeptask', deps, d) + + bb.data.setVar("PSTAGING_ACTIVE", "1", d) + else: + bb.data.setVar("PSTAGING_ACTIVE", "0", d) } +DEPLOY_DIR_PSTAGE ?= "${DEPLOY_DIR}/pstage" +PSTAGE_MACHCONFIG = "${DEPLOY_DIR_PSTAGE}/opkg.conf" + +PSTAGE_PKGMANAGER = "stage-manager-ipkg" + +PSTAGE_BUILD_CMD = "stage-manager-ipkg-build -o 0 -g 0" +PSTAGE_INSTALL_CMD = "${PSTAGE_PKGMANAGER} -f ${PSTAGE_MACHCONFIG} -force-depends -o ${TMPDIR} install" +PSTAGE_UPDATE_CMD = "${PSTAGE_PKGMANAGER} -f ${PSTAGE_MACHCONFIG} -o ${TMPDIR} update" +PSTAGE_REMOVE_CMD = "${PSTAGE_PKGMANAGER} -f ${PSTAGE_MACHCONFIG} -force-depends -o ${TMPDIR} remove" +PSTAGE_LIST_CMD = "${PSTAGE_PKGMANAGER} -f ${PSTAGE_MACHCONFIG} -o ${TMPDIR} list_installed" + +PSTAGE_TMPDIR_STAGE = "${WORKDIR}/staging-pkg" + +def pstage_manualclean(srcname, destvarname, d): + src = os.path.join(bb.data.getVar('PSTAGE_TMPDIR_STAGE', d, True), srcname) + dest = bb.data.getVar(destvarname, d, True) + + for walkroot, dirs, files in os.walk(src): + for file in files: + filepath = os.path.join(walkroot, file).replace(src, dest) + bb.note("rm %s" % filepath) + os.system("rm %s" % filepath) + +def pstage_set_pkgmanager(d): + path = bb.data.getVar("PATH", d, 1) + pkgmanager = bb.which(path, 'opkg-cl') + if pkgmanager == "": + pkgmanager = bb.which(path, 'ipkg-cl') + if pkgmanager != "": + bb.data.setVar("PSTAGE_PKGMANAGER", pkgmanager, d) + + +def pstage_cleanpackage(pkgname, d): + path = bb.data.getVar("PATH", d, 1) + pstage_set_pkgmanager(d) + list_cmd = bb.data.getVar("PSTAGE_LIST_CMD", d, True) + + bb.debug(2, "Checking if staging package installed") + lf = bb.utils.lockfile(bb.data.expand("${SYSROOT_LOCK}", d)) + ret = os.system("PATH=\"%s\" %s | grep %s" % (path, list_cmd, pkgname)) + if ret == 0: + bb.debug(1, "Uninstalling package from staging...") + removecmd = bb.data.getVar("PSTAGE_REMOVE_CMD", d, 1) + ret = os.system("PATH=\"%s\" %s %s" % (path, removecmd, pkgname)) + if ret != 0: + bb.note("Failure removing staging package") + else: + bb.debug(1, "Manually removing any installed files from staging...") + pstage_manualclean("staging", "STAGING_DIR", d) + pstage_manualclean("cross", "CROSS_DIR", d) + pstage_manualclean("deploy", "DEPLOY_DIR", d) + + bb.utils.unlockfile(lf) + +do_clean_prepend() { + """ + Clear the build and temp directories + """ + + removepkg = bb.data.expand("${PSTAGE_PKGPN}", d) + pstage_cleanpackage(removepkg, d) + + stagepkg = bb.data.expand("${PSTAGE_PKG}", d) + bb.note("Removing staging package %s" % base_path_out(stagepkg, d)) + os.system('rm -rf ' + stagepkg) +} -do_stage_prepend() { - - stage-manager -p ${STAGING_DIR} -c ${DEPLOY_DIR_PSTAGE}/staging-stamp-cache -u - - stage-manager -p ${CROSS_DIR} -c ${DEPLOY_DIR_PSTAGE}/cross-stamp-cache -u - - if [ ! -e ${STAGING_BASEDIR} ]; then - mkdir -p ${STAGING_BASEDIR} +staging_helper () { + # Assemble appropriate opkg.conf + conffile=${PSTAGE_MACHCONFIG} + mkdir -p ${DEPLOY_DIR_PSTAGE}/pstaging_lists + if [ ! -e $conffile ]; then + ipkgarchs="${BUILD_SYS}" + priority=1 + for arch in $ipkgarchs; do + echo "arch $arch $priority" >> $conffile + priority=$(expr $priority + 5) + done + echo "dest root /" >> $conffile fi - - if [ ! -e ${DEPLOY_DIR_PSTAGE} ]; then - mkdir -p ${DEPLOY_DIR_PSTAGE} + if [ ! -e ${TMPDIR}${libdir_native}/opkg/info/ ]; then + mkdir -p ${TMPDIR}${libdir_native}/opkg/info/ fi - - if [ -e ${STAGING_BASEDIR}/usr ]; then - oenote "${STAGING_BASEDIR}/usr already present, leaving it alone" - else - oenote "${STAGING_BASEDIR}/usr not present, symlinking it" - ln -s ${STAGING_BASEDIR}/ ${STAGING_BASEDIR}/usr + if [ ! -e ${TMPDIR}${libdir_native}/ipkg/ ]; then + ln -sf opkg/ ${TMPDIR}${libdir_native}/ipkg || true fi +} - #assemble appropriate ipkg.conf - if [ -e ${DEPLOY_DIR_PSTAGE}/ipkg.conf ]; then - rm ${DEPLOY_DIR_PSTAGE}/ipkg.conf - fi +PSTAGE_TASKS_COVERED = "fetch unpack munge patch configure qa_configure rig_locales compile sizecheck install deploy package populate_staging package_write_deb package_write_ipk package_write package_stage qa_staging" + +SCENEFUNCS += "packagestage_scenefunc" + +python packagestage_scenefunc () { + if bb.data.getVar("PSTAGING_ACTIVE", d, 1) == "0": + return + + bb.build.exec_func("staging_helper", d) + + removepkg = bb.data.expand("${PSTAGE_PKGPN}", d) + + pstage_cleanpackage(removepkg, d) + + stagepkg = bb.data.expand("${PSTAGE_PKG}", d) + + if os.path.exists(stagepkg): + path = bb.data.getVar("PATH", d, 1) + pstage_set_pkgmanager(d) + file = bb.data.getVar("FILE", d, True) + bb.debug(2, "Packaged staging active for %s\n" % file) + + # + # Install the staging package somewhere temporarily so we can extract the stamp files + # + bb.mkdirhier(bb.data.expand("${WORKDIR}/tstage/${libdir_native}/opkg/info/ ", d)) + cmd = bb.data.expand("${PSTAGE_PKGMANAGER} -f ${PSTAGE_MACHCONFIG} -force-depends -o ${WORKDIR}/tstage install", d) + ret = os.system("PATH=\"%s\" %s %s" % (path, cmd, stagepkg)) + if ret != 0: + bb.fatal("Couldn't install the staging package to a temp directory") + + # + # Copy the stamp files into the main stamps directoy + # + cmd = bb.data.expand("cp -dpR ${WORKDIR}/tstage/stamps/* ${TMPDIR}/stamps/", d) + ret = os.system(cmd) + if ret != 0: + bb.fatal("Couldn't copy the staging package stamp files") + + # + # Iterate over the stamps seeing if they're valid. If we find any that + # are invalid or the task wasn't in the taskgraph, assume caution and + # do a rebuild. + # + # FIXME - some tasks are safe to ignore in the task graph. e.g. package_write_* + stageok = True + taskscovered = bb.data.getVar("PSTAGE_TASKS_COVERED", d, True).split() + stamp = bb.data.getVar("STAMP", d, True) + for task in taskscovered: + task = 'do_' + task + stampfn = "%s.%s" % (stamp, task) + bb.debug(1, "Checking %s" % (stampfn)) + if os.path.exists(stampfn): + stageok = bb.runqueue.check_stamp_fn(file, task, d) + bb.debug(1, "Result %s" % (stageok)) + if not stageok: + break + + # Remove the stamps and files we added above + # FIXME - we should really only remove the stamps we added + os.system('rm -f ' + stamp + '.*') + os.system(bb.data.expand("rm -rf ${WORKDIR}/tstage", d)) + + if stageok: + bb.note("Staging package found, using it for %s." % file) + installcmd = bb.data.getVar("PSTAGE_INSTALL_CMD", d, 1) + lf = bb.utils.lockfile(bb.data.expand("${SYSROOT_LOCK}", d)) + ret = os.system("PATH=\"%s\" %s %s" % (path, installcmd, stagepkg)) + bb.utils.unlockfile(lf) + if ret != 0: + bb.note("Failure installing prestage package") + + bb.build.make_stamp("do_stage_package_populated", d) + else: + bb.note("Staging package found but invalid for %s" % file) - ipkgarchs="${BUILD_ARCH} all any noarch ${TARGET_ARCH} ${IPKG_ARCHS} ${IPKG_EXTRA_ARCHS} ${MACHINE}" - priority=1 - for arch in $ipkgarchs; do - echo "arch $arch $priority" >> ${DEPLOY_DIR_PSTAGE}/ipkg.conf - priority=$(expr $priority + 5) - done - echo "src oe file:${DEPLOY_DIR_IPK}" >> ${DEPLOY_DIR_PSTAGE}/ipkg.conf - export OLD_PWD=`pwd` - cd ${DEPLOY_DIR_IPK} && rm *${BUILD_ARCH}.ipk -f ; ipkg-make-index -p Packages . ; cd ${OLD_PWD} - ${PSTAGE_UPDATE_CMD} ${STAGING_BASEDIR} - - #check for generated packages - if [ -e ${SPAWNFILE} ]; then - oenote "List of spawned packages found: ${P}.spawn" - for spawn in `cat ${SPAWNFILE} | grep -v locale | grep -v dbg | grep -v gconv | grep -v charmap` ; do \ - if [ -e ${DEPLOY_DIR_IPK}/${spawn}_* ]; then - ${PSTAGE_INSTALL_CMD} ${STAGING_BASEDIR} ${spawn} - # clean up .la files to avoid having references to the builddirs in the binaries - for lafile in ${STAGING_LIBDIR}/*.la ; do \ - sed -i s:installed=yes:installed=no:g ${lafile} || true - done - - #fix up linker script to poin to staging - if [ -e ${STAGING_LIBDIR}/libc.so ]; then - sed -i s:\ /lib:\ ${STAGING_LIBDIR}:g ${STAGING_LIBDIR}/libc.so - sed -i s:\ /usr/lib:\ ${STAGING_LIBDIR}:g ${STAGING_LIBDIR}/libc.so - fi - else - oenote "${spawn} not found, probably empty package" - fi - done - exit 0 - else - oenote "Spawn file not found!" +} +packagestage_scenefunc[cleandirs] = "${PSTAGE_TMPDIR_STAGE}" +packagestage_scenefunc[dirs] = "${STAGING_DIR}" + +addhandler packagedstage_stampfixing_eventhandler +python packagedstage_stampfixing_eventhandler() { + if bb.event.getName(e) == "StampUpdate": + taskscovered = bb.data.getVar("PSTAGE_TASKS_COVERED", e.data, 1).split() + for (fn, task) in e.targets: + # strip off 'do_' + task = task[3:] + if task in taskscovered: + stamp = "%s.do_stage_package_populated" % e.stampPrefix[fn] + if os.path.exists(stamp): + # We're targetting a task which was skipped with packaged staging + # so we need to remove the autogenerated stamps. + for task in taskscovered: + dir = "%s.do_%s" % (e.stampPrefix[fn], task) + os.system('rm -f ' + dir) + os.system('rm -f ' + stamp) + + return NotHandled +} + +populate_staging_preamble () { + if [ "$PSTAGING_ACTIVE" = "1" ]; then + stage-manager -p ${STAGING_DIR} -c ${DEPLOY_DIR_PSTAGE}/stamp-cache-staging -u || true + stage-manager -p ${CROSS_DIR} -c ${DEPLOY_DIR_PSTAGE}/stamp-cache-cross -u || true fi +} - if [ -e ${DEPLOY_DIR_PSTAGE}/${PCROSS_PKGNAME} ]; then - oenote "Cross stuff already packaged, using that instead" - ${PSTAGE_INSTALL_CMD} ${CROSS_DIR} ${DEPLOY_DIR_PSTAGE}/${PCROSS_PKGNAME} - fi +populate_staging_postamble () { + if [ "$PSTAGING_ACTIVE" = "1" ]; then + # list the packages currently installed in staging + # ${PSTAGE_LIST_CMD} | awk '{print $1}' > ${DEPLOY_DIR_PSTAGE}/installed-list + + # exitcode == 5 is ok, it means the files change + set +e + stage-manager -p ${STAGING_DIR} -c ${DEPLOY_DIR_PSTAGE}/stamp-cache-staging -u -d ${PSTAGE_TMPDIR_STAGE}/staging + exitcode=$? + if [ "$exitcode" != "5" -a "$exitcode" != "0" ]; then + exit $exitcode + fi + stage-manager -p ${CROSS_DIR} -c ${DEPLOY_DIR_PSTAGE}/stamp-cache-cross -u -d ${PSTAGE_TMPDIR_STAGE}/cross/${BASE_PACKAGE_ARCH} + if [ "$exitcode" != "5" -a "$exitcode" != "0" ]; then + exit $exitcode + fi + set -e + fi +} - if [ -e ${DEPLOY_DIR_PSTAGE}/${PSTAGE_PKGNAME} ]; then - oenote "Staging stuff already packaged, using that instead" - ${PSTAGE_INSTALL_CMD} ${STAGING_DIR} ${DEPLOY_DIR_PSTAGE}/${PSTAGE_PKGNAME} - exit 0 +packagedstaging_fastpath () { + if [ "$PSTAGING_ACTIVE" = "1" ]; then + mkdir -p ${PSTAGE_TMPDIR_STAGE}/staging/ + mkdir -p ${PSTAGE_TMPDIR_STAGE}/cross/ + cp -fpPR ${SYSROOT_DESTDIR}/${STAGING_DIR}/* ${PSTAGE_TMPDIR_STAGE}/staging/ || /bin/true + cp -fpPR ${SYSROOT_DESTDIR}/${CROSS_DIR}/* ${PSTAGE_TMPDIR_STAGE}/cross/ || /bin/true fi +} +do_populate_staging[dirs] =+ "${DEPLOY_DIR_PSTAGE}" +python populate_staging_prehook() { + bb.build.exec_func("populate_staging_preamble", d) +} - mkdir -p ${STAGING_BINDIR} - mkdir -p ${STAGING_LIBDIR} - mkdir -p ${STAGING_INCDIR} - mkdir -p ${STAGING_DATADIR}/aclocal +python populate_staging_posthook() { + bb.build.exec_func("populate_staging_postamble", d) } -do_stage_append() { - mkdir -p ${DEPLOY_DIR_PSTAGE} +staging_packager () { - # list the packages currently installed in staging - ${PSTAGE_LIST_CMD} ${STAGING_DIR} | awk '{print $1}' > ${DEPLOY_DIR_PSTAGE}/installed-staging_list - ${PSTAGE_LIST_CMD} ${CROSS_DIR} | awk '{print $1}' > ${DEPLOY_DIR_PSTAGE}/installed-cross_list + mkdir -p ${PSTAGE_TMPDIR_STAGE}/CONTROL + mkdir -p ${DEPLOY_DIR_PSTAGE}/${PSTAGE_PKGPATH} - set +e - rm -rf ${PSTAGE_TMPDIR_STAGE} - stage-manager -p ${STAGING_DIR} -c ${DEPLOY_DIR_PSTAGE}/staging-stamp-cache -u -d ${PSTAGE_TMPDIR_STAGE} - rc=$? - set -e + echo "Package: ${PSTAGE_PKGPN}" > ${PSTAGE_TMPDIR_STAGE}/CONTROL/control + echo "Version: ${PSTAGE_PKGVERSION}" >> ${PSTAGE_TMPDIR_STAGE}/CONTROL/control + echo "Description: ${DESCRIPTION}" >> ${PSTAGE_TMPDIR_STAGE}/CONTROL/control + echo "Section: ${SECTION}" >> ${PSTAGE_TMPDIR_STAGE}/CONTROL/control + echo "Priority: Optional" >> ${PSTAGE_TMPDIR_STAGE}/CONTROL/control + echo "Maintainer: ${MAINTAINER}" >> ${PSTAGE_TMPDIR_STAGE}/CONTROL/control + echo "Architecture: ${PSTAGE_PKGARCH}" >> ${PSTAGE_TMPDIR_STAGE}/CONTROL/control + + # Protect against empty SRC_URI + if [ "${SRC_URI}" != "" ] ; then + echo "Source: ${SRC_URI}" >> ${PSTAGE_TMPDIR_STAGE}/CONTROL/control + else + echo "Source: OpenEmbedded" >> ${PSTAGE_TMPDIR_STAGE}/CONTROL/control + fi + + ${PSTAGE_BUILD_CMD} ${PSTAGE_TMPDIR_STAGE} ${DEPLOY_DIR_PSTAGE}/${PSTAGE_PKGPATH} +} - if [ $rc == 5 ]; then +staging_package_installer () { + #${PSTAGE_INSTALL_CMD} ${PSTAGE_PKG} - #make a package for staging - mkdir -p ${PSTAGE_TMPDIR_STAGE}/CONTROL + STATUSFILE=${TMPDIR}${libdir_native}/opkg/status + echo "Package: ${PSTAGE_PKGPN}" >> $STATUSFILE + echo "Version: ${PSTAGE_PKGVERSION}" >> $STATUSFILE + echo "Status: install user installed" >> $STATUSFILE + echo "Architecture: ${PSTAGE_PKGARCH}" >> $STATUSFILE + echo "" >> $STATUSFILE - echo "Package: staging-${PN}" > ${PSTAGE_TMPDIR_STAGE}/CONTROL/control - echo "Version: ${PV}-${PR}" >> ${PSTAGE_TMPDIR_STAGE}/CONTROL/control - echo "Description: ${DESCRIPTION}" >> ${PSTAGE_TMPDIR_STAGE}/CONTROL/control - echo "Section: ${SECTION}" >> ${PSTAGE_TMPDIR_STAGE}/CONTROL/control - echo "Priority: Optional" >> ${PSTAGE_TMPDIR_STAGE}/CONTROL/control - echo "Maintainer: ${MAINTAINER}" >> ${PSTAGE_TMPDIR_STAGE}/CONTROL/control - echo "Architecture: ${PACKAGE_ARCH}" >> ${PSTAGE_TMPDIR_STAGE}/CONTROL/control - echo "Source: ${SRC_URI}" >> ${PSTAGE_TMPDIR_STAGE}/CONTROL/control + CTRLFILE=${TMPDIR}${libdir_native}/opkg/info/${PSTAGE_PKGPN}.control + echo "Package: ${PSTAGE_PKGPN}" > $CTRLFILE + echo "Version: ${PSTAGE_PKGVERSION}" >> $CTRLFILE + echo "Architecture: ${PSTAGE_PKGARCH}" >> $CTRLFILE - ${PSTAGE_BUILD_CMD} ${PSTAGE_TMPDIR_STAGE} ${DEPLOY_DIR_PSTAGE} + cd ${PSTAGE_TMPDIR_STAGE} + find -type f | grep -v ./CONTROL | sed -e 's/^\.//' > ${TMPDIR}${libdir_native}/opkg/info/${PSTAGE_PKGPN}.list +} - ${PSTAGE_INSTALL_CMD} ${STAGING_DIR} ${DEPLOY_DIR_PSTAGE}/${PSTAGE_PKGNAME} - fi +python do_package_stage () { + if bb.data.getVar("PSTAGING_ACTIVE", d, 1) != "1": + return + + # + # Handle deploy/ packages + # + bb.build.exec_func("read_subpackage_metadata", d) + stagepath = bb.data.getVar("PSTAGE_TMPDIR_STAGE", d, 1) + tmpdir = bb.data.getVar("TMPDIR", d, True) + packages = (bb.data.getVar('PACKAGES', d, 1) or "").split() + if len(packages) > 0: + if bb.data.inherits_class('package_ipk', d): + ipkpath = bb.data.getVar('DEPLOY_DIR_IPK', d, True).replace(tmpdir, stagepath) + if bb.data.inherits_class('package_deb', d): + debpath = bb.data.getVar('DEPLOY_DIR_DEB', d, True).replace(tmpdir, stagepath) + if bb.data.inherits_class('package_rpm', d): + rpmpath = bb.data.getVar('DEPLOY_DIR_RPM', d, True).replace(tmpdir, stagepath) + + for pkg in packages: + pkgname = bb.data.getVar('PKG_%s' % pkg, d, 1) + if not pkgname: + pkgname = pkg + arch = bb.data.getVar('PACKAGE_ARCH_%s' % pkg, d, 1) + if not arch: + arch = bb.data.getVar('PACKAGE_ARCH', d, 1) + pr = bb.data.getVar('PR_%s' % pkg, d, 1) + if not pr: + pr = bb.data.getVar('PR', d, 1) + if not packaged(pkg, d): + continue + if bb.data.inherits_class('package_ipk', d): + srcname = bb.data.expand(pkgname + "_${PV}-" + pr + "_" + arch + ".ipk", d) + srcfile = bb.data.expand("${DEPLOY_DIR_IPK}/" + arch + "/" + srcname, d) + if os.path.exists(srcfile): + destpath = ipkpath + "/" + arch + "/" + bb.mkdirhier(destpath) + bb.copyfile(srcfile, destpath + srcname) + + if bb.data.inherits_class('package_deb', d): + if arch == 'all': + srcname = bb.data.expand(pkgname + "_${PV}-" + pr + "_all.deb", d) + else: + srcname = bb.data.expand(pkgname + "_${PV}-" + pr + "_${DPKG_ARCH}.deb", d) + srcfile = bb.data.expand("${DEPLOY_DIR_DEB}/" + arch + "/" + srcname, d) + if os.path.exists(srcfile): + destpath = debpath + "/" + arch + "/" + bb.mkdirhier(destpath) + bb.copyfile(srcfile, destpath + srcname) + + if bb.data.inherits_class('package_rpm', d): + version = bb.data.getVar('PV', d, 1) + version = version.replace('-', '+') + bb.data.setVar('RPMPV', version, d) + srcname = bb.data.expand(pkgname + "-${RPMPV}-" + pr + ".${TARGET_ARCH}.rpm", d) + srcfile = bb.data.expand("${DEPLOY_DIR_RPM}/" + arch + "/" + srcname, d) + if os.path.exists(srcfile): + destpath = rpmpath + "/" + arch + "/" + bb.mkdirhier(destpath) + bb.copyfile(srcfile, destpath + srcname) + + + # + # Handle stamps/ files + # + stampfn = bb.data.getVar("STAMP", d, True) + destdir = os.path.dirname(stampfn.replace(tmpdir, stagepath)) + bb.mkdirhier(destdir) + # We need to include the package_stage stamp in the staging package so create one + bb.build.make_stamp("do_package_stage", d) + os.system("cp -dpR %s.do_* %s/" % (stampfn, destdir)) + + pstage_set_pkgmanager(d) + bb.build.exec_func("staging_helper", d) + bb.build.exec_func("staging_packager", d) + lf = bb.utils.lockfile(bb.data.expand("${SYSROOT_LOCK}", d)) + bb.build.exec_func("staging_package_installer", d) + bb.utils.unlockfile(lf) +} - set +e - rm -rf ${PSTAGE_TMPDIR_CROSS} - stage-manager -p ${CROSS_DIR} -c ${DEPLOY_DIR_PSTAGE}/cross-stamp-cache -u -d ${PSTAGE_TMPDIR_CROSS} - rc=$? - set -e - - if [ $rc == 5 ]; then - - #make a package for cross - mkdir -p ${PSTAGE_TMPDIR_CROSS}/CONTROL - - echo "Package: cross-${PN}" > ${PSTAGE_TMPDIR_CROSS}/CONTROL/control - echo "Version: ${PV}-${PR}" >> ${PSTAGE_TMPDIR_CROSS}/CONTROL/control - echo "Description: ${DESCRIPTION}" >> ${PSTAGE_TMPDIR_CROSS}/CONTROL/control - echo "Section: ${SECTION}" >> ${PSTAGE_TMPDIR_CROSS}/CONTROL/control - echo "Priority: Optional" >> ${PSTAGE_TMPDIR_CROSS}/CONTROL/control - echo "Maintainer: ${MAINTAINER}" >> ${PSTAGE_TMPDIR_CROSS}/CONTROL/control - echo "Architecture: ${BUILD_ARCH}" >> ${PSTAGE_TMPDIR_CROSS}/CONTROL/control - echo "Source: ${SRC_URI}" >> ${PSTAGE_TMPDIR_CROSS}/CONTROL/control - - ${PSTAGE_BUILD_CMD} ${PSTAGE_TMPDIR_CROSS} ${DEPLOY_DIR_PSTAGE} +# +# Note an assumption here is that do_deploy runs before do_package_write/do_populate_staging +# +addtask package_stage after do_package_write do_populate_staging before do_build - ${PSTAGE_INSTALL_CMD} ${CROSS_DIR} ${DEPLOY_DIR_PSTAGE}/${PCROSS_PKGNAME} - fi +do_package_stage_all () { + : } - +do_package_stage_all[recrdeptask] = "do_package_stage" +addtask package_stage_all after do_package_stage before do_build diff --git a/classes/packagedata.bbclass b/classes/packagedata.bbclass new file mode 100644 index 0000000000..86f18a9e96 --- /dev/null +++ b/classes/packagedata.bbclass @@ -0,0 +1,73 @@ +def packaged(pkg, d): + return os.access(get_subpkgedata_fn(pkg, d) + '.packaged', os.R_OK) + +def read_pkgdatafile(fn): + pkgdata = {} + + def decode(str): + import codecs + c = codecs.getdecoder("string_escape") + return c(str)[0] + + if os.access(fn, os.R_OK): + import re + f = file(fn, 'r') + lines = f.readlines() + f.close() + r = re.compile("([^:]+):\s*(.*)") + for l in lines: + m = r.match(l) + if m: + pkgdata[m.group(1)] = decode(m.group(2)) + + return pkgdata + +def get_subpkgedata_fn(pkg, d): + archs = bb.data.expand("${PACKAGE_ARCHS}", d).split(" ") + archs.reverse() + pkgdata = bb.data.expand('${TMPDIR}/pkgdata/', d) + targetdir = bb.data.expand('${TARGET_VENDOR}-${TARGET_OS}/runtime/', d) + for arch in archs: + fn = pkgdata + arch + targetdir + pkg + if os.path.exists(fn): + return fn + return bb.data.expand('${PKGDATA_DIR}/runtime/%s' % pkg, d) + +def has_subpkgdata(pkg, d): + return os.access(get_subpkgedata_fn(pkg, d), os.R_OK) + +def read_subpkgdata(pkg, d): + return read_pkgdatafile(get_subpkgedata_fn(pkg, d)) + +def has_pkgdata(pn, d): + fn = bb.data.expand('${PKGDATA_DIR}/%s' % pn, d) + return os.access(fn, os.R_OK) + +def read_pkgdata(pn, d): + fn = bb.data.expand('${PKGDATA_DIR}/%s' % pn, d) + return read_pkgdatafile(fn) + +python read_subpackage_metadata () { + data = read_pkgdata(bb.data.getVar('PN', d, 1), d) + + for key in data.keys(): + bb.data.setVar(key, data[key], d) + + for pkg in bb.data.getVar('PACKAGES', d, 1).split(): + sdata = read_subpkgdata(pkg, d) + for key in sdata.keys(): + bb.data.setVar(key, sdata[key], d) +} + + +# +# Collapse FOO_pkg variables into FOO +# +def read_subpkgdata_dict(pkg, d): + ret = {} + subd = read_pkgdatafile(get_subpkgedata_fn(pkg, d)) + for var in subd: + newvar = var.replace("_" + pkg, "") + ret[newvar] = subd[var] + return ret + diff --git a/classes/packagehistory.bbclass b/classes/packagehistory.bbclass new file mode 100644 index 0000000000..492bbac218 --- /dev/null +++ b/classes/packagehistory.bbclass @@ -0,0 +1,97 @@ +# Must inherit package first before changing PACKAGEFUNCS +inherit package +PACKAGEFUNCS += "emit_pkghistory" + +PKGHIST_DIR = "${TMPDIR}/pkghistory/${BASEPKG_TARGET_SYS}/" + + +# +# Called during do_package to write out metadata about this package +# for comparision when writing future packages +# +python emit_pkghistory() { + packages = bb.data.getVar('PACKAGES', d, True) + pkghistdir = bb.data.getVar('PKGHIST_DIR', d, True) + + + # Should check PACKAGES here to see if anything removed + + def getpkgvar(pkg, var): + val = bb.data.getVar('%s_%s' % (var, pkg), d, 1) + if val: + return val + val = bb.data.getVar('%s' % (var), d, 1) + + return val + + def getlastversion(pkg): + try: + pe = os.path.basename(os.readlink(os.path.join(pkghistdir, pkg, "latest"))) + pv = os.path.basename(os.readlink(os.path.join(pkghistdir, pkg, pe, "latest"))) + pr = os.path.basename(os.readlink(os.path.join(pkghistdir, pkg, pe, pv, "latest"))) + return (pe, pv, pr) + except OSError: + return (None, None, None) + + for pkg in packages.split(): + pe = getpkgvar(pkg, 'PE') or "0" + pv = getpkgvar(pkg, 'PV') + pr = getpkgvar(pkg, 'PR') + destdir = os.path.join(pkghistdir, pkg, pe, pv, pr) + + # + # Find out what the last version was + # Make sure the version did not decrease + # + lastversion = getlastversion(pkg) + (last_pe, last_pv, last_pr) = lastversion + + if last_pe is not None: + r = bb.utils.vercmp((pe, pv, pr), lastversion) + if r < 0: + bb.fatal("Package version for package %s went backwards which would break package feeds from (%s:%s-%s to %s:%s-%s)" % (pkg, last_pe, last_pv, last_pr, pe, pv, pr)) + + write_pkghistory(pkg, pe, pv, pr, d) + + if last_pe is not None: + check_pkghistory(pkg, pe, pv, pr, lastversion) + + write_latestlink(pkg, pe, pv, pr, d) +} + + +def check_pkghistory(pkg, pe, pv, pr, lastversion): + (last_pe, last_pv, last_pr) = lastversion + + bb.debug(2, "Checking package history") + # RDEPENDS removed? + # PKG changed? + # Each file list of each package for file removals? + + +def write_pkghistory(pkg, pe, pv, pr, d): + bb.debug(2, "Writing package history") + + pkghistdir = bb.data.getVar('PKGHIST_DIR', d, True) + + verpath = os.path.join(pkghistdir, pkg, pe, pv, pr) + if not os.path.exists(verpath): + os.makedirs(verpath) + +def write_latestlink(pkg, pe, pv, pr, d): + pkghistdir = bb.data.getVar('PKGHIST_DIR', d, True) + + def rm_link(path): + try: + os.unlink(path) + except OSError: + return + + rm_link(os.path.join(pkghistdir, pkg, "latest")) + rm_link(os.path.join(pkghistdir, pkg, pe, "latest")) + rm_link(os.path.join(pkghistdir, pkg, pe, pv, "latest")) + + os.symlink(os.path.join(pkghistdir, pkg, pe), os.path.join(pkghistdir, pkg, "latest")) + os.symlink(os.path.join(pkghistdir, pkg, pe, pv), os.path.join(pkghistdir, pkg, pe, "latest")) + os.symlink(os.path.join(pkghistdir, pkg, pe, pv, pr), os.path.join(pkghistdir, pkg, pe, pv, "latest")) + diff --git a/classes/palmtop.bbclass b/classes/palmtop.bbclass index 9d54de8748..b4ee62c2a3 100644 --- a/classes/palmtop.bbclass +++ b/classes/palmtop.bbclass @@ -11,10 +11,16 @@ inherit qmake # special case for DISTRO = sharprom CPP_SUPPORT_LIB = "LIBS-=-lstdc++ LIBS+=-lsupc++" -CPP_SUPPORT_LIB_sharprom = "LIBS-=-lstdc++" +CPP_SUPPORT_LIB_sharprom-compatible = "LIBS+=-lstdc++" EXTRA_QMAKEVARS_POST += "DEFINES+=QWS CONFIG+=qt ${CPP_SUPPORT_LIB}" EXTRA_QMAKEVARS_POST += '${@base_conditional("PALMTOP_USE_MULTITHREADED_QT", "yes", "CONFIG+=thread", "CONFIG-=thread",d)}' EXTRA_QMAKEVARS_POST += "${@["LIBS+=-lqpe ", ""][(bb.data.getVar('PN', d, 1) == 'libqpe-opie')]}" DEPENDS_prepend = "${@["virtual/libqpe1 uicmoc-native ", ""][(bb.data.getVar('PN', d, 1) == 'libqpe-opie')]}" +QT_LIBRARY = '${@base_conditional("PALMTOP_USE_MULTITHREADED_QT", "yes", "qte-mt", "qte", d)}' +EXTRA_QMAKEVARS_POST += " DEFINES+=OPIE_BINDIR='\"${bindir}\"' DEFINES+=OPIE_LIBDIR='\"${libdir}/opie/lib\"' DEFINES+=OPIE_QTDIR='\"${libdir}/opie\"' " -FILES_${PN} = "${palmtopdir}" +PACKAGES = "${PN}-dbg ${PN}-dev ${PN} ${PN}-doc ${PN}-locale" +FILES_${PN} += " ${palmtopdir} " +FILES_${PN}-dbg += " ${palmtopdir}/lib/.debug \ + ${palmtopdir}/bin/.debug \ + ${palmtopdir}/plugins/*/.debug " diff --git a/classes/patch.bbclass b/classes/patch.bbclass index e3b89ba4f9..33184df0d0 100644 --- a/classes/patch.bbclass +++ b/classes/patch.bbclass @@ -1,13 +1,30 @@ # Copyright (C) 2006 OpenedHand LTD +# Point to an empty file so any user's custom settings don't break things +QUILTRCFILE ?= "${STAGING_BINDIR_NATIVE}/quiltrc" + def patch_init(d): - import os, sys + class NotFoundError(Exception): + def __init__(self, path): + self.path = path + def __str__(self): + return "Error: %s not found." % self.path def md5sum(fname): - import md5, sys + # when we move to Python 2.5 as minimal supported + # we can kill that try/except as hashlib is 2.5+ + try: + import hashlib + m = hashlib.md5() + except ImportError: + import md5 + m = md5.new() + + try: + f = file(fname, 'rb') + except IOError: + raise NotFoundError(fname) - f = file(fname, 'rb') - m = md5.new() while True: d = f.read(8096) if not d: @@ -24,11 +41,6 @@ def patch_init(d): def __str__(self): return "Command Error: exit status: %d Output:\n%s" % (self.status, self.output) - class NotFoundError(Exception): - def __init__(self, path): - self.path = path - def __str__(self): - return "Error: %s not found." % self.path def runcmd(args, dir = None): import commands @@ -38,7 +50,7 @@ def patch_init(d): if not os.path.exists(dir): raise NotFoundError(dir) os.chdir(dir) - # print("cwd: %s -> %s" % (olddir, self.dir)) + # print("cwd: %s -> %s" % (olddir, dir)) try: args = [ commands.mkarg(str(arg)) for arg in args ] @@ -60,8 +72,6 @@ def patch_init(d): def __str__(self): return "Patch Error: %s" % self.msg - import bb, bb.data, bb.fetch - class PatchSet(object): defaults = { "strippath": 1 @@ -123,11 +133,14 @@ def patch_init(d): i = 0 self.patches.insert(i, patch) - def _applypatch(self, patch, force = None, reverse = None): + def _applypatch(self, patch, force = False, reverse = False, run = True): shellcmd = ["cat", patch['file'], "|", "patch", "-p", patch['strippath']] if reverse: shellcmd.append('-R') + if not run: + return "sh" + "-c" + " ".join(shellcmd) + if not force: shellcmd.append('--dry-run') @@ -140,7 +153,7 @@ def patch_init(d): output = runcmd(["sh", "-c", " ".join(shellcmd)], self.dir) return output - def Push(self, force = None, all = None): + def Push(self, force = False, all = False, run = True): bb.note("self._current is %s" % self._current) bb.note("patches is %s" % self.patches) if all: @@ -157,7 +170,7 @@ def patch_init(d): else: self._current = 0 bb.note("applying patch %s" % self.patches[self._current]) - self._applypatch(self.patches[self._current], force) + return self._applypatch(self.patches[self._current], force) def Pop(self, force = None, all = None): @@ -170,9 +183,30 @@ def patch_init(d): def Clean(self): """""" + class GitApplyTree(PatchTree): + def __init__(self, dir, d): + PatchTree.__init__(self, dir, d) + + def _applypatch(self, patch, force = False, reverse = False, run = True): + shellcmd = ["git", "--git-dir=.", "apply", "-p%s" % patch['strippath']] + + if reverse: + shellcmd.append('-R') + + shellcmd.append(patch['file']) + + if not run: + return "sh" + "-c" + " ".join(shellcmd) + + return runcmd(["sh", "-c", " ".join(shellcmd)], self.dir) + + class QuiltTree(PatchSet): - def _runcmd(self, args): - runcmd(["quilt"] + args, self.dir) + def _runcmd(self, args, run = True): + quiltrc = bb.data.getVar('QUILTRCFILE', self.d, 1) + if not run: + return ["quilt"] + ["--quiltrc"] + [quiltrc] + args + runcmd(["quilt"] + ["--quiltrc"] + [quiltrc] + args, self.dir) def _quiltpatchpath(self, file): return os.path.join(self.dir, "patches", os.path.basename(file)) @@ -213,6 +247,7 @@ def patch_init(d): try: output = runcmd(["quilt", "applied"], self.dir) except CmdError: + import sys if sys.exc_value.output.strip() == "No patches applied": return else: @@ -231,6 +266,7 @@ def patch_init(d): args = ["import", "-p", patch["strippath"]] if force: args.append("-f") + args.append("-dn") args.append(patch["file"]) self._runcmd(args) @@ -245,7 +281,7 @@ def patch_init(d): self.patches.insert(self._current or 0, patch) - def Push(self, force = None, all = None): + def Push(self, force = False, all = False, run = True): # quilt push [-f] args = ["push"] @@ -253,6 +289,8 @@ def patch_init(d): args.append("-f") if all: args.append("-a") + if not run: + return self._runcmd(args, run) self._runcmd(args) @@ -323,6 +361,7 @@ def patch_init(d): try: self.patchset.Push() except Exception: + import sys os.chdir(olddir) raise sys.exc_value @@ -339,16 +378,34 @@ def patch_init(d): olddir = os.path.abspath(os.curdir) os.chdir(self.patchset.dir) - try: - self.patchset.Push(True) - except CmdError, v: - # Patch application failed - if sys.exc_value.output.strip() == "No patches applied": - return - print(sys.exc_value) - print('NOTE: dropping user into a shell, so that patch rejects can be fixed manually.') - - os.system('/bin/sh') + try: + self.patchset.Push(False) + except CmdError, v: + # Patch application failed + patchcmd = self.patchset.Push(True, False, False) + + t = bb.data.getVar('T', d, 1) + if not t: + bb.msg.fatal(bb.msg.domain.Build, "T not set") + bb.mkdirhier(t) + import random + rcfile = "%s/bashrc.%s.%s" % (t, str(os.getpid()), random.random()) + f = open(rcfile, "w") + f.write("echo '*** Manual patch resolution mode ***'\n") + f.write("echo 'Dropping to a shell, so patch rejects can be fixed manually.'\n") + f.write("echo 'Run \"quilt refresh\" when patch is corrected, press CTRL+D to exit.'\n") + f.write("echo ''\n") + f.write(" ".join(patchcmd) + "\n") + f.write("#" + bb.data.getVar('TERMCMDRUN', d, 1)) + f.close() + os.chmod(rcfile, 0775) + + os.environ['TERMWINDOWTITLE'] = "Bitbake: Please fix patch rejects manually" + os.environ['TERMRCFILE'] = rcfile + rc = os.system(bb.data.getVar('TERMCMDRUN', d, 1)) + if os.WIFEXITED(rc) and os.WEXITSTATUS(rc) != 0: + bb.msg.fatal(bb.msg.domain.Build, ("Cannot proceed with manual patch resolution - '%s' not found. " \ + + "Check TERMCMDRUN variable.") % bb.data.getVar('TERMCMDRUN', d, 1)) # Construct a new PatchSet after the user's changes, compare the # sets, checking patches for modifications, and doing a remote @@ -381,6 +438,7 @@ def patch_init(d): g["PatchSet"] = PatchSet g["PatchTree"] = PatchTree g["QuiltTree"] = QuiltTree + g["GitApplyTree"] = GitApplyTree g["Resolver"] = Resolver g["UserResolver"] = UserResolver g["NOOPResolver"] = NOOPResolver @@ -389,10 +447,11 @@ def patch_init(d): addtask patch after do_unpack do_patch[dirs] = "${WORKDIR}" -python patch_do_patch() { - import re - import bb.fetch +PATCHDEPENDENCY = "${PATCHTOOL}-native:do_populate_staging" +do_patch[depends] = "${PATCHDEPENDENCY}" + +python patch_do_patch() { patch_init(d) src_uri = (bb.data.getVar('SRC_URI', d, 1) or '').split() @@ -402,6 +461,7 @@ python patch_do_patch() { patchsetmap = { "patch": PatchTree, "quilt": QuiltTree, + "git": GitApplyTree, } cls = patchsetmap[bb.data.getVar('PATCHTOOL', d, 1) or 'quilt'] @@ -450,38 +510,40 @@ python patch_do_patch() { else: pname = os.path.basename(unpacked) - if "mindate" in parm: - mindate = parm["mindate"] - else: - mindate = 0 - - if "maxdate" in parm: - maxdate = parm["maxdate"] - else: - maxdate = "20711226" - - pn = bb.data.getVar('PN', d, 1) - srcdate = bb.data.getVar('SRCDATE_%s' % pn, d, 1) + if "mindate" in parm or "maxdate" in parm: + pn = bb.data.getVar('PN', d, 1) + srcdate = bb.data.getVar('SRCDATE_%s' % pn, d, 1) + if not srcdate: + srcdate = bb.data.getVar('SRCDATE', d, 1) - if not srcdate: - srcdate = bb.data.getVar('SRCDATE', d, 1) + if srcdate == "now": + srcdate = bb.data.getVar('DATE', d, 1) - if srcdate == "now": - srcdate = bb.data.getVar('DATE', d, 1) - - if (maxdate < srcdate) or (mindate > srcdate): - if (maxdate < srcdate): + if "maxdate" in parm and parm["maxdate"] < srcdate: bb.note("Patch '%s' is outdated" % pname) + continue - if (mindate > srcdate): + if "mindate" in parm and parm["mindate"] > srcdate: bb.note("Patch '%s' is predated" % pname) + continue - continue - bb.note("Applying patch '%s'" % pname) + if "minrev" in parm: + srcrev = bb.data.getVar('SRCREV', d, 1) + if srcrev and srcrev < parm["minrev"]: + bb.note("Patch '%s' applies to later revisions" % pname) + continue + + if "maxrev" in parm: + srcrev = bb.data.getVar('SRCREV', d, 1) + if srcrev and srcrev > parm["maxrev"]: + bb.note("Patch '%s' applies to earlier revisions" % pname) + continue + + bb.note("Applying patch '%s' (%s)" % (pname, base_path_out(unpacked, d))) try: patchset.Import({"file":unpacked, "remote":url, "strippath": pnum}, True) - except NotFoundError: + except: import sys raise bb.build.FuncFailed(str(sys.exc_value)) resolver.Resolve() diff --git a/classes/pkgconfig.bbclass b/classes/pkgconfig.bbclass index f2054b0b07..f3d93716d7 100644 --- a/classes/pkgconfig.bbclass +++ b/classes/pkgconfig.bbclass @@ -1,28 +1,18 @@ -inherit base - DEPENDS_prepend = "pkgconfig-native " -# The namespaces can clash here hence the two step replace -def get_pkgconfig_mangle(d): - import bb.data - s = "-e ''" - if not bb.data.inherits_class('native', d): - s += " -e 's:=${libdir}:=OELIBDIR:;'" - s += " -e 's:=${includedir}:=OEINCDIR:;'" - s += " -e 's:=${datadir}:=OEDATADIR:'" - s += " -e 's:=${prefix}:=OEPREFIX:'" - s += " -e 's:=${exec_prefix}:=OEEXECPREFIX:'" - s += " -e 's:OELIBDIR:${STAGING_LIBDIR}:;'" - s += " -e 's:OEINCDIR:${STAGING_INCDIR}:;'" - s += " -e 's:OEDATADIR:${STAGING_DATADIR}:'" - s += " -e 's:OEPREFIX:${STAGING_LIBDIR}/..:'" - s += " -e 's:OEEXECPREFIX:${STAGING_LIBDIR}/..:'" - return s +do_install_prepend () { + +for i in `find ${S}/ -name "*.pc" -type f` ; do \ + sed -i -e 's:-L${STAGING_LIBDIR}::g' -e 's:-I${STAGING_INCDIR}::g' $i + done +} + +SYSROOT_PREPROCESS_FUNCS += "pkgconfig_sysroot_preprocess" -do_stage_append () { +pkgconfig_sysroot_preprocess () { + install -d ${SYSROOT_DESTDIR}${PKG_CONFIG_DIR} for pc in `find ${S} -name '*.pc' -type f | grep -v -- '-uninstalled.pc$'`; do pcname=`basename $pc` - install -d ${PKG_CONFIG_PATH} - cat $pc | sed ${@get_pkgconfig_mangle(d)} > ${PKG_CONFIG_PATH}/$pcname + cat $pc > ${SYSROOT_DESTDIR}${PKG_CONFIG_DIR}/$pcname done } diff --git a/classes/qemu.bbclass b/classes/qemu.bbclass new file mode 100644 index 0000000000..66dfb2b0d2 --- /dev/null +++ b/classes/qemu.bbclass @@ -0,0 +1,15 @@ +# +# This class contains functions for recipes that need QEMU or test for its +# existance. +# + +def qemu_target_binary(data): + import bb + + target_arch = bb.data.getVar("TARGET_ARCH", data, 1) + if target_arch in ("i486", "i586", "i686"): + target_arch = "i386" + elif target_arch == "powerpc": + target_arch = "ppc" + + return "qemu-" + target_arch diff --git a/classes/qmake-base.bbclass b/classes/qmake-base.bbclass deleted file mode 100644 index 36ecfb622f..0000000000 --- a/classes/qmake-base.bbclass +++ /dev/null @@ -1,44 +0,0 @@ -DEPENDS_prepend = "qmake-native " - -OE_QMAKE_PLATFORM = "${TARGET_OS}-oe-g++" -QMAKESPEC := "${QMAKE_MKSPEC_PATH}/${OE_QMAKE_PLATFORM}" - -# We override this completely to eliminate the -e normally passed in -EXTRA_OEMAKE = ' MAKEFLAGS= ' - -export OE_QMAKE_CC="${CC}" -export OE_QMAKE_CFLAGS="${CFLAGS}" -export OE_QMAKE_CXX="${CXX}" -export OE_QMAKE_CXXFLAGS="-fno-exceptions -fno-rtti ${CXXFLAGS}" -export OE_QMAKE_LDFLAGS="${LDFLAGS}" -export OE_QMAKE_LINK="${CCLD}" -export OE_QMAKE_AR="${AR}" -export OE_QMAKE_STRIP="${STRIP}" -export OE_QMAKE_UIC="${STAGING_BINDIR}/uic" -export OE_QMAKE_MOC="${STAGING_BINDIR}/moc" -export OE_QMAKE_RCC="non-existant" -export OE_QMAKE_QMAKE="${STAGING_BINDIR}/qmake" -export OE_QMAKE_RPATH="-Wl,-rpath-link," - -# default to qte2 via bb.conf, inherit qt3x11 to configure for qt3x11 -export OE_QMAKE_INCDIR_QT="${QTDIR}/include" -export OE_QMAKE_LIBDIR_QT="${QTDIR}/lib" -export OE_QMAKE_LIBS_QT="qte" -export OE_QMAKE_LIBS_X11="" - -oe_qmake_mkspecs () { - mkdir -p mkspecs/${OE_QMAKE_PLATFORM} - for f in ${QMAKE_MKSPEC_PATH}/${OE_QMAKE_PLATFORM}/*; do - if [ -L $f ]; then - lnk=`readlink $f` - if [ -f mkspecs/${OE_QMAKE_PLATFORM}/$lnk ]; then - ln -s $lnk mkspecs/${OE_QMAKE_PLATFORM}/`basename $f` - else - cp $f mkspecs/${OE_QMAKE_PLATFORM}/ - fi - else - cp $f mkspecs/${OE_QMAKE_PLATFORM}/ - fi - done -} - diff --git a/classes/qmake.bbclass b/classes/qmake.bbclass index 4f2fceff35..7dfe459349 100644 --- a/classes/qmake.bbclass +++ b/classes/qmake.bbclass @@ -1,57 +1,15 @@ -inherit qmake-base +inherit qmake_base -qmake_do_configure() { - case ${QMAKESPEC} in - *linux-oe-g++|*linux-uclibc-oe-g++|*linux-gnueabi-oe-g++) - ;; - *-oe-g++) - die Unsupported target ${TARGET_OS} for oe-g++ qmake spec - ;; - *) - oenote Searching for qmake spec file - paths="${QMAKE_MKSPEC_PATH}/qws/${TARGET_OS}-${TARGET_ARCH}-g++" - paths="${QMAKE_MKSPEC_PATH}/${TARGET_OS}-g++ $paths" +DEPENDS_prepend = "qmake-native " - if (echo "${TARGET_ARCH}"|grep -q 'i.86'); then - paths="${QMAKE_MKSPEC_PATH}/qws/${TARGET_OS}-x86-g++ $paths" - fi - for i in $paths; do - if test -e $i; then - export QMAKESPEC=$i - break - fi - done - ;; - esac +export QMAKESPEC +export OE_QMAKE_UIC="${STAGING_BINDIR_NATIVE}/uic" +export OE_QMAKE_MOC="${STAGING_BINDIR_NATIVE}/moc" +export OE_QMAKE_QMAKE="${STAGING_BINDIR_NATIVE}/qmake" +export OE_QMAKE_CXXFLAGS="-fno-exceptions -fno-rtti ${CXXFLAGS}" +export OE_QMAKE_LINK="${CCLD}" +export OE_QMAKE_INCDIR_QT="${QTDIR}/include" +export OE_QMAKE_LIBDIR_QT="${QTDIR}/lib" +export OE_QMAKE_LIBS_QT="qte" +export OE_QMAKE_LIBS_X11="" - oenote "using qmake spec in ${QMAKESPEC}, using profiles '${QMAKE_PROFILES}'" - - if [ -z "${QMAKE_PROFILES}" ]; then - PROFILES="`ls *.pro`" - else - PROFILES="${QMAKE_PROFILES}" - fi - - if [ -z "$PROFILES" ]; then - die "QMAKE_PROFILES not set and no profiles found in $PWD" - fi - - if [ ! -z "${EXTRA_QMAKEVARS_POST}" ]; then - AFTER="-after" - QMAKE_VARSUBST_POST="${EXTRA_QMAKEVARS_POST}" - oenote "qmake postvar substitution: ${EXTRA_QMAKEVARS_POST}" - fi - - if [ ! -z "${EXTRA_QMAKEVARS_PRE}" ]; then - QMAKE_VARSUBST_PRE="${EXTRA_QMAKEVARS_PRE}" - oenote "qmake prevar substitution: ${EXTRA_QMAKEVARS_PRE}" - fi - -#oenote "Calling '${OE_QMAKE_QMAKE} -makefile -spec ${QMAKESPEC} -o Makefile $QMAKE_VARSUBST_PRE $AFTER $PROFILES $QMAKE_VARSUBST_POST'" - unset QMAKESPEC || true - ${OE_QMAKE_QMAKE} -makefile -spec ${QMAKESPEC} -o Makefile $QMAKE_VARSUBST_PRE $AFTER $PROFILES $QMAKE_VARSUBST_POST || die "Error calling ${OE_QMAKE_QMAKE} on $PROFILES" -} - -EXPORT_FUNCTIONS do_configure - -addtask configure after do_unpack do_patch before do_compile diff --git a/classes/qmake2.bbclass b/classes/qmake2.bbclass new file mode 100644 index 0000000000..37721898d6 --- /dev/null +++ b/classes/qmake2.bbclass @@ -0,0 +1,23 @@ +# +# QMake variables for Qt4 +# +inherit qmake_base + +DEPENDS_prepend = "qt4-tools-native " + +export QMAKESPEC = "${STAGING_DATADIR}/qt4/mkspecs/${TARGET_OS}-oe-g++" +export OE_QMAKE_UIC = "${STAGING_BINDIR_NATIVE}/uic4" +export OE_QMAKE_UIC3 = "${STAGING_BINDIR_NATIVE}/uic34" +export OE_QMAKE_MOC = "${STAGING_BINDIR_NATIVE}/moc4" +export OE_QMAKE_RCC = "${STAGING_BINDIR_NATIVE}/rcc4" +export OE_QMAKE_QDBUSCPP2XML = "${STAGING_BINDIR_NATIVE}/qdbuscpp2xml4" +export OE_QMAKE_QDBUSXML2CPP = "${STAGING_BINDIR_NATIVE}/qdbusxml2cpp4" +export OE_QMAKE_QMAKE = "${STAGING_BINDIR_NATIVE}/qmake2" +export OE_QMAKE_LINK = "${CXX}" +export OE_QMAKE_CXXFLAGS = "${CXXFLAGS}" +export OE_QMAKE_INCDIR_QT = "${STAGING_INCDIR}/qt4" +export OE_QMAKE_LIBDIR_QT = "${STAGING_LIBDIR}" +export OE_QMAKE_LIBS_QT = "qt" +export OE_QMAKE_LIBS_X11 = "-lXext -lX11 -lm" +export OE_QMAKE_LRELEASE = "${STAGING_BINDIR_NATIVE}/lrelease4" +export OE_QMAKE_LUPDATE = "${STAGING_BINDIR_NATIVE}/lupdate4" diff --git a/classes/qmake_base.bbclass b/classes/qmake_base.bbclass new file mode 100644 index 0000000000..4fbe21f2e1 --- /dev/null +++ b/classes/qmake_base.bbclass @@ -0,0 +1,91 @@ + +OE_QMAKE_PLATFORM = "${TARGET_OS}-oe-g++" +QMAKESPEC := "${QMAKE_MKSPEC_PATH}/${OE_QMAKE_PLATFORM}" + +# We override this completely to eliminate the -e normally passed in +EXTRA_OEMAKE = ' MAKEFLAGS= ' + +export OE_QMAKE_CC="${CC}" +export OE_QMAKE_CFLAGS="${CFLAGS}" +export OE_QMAKE_CXX="${CXX}" +export OE_QMAKE_LDFLAGS="${LDFLAGS}" +export OE_QMAKE_AR="${AR}" +export OE_QMAKE_STRIP="echo" +export OE_QMAKE_RPATH="-Wl,-rpath-link," + +# do not export STRIP to the environment +STRIP[unexport] = "1" + +# default to qte2 via bb.conf, inherit qt3x11 to configure for qt3x11 + +oe_qmake_mkspecs () { + mkdir -p mkspecs/${OE_QMAKE_PLATFORM} + for f in ${QMAKE_MKSPEC_PATH}/${OE_QMAKE_PLATFORM}/*; do + if [ -L $f ]; then + lnk=`readlink $f` + if [ -f mkspecs/${OE_QMAKE_PLATFORM}/$lnk ]; then + ln -s $lnk mkspecs/${OE_QMAKE_PLATFORM}/`basename $f` + else + cp $f mkspecs/${OE_QMAKE_PLATFORM}/ + fi + else + cp $f mkspecs/${OE_QMAKE_PLATFORM}/ + fi + done +} + +qmake_base_do_configure() { + case ${QMAKESPEC} in + *linux-oe-g++|*linux-uclibc-oe-g++|*linux-gnueabi-oe-g++|*linux-uclibceabi-oe-g++) + ;; + *-oe-g++) + die Unsupported target ${TARGET_OS} for oe-g++ qmake spec + ;; + *) + oenote Searching for qmake spec file + paths="${QMAKE_MKSPEC_PATH}/qws/${TARGET_OS}-${TARGET_ARCH}-g++" + paths="${QMAKE_MKSPEC_PATH}/${TARGET_OS}-g++ $paths" + + if (echo "${TARGET_ARCH}"|grep -q 'i.86'); then + paths="${QMAKE_MKSPEC_PATH}/qws/${TARGET_OS}-x86-g++ $paths" + fi + for i in $paths; do + if test -e $i; then + export QMAKESPEC=$i + break + fi + done + ;; + esac + + oenote "using qmake spec in ${QMAKESPEC}, using profiles '${QMAKE_PROFILES}'" + + if [ -z "${QMAKE_PROFILES}" ]; then + PROFILES="`ls *.pro`" + else + PROFILES="${QMAKE_PROFILES}" + fi + + if [ -z "$PROFILES" ]; then + die "QMAKE_PROFILES not set and no profiles found in $PWD" + fi + + if [ ! -z "${EXTRA_QMAKEVARS_POST}" ]; then + AFTER="-after" + QMAKE_VARSUBST_POST="${EXTRA_QMAKEVARS_POST}" + oenote "qmake postvar substitution: ${EXTRA_QMAKEVARS_POST}" + fi + + if [ ! -z "${EXTRA_QMAKEVARS_PRE}" ]; then + QMAKE_VARSUBST_PRE="${EXTRA_QMAKEVARS_PRE}" + oenote "qmake prevar substitution: ${EXTRA_QMAKEVARS_PRE}" + fi + +#oenote "Calling '${OE_QMAKE_QMAKE} -makefile -spec ${QMAKESPEC} -o Makefile $QMAKE_VARSUBST_PRE $AFTER $PROFILES $QMAKE_VARSUBST_POST'" + unset QMAKESPEC || true + ${OE_QMAKE_QMAKE} -makefile -spec ${QMAKESPEC} -o Makefile $QMAKE_VARSUBST_PRE $AFTER $PROFILES $QMAKE_VARSUBST_POST || die "Error calling ${OE_QMAKE_QMAKE} on $PROFILES" +} + +EXPORT_FUNCTIONS do_configure + +addtask configure after do_unpack do_patch before do_compile diff --git a/classes/qpf.bbclass b/classes/qpf.bbclass deleted file mode 100644 index d6e58871d5..0000000000 --- a/classes/qpf.bbclass +++ /dev/null @@ -1,36 +0,0 @@ -PACKAGE_ARCH = "all" - -do_configure() { - : -} - -do_compile() { - : -} - -pkg_postinst_fonts() { -#!/bin/sh -set -e -. /etc/profile -${sbindir}/update-qtfontdir -} - -pkg_postrm_fonts() { -#!/bin/sh -set -e -. /etc/profile -${sbindir}/update-qtfontdir -f -} - -python populate_packages_prepend() { - postinst = bb.data.getVar('pkg_postinst_fonts', d, 1) - postrm = bb.data.getVar('pkg_postrm_fonts', d, 1) - fontdir = bb.data.getVar('palmtopdir', d, 1) + '/lib/fonts' - pkgregex = "^([a-z-]*_[0-9]*).*.qpf$" - pkgpattern = bb.data.getVar('QPF_PKGPATTERN', d, 1) or 'qpf-%s' - pkgdescription = bb.data.getVar('QPF_DESCRIPTION', d, 1) or 'QPF font %s' - - do_split_packages(d, root=fontdir, file_regex=pkgregex, output_pattern=pkgpattern, - description=pkgdescription, postinst=postinst, postrm=postrm, recursive=True, hook=None, - extra_depends='qpf-font-common') -} diff --git a/classes/qt3e.bbclass b/classes/qt3e.bbclass index c34d7c04f5..35958b34ab 100644 --- a/classes/qt3e.bbclass +++ b/classes/qt3e.bbclass @@ -1,10 +1,10 @@ # -# override variables set by qmake-base to compile Qt/X11 apps +# override variables set by qmake_base to compile Qt/X11 apps # -export QTDIR="${STAGING_DIR}/${HOST_SYS}/qte3" -export QTEDIR="${STAGING_DIR}/${HOST_SYS}/qte3" -export OE_QMAKE_UIC="${STAGING_BINDIR}/uic3" -export OE_QMAKE_MOC="${STAGING_BINDIR}/moc3" +export QTDIR="${STAGING_DIR_HOST}/qte3" +export QTEDIR="${STAGING_DIR_HOST}/qte3" +export OE_QMAKE_UIC="${STAGING_BINDIR_NATIVE}/uic3" +export OE_QMAKE_MOC="${STAGING_BINDIR_NATIVE}/moc3" export OE_QMAKE_CXXFLAGS="${CXXFLAGS} " export OE_QMAKE_INCDIR_QT="${QTEDIR}/include" export OE_QMAKE_LIBDIR_QT="${QTEDIR}/lib" diff --git a/classes/qt3x11.bbclass b/classes/qt3x11.bbclass index 6e3d5f8ba2..5408b7f342 100644 --- a/classes/qt3x11.bbclass +++ b/classes/qt3x11.bbclass @@ -1,15 +1,15 @@ DEPENDS_prepend = "${@["qt3x11 ", ""][(bb.data.getVar('PN', d, 1) == 'qt-x11-free')]}" EXTRA_QMAKEVARS_POST += "CONFIG+=thread" # -# override variables set by qmake-base to compile Qt/X11 apps +# override variables set by qmake_base to compile Qt/X11 apps # -export QTDIR = "${STAGING_DIR}/${HOST_SYS}/qt3" -export OE_QMAKE_UIC = "${STAGING_BINDIR}/uic3" -export OE_QMAKE_MOC = "${STAGING_BINDIR}/moc3" +export QTDIR = "${STAGING_DIR_HOST}/qt3" +export OE_QMAKE_UIC = "${STAGING_BINDIR_NATIVE}/uic3" +export OE_QMAKE_MOC = "${STAGING_BINDIR_NATIVE}/moc3" export OE_QMAKE_CXXFLAGS = "${CXXFLAGS} -DQT_NO_XIM" export OE_QMAKE_INCDIR_QT = "${QTDIR}/include" export OE_QMAKE_LIBDIR_QT = "${QTDIR}/lib" export OE_QMAKE_LIBS_QT = "qt" export OE_QMAKE_LIBS_X11 = "-lXext -lX11 -lm" - - +export OE_QMAKE_LIBS_OPENGL = "-lGLU -lGL -lXmu" +export OE_QMAKE_LIBS_OPENGL_QT = "-lGL -lXmu" diff --git a/classes/qt4e.bbclass b/classes/qt4e.bbclass new file mode 100644 index 0000000000..f72e06b6eb --- /dev/null +++ b/classes/qt4e.bbclass @@ -0,0 +1,17 @@ +DEPENDS_prepend = "${@["qt4-embedded ", ""][(bb.data.getVar('PN', d, 1) == 'qt4-embedded')]}" +inherit qmake2 + +QT_DIR_NAME = "qtopia" +QT_LIBINFIX = "E" +# override variables set by qmake-base to compile Qt/Embedded apps +# +export QMAKESPEC = "${STAGING_DATADIR}/${QT_DIR_NAME}/mkspecs/${TARGET_OS}-oe-g++" +export OE_QMAKE_INCDIR_QT = "${STAGING_INCDIR}/${QT_DIR_NAME}" +export OE_QMAKE_LIBDIR_QT = "${STAGING_LIBDIR}" +export OE_QMAKE_LIBS_QT = "qt" +export OE_QMAKE_LIBS_X11 = "" +export OE_QMAKE_EXTRA_MODULES = "network" +EXTRA_QMAKEVARS_PRE += " QT_LIBINFIX=${QT_LIBINFIX} " + +# Qt4 uses atomic instructions not supported in thumb mode +ARM_INSTRUCTION_SET = "arm" diff --git a/classes/qt4x11.bbclass b/classes/qt4x11.bbclass index 635fc67694..2d56b7e95b 100644 --- a/classes/qt4x11.bbclass +++ b/classes/qt4x11.bbclass @@ -1,17 +1,6 @@ -DEPENDS_prepend = "qmake2-native " -DEPENDS_prepend = "${@["qt4x11 ", ""][(bb.data.getVar('PN', d, 1) == 'qt4-x11-free')]}" -# -# override variables set by qmake-base to compile Qt4/X11 apps -# -export QTDIR = "${STAGING_DIR}/${HOST_SYS}/qt4" -export QMAKESPEC = "${QTDIR}/mkspecs/${TARGET_OS}-oe-g++" -export OE_QMAKE_UIC = "${STAGING_BINDIR}/uic4" -export OE_QMAKE_MOC = "${STAGING_BINDIR}/moc4" -export OE_QMAKE_RCC = "${STAGING_BINDIR}/rcc4" -export OE_QMAKE_QMAKE = "${STAGING_BINDIR}/qmake2" -export OE_QMAKE_LINK = "${CXX}" -export OE_QMAKE_CXXFLAGS = "${CXXFLAGS}" -export OE_QMAKE_INCDIR_QT = "${QTDIR}/include" -export OE_QMAKE_LIBDIR_QT = "${QTDIR}/lib" -export OE_QMAKE_LIBS_QT = "qt" -export OE_QMAKE_LIBS_X11 = "-lXext -lX11 -lm" +DEPENDS_prepend = "${@["qt4-x11-free ", ""][(bb.data.getVar('PN', d, 1)[:12] == 'qt4-x11-free')]}" + +inherit qmake2 + +# Qt4 uses atomic instructions not supported in thumb mode +ARM_INSTRUCTION_SET = "arm" diff --git a/classes/recipe_sanity.bbclass b/classes/recipe_sanity.bbclass new file mode 100644 index 0000000000..d929da6319 --- /dev/null +++ b/classes/recipe_sanity.bbclass @@ -0,0 +1,179 @@ +def __note(msg, d): + bb.note("%s: recipe_sanity: %s" % (d.getVar("P", 1), msg)) + +__recipe_sanity_badtargetvars = "RDEPENDS RPROVIDES" +def bad_target_vars(cfgdata, d): + if bb.data.inherits_class("native", d) or \ + bb.data.inherits_class("cross", d): + return + + for var in d.getVar("__recipe_sanity_badtargetvars", 1).split(): + val = d.getVar(var, 0) + if val and val != cfgdata.get(var): + __note("%s should not be set, but is set to '%s'" % (var, val), d) + +__recipe_sanity_reqvars = "DESCRIPTION" +__recipe_sanity_reqdiffvars = "LICENSE" +def req_vars(cfgdata, d): + for var in d.getVar("__recipe_sanity_reqvars", 1).split(): + if not d.getVar(var, 0): + __note("%s should be set" % var, d) + + for var in d.getVar("__recipe_sanity_reqdiffvars", 1).split(): + val = d.getVar(var, 0) + cfgval = cfgdata.get(var) + + # Hardcoding is bad, but I'm lazy. We don't care about license being + # unset if the recipe has no sources! + if var == "LICENSE" and d.getVar("SRC_URI", 1) == cfgdata.get("SRC_URI"): + continue + + if not val: + __note("%s should be set" % var, d) + elif val == cfgval: + __note("%s should be defined to something other than default (%s)" % (var, cfgval), d) + +def var_renames_overwrite(cfgdata, d): + renames = d.getVar("__recipe_sanity_renames", 0) + if renames: + for (key, newkey, oldvalue, newvalue) in renames: + if oldvalue != newvalue and oldvalue != cfgdata.get(newkey): + __note("rename of variable '%s' to '%s' overwrote existing value '%s' with '%s'." % (key, newkey, oldvalue, newvalue), d) + +def incorrect_nonempty_PACKAGES(cfgdata, d): + if bb.data.inherits_class("native", d) or \ + bb.data.inherits_class("cross", d): + if d.getVar("PACKAGES", 1): + return True + +def can_use_autotools_base(cfgdata, d): + cfg = d.getVar("do_configure", 1) + if not bb.data.inherits_class("autotools", d): + return False + + for i in ["autoreconf"] + ["%s_do_configure" % cls for cls in ["gnome", "e", "autotools", "autotools_stage", "efl", "gpephone", "openmoko", "openmoko2", "xfce", "xlibs"]]: + if cfg.find(i) != -1: + return False + + import os + for clsfile in d.getVar("__inherit_cache", 0): + (base, _) = os.path.splitext(os.path.basename(clsfile)) + if cfg.find("%s_do_configure" % base) != -1: + __note("autotools_base usage needs verification, spotted %s_do_configure" % base, d) + + return True + +def can_remove_FILESPATH(cfgdata, d): + expected = cfgdata.get("FILESPATH") + #expected = "${@':'.join([os.path.normpath(os.path.join(fp, p, o)) for fp in d.getVar('FILESPATHBASE', 1).split(':') for p in d.getVar('FILESPATHPKG', 1).split(':') for o in (d.getVar('OVERRIDES', 1) + ':').split(':') if os.path.exists(os.path.join(fp, p, o))])}:${FILESDIR}" + expectedpaths = bb.data.expand(expected, d) + unexpanded = d.getVar("FILESPATH", 0) + filespath = d.getVar("FILESPATH", 1).split(":") + filespath = [os.path.normpath(f) for f in filespath if os.path.exists(f)] + for fp in filespath: + if not fp in expectedpaths: + # __note("Path %s in FILESPATH not in the expected paths %s" % + # (fp, expectedpaths), d) + return False + return expected != unexpanded + +def can_remove_FILESDIR(cfgdata, d): + expected = cfgdata.get("FILESDIR") + #expected = "${@bb.which(d.getVar('FILESPATH', 1), '.')}" + unexpanded = d.getVar("FILESDIR", 0) + if unexpanded is None: + return False + + expanded = os.path.normpath(d.getVar("FILESDIR", 1)) + filespath = d.getVar("FILESPATH", 1).split(":") + filespath = [os.path.normpath(f) for f in filespath if os.path.exists(f)] + + return unexpanded != expected and \ + os.path.exists(expanded) and \ + (expanded in filespath or + expanded == bb.data.expand(expected, d)) + +def can_remove_others(p, cfgdata, d): + for k in ["S", "PV", "PN", "DESCRIPTION", "LICENSE", "DEPENDS", + "SECTION", "PACKAGES", "EXTRA_OECONF", "EXTRA_OEMAKE"]: + #for k in cfgdata: + unexpanded = d.getVar(k, 0) + cfgunexpanded = cfgdata.get(k) + if not cfgunexpanded: + continue + + try: + expanded = d.getVar(k, 1) + cfgexpanded = bb.data.expand(cfgunexpanded, d) + except bb.fetch.ParameterError: + continue + + if unexpanded != cfgunexpanded and \ + cfgexpanded == expanded: + __note("candidate for removal of %s" % k, d) + bb.debug(1, "%s: recipe_sanity: cfg's '%s' and d's '%s' both expand to %s" % + (p, cfgunexpanded, unexpanded, expanded)) + +python do_recipe_sanity () { + p = d.getVar("P", 1) + p = "%s %s %s" % (d.getVar("PN", 1), d.getVar("PV", 1), d.getVar("PR", 1)) + + sanitychecks = [ + (can_remove_FILESDIR, "candidate for removal of FILESDIR"), + (can_remove_FILESPATH, "candidate for removal of FILESPATH"), + #(can_use_autotools_base, "candidate for use of autotools_base"), + (incorrect_nonempty_PACKAGES, "native or cross recipe with non-empty PACKAGES"), + ] + cfgdata = d.getVar("__recipe_sanity_cfgdata", 0) + + for (func, msg) in sanitychecks: + if func(cfgdata, d): + __note(msg, d) + + can_remove_others(p, cfgdata, d) + var_renames_overwrite(cfgdata, d) + req_vars(cfgdata, d) + bad_target_vars(cfgdata, d) +} +do_recipe_sanity[nostamp] = "1" +#do_recipe_sanity[recrdeptask] = "do_recipe_sanity" +addtask recipe_sanity + +do_recipe_sanity_all[nostamp] = "1" +do_recipe_sanity_all[recrdeptask] = "do_recipe_sanity" +do_recipe_sanity_all () { + : +} +addtask recipe_sanity_all after do_recipe_sanity + +python recipe_sanity_eh () { + from bb.event import getName + + if getName(e) != "ConfigParsed": + return NotHandled + + d = e.data + + cfgdata = {} + for k in d.keys(): + #for k in ["S", "PR", "PV", "PN", "DESCRIPTION", "LICENSE", "DEPENDS", + # "SECTION"]: + cfgdata[k] = d.getVar(k, 0) + + d.setVar("__recipe_sanity_cfgdata", cfgdata) + #d.setVar("__recipe_sanity_cfgdata", d) + + # Sick, very sick.. + from bb.data_smart import DataSmart + old = DataSmart.renameVar + def myrename(self, key, newkey): + oldvalue = self.getVar(newkey, 0) + old(self, key, newkey) + newvalue = self.getVar(newkey, 0) + if oldvalue: + renames = self.getVar("__recipe_sanity_renames", 0) or set() + renames.add((key, newkey, oldvalue, newvalue)) + self.setVar("__recipe_sanity_renames", renames) + DataSmart.renameVar = myrename +} +addhandler recipe_sanity_eh diff --git a/classes/rm_work.bbclass b/classes/rm_work.bbclass index 7f590e1b15..a53d12baf3 100644 --- a/classes/rm_work.bbclass +++ b/classes/rm_work.bbclass @@ -6,17 +6,45 @@ # INHERIT += "rm_work" # +# Use the completion scheulder by default when rm_work is active +# to try and reduce disk usage +BB_SCHEDULER ?= "completion" + +RMWORK_ORIG_TASK := "${BB_DEFAULT_TASK}" +BB_DEFAULT_TASK = "rm_work_all" + do_rm_work () { cd ${WORKDIR} for dir in * do - if [ `basename ${S}` == $dir ]; then - rm -rf $dir/* - elif [ $dir != 'temp' ]; then - rm -rf $dir + if [ `basename ${dir}` = "temp" ]; then + echo "Not removing temp" + else + echo "Removing $dir" ; rm $dir -rf fi done } +addtask rm_work after do_${RMWORK_ORIG_TASK} + +do_rm_work_all () { + : +} +do_rm_work_all[recrdeptask] = "do_rm_work" +addtask rm_work_all after do_rm_work + + +addhandler rmwork_stampfixing_eventhandler +python rmwork_stampfixing_eventhandler() { + if bb.event.getName(e) == "StampUpdate": + for (fn, task) in e.targets: + if task == 'rm_work_all': + continue + stamp = "%s.do_rm_work" % e.stampPrefix[fn] + if os.path.exists(stamp): + dir = "%s.*" % e.stampPrefix[fn] + bb.note("Removing stamps: " + dir) + os.system('rm -f '+ dir) + + return NotHandled +} -addtask rm_work before do_build -addtask rm_work after do_populate_staging diff --git a/classes/rootfs_deb.bbclass b/classes/rootfs_deb.bbclass new file mode 100644 index 0000000000..dc2b2cb02c --- /dev/null +++ b/classes/rootfs_deb.bbclass @@ -0,0 +1,162 @@ +# +# Copyright 2006-2007 Openedhand Ltd. +# +ROOTFS_PKGMANAGE = "run-postinsts dpkg" +ROOTFS_PKGMANAGE_BOOTSTRAP = "run-postinsts" + +do_rootfs[depends] += "dpkg-native:do_populate_staging apt-native:do_populate_staging" +do_rootfs[recrdeptask] += "do_package_write_deb" + +fakeroot rootfs_deb_do_rootfs () { + set +e + mkdir -p ${IMAGE_ROOTFS}/var/dpkg/info + mkdir -p ${IMAGE_ROOTFS}/var/dpkg/updates + + rm -f ${STAGING_ETCDIR_NATIVE}/apt/sources.list.rev + rm -f ${STAGING_ETCDIR_NATIVE}/apt/preferences + > ${IMAGE_ROOTFS}/var/dpkg/status + > ${IMAGE_ROOTFS}/var/dpkg/available + mkdir -p ${IMAGE_ROOTFS}/var/dpkg/alternatives + + priority=1 + for arch in ${PACKAGE_ARCHS}; do + if [ ! -d ${DEPLOY_DIR_DEB}/$arch ]; then + continue; + fi + cd ${DEPLOY_DIR_DEB}/$arch + rm -f Packages.gz Packages Packages.bz2 + + # apt-native ignores Packages.bz2 unless /bin/bzip2 exists + # on the build host, so stick with gzip + dpkg-scanpackages . | gzip > Packages.gz + + echo "Label: $arch" > Release + + echo "deb file:${DEPLOY_DIR_DEB}/$arch/ ./" >> ${STAGING_ETCDIR_NATIVE}/apt/sources.list.rev + (echo "Package: *" + echo "Pin: release l=$arch" + echo "Pin-Priority: $((800 + $priority))" + echo) >> ${STAGING_ETCDIR_NATIVE}/apt/preferences + priority=$(expr $priority + 5) + done + + tac ${STAGING_ETCDIR_NATIVE}/apt/sources.list.rev > ${STAGING_ETCDIR_NATIVE}/apt/sources.list + + cat "${STAGING_ETCDIR_NATIVE}/apt/apt.conf.sample" \ + | sed -e 's#Architecture ".*";#Architecture "${DPKG_ARCH}";#' \ + | sed -e 's#status ".*";#status "${IMAGE_ROOTFS}/var/dpkg/status";#' \ + | sed -e 's#DPkg::Options {".*"};#DPkg::Options {"--root=${IMAGE_ROOTFS}";"--admindir=${IMAGE_ROOTFS}/var/dpkg";"--force-all";"--no-debsig"};#' \ + > "${STAGING_ETCDIR_NATIVE}/apt/apt-rootfs.conf" + + export APT_CONFIG="${STAGING_ETCDIR_NATIVE}/apt/apt-rootfs.conf" + export D=${IMAGE_ROOTFS} + export OFFLINE_ROOT=${IMAGE_ROOTFS} + export IPKG_OFFLINE_ROOT=${IMAGE_ROOTFS} + export OPKG_OFFLINE_ROOT=${IMAGE_ROOTFS} + + apt-get update + + _flag () { + sed -i -e "/^Package: $2\$/{n; s/Status: install ok .*/Status: install ok $1/;}" ${IMAGE_ROOTFS}/var/dpkg/status + } + _getflag () { + cat ${IMAGE_ROOTFS}/var/dpkg/status | sed -n -e "/^Package: $2\$/{n; s/Status: install ok .*/$1/; p}" + } + + if [ x${TARGET_OS} = "xlinux" ] || [ x${TARGET_OS} = "xlinux-gnueabi" ] ; then + if [ ! -z "${LINGUAS_INSTALL}" ]; then + apt-get install glibc-localedata-i18n --force-yes --allow-unauthenticated + if [ $? -ne 0 ]; then + exit 1 + fi + for i in ${LINGUAS_INSTALL}; do + apt-get install $i --force-yes --allow-unauthenticated + if [ $? -ne 0 ]; then + exit 1 + fi + done + fi + fi + + if [ ! -z "${PACKAGE_INSTALL}" ]; then + for i in ${PACKAGE_INSTALL}; do + apt-get install $i --force-yes --allow-unauthenticated + if [ $? -ne 0 ]; then + exit 1 + fi + done + fi + + rm ${WORKDIR}/temp/log.do_$target-attemptonly.${PID} + if [ ! -z "${PACKAGE_INSTALL_ATTEMPTONLY}" ]; then + for i in ${PACKAGE_INSTALL_ATTEMPTONLY}; do + apt-get install $i --force-yes --allow-unauthenticated >> ${WORKDIR}/temp/log.do_rootfs-attemptonly.${PID} || true + done + fi + + find ${IMAGE_ROOTFS} -name \*.dpkg-new | for i in `cat`; do + mv $i `echo $i | sed -e's,\.dpkg-new$,,'` + done + + install -d ${IMAGE_ROOTFS}/${sysconfdir} + echo ${BUILDNAME} > ${IMAGE_ROOTFS}/${sysconfdir}/version + + # Mark all packages installed + sed -i -e "s/Status: install ok unpacked/Status: install ok installed/;" ${IMAGE_ROOTFS}/var/dpkg/status + + # Attempt to run preinsts + # Mark packages with preinst failures as unpacked + for i in ${IMAGE_ROOTFS}/var/dpkg/info/*.preinst; do + if [ -f $i ] && ! sh $i; then + _flag unpacked `basename $i .preinst` + fi + done + + # Attempt to run postinsts + # Mark packages with postinst failures as unpacked + for i in ${IMAGE_ROOTFS}/var/dpkg/info/*.postinst; do + if [ -f $i ] && ! sh $i configure; then + _flag unpacked `basename $i .postinst` + fi + done + + set -e + + # Hacks to allow opkg's update-alternatives and opkg to coexist for now + mkdir -p ${IMAGE_ROOTFS}${libdir}/opkg + if [ -e ${IMAGE_ROOTFS}/var/dpkg/alternatives ]; then + rmdir ${IMAGE_ROOTFS}/var/dpkg/alternatives + fi + ln -s ${libdir}/opkg/alternatives ${IMAGE_ROOTFS}/var/dpkg/alternatives + ln -s /var/dpkg/info ${IMAGE_ROOTFS}${libdir}/opkg/info + ln -s /var/dpkg/status ${IMAGE_ROOTFS}${libdir}/opkg/status + + ${ROOTFS_POSTPROCESS_COMMAND} + + log_check rootfs +} + +rootfs_deb_log_check() { + target="$1" + lf_path="$2" + + lf_txt="`cat $lf_path`" + for keyword_die in "E:" + do + if (echo "$lf_txt" | grep -v log_check | grep "$keyword_die") >/dev/null 2>&1 + then + echo "log_check: There were error messages in the logfile" + echo -e "log_check: Matched keyword: [$keyword_die]\n" + echo "$lf_txt" | grep -v log_check | grep -C 5 -i "$keyword_die" + echo "" + do_exit=1 + fi + done + test "$do_exit" = 1 && exit 1 + true +} + +remove_packaging_data_files() { + rm -rf ${IMAGE_ROOTFS}${libdir}/opkg/ + rm -rf ${IMAGE_ROOTFS}/usr/dpkg/ +} diff --git a/classes/rootfs_ipk.bbclass b/classes/rootfs_ipk.bbclass index 9d8e54fa8c..16dd511fcb 100644 --- a/classes/rootfs_ipk.bbclass +++ b/classes/rootfs_ipk.bbclass @@ -2,153 +2,127 @@ # Creates a root filesystem out of IPKs # # This rootfs can be mounted via root-nfs or it can be put into an cramfs/jffs etc. -# See image_ipk.oeclass for a usage of this. +# See image.bbclass for a usage of this. # -DEPENDS_prepend="ipkg-native ipkg-utils-native fakeroot-native " -DEPENDS_append=" ${EXTRA_IMAGEDEPENDS}" -RDEPENDS += "ipkg ipkg-link ipkg-collateral" +do_rootfs[depends] += "opkg-native:do_populate_staging" -PACKAGES = "" +IPKG_ARGS = "-f ${IPKGCONF_TARGET} -o ${IMAGE_ROOTFS} ${@base_conditional("PACKAGE_INSTALL_NO_DEPS", "1", "-nodeps", "", d)}" -do_rootfs[nostamp] = 1 -do_rootfs[dirs] = ${TOPDIR} -do_build[nostamp] = 1 +PACKAGE_INSTALL_NO_DEPS ?= "0" -IPKG_ARGS = "-f ${T}/ipkg.conf -o ${IMAGE_ROOTFS}" +# What support to provide for online management of packages at run time? +# full -> traditional system, opkg is installed with all metadata +# add -> opkg is installed with basic conf files but no status database; can add new packages at runtime but not modify existing ones +# none -> opkg not installed at all, no metadata or config files provided +ONLINE_PACKAGE_MANAGEMENT ?= "full" -IPKG_INSTALL += "ipkg ipkg-link ipkg-collateral" +# Which packages to not install on the basis of a recommendation +BAD_RECOMMENDATIONS ?= "" -ROOTFS_POSTPROCESS_COMMAND ?= "" +IPKG_VARIANT ?= "opkg" -PID = "${@os.getpid()}" +RDEPENDS_append = " ${@base_conditional("ONLINE_PACKAGE_MANAGEMENT", "none", "", "${IPKG_VARIANT} opkg-collateral", d)}" +PACKAGE_INSTALL_append = " ${@base_conditional("ONLINE_PACKAGE_MANAGEMENT", "none", "", "${IPKG_VARIANT} opkg-collateral", d)}" -# some default locales -IMAGE_LINGUAS ?= "de-de fr-fr en-gb" - -LINGUAS_INSTALL = "${@" ".join(map(lambda s: "locale-base-%s" % s, bb.data.getVar('IMAGE_LINGUAS', d, 1).split()))}" - -real_do_rootfs () { +fakeroot rootfs_ipk_do_rootfs () { set -x - - mkdir -p ${IMAGE_ROOTFS}/dev - if [ -z "${DEPLOY_KEEP_PACKAGES}" ]; then - touch ${DEPLOY_DIR_IPK}/Packages - ipkg-make-index -r ${DEPLOY_DIR_IPK}/Packages -p ${DEPLOY_DIR_IPK}/Packages -l ${DEPLOY_DIR_IPK}/Packages.filelist -m ${DEPLOY_DIR_IPK} - fi + package_generate_ipkg_conf + mkdir -p ${T} - echo "src oe file:${DEPLOY_DIR_IPK}" > ${T}/ipkg.conf - ipkgarchs="${IPKG_ARCHS}" - priority=1 - for arch in $ipkgarchs; do - echo "arch $arch $priority" >> ${T}/ipkg.conf - priority=$(expr $priority + 5) + mkdir -p ${IMAGE_ROOTFS}${libdir}/opkg/ + + STATUS=${IMAGE_ROOTFS}${libdir}/opkg/status + # prime the status file with bits that we don't want + for i in ${BAD_RECOMMENDATIONS}; do + echo "Package: $i" >> $STATUS + echo "Architecture: ${TARGET_ARCH}" >> $STATUS + echo "Status: deinstall ok not-installed" >> $STATUS + echo >> $STATUS done - ipkg-cl ${IPKG_ARGS} update - if [ ! -z "${LINGUAS_INSTALL}" ]; then - ipkg-cl ${IPKG_ARGS} install glibc-localedata-i18n - for i in ${LINGUAS_INSTALL}; do - ipkg-cl ${IPKG_ARGS} install $i - done + + opkg-cl ${IPKG_ARGS} update + + # Uclibc builds don't provide this stuff... + if [ x${TARGET_OS} = "xlinux" ] || [ x${TARGET_OS} = "xlinux-gnueabi" ] ; then + if [ ! -z "${LINGUAS_INSTALL}" ]; then + opkg-cl ${IPKG_ARGS} install glibc-localedata-i18n + for i in ${LINGUAS_INSTALL}; do + opkg-cl ${IPKG_ARGS} install $i + done + fi fi - if [ ! -z "${IPKG_INSTALL}" ]; then - ipkg-cl ${IPKG_ARGS} install ${IPKG_INSTALL} + if [ ! -z "${PACKAGE_INSTALL}" ]; then + opkg-cl ${IPKG_ARGS} install ${PACKAGE_INSTALL} fi export D=${IMAGE_ROOTFS} + export OFFLINE_ROOT=${IMAGE_ROOTFS} export IPKG_OFFLINE_ROOT=${IMAGE_ROOTFS} - mkdir -p ${IMAGE_ROOTFS}/etc/ipkg/ - grep "^arch" ${T}/ipkg.conf >${IMAGE_ROOTFS}/etc/ipkg/arch.conf + export OPKG_OFFLINE_ROOT=${IPKG_OFFLINE_ROOT} + + if [ "${ONLINE_PACKAGE_MANAGEMENT}" != "none" ]; then + mkdir -p ${IMAGE_ROOTFS}${sysconfdir}/opkg/ + grep "^arch" ${IPKGCONF_TARGET} >${IMAGE_ROOTFS}${sysconfdir}/opkg/arch.conf + fi - for i in ${IMAGE_ROOTFS}${libdir}/ipkg/info/*.preinst; do + for i in ${IMAGE_ROOTFS}${libdir}/opkg/info/*.preinst; do if [ -f $i ] && ! sh $i; then - ipkg-cl ${IPKG_ARGS} flag unpacked `basename $i .preinst` + opkg-cl ${IPKG_ARGS} flag unpacked `basename $i .preinst` fi done - for i in ${IMAGE_ROOTFS}${libdir}/ipkg/info/*.postinst; do + for i in ${IMAGE_ROOTFS}${libdir}/opkg/info/*.postinst; do if [ -f $i ] && ! sh $i configure; then - ipkg-cl ${IPKG_ARGS} flag unpacked `basename $i .postinst` + opkg-cl ${IPKG_ARGS} flag unpacked `basename $i .postinst` fi done install -d ${IMAGE_ROOTFS}/${sysconfdir} echo ${BUILDNAME} > ${IMAGE_ROOTFS}/${sysconfdir}/version + if [ "${ONLINE_PACKAGE_MANAGEMENT}" != "none" ]; then + if [ "${ONLINE_PACKAGE_MANAGEMENT}" == "add" ]; then + rm -f ${IMAGE_ROOTFS}${libdir}/opkg/status + rm -f ${IMAGE_ROOTFS}${libdir}/opkg/*/* + else + rm -f ${IMAGE_ROOTFS}${libdir}/opkg/lists/* + fi + + # Keep these lines until package manager selection is implemented + ln -s opkg ${IMAGE_ROOTFS}${sysconfdir}/ipkg + ln -s opkg ${IMAGE_ROOTFS}${libdir}/ipkg + else + rm -rf ${IMAGE_ROOTFS}${libdir}/opkg + rm -rf ${IMAGE_ROOTFS}/usr/lib/opkg + fi + ${ROOTFS_POSTPROCESS_COMMAND} log_check rootfs } -log_check() { - set +x - for target in $* - do - lf_path="${WORKDIR}/temp/log.do_$target.${PID}" - - echo "log_check: Using $lf_path as logfile" - - if test -e "$lf_path" +rootfs_ipk_log_check() { + target="$1" + lf_path="$2" + + lf_txt="`cat $lf_path`" + for keyword_die in "Cannot find package" "Cannot satisfy the following dependencies" \ + "exit 1" ERR Fail + do + if (echo "$lf_txt" | grep -v log_check | grep -w "$keyword_die") >/dev/null 2>&1 then - lf_txt="`cat $lf_path`" - - for keyword_die in "Cannot find package" "exit 1" ERR Fail - do - - if (echo "$lf_txt" | grep -v log_check | grep "$keyword_die") &>/dev/null - then - echo "log_check: There were error messages in the logfile" - echo -e "log_check: Matched keyword: [$keyword_die]\n" - echo "$lf_txt" | grep -v log_check | grep -i "$keyword_die" -C1 - echo "" - do_exit=1 - fi - done - test "$do_exit" = 1 && exit 1 - else - echo "Cannot find logfile [$lf_path]" + echo "log_check: There were error messages in the logfile" + printf "log_check: Matched keyword: [$keyword_die]\n" + echo "$lf_txt" | grep -v log_check | grep -i "$keyword_die" -C1 + echo "" + do_exit=1 fi - echo "Logfile is clean" done - - set -x - -} - -fakeroot do_rootfs () { - rm -rf ${IMAGE_ROOTFS} - real_do_rootfs -} - -# set '*' as the rootpassword so the images -# can decide if they want it or not - -zap_root_password () { - sed 's%^root:[^:]*:%root:*:%' < ${IMAGE_ROOTFS}/etc/passwd >${IMAGE_ROOTFS}/etc/passwd.new - mv ${IMAGE_ROOTFS}/etc/passwd.new ${IMAGE_ROOTFS}/etc/passwd -} - -create_etc_timestamp() { - date +%2m%2d%2H%2M%Y >${IMAGE_ROOTFS}/etc/timestamp -} - -# Turn any symbolic /sbin/init link into a file -remove_init_link () { - if [ -h ${IMAGE_ROOTFS}/sbin/init ]; then - LINKFILE=${IMAGE_ROOTFS}`readlink ${IMAGE_ROOTFS}/sbin/init` - rm ${IMAGE_ROOTFS}/sbin/init - cp $LINKFILE ${IMAGE_ROOTFS}/sbin/init - fi + test "$do_exit" = 1 && exit 1 + true } -make_zimage_symlink_relative () { - if [ -L ${IMAGE_ROOTFS}/boot/zImage ]; then - (cd ${IMAGE_ROOTFS}/boot/ && for i in `ls zImage-* | sort`; do ln -sf $i zImage; done) - fi +remove_packaging_data_files() { + rm -rf ${IMAGE_ROOTFS}${libdir}/opkg/ } - -# export the zap_root_password, create_etc_timestamp and remote_init_link -EXPORT_FUNCTIONS zap_root_password create_etc_timestamp remove_init_link make_zimage_symlink_relative - - -addtask rootfs before do_build after do_install diff --git a/classes/rootfs_rpm.bbclass b/classes/rootfs_rpm.bbclass new file mode 100644 index 0000000000..e3e306450e --- /dev/null +++ b/classes/rootfs_rpm.bbclass @@ -0,0 +1,210 @@ +# +# Creates a root filesystem out of rpm packages +# + +ROOTFS_PKGMANAGE = "rpm yum" + +ROOTFS_PKGMANAGE_BOOTSTRAP = "run-postinsts" + +do_rootfs[depends] += "rpm-native:do_populate_staging yum-native:do_populate_staging createrepo-native:do_populate_staging fakechroot-native:do_populate_staging" +do_rootfs[recrdeptask] += "do_package_write_rpm" + +YUMCONF = "${IMAGE_ROOTFS}/etc/yum.conf" +YUMARGS = "-c ${YUMCONF} --installroot ${IMAGE_ROOTFS}" +export YUM_ARCH_FORCE = "${TARGET_ARCH}" + +AWKPOSTINSTSCRIPT = "${STAGING_BINDIR_NATIVE}/extract-postinst.awk" + +RPM_PREPROCESS_COMMANDS = "" +RPM_POSTPROCESS_COMMANDS = "rpm_insert_feeds_uris" + +rpm_insert_feeds_uris () { + + echo "Building from feeds activated!" + + mkdir -p ${IMAGE_ROOTFS}/etc/yum/repos.d/ + for line in ${RPM_FEED_URIS} + do + # strip leading and trailing spaces/tabs, then split into name and uri + line_clean="`echo "$line"|sed 's/^[ \t]*//;s/[ \t]*$//'`" + feed_name="`echo "$line_clean" | sed -n 's/\(.*\)##\(.*\)/\1/p'`" + feed_uri="`echo "$line_clean" | sed -n 's/\(.*\)##\(.*\)/\2/p'`" + + echo "Added $feed_name feed with URL $feed_uri" + + FEED_FILE=${IMAGE_ROOTFS}/etc/yum/repos.d/$feed_name + + echo "[${DISTRO}-feed-$feed_name]" >> $FEED_FILE + echo "name = $feed_name" >> $FEED_FILE + echo "baseurl = $feed_uri" >> $FEED_FILE + echo "gpgcheck = 0" >> $FEED_FILE + done +} + +fakeroot rootfs_rpm_do_rootfs () { + set -x + + ${RPM_PREPROCESS_COMMANDS} + + mkdir -p ${IMAGE_ROOTFS}/etc/rpm/ + echo "${TARGET_ARCH}-linux" >${IMAGE_ROOTFS}/etc/rpm/platform + + # Generate an apprpriate yum.conf + rm -rf ${YUMCONF} + cat > ${YUMCONF} << EOF +[main] +cachedir=/var/cache2/yum +keepcache=1 +debuglevel=10 +logfile=/var/log2/yum.log +exactarch=0 +obsoletes=1 +tolerant=1 + +EOF + + #priority=1 + mkdir -p ${IMAGE_ROOTFS}${DEPLOY_DIR_RPM} + + for arch in ${PACKAGE_ARCHS}; do + if [ ! -d ${DEPLOY_DIR_RPM}/$arch ]; then + continue; + fi + createrepo ${DEPLOY_DIR_RPM}/$arch + + echo "[${DISTRO}-feed-$arch]" >> ${YUMCONF} + echo "name = ${DISTRO} RPM $arch Feed" >> ${YUMCONF} + echo "baseurl=file://${DEPLOY_DIR_RPM}/$arch" >> ${YUMCONF} + echo "gpgcheck=0" >> ${YUMCONF} + echo "" >> ${YUMCONF} + #priority=$(expr $priority + 5) + + # Copy the packages into the target image + # Ugly ugly ugly but rpm is braindead and can't see outside the chroot + # when installing :( + cp -r ${DEPLOY_DIR_RPM}/$arch ${IMAGE_ROOTFS}${DEPLOY_DIR_RPM}/ + done + + # Uclibc builds don't provide this stuff... + if [ x${TARGET_OS} = "xlinux" ] || [ x${TARGET_OS} = "xlinux-gnueabi" ] ; then + if [ ! -z "${LINGUAS_INSTALL}" ]; then + for i in ${LINGUAS_INSTALL}; do + fakechroot yum ${YUMARGS} -y install $i + done + fi + fi + if [ ! -z "${PACKAGE_INSTALL}" ]; then + fakechroot yum ${YUMARGS} -y install ${PACKAGE_INSTALL} + fi + + # Add any recommended packages to the image + # (added as an extra script since yum itself doesn't support this) + yum-install-recommends.py ${IMAGE_ROOTFS} "fakechroot yum ${YUMARGS} -y install" + + # Symlinks created under fakeroot are wrong, now we have to fix them... + cd ${IMAGE_ROOTFS} + for f in `find . -type l -print` + do + link=`readlink $f | sed -e 's#${IMAGE_ROOTFS}##'` + rm $f + ln -s $link $f + done + + export D=${IMAGE_ROOTFS} + export OFFLINE_ROOT=${IMAGE_ROOTFS} + export IPKG_OFFLINE_ROOT=${IMAGE_ROOTFS} + export OPKG_OFFLINE_ROOT=${IMAGE_ROOTFS} + + ${ROOTFS_POSTINSTALL_COMMAND} + + mkdir -p ${IMAGE_ROOTFS}/etc/rpm-postinsts/ + rpm --root ${IMAGE_ROOTFS} -aq --queryformat 'Name: %{NAME}\n' --scripts > ${IMAGE_ROOTFS}/etc/rpm-postinsts/combined + awk -f ${AWKPOSTINSTSCRIPT} < ${IMAGE_ROOTFS}/etc/rpm-postinsts/combined + rm ${IMAGE_ROOTFS}/etc/rpm-postinsts/combined + + for i in ${IMAGE_ROOTFS}/etc/rpm-postinsts/*.sh; do + if [ -f $i ] && sh $i; then + # rm $i + mv $i $i.done + fi + done + + install -d ${IMAGE_ROOTFS}/${sysconfdir}/rcS.d + # Stop $i getting expanded below... + i=\$i + cat > ${IMAGE_ROOTFS}${sysconfdir}/rcS.d/S98configure << EOF +#!/bin/sh +for i in /etc/rpm-postinsts/*.sh; do + echo "Running postinst $i..." + if [ -f $i ] && sh $i; then + # rm $i + mv $i $i.done + else + echo "ERROR: postinst $i failed." + fi +done +rm -f ${sysconfdir}/rcS.d/S98configure +EOF + chmod 0755 ${IMAGE_ROOTFS}${sysconfdir}/rcS.d/S98configure + + install -d ${IMAGE_ROOTFS}/${sysconfdir} + echo ${BUILDNAME} > ${IMAGE_ROOTFS}/${sysconfdir}/version + + ${RPM_POSTPROCESS_COMMANDS} + ${ROOTFS_POSTPROCESS_COMMAND} + + rm -rf ${IMAGE_ROOTFS}/var/cache2/ + rm -rf ${IMAGE_ROOTFS}/var/run2/ + rm -rf ${IMAGE_ROOTFS}/var/log2/ + rm -rf ${IMAGE_ROOTFS}${DEPLOY_DIR_RPM}/ + + # remove lock files + rm -f ${IMAGE_ROOTFS}/var/lib/rpm/__db.* + + # remove no longer used yum.conf + rm -f ${IMAGE_ROOTFS}/etc/yum.conf + + log_check rootfs +} + +rootfs_rpm_log_check() { + target="$1" + lf_path="$2" + + lf_txt="`cat $lf_path`" + for keyword_die in "Cannot find package" "exit 1" ERR Fail + do + if (echo "$lf_txt" | grep -v log_check | grep "$keyword_die") >/dev/null 2>&1 + then + echo "log_check: There were error messages in the logfile" + echo -e "log_check: Matched keyword: [$keyword_die]\n" + echo "$lf_txt" | grep -v log_check | grep -C 5 -i "$keyword_die" + echo "" + do_exit=1 + fi + done + test "$do_exit" = 1 && exit + true +} + +remove_packaging_data_files() { +# empty for now + : +} + +install_all_locales() { +# empty for now + : +} + +python () { + import bb + if bb.data.getVar('BUILD_IMAGES_FROM_FEEDS', d, True): + flags = bb.data.getVarFlag('do_rootfs', 'recrdeptask', d) + flags = flags.replace("do_package_write_rpm", "") + flags = flags.replace("do_deploy", "") + flags = flags.replace("do_populate_staging", "") + bb.data.setVarFlag('do_rootfs', 'recrdeptask', flags, d) + bb.data.setVar('RPM_PREPROCESS_COMMANDS', "rpm_insert_feed_uris", d) + bb.data.setVar('RPM_POSTPROCESS_COMMANDS', '', d) +} diff --git a/classes/rpm_core.bbclass b/classes/rpm_core.bbclass deleted file mode 100644 index f28abbb1c3..0000000000 --- a/classes/rpm_core.bbclass +++ /dev/null @@ -1,16 +0,0 @@ -RPMBUILDPATH="${WORKDIR}/rpm" - -RPMOPTS="--rcfile=${WORKDIR}/rpmrc" -RPMOPTS="--rcfile=${WORKDIR}/rpmrc --target ${TARGET_SYS}" -RPM="rpm ${RPMOPTS}" -RPMBUILD="rpmbuild --buildroot ${D} --short-circuit ${RPMOPTS}" - -rpm_core_do_preprpm() { - mkdir -p ${RPMBUILDPATH}/{SPECS,RPMS/{i386,i586,i686,noarch,ppc,mips,mipsel,arm},SRPMS,SOURCES,BUILD} - echo 'macrofiles:/usr/lib/rpm/macros:${WORKDIR}/macros' > ${WORKDIR}/rpmrc - echo '%_topdir ${RPMBUILDPATH}' > ${WORKDIR}/macros - echo '%_repackage_dir ${WORKDIR}' >> ${WORKDIR}/macros -} - -EXPORT_FUNCTIONS do_preprpm -addtask preprpm before do_fetch diff --git a/classes/rubyextension.bbclass b/classes/rubyextension.bbclass index 9c9d66e260..628ebdb7c7 100644 --- a/classes/rubyextension.bbclass +++ b/classes/rubyextension.bbclass @@ -2,17 +2,17 @@ DEPENDS += "ruby-native" RDEPENDS += "ruby" rubyextension_do_configure() { - ${STAGING_BINDIR}/ruby setup.rb config || \ + ${STAGING_BINDIR_NATIVE}/ruby setup.rb config || \ oefatal "ruby setup.rb config stage failed." } rubyextension_do_compile() { - ${STAGING_BINDIR}/ruby setup.rb setup || \ + ${STAGING_BINDIR_NATIVE}/ruby setup.rb setup || \ oefatal "ruby setup.rb setup stage failed." } rubyextension_do_install() { - ${STAGING_BINDIR}/ruby setup.rb install || \ + ${STAGING_BINDIR_NATIVE}/ruby setup.rb install || \ oefatal "ruby setup.rb install stage failed." } diff --git a/classes/sanity.bbclass b/classes/sanity.bbclass index 64c1bc0a0c..b6c6ed939a 100644 --- a/classes/sanity.bbclass +++ b/classes/sanity.bbclass @@ -2,6 +2,8 @@ # Sanity check the users setup for common misconfigurations # +inherit qemu + def raise_sanity_error(msg): import bb bb.fatal(""" Openembedded's config sanity checker detected a potential misconfiguration. @@ -11,8 +13,6 @@ def raise_sanity_error(msg): %s""" % msg) def check_conf_exists(fn, data): - import bb, os - bbpath = [] fn = bb.data.expand(fn, data) vbbpath = bb.data.getVar("BBPATH", data) @@ -24,22 +24,14 @@ def check_conf_exists(fn, data): return True return False -def check_app_exists(app, d): - from bb import which, data - - app = data.expand(app, d) - path = data.getVar('PATH', d) - return len(which(path, app)) != 0 - - def check_sanity(e): from bb import note, error, data, __version__ - from bb.event import Handled, NotHandled, getName + try: from distutils.version import LooseVersion except ImportError: def LooseVersion(v): print "WARNING: sanity.bbclass can't compare versions without python-distutils"; return 1 - import os + import commands # Check the bitbake version meets minimum requirements minversion = data.getVar('BB_MIN_VERSION', e.data , True) @@ -49,55 +41,146 @@ def check_sanity(e): print "Foo %s" % minversion return + if 0 == os.getuid(): + raise_sanity_error("Do not use Bitbake as root.") + + messages = "" + if (LooseVersion(__version__) < LooseVersion(minversion)): - raise_sanity_error('Bitbake version %s is required and version %s was found' % (minversion, __version__)) + messages = messages + 'Bitbake version %s is required and version %s was found\n' % (minversion, __version__) # Check TARGET_ARCH is set if data.getVar('TARGET_ARCH', e.data, True) == 'INVALID': - raise_sanity_error('Please set TARGET_ARCH directly, or choose a MACHINE or DISTRO that does so.') + messages = messages + 'Please set TARGET_ARCH directly, or choose a MACHINE or DISTRO that does so.\n' # Check TARGET_OS is set if data.getVar('TARGET_OS', e.data, True) == 'INVALID': - raise_sanity_error('Please set TARGET_OS directly, or choose a MACHINE or DISTRO that does so.') + messages = messages + 'Please set TARGET_OS directly, or choose a MACHINE or DISTRO that does so.\n' + assume_provided = data.getVar('ASSUME_PROVIDED', e.data , True).split() # Check user doesn't have ASSUME_PROVIDED = instead of += in local.conf - if "diffstat-native" not in data.getVar('ASSUME_PROVIDED', e.data, True).split(): - raise_sanity_error('Please use ASSUME_PROVIDED +=, not ASSUME_PROVIDED = in your local.conf') + if "diffstat-native" not in assume_provided: + messages = messages + 'Please use ASSUME_PROVIDED +=, not ASSUME_PROVIDED = in your local.conf\n' - # Check that the MACHINE is valid - if not check_conf_exists("conf/machine/${MACHINE}.conf", e.data): - raise_sanity_error('Please set a valid MACHINE in your local.conf') + # Check that the MACHINE is valid, if it is set + if data.getVar('MACHINE', e.data, True): + if not check_conf_exists("conf/machine/${MACHINE}.conf", e.data): + messages = messages + 'Please set a valid MACHINE in your local.conf\n' # Check that the DISTRO is valid # need to take into account DISTRO renaming DISTRO if not ( check_conf_exists("conf/distro/${DISTRO}.conf", e.data) or check_conf_exists("conf/distro/include/${DISTRO}.inc", e.data) ): - raise_sanity_error("DISTRO '%s' not found. Please set a valid DISTRO in your local.conf" % data.getVar("DISTRO", e.data, True )) + messages = messages + "DISTRO '%s' not found. Please set a valid DISTRO in your local.conf\n" % data.getVar("DISTRO", e.data, True ) + + missing = "" if not check_app_exists("${MAKE}", e.data): - raise_sanity_error('GNU make missing. Please install GNU make') + missing = missing + "GNU make," if not check_app_exists('${BUILD_PREFIX}gcc', e.data): - raise_sanity_error('C Host-Compiler is missing, please install one' ) + missing = missing + "C Compiler (${BUILD_PREFIX}gcc)," if not check_app_exists('${BUILD_PREFIX}g++', e.data): - raise_sanity_error('C++ Host-Compiler is missing, please install one' ) + missing = missing + "C++ Compiler (${BUILD_PREFIX}g++)," + + required_utilities = "patch help2man diffstat texi2html makeinfo cvs svn bzip2 tar gzip gawk md5sum" - required_utilities = "patch diffstat texi2html makeinfo cvs svn git bzip2 tar gzip" + # If we'll be running qemu, perform some sanity checks + if data.getVar('ENABLE_BINARY_LOCALE_GENERATION', e.data, True): + if "qemu-native" in assume_provided: + required_utilities += " %s" % (qemu_target_binary(e.data)) for util in required_utilities.split(): if not check_app_exists( util, e.data ): - raise_sanity_error( "Please install the %s utility." % util ) + missing = missing + "%s," % util + + if missing != "": + missing = missing.rstrip(',') + messages = messages + "Please install following missing utilities: %s\n" % missing + + try: + if os.path.basename(os.readlink('/bin/sh')) == 'dash': + messages = messages + "Using dash as /bin/sh causes various subtle build problems, please use bash instead.\n" + except: + pass + + omask = os.umask(022) + if omask & 0755: + messages = messages + "Please use a umask which allows a+rx and u+rwx\n" + os.umask(omask) oes_bb_conf = data.getVar( 'OES_BITBAKE_CONF', e.data, True ) if not oes_bb_conf: - raise_sanity_error('You do not include OpenEmbeddeds version of conf/bitbake.conf') + messages = messages + 'You do not include OpenEmbeddeds version of conf/bitbake.conf. This means your environment is misconfigured, in particular check BBPATH.\n' + + # + # Check that TMPDIR hasn't changed location since the last time we were run + # + tmpdir = data.getVar('TMPDIR', e.data, True) + checkfile = os.path.join(tmpdir, "saved_tmpdir") + if os.path.exists(checkfile): + f = file(checkfile, "r") + if (f.read().strip() != tmpdir): + messages = messages + "Error, TMPDIR has changed location. You need to either move it back to %s or rebuild\n" % tmpdir + else: + import bb + bb.mkdirhier(tmpdir) + f = file(checkfile, "w") + f.write(tmpdir) + f.close() + + # + # Check the 'ABI' of TMPDIR + # + current_abi = data.getVar('OELAYOUT_ABI', e.data, True) + abifile = data.getVar('SANITY_ABIFILE', e.data, True) + if os.path.exists(abifile): + f = file(abifile, "r") + abi = f.read().strip() + if not abi.isdigit(): + f = file(abifile, "w") + f.write(current_abi) + elif (abi != current_abi): + # Code to convert from one ABI to another could go here if possible. + messages = messages + "Error, TMPDIR has changed ABI (%s to %s) and you need to either rebuild, revert or adjust it at your own risk.\n" % (abi, current_abi) + else: + f = file(abifile, "w") + f.write(current_abi) + f.close() + + # + # Check the Distro PR value didn't change + # + distro_pr = data.getVar('DISTRO_PR', e.data, True) + prfile = data.getVar('SANITY_PRFILE', e.data, True) + if os.path.exists(prfile): + f = file(prfile, "r") + pr = f.read().strip() + if (pr != distro_pr): + # Code to convert from one ABI to another could go here if possible. + messages = messages + "Error, DISTRO_PR has changed (%s to %s) which means all packages need to rebuild. Please remove your TMPDIR so this can happen. For autobuilder setups you can avoid this by using a TMPDIR that include DISTRO_PR in the path.\n" % (pr, distro_pr) + else: + f = file(prfile, "w") + f.write(distro_pr) + f.close() + + + # + # Check there aren't duplicates in PACKAGE_ARCHS + # + archs = data.getVar('PACKAGE_ARCHS', e.data, True).split() + for arch in archs: + if archs.count(arch) != 1: + messages = messages + "Error, Your PACKAGE_ARCHS field contains duplicates. Perhaps you set PACKAGE_EXTRA_ARCHS twice accidently through some tune file?\n" + break + + if messages != "": + raise_sanity_error(messages) addhandler check_sanity_eventhandler python check_sanity_eventhandler() { - from bb import note, error, data, __version__ - from bb.event import getName - - if getName(e) == "BuildStarted": + from bb.event import Handled, NotHandled + if bb.event.getName(e) == "ConfigParsed": check_sanity(e) return NotHandled diff --git a/classes/scons.bbclass b/classes/scons.bbclass index 3160eca69a..b139411c19 100644 --- a/classes/scons.bbclass +++ b/classes/scons.bbclass @@ -1,13 +1,20 @@ DEPENDS += "python-scons-native" scons_do_compile() { - ${STAGING_BINDIR}/scons || \ + ${STAGING_BINDIR_NATIVE}/scons ${PARALLEL_MAKE} PREFIX=${prefix} prefix=${prefix} || \ oefatal "scons build execution failed." } scons_do_install() { - ${STAGING_BINDIR}/scons install || \ + install -d ${D}${prefix} + ${STAGING_BINDIR_NATIVE}/scons PREFIX=${D}${prefix} prefix=${D}${prefix} install || \ oefatal "scons install execution failed." } -EXPORT_FUNCTIONS do_compile do_install +scons_do_stage() { + install -d ${D}${prefix} + ${STAGING_BINDIR_NATIVE}/scons PREFIX=${STAGING_DIR_HOST}/${prefix} prefix=${STAGING_DIR_HOST}/${prefix} install || \ + oefatal "scons stage execution failed." +} + +EXPORT_FUNCTIONS do_compile do_install do_stage diff --git a/classes/scratchbox-compat.bbclass b/classes/scratchbox-compat.bbclass new file mode 100644 index 0000000000..6cf92bde5d --- /dev/null +++ b/classes/scratchbox-compat.bbclass @@ -0,0 +1,13 @@ +# By adding this class to your build all binaries get the special rpath +# "/scratchbox/host_shared/lib/:/scratchbox/tools/lib/" +# Doing so makes libraries and programs runnable inside the Scratchbox +# environment as native binaries (not for the CPU that Scratchbox is +# emulating). + +do_configure_prepend () { + export LD_RUN_PATH="/scratchbox/host_shared/lib:/scratchbox/tools/lib" +} + +do_compile_prepend () { + export LD_RUN_PATH="/scratchbox/host_shared/lib:/scratchbox/tools/lib" +} diff --git a/classes/sdk.bbclass b/classes/sdk.bbclass index bcabbc79bd..198d147cb3 100644 --- a/classes/sdk.bbclass +++ b/classes/sdk.bbclass @@ -1,26 +1,68 @@ +# +# Note this class is deprecated and replaced by nativesdk.bbclass +# + + # SDK packages are built either explicitly by the user, # or indirectly via dependency. No need to be in 'world'. EXCLUDE_FROM_WORLD = "1" -SDK_NAME = "${TARGET_ARCH}/oe" -PACKAGE_ARCH = "${BUILD_ARCH}" +# Save MULTIMACH_ARCH +OLD_MULTIMACH_ARCH := "${MULTIMACH_ARCH}" +# Save PACKAGE_ARCH +OLD_PACKAGE_ARCH := ${PACKAGE_ARCH} +PACKAGE_ARCH = "${BUILD_ARCH}-${OLD_PACKAGE_ARCH}-sdk" +# Also save BASE_PACKAGE_ARCH since HOST_ARCH can influence it +OLD_BASE_PACKAGE_ARCH := "${BASE_PACKAGE_ARCH}" +BASE_PACKAGE_ARCH = "${OLD_BASE_PACKAGE_ARCH}" + +STAGING_DIR_HOST = "${STAGING_DIR}/${HOST_SYS}-sdk" +STAGING_DIR_TARGET = "${STAGING_DIR}/${OLD_MULTIMACH_ARCH}${TARGET_VENDOR}-${TARGET_OS}" HOST_ARCH = "${BUILD_ARCH}" HOST_VENDOR = "${BUILD_VENDOR}" HOST_OS = "${BUILD_OS}" HOST_PREFIX = "${BUILD_PREFIX}" HOST_CC_ARCH = "${BUILD_CC_ARCH}" +#HOST_SYS = "${HOST_ARCH}${TARGET_VENDOR}-${HOST_OS}" +HOST_EXEEXT = "${BUILD_EXEEXT}" CPPFLAGS = "${BUILD_CPPFLAGS}" CFLAGS = "${BUILD_CFLAGS}" CXXFLAGS = "${BUILD_CFLAGS}" LDFLAGS = "${BUILD_LDFLAGS}" -prefix = "/usr/local/${SDK_NAME}" +# Path prefixes +prefix = "${SDK_PATH}" exec_prefix = "${prefix}" -base_prefix = "${exec_prefix}" +base_prefix = "${prefix}" -FILES_${PN} = "${prefix}" +# Base paths +export base_bindir = "${prefix}/bin" +export base_sbindir = "${prefix}/bin" +export base_libdir = "${prefix}/lib" + +# Architecture independent paths +export datadir = "${prefix}/share" +export sysconfdir = "${prefix}/etc" +export sharedstatedir = "${datadir}/com" +export localstatedir = "${prefix}/var" +export infodir = "${datadir}/info" +export mandir = "${datadir}/man" +export docdir = "${datadir}/doc" +export servicedir = "${prefix}/srv" +# Architecture dependent paths +export bindir = "${prefix}/bin" +export sbindir = "${prefix}/bin" +export libexecdir = "${prefix}/libexec" +export libdir = "${prefix}/lib" +export includedir = "${prefix}/include" +export oldincludedir = "${prefix}/include" +FILES_${PN} = "${prefix}" +FILES_${PN}-dbg += "${prefix}/.debug \ + ${prefix}/bin/.debug \ + " +export PKG_CONFIG_SYSROOT_DIR = "${STAGING_DIR_HOST}" diff --git a/classes/sdl.bbclass b/classes/sdl.bbclass index d478d97f18..dc4cd8ffa2 100644 --- a/classes/sdl.bbclass +++ b/classes/sdl.bbclass @@ -4,41 +4,43 @@ DEPENDS += "virtual/libsdl libsdl-mixer libsdl-image" -APPDESKTOP ?= "${PN}.desktop" +APPDESKTOP ?= "${WORKDIR}/${PN}.desktop" APPNAME ?= "${PN}" -APPIMAGE ?= "${PN}.png" +APPIMAGE ?= "${WORKDIR}/${PN}.png" + +export SDL_CONFIG = "${STAGING_BINDIR_CROSS}/sdl-config" sdl_do_sdl_install() { - install -d ${D}${palmtopdir}/bin - install -d ${D}${palmtopdir}/pics - install -d ${D}${palmtopdir}/apps/Games - ln -sf ${bindir}/${APPNAME} ${D}${palmtopdir}/bin/${APPNAME} - install -m 0644 ${APPIMAGE} ${D}${palmtopdir}/pics/${PN}.png + install -d ${D}${datadir}/applications + install -d ${D}${datadir}/pixmaps + + install -m 0644 ${APPIMAGE} ${D}${datadir}/pixmaps/${PN}.png if [ -e "${APPDESKTOP}" ] then - echo ${APPDESKTOP} present, installing to palmtopdir... - install -m 0644 ${APPDESKTOP} ${D}${palmtopdir}/apps/Games/${PN}.desktop + echo ${APPDESKTOP} present, using it... + install -m 0644 ${APPDESKTOP} ${D}${datadir}/applications/ else echo ${APPDESKTOP} not present, creating one on-the-fly... - cat >${D}${palmtopdir}/apps/Games/${PN}.desktop <<EOF + cat >${D}${datadir}/applications/${PN}.desktop <<EOF [Desktop Entry] -Note=Auto Generated... this may be not what you want +Name=${PN} Comment=${DESCRIPTION} +Note=Auto Generated by OE SDL bbclass Exec=${APPNAME} Icon=${PN}.png Type=Application -Name=${PN} +Categories=Games EOF fi } EXPORT_FUNCTIONS do_sdl_install -addtask sdl_install after do_compile before do_populate_staging +addtask sdl_install after do_install before do_package -SECTION = "x11/games" -SECTION_${PN}-opie = "opie/games" +#SECTION = "x11/games" +#SECTION_${PN}-opie = "opie/games" -PACKAGES += "${PN}-opie" -RDEPENDS_${PN}-opie += "${PN}" -FILES_${PN}-opie = "${palmtopdir}" +#PACKAGES += "${PN}-opie" +#RDEPENDS_${PN}-opie += "${PN}" +#FILES_${PN}-opie = "${palmtopdir}" diff --git a/classes/seppuku.bbclass b/classes/seppuku.bbclass new file mode 100644 index 0000000000..546738dde8 --- /dev/null +++ b/classes/seppuku.bbclass @@ -0,0 +1,395 @@ +# +# Small event handler to automatically open URLs and file +# bug reports at a bugzilla of your choiche +# +# This class requires python2.4 because of the urllib2 usage +# + +def seppuku_spliturl(url): + """ + Split GET URL to return the host base and the query + as a param dictionary + """ + import urllib + (uri,query) = urllib.splitquery(url) + param = {} + for par in query.split("&"): + (key,value) = urllib.splitvalue(par) + if not key or len(key) == 0 or not value: + continue + key = urllib.unquote(key) + value = urllib.unquote(value) + param[key] = value + + return (uri,param) + + + +def seppuku_login(opener, login, user, password): + """ + We need to post to query.cgi with the parameters + Bugzilla_login and Bugzilla_password and will scan + the resulting page then + + @param opened = cookie enabled urllib2 opener + @param login = http://bugs.openembedded.net/query.cgi? + @param user = Your username + @param password = Your password + """ + import urllib + param = urllib.urlencode( {"GoAheadAndLogIn" : 1, "Bugzilla_login" : user, "Bugzilla_password" : password } ) + result = opener.open(login + param) + + if result.code != 200: + return False + txt = result.read() + if not '<a href="relogin.cgi">Log out</a>' in txt: + return False + + return True + +def seppuku_find_bug_report_old(): + from HTMLParser import HTMLParser + + class BugQueryExtractor(HTMLParser): + STATE_NONE = 0 + STATE_FOUND_TR = 1 + STATE_FOUND_NUMBER = 2 + STATE_FOUND_PRIO = 3 + STATE_FOUND_PRIO2 = 4 + STATE_FOUND_NAME = 5 + STATE_FOUND_PLATFORM = 6 + STATE_FOUND_STATUS = 7 + STATE_FOUND_WHATEVER = 8 # I don't know this field + STATE_FOUND_DESCRIPTION =9 + + def __init__(self): + HTMLParser.__init__(self) + self.state = self.STATE_NONE + self.bugs = [] + self.bug = None + + def handle_starttag(self, tag, attr): + if self.state == self.STATE_NONE and tag.lower() == "tr": + if len(attr) == 1 and attr[0][0] == 'class' and \ + ('bz_normal' in attr[0][1] or 'bz_blocker' in attr[0][1] or 'bz_enhancement' in attr[0][1] or 'bz_major' in attr[0][1] or 'bz_minor' in attr[0][1] or 'bz_trivial' in attr[0][1] or 'bz_critical' in attr[0][1] or 'bz_wishlist' in attr[0][1]) \ + and 'bz_P' in attr[0][1]: + self.state = self.STATE_FOUND_TR + elif self.state == self.STATE_FOUND_TR and tag.lower() == "td": + self.state += 1 + + def handle_endtag(self, tag): + if tag.lower() == "tr": + if self.state != self.STATE_NONE: + self.bugs.append( (self.bug,self.status) ) + self.state = self.STATE_NONE + self.bug = None + if self.state > 1 and tag.lower() == "td": + self.state += 1 + + def handle_data(self,data): + data = data.strip() + + # skip garbage + if len(data) == 0: + return + + if self.state == self.STATE_FOUND_NUMBER: + """ + #1995 in bugs.oe.org has [SEC] additionally to the number and we want to ignore it + """ + if not self.bug: + self.bug = data + elif self.state == self.STATE_FOUND_STATUS: + self.status = data + + def result(self): + return self.bugs + + return BugQueryExtractor() + + + +def seppuku_find_bug_report(debug_file, opener, query, product, component, bugname): + """ + Find a bug report with the sane name and return the bug id + and the status. + + @param opener = urllib2 opener + @param query = e.g. http://bugs.openembedded.net/query.cgi? + @param product = search for this product + @param component = search for this component + @param bugname = the bug to search for + + http://bugs.openembedded.net/buglist.cgi?short_desc_type=substring&short_desc=manual+test+bug&product=Openembedded&emailreporter2=1&emailtype2=substring&email2=freyther%40yahoo.com + but it does not support ctype=csv... + """ + import urllib + product = urllib.quote(product) + component = urllib.quote(component) + bugname = urllib.quote(bugname) + + file = "%(query)sproduct=%(product)s&component=%(component)s&short_desc_type=substring&short_desc=%(bugname)s" % vars() + print >> debug_file, "Trying %s" % file + result = opener.open(file) + if result.code != 200: + raise "Can not query the bugzilla at all" + txt = result.read() + scanner = seppuku_find_bug_report_old() + scanner.feed(txt) + if len(scanner.result()) == 0: + print >> debug_file, "Scanner failed to scan the html site" + print >> debug_file, "%(query)sproduct=%(product)s&component=%(component)s&short_desc_type=substring&short_desc=%(bugname)s" % vars() + #print >> debug_file, txt + return (False,None) + else: # silently pick the first result + print >> debug_file, "Result of bug search is " + #print >> debug_file, txt + (number,status) = scanner.result()[0] + return (not status in ["CLOS", "RESO", "VERI"],number) + +def seppuku_reopen_bug(poster, file, product, component, bug_number, bugname, text): + """ + Reopen a bug report and append to the comment + + Same as with opening a new report, some bits need to be inside the url + + http://bugs.openembedded.net/process_bug.cgi?id=239&bug_file_loc=http%3A%2F%2F&version=Angstrom&longdesclength=2&product=Openembedded&component=Build&comment=bla&priority=P2&bug_severity=normal&op_sys=Linux&rep_platform=Other&knob=reopen&short_desc=foo + """ + + import urllib2 + (uri, param) = seppuku_spliturl( file ) + + # Prepare the post + param["product"] = product + param["component"] = component + param["longdesclength"] = 2 + param["short_desc"] = bugname + param["knob"] = "reopen" + param["id"] = bug_number + param["comment"] = text + + try: + result = poster.open( uri, param ) + except urllib2.HTTPError, e: + print e.geturl() + print e.info() + return False + except Exception, e: + print e + return False + + if result.code != 200: + return False + else: + return True + +def seppuku_file_bug(poster, file, product, component, bugname, text): + """ + Create a completely new bug report + + + http://bugs.openembedded.net/post_bug.cgi?bug_file_loc=http%3A%2F%2F&version=Angstrom&product=Openembedded&component=Build&short_desc=foo&comment=bla&priority=P2&bug_severity=normal&op_sys=Linux&rep_platform=Other + + You are forced to add some default values to the bugzilla query and stop with '&' + + @param opener urllib2 opener + @param file The url used to file a bug report + @param product Product + @param component Component + @param bugname Name of the to be created bug + @param text Text + """ + + import urllib2 + (uri, param) = seppuku_spliturl( file ) + param["product"] = product + param["component"] = component + param["short_desc"] = bugname + param["comment"] = text + + try: + result = poster.open( uri, param ) + except urllib2.HTTPError, e: + print e.geturl() + print e.info() + return False + except Exception, e: + print e + return False + + # scan the result for a bug number + # it will look like + # '<title>Bug 2742 Submitted</title>' + import re + res = re.findall(("\>Bug (?P<int>\d+) Submitted"), result.read() ) + if result.code != 200 or len(res) != 1: + return None + else: + return res[0] + +def seppuku_create_attachment(data, debug, poster, attach_query, product, component, bug_number, text, file): + """ + + Create a new attachment for the failed report + """ + + if not bug_number: + import bb + bb.note("Can't create an attachment, no bugnumber passed to method") + print >> debug, "Can't create an attachment, no bugnumber passed to method" + return False + + if not attach_query: + import bb + bb.note("Can't create an attachment, no attach_query passed to method") + print >> debug, "Can't create an attachment, no attach_query passed to method" + return False + + import bb + logdescription = "Build log for machine %s" % (bb.data.getVar('MACHINE', data, True)) + + import urllib2 + param = { "bugid" : bug_number, "action" : "insert", "data" : file, "description" : logdescription, "ispatch" : "0", "contenttypemethod" : "list", "contenttypeselection" : "text/plain", "comment" : text } + + try: + result = poster.open( attach_query, param ) + except urllib2.HTTPError, e: + print e.geturl() + print e.info() + return False + except Exception, e: + print e + print >> debug, "Got exception in poster.open( attach_query, param )" + print >> debug, "attach_query: %s param: %s" % (attach_query, param ) + return False + + txt = result.read() + if result.code != 200: + print >> debug, "Got bad return code (%s)" % result.code + return False + else: + print >> debug, "Got good return code (200)" + return True + + +addhandler seppuku_eventhandler +python seppuku_eventhandler() { + """ + Report task failures to the bugzilla + and succeeded builds to the box + """ + from bb.event import NotHandled, getName + from bb import data, mkdirhier, build + import bb, os, glob + + event = e + data = e.data + name = getName(event) + if name == "MsgNote": + # avoid recursion + return NotHandled + + # Try to load our exotic libraries + try: + import MultipartPostHandler + except: + bb.note("You need to put the MultipartPostHandler into your PYTHONPATH. Download it from http://pipe.scs.fsu.edu/PostHandler/MultipartPostHandler.py") + return NotHandled + + try: + import urllib2, cookielib + except: + bb.note("Failed to import the cookielib and urllib2, make sure to use python2.4") + return NotHandled + + if name == "PkgFailed": + if not bb.data.getVar('SEPPUKU_AUTOBUILD', data, True) == "0": + build.exec_func('do_clean', data) + elif name == "TaskFailed": + cj = cookielib.CookieJar() + opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj)) + poster = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj),MultipartPostHandler.MultipartPostHandler) + login = bb.data.getVar("SEPPUKU_LOGIN", data, True) + query = bb.data.getVar("SEPPUKU_QUERY", data, True) + newbug = bb.data.getVar("SEPPUKU_NEWREPORT", data, True) + reopen = bb.data.getVar("SEPPUKU_ADDCOMMENT", data, True) + attach = bb.data.getVar("SEPPUKU_ATTACHMENT", data, True) + user = bb.data.getVar("SEPPUKU_USER", data, True) + passw = bb.data.getVar("SEPPUKU_PASS", data, True) + product = bb.data.getVar("SEPPUKU_PRODUCT", data, True) + component = bb.data.getVar("SEPPUKU_COMPONENT", data, True) + proxy = bb.data.getVar('HTTP_PROXY', data, True ) + if (proxy): + phl = urllib2.ProxyHandler({'http' : proxy}) + poster.add_handler(phl) + opener.add_handler(phl) + + # evil hack to figure out what is going on + debug_file = open(os.path.join(bb.data.getVar("TMPDIR", data, True),"..","seppuku-log"),"a") + + if not seppuku_login(opener, login, user, passw): + bb.note("Login to bugzilla failed") + print >> debug_file, "Login to bugzilla failed" + return NotHandled + else: + print >> debug_file, "Logged into the box" + + file = None + if name == "TaskFailed": + bugname = "%(package)s-%(pv)s-autobuild" % { "package" : bb.data.getVar("PN", data, True), + "pv" : bb.data.getVar("PV", data, True), + } + log_file = glob.glob("%s/log.%s.*" % (bb.data.getVar('T', event.data, True), event.task)) + text = "The %s step in %s failed at %s for machine %s" % (e.task, bb.data.getVar("PN", data, True), bb.data.getVar('DATETIME', data, True), bb.data.getVar( 'MACHINE', data, True ) ) + if len(log_file) != 0: + print >> debug_file, "Adding log file %s" % log_file[0] + file = open(log_file[0], 'r') + else: + print >> debug_file, "No log file found for the glob" + else: + print >> debug_file, "Unknown name '%s'" % name + assert False + + (bug_open, bug_number) = seppuku_find_bug_report(debug_file, opener, query, product, component, bugname) + print >> debug_file, "Bug is open: %s and bug number: %s" % (bug_open, bug_number) + + # The bug is present and still open, attach an error log + if bug_number and bug_open: + print >> debug_file, "The bug is known as '%s'" % bug_number + if file: + if not seppuku_create_attachment(data, debug_file, poster, attach, product, component, bug_number, text, file): + print >> debug_file, "Failed to attach the build log for bug #%s" % bug_number + else: + print >> debug_file, "Created an attachment for '%s' '%s' '%s'" % (product, component, bug_number) + else: + print >> debug_file, "Not trying to create an attachment for bug #%s" % bug_number + return NotHandled + + if bug_number and not bug_open: + if not seppuku_reopen_bug(poster, reopen, product, component, bug_number, bugname, text): + print >> debug_file, "Failed to reopen the bug #%s" % bug_number + else: + print >> debug_file, "Reopened the bug #%s" % bug_number + else: + bug_number = seppuku_file_bug(poster, newbug, product, component, bugname, text) + if not bug_number: + print >> debug_file, "Couldn't acquire a new bug_numer, filing a bugreport failed" + else: + print >> debug_file, "The new bug_number: '%s'" % bug_number + + if bug_number and file: + if not seppuku_create_attachment(data, debug_file, poster, attach, product, component, bug_number, text, file): + print >> debug_file, "Failed to attach the build log for bug #%s" % bug_number + else: + print >> debug_file, "Created an attachment for '%s' '%s' '%s'" % (product, component, bug_number) + else: + print >> debug_file, "Not trying to create an attachment for bug #%s" % bug_number + + # store bug number for oestats-client + if bug_number: + bb.data.setVar('OESTATS_BUG_NUMBER', bug_number, event.data) + bb.data.setVar('OESTATS_BUG_TRACKER', "http://bugs.openembedded.net/", event.data) + + return NotHandled +} diff --git a/classes/setuptools.bbclass b/classes/setuptools.bbclass new file mode 100644 index 0000000000..ced9509df2 --- /dev/null +++ b/classes/setuptools.bbclass @@ -0,0 +1,8 @@ +inherit distutils + +DEPENDS += "python-setuptools-native" + +DISTUTILS_INSTALL_ARGS = "--root=${D} \ + --single-version-externally-managed \ + --prefix=${prefix} \ + --install-data=${datadir}" diff --git a/classes/singlemachine.bbclass b/classes/singlemachine.bbclass new file mode 100644 index 0000000000..e4b2b6f7b3 --- /dev/null +++ b/classes/singlemachine.bbclass @@ -0,0 +1,12 @@ +# +# Emulates the old mode of OE operation where only one machine can be targetted. +# + +MULTIMACH_TARGET_SYS = "${TARGET_SYS}" +MULTIMACH_HOST_SYS = "${HOST_SYS}" + +STAMP = "${TMPDIR}/stamps/${PF}" +WORKDIR = "${TMPDIR}/work/${PF}" +PKGDATA_DIR = "${STAGING_DIR}/pkgdata" +STAGING_KERNEL_DIR = "${STAGING_DIR_HOST}/kernel" + diff --git a/classes/sip.bbclass b/classes/sip.bbclass index adf179b130..30c08b1ed9 100644 --- a/classes/sip.bbclass +++ b/classes/sip.bbclass @@ -2,10 +2,12 @@ # (C) Michael 'Mickey' Lauer <mickey@Vanille.de> # -DEPENDS =+ "sip-native python-sip" +# yes, python-sip is actually a build-time dependency, since +# the recipe installs sip.h +DEPENDS += "sip-native python-sip" # default stuff, do not uncomment -# EXTRA_SIPTAGS = "-tWS_QWS -tQtPE_1_6_0 -tQt_2_3_1" +# EXTRA_SIPTAGS = "-tWS_X11 -tQt_4_3_0" sip_do_generate() { if [ -z "${SIP_MODULES}" ]; then @@ -33,10 +35,10 @@ sip_do_generate() { for module in $MODULES do - install -d ${module}/ - oenote "calling 'sip -I sip -I ${STAGING_SIPDIR} ${SIPTAGS} ${FEATURES} -c ${module} -b ${module}/${module}.pro.in sip/${module}/${module}mod.sip'" - sip -I ${STAGING_SIPDIR} -I sip ${SIPTAGS} ${FEATURES} -c ${module} -b ${module}/${module}.sbf sip/${module}/${module}mod.sip \ - || die "Error calling sip on ${module}" + install -d ${module}/ + echo "calling 'sip -I sip -I ${STAGING_SIPDIR} ${SIPTAGS} ${FEATURES} -c ${module} -b ${module}/${module}.pro.in sip/${module}/${module}mod.sip'" + sip -I ${STAGING_SIPDIR} -I sip ${SIPTAGS} ${FEATURES} -c ${module} -b ${module}/${module}.sbf \ + sip/${module}/${module}mod.sip || die "Error calling sip on ${module}" cat ${module}/${module}.sbf | sed s,target,TARGET, \ | sed s,sources,SOURCES, \ | sed s,headers,HEADERS, \ @@ -53,6 +55,8 @@ sip_do_generate() { done } +do_generate[deptask] = "do_populate_staging" + EXPORT_FUNCTIONS do_generate addtask generate after do_unpack do_patch before do_configure diff --git a/classes/sip4.bbclass b/classes/sip3.bbclass index ca2b1dae20..7ecc63bf02 100644 --- a/classes/sip4.bbclass +++ b/classes/sip3.bbclass @@ -1,13 +1,13 @@ # Build Class for Sip based Python Bindings # (C) Michael 'Mickey' Lauer <mickey@Vanille.de> # -DEPENDS =+ "sip4-native" -RDEPENDS += "python-sip4" + +DEPENDS =+ "sip-native python-sip" # default stuff, do not uncomment -# EXTRA_SIPTAGS = "-tWS_X11 -tQt_4_1_1" +# EXTRA_SIPTAGS = "-tWS_QWS -tQtPE_1_6_0 -tQt_2_3_1" -sip4_do_generate() { +sip3_do_generate() { if [ -z "${SIP_MODULES}" ]; then MODULES="`ls sip/*mod.sip`" else @@ -33,10 +33,10 @@ sip4_do_generate() { for module in $MODULES do - install -d ${module}/ - echo "calling 'sip4 -I sip -I ${STAGING_SIPDIR} ${SIPTAGS} ${FEATURES} -c ${module} -b ${module}/${module}.pro.in sip/${module}/${module}mod.sip'" - sip4 -I ${STAGING_SIPDIR} -I sip ${SIPTAGS} ${FEATURES} -c ${module} -b ${module}/${module}.sbf \ - sip/${module}/${module}mod.sip || die "Error calling sip on ${module}" + install -d ${module}/ + oenote "calling 'sip -I sip -I ${STAGING_SIPDIR} ${SIPTAGS} ${FEATURES} -c ${module} -b ${module}/${module}.pro.in sip/${module}/${module}mod.sip'" + sip -I ${STAGING_SIPDIR} -I sip ${SIPTAGS} ${FEATURES} -c ${module} -b ${module}/${module}.sbf sip/${module}/${module}mod.sip \ + || die "Error calling sip on ${module}" cat ${module}/${module}.sbf | sed s,target,TARGET, \ | sed s,sources,SOURCES, \ | sed s,headers,HEADERS, \ @@ -53,6 +53,8 @@ sip4_do_generate() { done } +do_generate[deptask] = "do_populate_staging" + EXPORT_FUNCTIONS do_generate addtask generate after do_unpack do_patch before do_configure diff --git a/classes/siteinfo.bbclass b/classes/siteinfo.bbclass new file mode 100644 index 0000000000..93cee4f890 --- /dev/null +++ b/classes/siteinfo.bbclass @@ -0,0 +1,145 @@ +# This class exists to provide information about the targets that +# may be needed by other classes and/or recipes. If you add a new +# target this will probably need to be updated. + +# +# Returns information about 'what' for the named target 'target' +# where 'target' == "<arch>-<os>" +# +# 'what' can be one of +# * target: Returns the target name ("<arch>-<os>") +# * endianess: Return "be" for big endian targets, "le" for little endian +# * bits: Returns the bit size of the target, either "32" or "64" +# * libc: Returns the name of the c library used by the target +# +# It is an error for the target not to exist. +# If 'what' doesn't exist then an empty value is returned +# +def get_siteinfo_list(d): + target = bb.data.getVar('HOST_ARCH', d, 1) + "-" + bb.data.getVar('HOST_OS', d, 1) + + targetinfo = {\ + "armeb-linux": "endian-big bit-32 common-linux common-glibc arm-common",\ + "armeb-linux-gnueabi": "endian-big bit-32 common-linux common-glibc arm-common armeb-linux",\ + "armeb-linux-uclibc": "endian-big bit-32 common-linux common-uclibc arm-common",\ + "armeb-linux-uclibceabi": "endian-big bit-32 common-linux common-uclibc arm-common armeb-linux-uclibc",\ + "arm-darwin": "endian-little bit-32 common-darwin",\ + "arm-darwin9": "endian-little bit-32 common-darwin",\ + "arm-linux": "endian-little bit-32 common-linux common-glibc arm-common",\ + "arm-linux-gnueabi": "endian-little bit-32 common-linux common-glibc arm-common arm-linux",\ + "arm-linux-uclibc": "endian-little bit-32 common-linux common-uclibc arm-common",\ + "arm-linux-uclibceabi": "endian-little bit-32 common-linux common-uclibc arm-common arm-linux-uclibc",\ + "avr32-linux-uclibc": "endian-big bit-32 common-linux common-uclibc avr32-common",\ + "bfin-uclinux-uclibc": "endian-little bit-32 common-uclibc bfin-common",\ + "i386-linux": "endian-little bit-32 common-linux common-glibc ix86-common",\ + "i486-linux": "endian-little bit-32 common-linux common-glibc ix86-common",\ + "i586-linux": "endian-little bit-32 common-linux common-glibc ix86-common",\ + "i686-linux": "endian-little bit-32 common-linux common-glibc ix86-common",\ + "i386-linux-uclibc": "endian-little bit-32 common-linux common-uclibc ix86-common",\ + "i486-linux-uclibc": "endian-little bit-32 common-linux common-uclibc ix86-common",\ + "i586-linux-uclibc": "endian-little bit-32 common-linux common-uclibc ix86-common",\ + "i686-linux-uclibc": "endian-little bit-32 common-linux common-uclibc ix86-common",\ + "i386-cygwin": "endian-little bit-32 common-cygwin ix86-common",\ + "i486-cygwin": "endian-little bit-32 common-cygwin ix86-common",\ + "i586-cygwin": "endian-little bit-32 common-cygwin ix86-common",\ + "i686-cygwin": "endian-little bit-32 common-cygwin ix86-common",\ + "i386-mingw32": "endian-little bit-32 common-mingw ix86-common",\ + "i486-mingw32": "endian-little bit-32 common-mingw ix86-common",\ + "i586-mingw32": "endian-little bit-32 common-mingw ix86-common",\ + "i686-mingw32": "endian-little bit-32 common-mingw ix86-common",\ + "ia64-linux": "endian-little bit-64 common-linux common-glibc",\ + "mipsel-linux": "endian-little bit-32 common-linux common-glibc mips-common",\ + "mipsel-linux-uclibc": "endian-little bit-32 common-linux common-uclibc mips-common",\ + "mips-linux": "endian-big bit-32 common-linux common-glibc mips-common",\ + "mips-linux-uclibc": "endian-big bit-32 common-linux common-uclibc mips-common",\ + "powerpc-darwin": "endian-big bit-32 common-darwin",\ + "ppc-linux": "endian-big bit-32 common-linux common-glibc powerpc-common powerpc-linux",\ + "ppc64-linux": "endian-big bit-64 common-linux common-glibc powerpc-common powerpc64-linux",\ + "powerpc-linux": "endian-big bit-32 common-linux common-glibc powerpc-common",\ + "powerpc-linux-gnuspe": "endian-big bit-32 common-linux common-glibc powerpc-common powerpc-linux",\ + "powerpc-linux-uclibc": "endian-big bit-32 common-linux common-uclibc powerpc-common",\ + "powerpc-linux-uclibcspe": "endian-big bit-32 common-linux common-uclibc powerpc-common powerpc-linux-uclibc",\ + "sh3-linux": "endian-little bit-32 common-linux common-glibc sh-common",\ + "sh4-linux": "endian-little bit-32 common-linux common-glibc sh-common",\ + "sh4-linux-uclibc": "endian-little bit-32 common-linux common-uclibc sh-common",\ + "sparc-linux": "endian-big bit-32 common-linux common-glibc",\ + "viac3-linux": "endian-little bit-32 common-linux common-glibc ix86-common",\ + "x86_64-linux": "endian-little bit-64 common-linux common-glibc",\ + "x86_64-linux-uclibc": "endian-little bit-64 common-linux common-uclibc"} + if target in targetinfo: + info = targetinfo[target].split() + info.append(target) + info.append("common") + return info + else: + bb.error("Information not available for target '%s'" % target) + + +# +# Define which site files to use. We check for several site files and +# use each one that is found, based on the list returned by get_siteinfo_list() +# +# Search for the files in the following directories: +# 1) ${BBPATH}/site (in reverse) - app specific, then site wide +# 2) ${FILE_DIRNAME}/site-${PV} - app version specific +# +def siteinfo_get_files(d): + sitefiles = "" + + # Determine which site files to look for + sites = get_siteinfo_list(d) + sites.append("common"); + + # Check along bbpath for site files and append in reverse order so + # the application specific sites files are last and system site + # files first. + path_bb = bb.data.getVar('BBPATH', d, 1) + for p in (path_bb or "").split(':'): + tmp = "" + for i in sites: + fname = os.path.join(p, 'site', i) + if os.path.exists(fname): + tmp += fname + " " + sitefiles = tmp + sitefiles; + + # Now check for the applications version specific site files + path_pkgv = os.path.join(bb.data.getVar('FILE_DIRNAME', d, 1), "site-" + bb.data.getVar('PV', d, 1)) + for i in sites: + fname = os.path.join(path_pkgv, i) + if os.path.exists(fname): + sitefiles += fname + " " + + bb.debug(1, "SITE files " + sitefiles); + return sitefiles + +# +# Export CONFIG_SITE to the enviroment. The autotools will make use +# of this to determine where to load in variables from. This is a +# space seperate list of shell scripts processed in the order listed. +# +export CONFIG_SITE = "${@siteinfo_get_files(d)}" + + +def siteinfo_get_endianess(d): + info = get_siteinfo_list(d) + if 'endian-little' in info: + return "le" + elif 'endian-big' in info: + return "be" + bb.error("Site info could not determine endianess for target") + +def siteinfo_get_bits(d): + info = get_siteinfo_list(d) + if 'bit-32' in info: + return "32" + elif 'bit-64' in info: + return "64" + bb.error("Site info could not determine bit size for target") + +# +# Make some information available via variables +# +SITEINFO_ENDIANESS = "${@siteinfo_get_endianess(d)}" +SITEINFO_BITS = "${@siteinfo_get_bits(d)}" + + diff --git a/classes/sourcepkg.bbclass b/classes/sourcepkg.bbclass index 390d3684d4..5aacf92d10 100644 --- a/classes/sourcepkg.bbclass +++ b/classes/sourcepkg.bbclass @@ -1,12 +1,10 @@ -DEPLOY_DIR_SRC ?= "${DEPLOY_DIR}/source" +DEPLOY_DIR_SRC ?= "${DEPLOY_DIR}/sources" EXCLUDE_FROM ?= ".pc autom4te.cache" # used as part of a path. make sure it's set DISTRO ?= "openembedded" def get_src_tree(d): - import bb - import os, os.path workdir = bb.data.getVar('WORKDIR', d, 1) if not workdir: @@ -56,8 +54,6 @@ sourcepkg_do_archive_bb() { } python sourcepkg_do_dumpdata() { - import os - import os.path workdir = bb.data.getVar('WORKDIR', d, 1) distro = bb.data.getVar('DISTRO', d, 1) @@ -104,8 +100,13 @@ sourcepkg_do_create_diff_gz(){ EXPORT_FUNCTIONS do_create_orig_tgz do_archive_bb do_dumpdata do_create_diff_gz +do_create_orig_tgz[deptask] = "do_unpack" +do_create_diff_gz[deptask] = "do_patch" +do_archive_bb[deptask] = "do_patch" +do_dumpdata[deptask] = "do_unpack" + addtask create_orig_tgz after do_unpack before do_patch addtask archive_bb after do_patch before do_dumpdata -addtask dumpdata after archive_bb before do_create_diff_gz -addtask create_diff_gz after do_dump_data before do_configure +addtask dumpdata after do_archive_bb before do_create_diff_gz +addtask create_diff_gz after do_dumpdata before do_configure diff --git a/classes/src_distribute.bbclass b/classes/src_distribute.bbclass index 5daf526018..22044752ef 100644 --- a/classes/src_distribute.bbclass +++ b/classes/src_distribute.bbclass @@ -1,40 +1,46 @@ -include conf/licenses.conf - +SRC_DISTRIBUTE_DLONLY ?= "0" SRC_DISTRIBUTECOMMAND[func] = "1" + +addtask distribute_sources before do_build after do_fetch python do_distribute_sources () { + import re + + bb.build.exec_func("do_fetch", d) + l = bb.data.createCopy(d) bb.data.update_data(l) - licenses = (bb.data.getVar('LICENSE', d, 1) or "").split() - if not licenses: - bb.note("LICENSE not defined") - src_distribute_licenses = (bb.data.getVar('SRC_DISTRIBUTE_LICENSES', d, 1) or "").split() - # Explanation: - # Space seperated items in LICENSE must *all* be distributable - # Each space seperated item may be used under any number of | seperated licenses. - # If any of those | seperated licenses are distributable, then that component is. - # i.e. LICENSE = "GPL LGPL" - # In this case, both components are distributable. - # LICENSE = "GPL|QPL|Proprietary" - # In this case, GPL is distributable, so the component is. - valid = 1 - for l in licenses: - lvalid = 0 - for i in l.split("|"): - if i in src_distribute_licenses: - lvalid = 1 - if lvalid != 1: - valid = 0 - if valid == 0: - bb.note("Licenses (%s) are not all listed in SRC_DISTRIBUTE_LICENSES, skipping source distribution" % licenses) - return - import re - for s in (bb.data.getVar('A', d, 1) or "").split(): - s = re.sub(';.*$', '', s) - cmd = bb.data.getVar('SRC_DISTRIBUTECOMMAND', d, 1) - if not cmd: - raise bb.build.FuncFailed("Unable to distribute sources, SRC_DISTRIBUTECOMMAND not defined") - bb.data.setVar('SRC', s, d) - bb.build.exec_func('SRC_DISTRIBUTECOMMAND', d) + + licenses = (bb.data.getVar('LICENSE', d, 1) or "unknown").split() + for license in licenses: + for entry in license.split("|"): + for url in ((bb.data.getVar('SRC_URI', d, 1) or '').split()): + bb.fetch.init([url], d) + s = bb.fetch.localpath(url, d) + s = re.sub(';.*$', '', s) + + try: + dlonly = int(d.getVar("SRC_DISTRIBUTE_DLONLY", 1)) + except ValueError: + raise bb.build.FuncFailed("Invalid value for SRC_DISTRIBUTE_DLONLY: expected integer.") + if dlonly: + dldir = os.path.realpath(d.getVar("DL_DIR", 1) or "") + if dldir and not \ + os.path.realpath(s).startswith(dldir + os.path.sep): + continue + + cmd = bb.data.getVar('SRC_DISTRIBUTECOMMAND', d, 1) + if not cmd: + raise bb.build.FuncFailed("Unable to distribute sources, SRC_DISTRIBUTECOMMAND not set") + bb.debug(2, "srcdist: running %s" % cmd) + bb.data.setVar('SRC', os.path.normpath(s), l) + bb.data.setVar('LIC', entry, l) + bb.build.exec_func('SRC_DISTRIBUTECOMMAND', l) } -addtask distribute_sources before do_build after do_fetch +addtask distribute_sources_all after do_distribute_sources +do_distribute_sources_all[recrdeptask] = "do_distribute_sources" +do_distribute_sources_all[nostamp] = "1" + +# compatability wrapper +addtask distsrcall after do_distribute_sources_all +do_distsrcall[nostamp] = "1" diff --git a/classes/src_distribute_local.bbclass b/classes/src_distribute_local.bbclass index 5f0cef5bec..5cec2880aa 100644 --- a/classes/src_distribute_local.bbclass +++ b/classes/src_distribute_local.bbclass @@ -1,31 +1,37 @@ inherit src_distribute -# SRC_DIST_LOCAL possible values: -# copy copies the files from ${A} to the distributedir -# symlink symlinks the files from ${A} to the distributedir -# move+symlink moves the files into distributedir, and symlinks them back SRC_DIST_LOCAL ?= "move+symlink" SRC_DISTRIBUTEDIR ?= "${DEPLOY_DIR}/sources" -SRC_DISTRIBUTECOMMAND () { - s="${SRC}" - if [ ! -L "$s" ] && (echo "$s"|grep "^${DL_DIR}"); then - : - else - exit 0; - fi - mkdir -p ${SRC_DISTRIBUTEDIR} - case "${SRC_DIST_LOCAL}" in - copy) - test -e $s.md5 && cp -f $s.md5 ${SRC_DISTRIBUTEDIR}/ - cp -f $s ${SRC_DISTRIBUTEDIR}/ - ;; - symlink) - test -e $s.md5 && ln -sf $s.md5 ${SRC_DISTRIBUTEDIR}/ - ln -sf $s ${SRC_DISTRIBUTEDIR}/ - ;; - move+symlink) - mv $s ${SRC_DISTRIBUTEDIR}/ - ln -sf ${SRC_DISTRIBUTEDIR}/`basename $s` $s - ;; - esac +SRC_DISTRIBUTECOMMAND[dirs] = "${SRC_DISTRIBUTEDIR}/${LIC}/${PN}" + +# symlinks the files to the SRC_DISTRIBUTEDIR +SRC_DISTRIBUTECOMMAND-symlink () { + test -e ${SRC}.md5 && ln -sf ${SRC}.md5 . + ln -sf ${SRC} . +} + +# copies the files to the SRC_DISTRIBUTEDIR +SRC_DISTRIBUTECOMMAND-copy () { + test -e ${SRC}.md5 && cp -f ${SRC}.md5 . + cp -fr ${SRC} . +} + +# moves the files to the SRC_DISTRIBUTEDIR and symlinks them back +SRC_DISTRIBUTECOMMAND-move+symlink () { + if ! [ -L ${SRC} ]; then + mv ${SRC} . + ln -sf $PWD/`basename ${SRC}` ${SRC} + if [ -e ${SRC}.md5 ]; then + mv ${SRC}.md5 . + ln -sf $PWD/`basename ${SRC}.md5` ${SRC}.md5 + fi + fi +} + +#SRC_DISTRIBUTECOMMAND = "${@str(d.getVar('SRC_DISTRIBUTECOMMAND-%s' % d.getVar('SRC_DIST_LOCAL', 1), 1))}" +python () { + if d.getVar("SRC_DISTRIBUTECOMMAND", 1) is None: + cmd = d.getVar("SRC_DISTRIBUTECOMMAND-%s" % d.getVar("SRC_DIST_LOCAL", 1), 0) + if cmd: + d.setVar("SRC_DISTRIBUTECOMMAND", cmd) } diff --git a/classes/srctree.bbclass b/classes/srctree.bbclass new file mode 100644 index 0000000000..dbf8ad2c3f --- /dev/null +++ b/classes/srctree.bbclass @@ -0,0 +1,115 @@ +# Copyright (C) 2009 Chris Larson <clarson@kergoth.com> +# Released under the MIT license (see COPYING.MIT for the terms) +# +# srctree.bbclass enables operation inside of an existing source tree for a +# project, rather than using the fetch/unpack/patch idiom. +# +# By default, it expects that you're keeping the recipe(s) inside the +# aforementioned source tree, but you could override S to point at an external +# directory and place the recipes in a normal collection/overlay, if you so +# chose. +# +# It also provides some convenience python functions for assembling your +# do_clean, if you want to leverage things like 'git clean' to simplify the +# operation. + + +# Grab convenience methods & sane default for do_clean +inherit clean + +# Build here +S = "${FILE_DIRNAME}" +SRC_URI = "" + + +def merge_tasks(d): + """ + merge_tasks performs two operations: + 1) removes do_patch and its deps from the build entirely. + 2) merges all of the operations that occur prior to do_populate_staging + into do_populate_staging. + + This is necessary, because of recipe variants (normal, native, cross, + sdk). If a bitbake run happens to want to build more than one of + these variants in a single run, it's possible for them to step on one + another's toes, due to the shared ${S}. Interleaved + configure/compile/install amongst variants will break things badly. + """ + from itertools import chain + from bb import note + + def __gather_taskdeps(task, seen): + for dep in d.getVarFlag(task, "deps"): + if not dep in seen: + __gather_taskdeps(dep, seen) + if not task in seen: + seen.append(task) + + def gather_taskdeps(task): + items = [] + __gather_taskdeps(task, items) + return items + + newtask = "do_populate_staging" + mergedtasks = gather_taskdeps(newtask) + mergedtasks.pop() + deltasks = gather_taskdeps("do_patch") + + for task in (key for key in d.keys() + if d.getVarFlag(key, "task") and + not key in mergedtasks): + deps = d.getVarFlag(task, "deps") + for mergetask in mergedtasks: + if mergetask in (d.getVarFlag(task, "recrdeptask"), + d.getVarFlag(task, "recdeptask"), + d.getVarFlag(task, "deptask")): + continue + + if mergetask in deps: + deps.remove(mergetask) + #note("removing dep on %s from %s" % (mergetask, task)) + + if not mergetask in deltasks and \ + not newtask in deps: + #note("adding dep on %s to %s" % (newtask, task)) + deps.append(newtask) + d.setVarFlag(task, "deps", deps) + + for task in mergedtasks[:-1]: + deps = d.getVarFlag(task, "deps") + for deltask in deltasks: + if deltask in deps: + deps.remove(deltask) + d.setVarFlag(task, "deps", deps) + + # Pull cross recipe task deps over + depends = (d.getVarFlag(task, "depends") or "" + for task in mergedtasks[:-1] + if not task in deltasks) + d.setVarFlag("do_populate_staging", "depends", " ".join(depends)) + +python () { + merge_tasks(d) +} + +# Manually run do_install & all of its deps, then do_stage +python do_populate_staging () { + from os.path import exists + from bb.build import exec_task, exec_func + from bb import note + + stamp = d.getVar("STAMP", True) + + def rec_exec_task(task, seen): + for dep in d.getVarFlag(task, "deps"): + if not dep in seen: + rec_exec_task(dep, seen) + seen.add(task) + #if not exists("%s.%s" % (stamp, task)): + note("%s: executing task %s" % (d.getVar("PF", True), task)) + exec_task(task, d) + + rec_exec_task("do_install", set()) + exec_func("do_stage", d) +} +do_populate_staging[lockfiles] += "${S}/.lock" diff --git a/classes/srec.bbclass b/classes/srec.bbclass index e7bdc6c75d..a869a4f1f3 100644 --- a/classes/srec.bbclass +++ b/classes/srec.bbclass @@ -10,7 +10,7 @@ SREC_CMD = "${TARGET_PREFIX}objcopy -O srec -I binary --adjust-vma ${SREC_VMAADD # Do not build srec files for these types of images: SREC_SKIP = "tar" -do_srec[nostamp] = 1 +do_srec[nostamp] = "1" do_srec () { if [ ${SREC_VMAADDR} = "" ] ; then diff --git a/classes/storcenter-image.bbclass b/classes/storcenter-image.bbclass new file mode 100644 index 0000000000..de77f1b417 --- /dev/null +++ b/classes/storcenter-image.bbclass @@ -0,0 +1,30 @@ +storcenter_pack_image() { + # find latest kernel + KERNEL=`ls -tr ${DEPLOY_DIR_IMAGE}/uImage* | tail -1` + if [ -z "$KERNEL" ]; then + oefatal "No kernel found in ${DEPLOY_DIR_IMAGE}. Bitbake linux-storcenter to create one." + exit 1 + fi + ROOTFS=${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.jffs2 + OUTPUT=${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.flash.img + PADFILE=${DEPLOY_DIR_IMAGE}/padfile.zzz + HEX_MAX_KERN_SIZE=170000 + DEC_MAX_KERN_SIZE=`echo "ibase=16; $HEX_MAX_KERN_SIZE" | bc ` + HEX_MAX_ROOT_SIZE=590000 + DEC_MAX_ROOT_SIZE=`echo "ibase=16; $HEX_MAX_ROOT_SIZE" | bc ` + KERNEL_SIZE=`ls -l $KERNEL | awk '{print $5}'` + if [ $KERNEL_SIZE -gt $DEC_MAX_KERN_SIZE ]; then + oefatal "Kernel too large at $KERNEL_SIZE bytes. Max is $DEC_MAX_KERN_SIZE." + exit 1 + fi + ROOT_SIZE=`ls -l $ROOTFS | awk '{print $5}'` + if [ $ROOT_SIZE -gt $DEC_MAX_ROOT_SIZE ]; then + oefatal "Rootfs is too large at $ROOT_SIZE bytes. Max is $DEC_MAX_ROOT_SIZE." + exit 1 + fi + PAD_SIZE=`echo "$DEC_MAX_KERN_SIZE - $KERNEL_SIZE" | bc ` + dd if=/dev/zero of=$PADFILE bs=$PAD_SIZE count=1 2>>/dev/null + cat $KERNEL $PADFILE $ROOTFS > $OUTPUT + rm -f $PADFILE + ls -l $OUTPUT +} diff --git a/classes/task-metadata-track.bbclass b/classes/task-metadata-track.bbclass new file mode 100644 index 0000000000..d3622aef68 --- /dev/null +++ b/classes/task-metadata-track.bbclass @@ -0,0 +1,96 @@ +# Copyright (C) 2009 Chris Larson <clarson@kergoth.com> +# Released under the MIT license (see COPYING.MIT for the terms) +# +# This class uses events to capture the state of the datastore when the task +# starts, and after it completes. It diffs those captured states, and emits +# messages showing which variables changed, and what their values were changed +# to. +# +# It provides a mechanism to blacklist variables you expect to change, both +# globally and on a per-task basis. +# +# Known instances of tasks changing metadata: +# +# PSTAGE_PKGMANAGER changes by calls to pstage_set_pkgmanager in: +# do_clean, do_setscene, do_package_stage +# +# Subpackage metadata, read by the pkgdata functions in base.bbclass, in: +# do_package, do_package_stage, do_package_write_* + + +TASK_METADATA_BLACKLIST = "\ + __RUNQUEUE_DO_NOT_USE_EXTERNALLY \ +" + +#TASK_METADATA_BLACKLIST_do_clean = "\ +# PSTAGE_PKGMANAGER \ +#" + + +def dict_diff(olddict, newdict): + diff = {} + for key in set(olddict).union(set(newdict)): + old = olddict.get(key) + new = newdict.get(key) + if old != new: + diff[key] = (old, new) + + return diff + +def dict_for_data(data): + newdict = {} + for key in data.keys(): + newdict[key] = data.getVar(key, False) + return newdict + +def task_metadata_track_start(task, data): + originaldata = dict_for_data(data) + data.setVar("__originaldata_%s" % task, originaldata) + +def task_metadata_track_stop(task, data): + from bb import note + + pf = data.getVar("PF", True) + def emit(msg): + note("%s: %s" % (pf, msg)) + + originaldata = data.getVar("__originaldata_%s" % task, False) + newdata = dict_for_data(data) + blacklist = data.getVar("TASK_METADATA_BLACKLIST", True).split() + \ + (data.getVar("TASK_METADATA_BLACKLIST_%s" % task, True) or "").split() + + diff = dict_diff(originaldata, newdata) + diff_clean = [key for key in diff \ + if not key in blacklist and \ + not key.startswith("__originaldata_")] + + if diff_clean: + emit("Variables changed by %s:" % task) + for key in diff_clean: + (old, new) = diff[key] + emit(" %s:" % key) + emit(" '%s' -> '%s'" % (old, new)) + +python __task_metadata_track_eh () { + from bb.build import TaskStarted, TaskSucceeded + + if isinstance(e, TaskStarted): + if e.data is None: + from bb import fatal + fatal("e.data is none for %s" % e) + task_metadata_track_start(e.task, e.data) + elif isinstance(e, TaskSucceeded): + task_metadata_track_stop(e.task, e.data) +} +addhandler __task_metadata_track_eh + +addtask py_listtasks +do_py_listtasks[nostamp] = "1" +do_py_listtasks[recrdeptask] = "do_py_listtasks" +python do_py_listtasks() { + import sys + for e in d.keys(): + if d.getVarFlag(e, "task") and \ + d.getVarFlag(e, "python"): + sys.stdout.write("%s\n" % e) +} diff --git a/classes/task.bbclass b/classes/task.bbclass new file mode 100644 index 0000000000..4edd704829 --- /dev/null +++ b/classes/task.bbclass @@ -0,0 +1,27 @@ +# Task packages are only used to pull in other packages +# via their dependencies. They are empty. +ALLOW_EMPTY = "1" + +# By default, only the task package itself is in PACKAGES. +# -dbg and -dev flavours are handled by the anonfunc below. +# This means that task recipes used to build multiple task +# packages have to modify PACKAGES after inheriting task.bbclass. +PACKAGES = "${PN}" + +# By default, task packages do not depend on a certain architecture. +# Only if dependencies are modified by MACHINE_FEATURES, packages +# need to be set to MACHINE_ARCH after inheriting task.bbclass +PACKAGE_ARCH = "all" + +# This automatically adds -dbg and -dev flavours of all PACKAGES +# to the list. Their dependencies (RRECOMMENDS) are handled as usual +# by package_depchains in a following step. +python () { + packages = bb.data.getVar('PACKAGES', d, 1).split() + genpackages = [] + for pkg in packages: + for postfix in ['-dbg', '-dev']: + genpackages.append(pkg+postfix) + bb.data.setVar('PACKAGES', ' '.join(packages+genpackages), d) +} + diff --git a/classes/test.bbclass b/classes/test.bbclass index 71afe88404..ff3e945395 100644 --- a/classes/test.bbclass +++ b/classes/test.bbclass @@ -7,7 +7,7 @@ # -addtask test after do_compile +addtask test after do_compile before do_build test_do_test () { : } diff --git a/classes/testlab.bbclass b/classes/testlab.bbclass new file mode 100644 index 0000000000..fc923c5112 --- /dev/null +++ b/classes/testlab.bbclass @@ -0,0 +1,65 @@ +# +# Performs various tests and analysises on images +# +# Copyright (C) 2007, 2008 Koen Kooi <koen@openembedded.org> + +# The current features are: +# 1) dump a list of installed packages +# 2) dump a list of sizes of installed packages +# 3) dependency graphs of installed packages + +# See +# * http://dominion.thruhere.net/koen/cms/the-testlab-strikes-again +# * http://dominion.thruhere.net/koen/cms/package-relations-inside-images +# for use cases + +# TODO: +# * log information to a server for safekeeping +# * use mtn certs to record this info into the scm +# * add test suite to run on the target device + + +# Needs 'dot', 'opkg-cl' + +do_testlab() { +if [ -e ${IMAGE_ROOTFS}/etc/opkg ] && [ "${ONLINE_PACKAGE_MANAGEMENT}" = "full" ] ; then + + TESTLAB_DIR="${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}-testlab" + mkdir -p ${TESTLAB_DIR}/ + ls -laR ${IMAGE_ROOTFS} > ${TESTLAB_DIR}/files-in-image.txt + + echo > ${TESTLAB_DIR}/installed-packages.txt + echo -e "digraph depends {\n node [shape=plaintext]" > ${TESTLAB_DIR}/depends.dot + + for pkg in $(opkg-cl -f ${IMAGE_ROOTFS}/etc/opkg -o ${IMAGE_ROOTFS} list_installed | awk '{print $1}') ; do + opkg-cl -f ${IMAGE_ROOTFS}/etc/opkg -o ${IMAGE_ROOTFS} info $pkg | awk '/Package/ {printf $2"_"} /Version/ {printf $2"_"} /Archi/ {print $2".ipk"}' >> ${TESTLAB_DIR}/installed-packages.txt + + for depends in $(opkg-cl -f ${IMAGE_ROOTFS}/etc/opkg -o ${IMAGE_ROOTFS} info $pkg | grep Depends) ; do + echo "$pkg OPP $depends;" | grep -v "(" | grep -v ")" | grep -v Depends | sed -e 's:,::g' -e 's:-:_:g' -e 's:\.:_:g' -e 's:+::g' |sed 's:OPP:->:g' >> ${TESTLAB_DIR}/depends.dot + done + + for recommends in $(opkg-cl -f ${IMAGE_ROOTFS}/etc/opkg -o ${IMAGE_ROOTFS} info $pkg | grep Recom) ; do + echo "$pkg OPP $recommends [style=dotted];" | grep -v "(" | grep -v ")" | grep -v Recom | sed -e 's:,::g' -e 's:-:_:g' -e 's:\.:_:g' -e 's:+::g' |sed 's:OPP:->:g' >> ${TESTLAB_DIR}/depends.dot + done + done + + echo "}" >> ${TESTLAB_DIR}/depends.dot + + grep -v kernel_2 ${TESTLAB_DIR}/depends.dot | grep -v kernel_image > ${TESTLAB_DIR}/depends-nokernel.dot + grep -v libc6 ${TESTLAB_DIR}/depends-nokernel.dot | grep -v libgcc > ${TESTLAB_DIR}/depends-nokernel-nolibc.dot + grep -v update_ ${TESTLAB_DIR}/depends-nokernel-nolibc.dot > ${TESTLAB_DIR}/depends-nokernel-nolibc-noupdate.dot + grep -v kernel_module ${TESTLAB_DIR}/depends-nokernel-nolibc-noupdate.dot > ${TESTLAB_DIR}/depends-nokernel-nolibc-noupdate-nomodules.dot + + #dot has some library troubles when run under fakeroot, uncomment at your own risk + #dot -Tpng -o ${TESTLAB_DIR}/image-dependencies.png ${TESTLAB_DIR}/depends.dot + #dot -Tpng -o ${TESTLAB_DIR}/image-dependencies-nokernel-nolibc.png ${TESTLAB_DIR}/depends-nokernel-nolibc.dot + #dot -Tpng -o ${TESTLAB_DIR}/image-dependencies-nokernel-nolibc-noupdate.png ${TESTLAB_DIR}/depends-nokernel-nolibc-noupdate.dot + #dot -Tpng -o ${TESTLAB_DIR}/image-dependencies-nokernel-nolibc-noupdate-nomodules.png ${TESTLAB_DIR}/depends-nokernel-nolibc-noupdate-nomodules.dot + + for file in $(cat ${TESTLAB_DIR}/installed-packages.txt) ; do + du -k $(find ${DEPLOY_DIR_IPK} -name "$file") | head -n1 + done | grep "\.ipk" | sed -e s:${DEPLOY_DIR_IPK}::g | sort -n -r | awk '{print $1 "\tKiB " $2}' > ${TESTLAB_DIR}/installed-package-sizes.txt +fi +} + +IMAGE_POSTPROCESS_COMMAND += " do_testlab ;" diff --git a/classes/tinderclient.bbclass b/classes/tinderclient.bbclass index d36ef0b343..a45c1e679b 100644 --- a/classes/tinderclient.bbclass +++ b/classes/tinderclient.bbclass @@ -1,10 +1,19 @@ -def tinder_http_post(server, selector, content_type, body): +def tinder_http_post(d, server, selector, content_type, body): import httplib # now post it for i in range(0,5): try: - h = httplib.HTTP(server) - h.putrequest('POST', selector) + proxy = data.getVar('HTTP_PROXY', d, True ) + if (proxy): + if (proxy.endswith('/')): + proxy = proxy[:-1] + if (proxy.startswith('http://')): + proxy = proxy[7:] + h = httplib.HTTP(proxy) + h.putrequest('POST', 'http://%s%s' % (server, selector)) + else: + h = httplib.HTTP(server) + h.putrequest('POST', selector) h.putheader('content-type', content_type) h.putheader('content-length', str(len(body))) h.endheaders() @@ -12,8 +21,8 @@ def tinder_http_post(server, selector, content_type, body): errcode, errmsg, headers = h.getreply() #print errcode, errmsg, headers return (errcode,errmsg, headers, h.file) - except: - print "Error sending the report!" + except Exception, e: + print "Error sending the report! ", e # try again pass @@ -24,6 +33,7 @@ def tinder_form_data(bound, dict, log): output = [] # for each key in the dictionary for name in dict: + assert dict[name] output.append( "--" + bound ) output.append( 'Content-Disposition: form-data; name="%s"' % name ) output.append( "" ) @@ -50,8 +60,7 @@ def tinder_format_http_post(d,status,log): for the tinderbox to be happy. """ - from bb import data, build - import os,random + import random # the variables we will need to send on this form post variables = { @@ -60,7 +69,17 @@ def tinder_format_http_post(d,status,log): "os" : os.uname()[0], "os_version" : os.uname()[2], "compiler" : "gcc", - "clobber" : data.getVar('TINDER_CLOBBER', d, True) + "clobber" : data.getVar('TINDER_CLOBBER', d, True) or "0", + "srcdate" : data.getVar('SRCDATE', d, True), + "PN" : data.getVar('PN', d, True), + "PV" : data.getVar('PV', d, True), + "PR" : data.getVar('PR', d, True), + "FILE" : data.getVar('FILE', d, True) or "N/A", + "TARGETARCH" : data.getVar('TARGET_ARCH', d, True), + "TARGETFPU" : data.getVar('TARGET_FPU', d, True) or "Unknown", + "TARGETOS" : data.getVar('TARGET_OS', d, True) or "Unknown", + "MACHINE" : data.getVar('MACHINE', d, True) or "Unknown", + "DISTRO" : data.getVar('DISTRO', d, True) or "Unknown", } # optionally add the status @@ -104,7 +123,7 @@ def tinder_build_start(d): #print "selector %s and url %s" % (selector, url) # now post it - errcode, errmsg, headers, h_file = tinder_http_post(server,selector,content_type, body) + errcode, errmsg, headers, h_file = tinder_http_post(d,server,selector,content_type, body) #print errcode, errmsg, headers report = h_file.read() @@ -139,7 +158,7 @@ def tinder_send_http(d, status, _log): new_log = _log while len(new_log) > 0: content_type, body = tinder_format_http_post(d,status,new_log[0:18000]) - errcode, errmsg, headers, h_file = tinder_http_post(server,selector,content_type, body) + errcode, errmsg, headers, h_file = tinder_http_post(d,server,selector,content_type, body) #print errcode, errmsg, headers #print h.file.read() new_log = new_log[18000:] @@ -316,7 +335,7 @@ def tinder_do_tinder_report(event): log += "<--- TINDERBOX Package %s done (SUCCESS)\n" % data.getVar('PF', event.data, True) elif name == "PkgFailed": if not data.getVar('TINDER_AUTOBUILD', event.data, True) == "0": - build.exec_task('do_clean', event.data) + build.exec_func('do_clean', event.data) log += "<--- TINDERBOX Package %s failed (FAILURE)\n" % data.getVar('PF', event.data, True) status = 200 # remember the failure for the -k case @@ -359,7 +378,11 @@ def tinder_do_tinder_report(event): addhandler tinderclient_eventhandler python tinderclient_eventhandler() { from bb import note, error, data - from bb.event import NotHandled + from bb.event import NotHandled, getName + + if e.data is None or getName(e) == "MsgNote": + return NotHandled + do_tinder_report = data.getVar('TINDER_REPORT', e.data, True) if do_tinder_report and do_tinder_report == "1": tinder_do_tinder_report(e) diff --git a/classes/tmake.bbclass b/classes/tmake.bbclass index 05b82e496d..dbd0bf2763 100644 --- a/classes/tmake.bbclass +++ b/classes/tmake.bbclass @@ -54,7 +54,7 @@ python tmake_do_createpro() { } tmake_do_configure() { - paths="${STAGING_DATADIR}/tmake/qws/${TARGET_OS}-${TARGET_ARCH}-g++ $STAGING_DIR/share/tmake/$OS-g++" + paths="${STAGING_DATADIR}/tmake/qws/${TARGET_OS}-${TARGET_ARCH}-g++ ${STAGING_DATADIR}/tmake/$OS-g++" if (echo "${TARGET_ARCH}"|grep -q 'i.86'); then paths="${STAGING_DATADIR}/tmake/qws/${TARGET_OS}-x86-g++ $paths" fi diff --git a/classes/turbostation-image.bbclass b/classes/turbostation-image.bbclass new file mode 100644 index 0000000000..5a0768c687 --- /dev/null +++ b/classes/turbostation-image.bbclass @@ -0,0 +1,32 @@ +turbostation_pack_image() { + # find latest kernel + KERNEL=`ls -tr ${DEPLOY_DIR_IMAGE}/uImage* | tail -1` + if [ -z "$KERNEL" ]; then + oefatal "No kernel found in ${DEPLOY_DIR_IMAGE}. Bitbake linux-turbostation to create one." + exit 1 + fi + ROOTFS=${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.jffs2 + OUTPUT=${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.flash.img + PADFILE=${DEPLOY_DIR_IMAGE}/padfile.zzz + HEX_MAX_KERN_SIZE=200000 + DEC_MAX_KERN_SIZE=`echo "ibase=16; $HEX_MAX_KERN_SIZE" | bc ` + HEX_MAX_ROOT_SIZE=D00000 + DEC_MAX_ROOT_SIZE=`echo "ibase=16; $HEX_MAX_ROOT_SIZE" | bc ` + KERNEL_SIZE=`ls -l $KERNEL | awk '{print $5}'` + if [ $KERNEL_SIZE -gt $DEC_MAX_KERN_SIZE ]; then + oefatal "Kernel too large at $KERNEL_SIZE bytes. Max is $DEC_MAX_KERN_SIZE." + exit 1 + fi + ROOT_SIZE=`ls -l $ROOTFS | awk '{print $5}'` + if [ $ROOT_SIZE -gt $DEC_MAX_ROOT_SIZE ]; then + oefatal "Rootfs is too large at $ROOT_SIZE bytes. Max is $DEC_MAX_ROOT_SIZE." + exit 1 + fi + PAD_SIZE=`echo "$DEC_MAX_KERN_SIZE - $KERNEL_SIZE" | bc ` + dd if=/dev/zero of=$PADFILE bs=$PAD_SIZE count=1 2>>/dev/null + cat $KERNEL $PADFILE $ROOTFS > $OUTPUT + rm -f $PADFILE + ls -l $OUTPUT +} + +IMAGE_POSTPROCESS_COMMAND += "turbostation_pack_image; " diff --git a/classes/update-alternatives.bbclass b/classes/update-alternatives.bbclass index 6b2b547d5f..ddbf4c1947 100644 --- a/classes/update-alternatives.bbclass +++ b/classes/update-alternatives.bbclass @@ -10,11 +10,14 @@ update_alternatives_postrm() { update-alternatives --remove ${ALTERNATIVE_NAME} ${ALTERNATIVE_PATH} } +def update_alternatives_after_parse(d): + if bb.data.getVar('ALTERNATIVE_NAME', d) == None: + raise bb.build.FuncFailed, "%s inherits update-alternatives but doesn't set ALTERNATIVE_NAME" % bb.data.getVar('FILE', d) + if bb.data.getVar('ALTERNATIVE_PATH', d) == None: + raise bb.build.FuncFailed, "%s inherits update-alternatives but doesn't set ALTERNATIVE_PATH" % bb.data.getVar('FILE', d) + python __anonymous() { - if bb.data.getVar('ALTERNATIVE_NAME', d) == None: - raise bb.build.FuncFailed, "%s inherits update-alternatives but doesn't set ALTERNATIVE_NAME" % bb.data.getVar('FILE', d) - if bb.data.getVar('ALTERNATIVE_PATH', d) == None: - raise bb.build.FuncFailed, "%s inherits update-alternatives but doesn't set ALTERNATIVE_PATH" % bb.data.getVar('FILE', d) + update_alternatives_after_parse(d) } python populate_packages_prepend () { diff --git a/classes/update-rc.d.bbclass b/classes/update-rc.d.bbclass index 0bfba467c1..b6491ed9d6 100644 --- a/classes/update-rc.d.bbclass +++ b/classes/update-rc.d.bbclass @@ -1,5 +1,5 @@ DEPENDS_append = " update-rc.d" -RDEPENDS_append = " update-rc.d" +RDEPENDS_${PN}_append = " ${@base_conditional("ONLINE_PACKAGE_MANAGEMENT", "none", "", "update-rc.d", d)}" INITSCRIPT_PARAMS ?= "defaults" @@ -7,31 +7,48 @@ INIT_D_DIR = "${sysconfdir}/init.d" updatercd_postinst() { if test "x$D" != "x"; then - D="-r $D" + OPT="-r $D" else - D="-s" + OPT="-s" fi -update-rc.d $D ${INITSCRIPT_NAME} ${INITSCRIPT_PARAMS} +update-rc.d $OPT ${INITSCRIPT_NAME} ${INITSCRIPT_PARAMS} } updatercd_prerm() { -if test "x$D" != "x"; then - D="-r $D" -else - ${INIT_D_DIR}/${INITSCRIPT_NAME} stop +if test "x$D" = "x"; then + if test "$1" = "upgrade" -o "$1" = "remove"; then + ${INIT_D_DIR}/${INITSCRIPT_NAME} stop + fi fi } +# Note: to be Debian compliant, we should only invoke update-rc.d remove +# at the "purge" step, but opkg does not support it. So instead we also +# run it at the "remove" step if the init script no longer exists. + updatercd_postrm() { -update-rc.d $D ${INITSCRIPT_NAME} remove +if test "x$D" != "x"; then + OPT="-r $D" +else + OPT="" +fi +if test "$1" = "remove" -o "$1" = "purge"; then + if ! test -e "${INIT_D_DIR}/${INITSCRIPT_NAME}"; then + update-rc.d $OPT ${INITSCRIPT_NAME} remove + fi +fi } + +def update_rc_after_parse(d): + if bb.data.getVar('INITSCRIPT_PACKAGES', d) == None: + if bb.data.getVar('INITSCRIPT_NAME', d) == None: + raise bb.build.FuncFailed, "%s inherits update-rc.d but doesn't set INITSCRIPT_NAME" % bb.data.getVar('FILE', d) + if bb.data.getVar('INITSCRIPT_PARAMS', d) == None: + raise bb.build.FuncFailed, "%s inherits update-rc.d but doesn't set INITSCRIPT_PARAMS" % bb.data.getVar('FILE', d) + python __anonymous() { - if bb.data.getVar('INITSCRIPT_PACKAGES', d) == None: - if bb.data.getVar('INITSCRIPT_NAME', d) == None: - raise bb.build.FuncFailed, "%s inherits update-rc.d but doesn't set INITSCRIPT_NAME" % bb.data.getVar('FILE', d) - if bb.data.getVar('INITSCRIPT_PARAMS', d) == None: - raise bb.build.FuncFailed, "%s inherits update-rc.d but doesn't set INITSCRIPT_PARAMS" % bb.data.getVar('FILE', d) + update_rc_after_parse(d) } python populate_packages_prepend () { @@ -42,10 +59,12 @@ python populate_packages_prepend () { bb.data.setVar("OVERRIDES", "%s:%s" % (pkg, overrides), localdata) bb.data.update_data(localdata) - postinst = bb.data.getVar('pkg_postinst', localdata, 1) - if not postinst: - postinst = '#!/bin/sh\n' + postinst = '#!/bin/sh\n' postinst += bb.data.getVar('updatercd_postinst', localdata, 1) + try: + postinst += bb.data.getVar('pkg_postinst', localdata, 1) + except: + pass bb.data.setVar('pkg_postinst_%s' % pkg, postinst, d) prerm = bb.data.getVar('pkg_prerm', localdata, 1) if not prerm: diff --git a/classes/vala.bbclass b/classes/vala.bbclass new file mode 100644 index 0000000000..125820c00c --- /dev/null +++ b/classes/vala.bbclass @@ -0,0 +1,14 @@ +DEPENDS += "vala-native" + +FILES_${PN}-dev += "\ + ${datadir}/vala/vapi/*.vapi \ + ${datadir}/vala/vapi/*.deps \ +" + +# .vapi and .deps files are arch independent and need to be present in the +# staging datadir for the native vala compiler +do_stage_append() { + install -d ${STAGING_DATADIR_NATIVE}/vala/vapi + find . -name "*.vapi" -exec install -m 0644 {} ${STAGING_DATADIR_NATIVE}/vala/vapi/ \; + find . -name "*.deps" -exec install -m 0644 {} ${STAGING_DATADIR_NATIVE}/vala/vapi/ \; +} diff --git a/classes/wrt-image.bbclass b/classes/wrt-image.bbclass index ba1163a719..45d9ac923f 100644 --- a/classes/wrt-image.bbclass +++ b/classes/wrt-image.bbclass @@ -3,7 +3,7 @@ ROOTFS_POSTPROCESS_COMMAND += "rm -f ${IMAGE_ROOTFS}/boot/zImage*" def wrt_get_kernel_version(d): import bb - if bb.data.inherits_class('image_ipk', d): + if bb.data.inherits_class('image', d): skd = bb.data.getVar('STAGING_KERNEL_DIR', d, 1) return base_read_file(skd+'/kernel-abiversion') return "-no kernel version for available-" diff --git a/classes/xfce.bbclass b/classes/xfce.bbclass index 793348597f..db6329c4ad 100644 --- a/classes/xfce.bbclass +++ b/classes/xfce.bbclass @@ -5,15 +5,23 @@ # Global class to make it easier to maintain XFCE packages HOMEPAGE = "http://www.xfce.org" -LICENSE = "LGPL-2" +LICENSE = "LGPLv2" +DEPENDS += "startup-notification" -SRC_URI = "http://www.us.xfce.org/archive/xfce-${PV}/src/${PN}-${PV}.tar.gz" +XFCE_VERSION = ${PV} +SRC_URI = "http://www.us.xfce.org/archive/xfce/${XFCE_VERSION}/src/${PN}-${PV}.tar.bz2" inherit autotools +AUTOTOOLS_STAGE_PKGCONFIG = "1" + EXTRA_OECONF += "--with-pluginsdir=${libdir}/xfce4/panel-plugins/" # FIXME: Put icons in their own package too? FILES_${PN} += "${datadir}/icons/* ${datadir}/applications/* ${libdir}/xfce4/modules/*.so*" FILES_${PN}-doc += "${datadir}/xfce4/doc" + +FILES_${PN}-dev += "${libdir}/xfce4/*/*.la" +FILES_${PN}-dbg += "${libdir}/xfce4/*/.debug" + diff --git a/classes/xfce46.bbclass b/classes/xfce46.bbclass new file mode 100644 index 0000000000..c24dfa4d8c --- /dev/null +++ b/classes/xfce46.bbclass @@ -0,0 +1,28 @@ +# xfce46.bbclass + +# Global class to help maintain XFCE 4.6.* packages + +HOMEPAGE = "http://www.xfce.org" +LICENSE = "LGPLv2" + +DEPENDS += "startup-notification" + +SECTION ?= "x11/xfce" + +XFCE_VERSION = ${PV} + +SRC_URI = "http://mocha.xfce.org/archive/src/xfce/${PN}/${@'${PV}'[0:3]}/${PN}-${PV}.tar.bz2" + +inherit autotools gtk-icon-cache pkgconfig + +AUTOTOOLS_STAGE_PKGCONFIG = "1" + +EXTRA_OECONF += "--with-pluginsdir=${libdir}/xfce4/panel-plugins/" + +# FIXME: Put icons in their own package too? + +FILES_${PN} += "${datadir}/icons/* ${datadir}/applications/* ${libdir}/xfce4/modules/*.so*" +FILES_${PN}-doc += "${datadir}/xfce4/doc" + +FILES_${PN}-dev += "${libdir}/xfce4/*/*.la" +FILES_${PN}-dbg += "${libdir}/xfce4/*/.debug" diff --git a/classes/xilinx-bsp.bbclass b/classes/xilinx-bsp.bbclass new file mode 100644 index 0000000000..f657e5be94 --- /dev/null +++ b/classes/xilinx-bsp.bbclass @@ -0,0 +1,53 @@ +# Copyright (C) 2007, Stelios Koroneos - Digital OPSiS, All Rights Reserved +# Released under the MIT license (see packages/COPYING) +# +#This class handles all the intricasies of getting the required files from the +#ISE/EDK/project to the kernel and prepare the kernel for compilation. +#The Xilinx EDK supports 2 different architectures : PowerPC (ppc 405) and Microblaze +#Only the PowerPC BSP has been tested so far +#For this to work correctly you need to add XILINX_BSP_PATH and XILINX_BOARD to your +#local.conf +#XILINX_BSP_PATH should have the complete path to your project dir +#XILINX_BOARD should have the board type i.e ML403 +# +#Currently supported boards +#Xilinx ML403 +#More to come soon ;) + +do_configure_prepend() { + + +#first check that the XILINX_BSP_PATH and XILINX_BOARD have been defined in local.conf +if [ -z "${XILINX_BSP_PATH}" ]; then + oefatal "XILINX_BSP_PATH not defined ! Exiting..." + exit 1 + +else + if [ -z "${XILINX_BOARD}" ]; then + oefatal "XILINX_BOARD not defined ! Exiting" + exit 1 + fi + +fi +#now depending on the board type and arch do what is nessesary + +case "${XILINX_BOARD}" in + ML403) + oenote "ML403 board setup" + cp -pPR ${XILINX_BSP_PATH}/ppc405_0/libsrc/linux_2_6_v1_00_a/linux/arch/ppc/platforms/4xx/xparameters/xparameters_ml40x.h \ + ${S}/arch/ppc/platforms/4xx/xparameters/xparameters_ml403.h + ;; + + * ) + oefatal "! Unknow Xilinx board ! Exiting..." + exit 1 + ;; +esac + + +} + + + + + diff --git a/classes/xlibs.bbclass b/classes/xlibs.bbclass index e797748770..fc52400b9f 100644 --- a/classes/xlibs.bbclass +++ b/classes/xlibs.bbclass @@ -6,10 +6,10 @@ XLIBS_CVS = "${FREEDESKTOP_CVS}/xlibs" inherit autotools pkgconfig do_stage() { - oe_runmake install prefix=${STAGING_DIR} \ + oe_runmake install prefix=${STAGING_DIR_HOST}${prefix} \ bindir=${STAGING_BINDIR} \ includedir=${STAGING_INCDIR} \ libdir=${STAGING_LIBDIR} \ datadir=${STAGING_DATADIR} \ - mandir=${STAGING_DATADIR}/man + mandir=${STAGING_DIR_HOST}${mandir} } diff --git a/classes/xorg-module.bbclass b/classes/xorg-module.bbclass new file mode 100644 index 0000000000..135ca31c16 --- /dev/null +++ b/classes/xorg-module.bbclass @@ -0,0 +1,31 @@ +python populate_packages_prepend () { + import re, os.path + + new_packages = [] + + def the_hook(file, pkg, pattern, format, basename): + new_packages.append(pkg) + + do_split_packages(d, root=bb.data.expand('${libdir}/xorg/modules/drivers', d), file_regex='(.*)_drv\.so', output_pattern='xorg-driver-%s', description='xorg %s driver', extra_depends='xserver-xorg', hook=the_hook) + + packages = bb.data.getVar('PACKAGES', d, 1).split() + + so_to_la_re = "\.so$" + + # fish out any debug or devel files corresponding to the new packages + for p in new_packages: + packages.append("%s-dbg" % p) + packages.append("%s-dev" % p) + + files = bb.data.getVar("FILES_%s" % p, d).split() + dev_files = [] + dbg_files = [] + for f in files: + dev_files.append(re.sub(so_to_la_re, ".la", f)) + (dir, file) = os.path.split(f) + dbg_files.append(os.path.join(dir, ".debug", file)) + bb.data.setVar("FILES_%s-dbg" % p, " ".join(dbg_files), d) + bb.data.setVar("FILES_%s-dev" % p, " ".join(dev_files), d) + + bb.data.setVar('PACKAGES', ' '.join(packages), d) +} |
