diff options
Diffstat (limited to 'classes/insane.bbclass')
| -rw-r--r-- | classes/insane.bbclass | 164 |
1 files changed, 119 insertions, 45 deletions
diff --git a/classes/insane.bbclass b/classes/insane.bbclass index 1f7c761b47..804caf06ee 100644 --- a/classes/insane.bbclass +++ b/classes/insane.bbclass @@ -31,6 +31,9 @@ PACKAGEFUNCS += " do_package_qa " # 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), @@ -58,8 +61,11 @@ def package_qa_get_machine_dict(): "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), @@ -68,10 +74,16 @@ def package_qa_get_machine_dict(): "arm" : (40, 0, 0, True, True), "armeb" : (40, 0, 0, False, True), }, - "linux-uclibcgnueabi" : { + "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), + }, } @@ -166,10 +178,10 @@ def package_qa_get_elf(path, bits32): # 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""" - import bb return path.replace(bb.data.getVar('TMPDIR',d,True),"") def package_qa_make_fatal_error(error_class, name, path,d): @@ -184,7 +196,6 @@ def package_qa_write_error(error_class, name, path, d): """ Log the error """ - import bb, os 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 @@ -199,6 +210,7 @@ def package_qa_write_error(error_class, name, path, d): "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" ) @@ -208,15 +220,17 @@ def package_qa_write_error(error_class, name, path, d): f.close() def package_qa_handle_error(error_class, error_msg, name, path, d): - import bb - bb.error("QA Issue: %s" % error_msg) + 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): +def package_qa_check_rpath(file,name,d, elf): """ Check for dangerous RPATHs """ + if not elf: + return True + import bb, os sane = True scanelf = os.path.join(bb.data.getVar('STAGING_BINDIR_NATIVE',d,True),'scanelf') @@ -237,21 +251,33 @@ def package_qa_check_rpath(file,name,d): 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, os 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" 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 '.debug' in path: error_msg = "non debug package contains .debug directory: %s path %s" % \ @@ -260,25 +286,28 @@ def package_qa_check_devdbg(path, name,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 """ 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 """ - import bb, os + 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 - if bb.data.inherits_class('cross', d) or bb.data.inherits_class('sdk', d): - return True + 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... @@ -288,11 +317,6 @@ def package_qa_check_arch(path,name,d): #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] - elf = package_qa_get_elf(path, bits32) - try: - elf.open() - except: - return True # Check the architecture and endiannes of the binary if not machine == elf.machine(): @@ -306,11 +330,10 @@ def package_qa_check_arch(path,name,d): return sane -def package_qa_check_desktop(path, name, d): +def package_qa_check_desktop(path, name, d, elf): """ Run all desktop files through desktop-file-validate. """ - import bb, os sane = True if path.endswith(".desktop"): output = os.popen("desktop-file-validate %s" % path) @@ -320,6 +343,47 @@ def package_qa_check_desktop(path, name, d): return sane +def package_qa_hash_style(path, name, d, elf): + """ + 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 @@ -329,17 +393,18 @@ def package_qa_check_staged(path,d): to find the one responsible for the errors easily even if we look at every .pc and .la file """ - import os, bb sane = True tmpdir = bb.data.getVar('TMPDIR', d, True) workdir = os.path.join(tmpdir, "work") installed = "installed=yes" - if bb.data.inherits_class("native", d) or bb.data.inherits_class("cross", d): - pkgconfigcheck = workdir - else: - pkgconfigcheck = tmpdir + 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 @@ -350,7 +415,7 @@ def package_qa_check_staged(path,d): if file[-2:] == "la": file_content = open(path).read() # Don't check installed status for native/cross packages - if not bb.data.inherits_class("native", d) and not bb.data.inherits_class("cross", d): + 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) @@ -367,26 +432,35 @@ def package_qa_check_staged(path,d): # 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: - if not func(path, package,d): + if not func(path, package,d, elf): sane = False return sane -def package_qa_check_rdepends(pkg, workdir, d): - import bb +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/install/%s" % (workdir, pkg) + root = "%s/%s" % (pkgdest, pkg) bb.data.setVar('ROOT', '', localdata) bb.data.setVar('ROOT_%s' % pkg, root, localdata) @@ -417,41 +491,42 @@ def package_qa_check_rdepends(pkg, workdir, d): # 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_devdbg, + checks = [package_qa_check_rpath, package_qa_check_dev, package_qa_check_perm, package_qa_check_arch, - package_qa_check_desktop] + package_qa_check_desktop, package_qa_hash_style, + package_qa_check_dbg] walk_sane = True rdepends_sane = True for package in packages.split(): if bb.data.getVar('INSANE_SKIP_' + package, d, True): - bb.note("Package: %s (skipped)" % package) + bb.note("package %s skipped" % package) continue - bb.note("Checking Package: %s" % package) - path = "%s/install/%s" % (workdir, package) + 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, workdir, d): + 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.note("DONE with PACKAGE QA") + 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("QA checking staging") + 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") @@ -460,8 +535,7 @@ python do_qa_staging() { # Check broken config.log files addtask qa_configure after do_configure before do_compile python do_qa_configure() { - bb.note("Checking sanity of the config.log file") - import os + 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") |
