# 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),
"i686": ( 3, 0, 0, True, 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),
# 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"""
"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" )
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')
return sane
-def package_qa_check_devdbg(path, name,d):
+def package_qa_check_devdbg(path, name,d, elf):
"""
Check for debug remains inside the binary or
non dev packages containing
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
"""
+ if not elf:
+ return True
+
import bb, os
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...
#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():
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.
"""
return sane
+def package_qa_hash_style(path, name, d, elf):
+ """
+ Check if the binary has the right hash style...
+ """
+ import bb, os
+
+ 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
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
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)
# Walk over all files in a directory and call func
def package_qa_walk(path, funcs, package,d):
- import os
+ import bb, 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
# The PACKAGE FUNC to scan each package
python do_package_qa () {
+ import bb
bb.note("DO PACKAGE QA")
workdir = bb.data.getVar('WORKDIR', d, True)
packages = bb.data.getVar('PACKAGES',d, True)
checks = [package_qa_check_rpath, package_qa_check_devdbg,
package_qa_check_perm, package_qa_check_arch,
- package_qa_check_desktop]
+ package_qa_check_desktop, package_qa_hash_style]
walk_sane = True
rdepends_sane = True
for package in packages.split():