[OE-core] [PATCH] package: let dependency on a package name to be architecture specific

Ming Liu ming.liu at windriver.com
Fri Mar 7 07:51:36 UTC 2014


On 03/07/2014 03:26 PM, Richard Purdie wrote:
> On Wed, 2014-03-05 at 18:08 +0800, Ming Liu wrote:
>> For multilib builds that rpm is the first package backend, it would be
>> often desireable to express that a package of compatible architecture
>> is needed to satisfy a dependency. In most of the cases this is already
>> handled by the automatically extracted soname dependencies, but this is
>> not always the case: sometimes it's necessary to disable the automatic
>> dependency generation, and then there are cases where the information
>> cannot be automatically generated, such as: -dev package dependencies
>> on other -dev packages or plugins are dynamically loaded via dlopen,
>> leading to obscure build failure that a 32bit package would incorrectly
>> satisfy the dependency for a 64bit package and similarly vice versa.
>>
>> The patch mainly aims to resolve this problem, the basic idea is adding
>> a ARCH_SPECIFIC variable for packages satisfying following scenarios:
>>    * when rpm is being set as the first package backend
> I don't like this idea at all. It shouldn't matter whether rpm is set
> first or last, it should behave the same.
>
> I'm also rather dubious about this patch in general. It seems wrong to
> have to put this into generic code for what amounts to an rpm backend
> issue.
I was so thoughtless. Yes, you are correct, I should move them into 
pakcage_rpm.bbclass.

>
> Finally, this patch causes build failures in do_package_write_deb:
>
> eg:
>
> http://autobuilder.yoctoproject.org/main/builders/build-appliance/builds/61/steps/BuildImages_1/logs/stdio
> http://autobuilder.yoctoproject.org/main/builders/nightly-arm/builds/82/steps/BuildImages/logs/stdio
>
> and many more. I'm trying to get the tree stablised and having build
> failures like this is extremely frustrating as once again I'm blocked on
> merging patches until I remove this patch and run another build :(
Sorry about that, I only test it with rpm and ipk, then I thought it 
should not impact deb, I will try to figure out the V2 patch and give it 
a full test.

//Ming Liu
>
> Cheers,
>
> Richard
>
>
>
>>    * it's not a allarch package
>>    * it only provides libs without bins meanwhile
>>
>> Every satisfied package would be set with
>> "ARCH_SPECIFIC_pkgname = 1:${TARGET_ARCH}" and it's gonna be written into
>> pkgdata if it exists, to mark the package as architecture specific, and
>> it will be checked during runtime_mapping_rename, all architecture
>> specific dependencies would be expanded with a ${TARGET_ARCH} suffix,
>> that declares a dependency on a package name architecture specific and
>> permits differentiating between 32-bit and 64-bit versions.
>>
>> Off course, the user could set "ARCH_SPECIFIC_pkgname = 0" in recipes to
>> disable this feature.
>>
>> Signed-off-by: Ming Liu <ming.liu at windriver.com>
>> ---
>>   meta/classes/image.bbclass             |    6 +-
>>   meta/classes/package.bbclass           |   78 ++++++++++++++++++++++++++------
>>   meta/classes/populate_sdk_base.bbclass |    2 +-
>>   3 files changed, 68 insertions(+), 18 deletions(-)
>>
>> diff --git a/meta/classes/image.bbclass b/meta/classes/image.bbclass
>> index 28b68f9..670f173 100644
>> --- a/meta/classes/image.bbclass
>> +++ b/meta/classes/image.bbclass
>> @@ -225,9 +225,9 @@ do_rootfs[prefuncs] += "rootfs_process_ignore"
>>   # may have occurred.
>>   python rootfs_runtime_mapping() {
>>       pn = d.getVar('PN', True)
>> -    runtime_mapping_rename("PACKAGE_INSTALL", pn, d)
>> -    runtime_mapping_rename("PACKAGE_INSTALL_ATTEMPTONLY", pn, d)
>> -    runtime_mapping_rename("BAD_RECOMMENDATIONS", pn, d)
>> +    runtime_mapping_rename("PACKAGE_INSTALL", pn, False, d)
>> +    runtime_mapping_rename("PACKAGE_INSTALL_ATTEMPTONLY", pn, False, d)
>> +    runtime_mapping_rename("BAD_RECOMMENDATIONS", pn, False, d)
>>   }
>>   do_rootfs[prefuncs] += "rootfs_runtime_mapping"
>>   
>> diff --git a/meta/classes/package.bbclass b/meta/classes/package.bbclass
>> index 0018a62..3e0ca30 100644
>> --- a/meta/classes/package.bbclass
>> +++ b/meta/classes/package.bbclass
>> @@ -346,19 +346,29 @@ def copydebugsources(debugsrcdir, d):
>>   # Package data handling routines
>>   #
>>   
>> -def get_package_mapping (pkg, basepkg, d):
>> +def get_package_mapping (pkg, basepkg, check_arch, d):
>>       import oe.packagedata
>>   
>> +    ret = pkg
>>       data = oe.packagedata.read_subpkgdata(pkg, d)
>> -    key = "PKG_%s" % pkg
>> +    pkg_key = "PKG_%s" % pkg
>> +    arch_key = "ARCH_SPECIFIC_%s" % pkg
>> +    arch_specific = '0'
>>   
>> -    if key in data:
>> +    if pkg_key in data:
>>           # Have to avoid undoing the write_extra_pkgs(global_variants...)
>> -        if bb.data.inherits_class('allarch', d) and data[key] == basepkg:
>> +        if bb.data.inherits_class('allarch', d) and data[pkg_key] == basepkg:
>>               return pkg
>> -        return data[key]
>> +        ret = data[pkg_key]
>>   
>> -    return pkg
>> +    if arch_key in data:
>> +        arch_specific = data[arch_key]
>> +
>> +    items = arch_specific.split(':')
>> +    if len(items) > 1 and items[0] == '1' and check_arch == True:
>> +        ret += '(' + items[1] + ')'
>> +
>> +    return ret
>>   
>>   def get_package_additional_metadata (pkg_type, d):
>>       base_key = "PACKAGE_ADD_METADATA"
>> @@ -371,13 +381,13 @@ def get_package_additional_metadata (pkg_type, d):
>>           metadata_fields = [field.strip() for field in oe.data.typed_value(key, d)]
>>           return "\n".join(metadata_fields).strip()
>>   
>> -def runtime_mapping_rename (varname, pkg, d):
>> +def runtime_mapping_rename (varname, pkg, check_arch, d):
>>       #bb.note("%s before: %s" % (varname, d.getVar(varname, True)))
>>   
>>       new_depends = {}
>>       deps = bb.utils.explode_dep_versions2(d.getVar(varname, True) or "")
>>       for depend in deps:
>> -        new_depend = get_package_mapping(depend, pkg, d)
>> +        new_depend = get_package_mapping(depend, pkg, check_arch, d)
>>           new_depends[new_depend] = deps[depend]
>>   
>>       d.setVar(varname, bb.utils.join_deps(new_depends, commasep=False))
>> @@ -1119,6 +1129,34 @@ python package_fixsymlinks () {
>>           d.setVar('RDEPENDS_' + pkg, bb.utils.join_deps(rdepends, commasep=False))
>>   }
>>   
>> +python package_check_arch () {
>> +    import glob, re
>> +
>> +    def check_arch_specific(pkg):
>> +        bin_re = re.compile(".*/s?" + os.path.basename(d.getVar("bindir", True)) + "$")
>> +        lib_re = re.compile(".*/" + os.path.basename(d.getVar("libdir", True)) + "($|/.*$)")
>> +        has_bins = 0
>> +        has_libs = 0
>> +
>> +        for file in pkgfiles[pkg]:
>> +            root = os.path.dirname(file)
>> +            if bin_re.match(root):
>> +                has_bins = 1
>> +            if lib_re.match(root):
>> +                has_libs = 1
>> +
>> +        if not bb.data.inherits_class('allarch', d) and not has_bins and has_libs:
>> +            if not d.getVar('ARCH_SPECIFIC_' + pkg):
>> +                d.setVar('ARCH_SPECIFIC_' + pkg, "%s:%s" % ('1', d.getVar('TARGET_ARCH', True)))
>> +
>> +    # Do nothing if rpm is not the first package backend
>> +    if d.getVar('PACKAGE_CLASSES', True).split()[0] != "package_rpm":
>> +        return
>> +
>> +    for pkg in sorted((d.getVar('PACKAGES', True) or "").split()):
>> +        check_arch_specific(pkg)
>> +}
>> +
>>   PKGDESTWORK = "${WORKDIR}/pkgdata"
>>   
>>   python emit_pkgdata() {
>> @@ -1184,6 +1222,16 @@ python emit_pkgdata() {
>>               pkgval = pkg
>>               d.setVar('PKG_%s' % pkg, pkg)
>>   
>> +        arch_specific = d.getVar('ARCH_SPECIFIC_%s' % pkg, True) or ""
>> +        items = arch_specific.split(':')
>> +        if len(items) > 1 and items[0] == '1':
>> +            rprovides = d.getVar('RPROVIDES_%s' % pkg, True)
>> +            if rprovides == None:
>> +                rprovides = pkg + ' (=' + d.getVar('EXTENDPKGV', True) + ')'
>> +            else:
>> +                rprovides += ' ' + pkg + ' (=' + d.getVar('EXTENDPKGV', True) + ')'
>> +            d.setVar('RPROVIDES_%s' % pkg, rprovides)
>> +
>>           pkgdestpkg = os.path.join(pkgdest, pkg)
>>           files = {}
>>           total_size = 0
>> @@ -1215,6 +1263,7 @@ python emit_pkgdata() {
>>           write_if_exists(sf, pkg, 'SECTION')
>>           write_if_exists(sf, pkg, 'PKG')
>>           write_if_exists(sf, pkg, 'ALLOW_EMPTY')
>> +        write_if_exists(sf, pkg, 'ARCH_SPECIFIC')
>>           write_if_exists(sf, pkg, 'FILES')
>>           write_if_exists(sf, pkg, 'pkg_postinst')
>>           write_if_exists(sf, pkg, 'pkg_postrm')
>> @@ -1878,6 +1927,7 @@ PACKAGESPLITFUNCS ?= " \
>>   PACKAGEFUNCS += " \
>>                   package_fixsymlinks \
>>                   package_name_hook \
>> +                package_check_arch \
>>                   package_do_filedeps \
>>                   package_do_shlibs \
>>                   package_do_pkgconfig \
>> @@ -2010,10 +2060,10 @@ def mapping_rename_hook(d):
>>       like debian.bbclass or manual PKG variable name changes
>>       """
>>       pkg = d.getVar("PKG", True)
>> -    runtime_mapping_rename("RDEPENDS", pkg, d)
>> -    runtime_mapping_rename("RRECOMMENDS", pkg, d)
>> -    runtime_mapping_rename("RSUGGESTS", pkg, d)
>> -    runtime_mapping_rename("RPROVIDES", pkg, d)
>> -    runtime_mapping_rename("RREPLACES", pkg, d)
>> -    runtime_mapping_rename("RCONFLICTS", pkg, d)
>> +    runtime_mapping_rename("RDEPENDS", pkg, True, d)
>> +    runtime_mapping_rename("RRECOMMENDS", pkg, True, d)
>> +    runtime_mapping_rename("RSUGGESTS", pkg, True, d)
>> +    runtime_mapping_rename("RPROVIDES", pkg, True, d)
>> +    runtime_mapping_rename("RREPLACES", pkg, True, d)
>> +    runtime_mapping_rename("RCONFLICTS", pkg, True, d)
>>   
>> diff --git a/meta/classes/populate_sdk_base.bbclass b/meta/classes/populate_sdk_base.bbclass
>> index 235d672..3a7927a 100644
>> --- a/meta/classes/populate_sdk_base.bbclass
>> +++ b/meta/classes/populate_sdk_base.bbclass
>> @@ -54,7 +54,7 @@ fakeroot python do_populate_sdk() {
>>       from oe.manifest import create_manifest, Manifest
>>   
>>       pn = d.getVar('PN', True)
>> -    runtime_mapping_rename("TOOLCHAIN_TARGET_TASK", pn, d)
>> +    runtime_mapping_rename("TOOLCHAIN_TARGET_TASK", pn, False, d)
>>   
>>       # create target/host SDK manifests
>>       create_manifest(d, manifest_dir=d.getVar('SDK_DIR', True),
>
>
>




More information about the Openembedded-core mailing list