From: Ming Liu <ming.liu@windriver.com>
To: <openembedded-core@lists.openembedded.org>
Subject: Re: [PATCH V2] package: let dependency on a package name to be architecture specific
Date: Sun, 9 Mar 2014 10:16:31 +0800 [thread overview]
Message-ID: <531BCEFF.6040403@windriver.com> (raw)
In-Reply-To: <1394328376-8296-1-git-send-email-ming.liu@windriver.com>
On 03/09/2014 09:26 AM, 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:
> * 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}" by package_check_arch function
s/TARGET_ARCH /PACKAGE_ARCH.
//Ming Liu
> added in PACKAGEFUNCS and the variable is gonna be written into pkgdata
> if it exists, to mark the package as architecture specific, and it will
> be checked during runtime_mapping_rename is executed when generating rpm
> packages, all architecture specific dependencies would be expanded with
> a ${PACKAGE_ARCH} suffix, that declares a dependency on a package name
> architecture specific and permits differentiating between 32-bit and
> 64-bit versions.
>
> The end user could set "ARCH_SPECIFIC_pkgname = 0" in recipes to disable
> this feature.
>
> Signed-off-by: Ming Liu <ming.liu@windriver.com>
> ---
> meta/classes/image.bbclass | 6 +-
> meta/classes/package.bbclass | 76 +++++++++++++++++++++++++------
> meta/classes/package_deb.bbclass | 2 +-
> meta/classes/package_ipk.bbclass | 2 +-
> meta/classes/package_rpm.bbclass | 2 +-
> meta/classes/populate_sdk_base.bbclass | 2 +-
> 6 files changed, 68 insertions(+), 22 deletions(-)
>
> diff --git a/meta/classes/image.bbclass b/meta/classes/image.bbclass
> index 51d16d7..36528fd 100644
> --- a/meta/classes/image.bbclass
> +++ b/meta/classes/image.bbclass
> @@ -230,9 +230,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..1fda2f7 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,30 @@ python package_fixsymlinks () {
> d.setVar('RDEPENDS_' + pkg, bb.utils.join_deps(rdepends, commasep=False))
> }
>
> +# Check architecture specific packages
> +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('PACKAGE_ARCH', True)))
> +
> + for pkg in sorted((d.getVar('PACKAGES', True) or "").split()):
> + check_arch_specific(pkg)
> +}
> +
> PKGDESTWORK = "${WORKDIR}/pkgdata"
>
> python emit_pkgdata() {
> @@ -1184,6 +1218,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 +1259,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 +1923,7 @@ PACKAGESPLITFUNCS ?= " \
> PACKAGEFUNCS += " \
> package_fixsymlinks \
> package_name_hook \
> + package_check_arch \
> package_do_filedeps \
> package_do_shlibs \
> package_do_pkgconfig \
> @@ -2004,16 +2050,16 @@ addtask do_packagedata_setscene
> # Helper functions for the package writing classes
> #
>
> -def mapping_rename_hook(d):
> +def mapping_rename_hook(check_arch, d):
> """
> Rewrite variables to account for package renaming in things
> 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, check_arch, d)
> + runtime_mapping_rename("RRECOMMENDS", pkg, check_arch, d)
> + runtime_mapping_rename("RSUGGESTS", pkg, check_arch, d)
> + runtime_mapping_rename("RPROVIDES", pkg, check_arch, d)
> + runtime_mapping_rename("RREPLACES", pkg, check_arch, d)
> + runtime_mapping_rename("RCONFLICTS", pkg, check_arch, d)
>
> diff --git a/meta/classes/package_deb.bbclass b/meta/classes/package_deb.bbclass
> index a16d57e..846f13e 100644
> --- a/meta/classes/package_deb.bbclass
> +++ b/meta/classes/package_deb.bbclass
> @@ -178,7 +178,7 @@ python do_package_deb () {
> ctrlfile.write(unicode(custom_fields_chunk))
> ctrlfile.write("\n")
>
> - mapping_rename_hook(localdata)
> + mapping_rename_hook(False, localdata)
>
> def debian_cmp_remap(var):
> # dpkg does not allow for '(' or ')' in a dependency name
> diff --git a/meta/classes/package_ipk.bbclass b/meta/classes/package_ipk.bbclass
> index aab31e5..1c88d07 100644
> --- a/meta/classes/package_ipk.bbclass
> +++ b/meta/classes/package_ipk.bbclass
> @@ -142,7 +142,7 @@ python do_package_ipk () {
> ctrlfile.write(custom_fields_chunk)
> ctrlfile.write("\n")
>
> - mapping_rename_hook(localdata)
> + mapping_rename_hook(False, localdata)
>
> def debian_cmp_remap(var):
> # In debian '>' and '<' do not mean what it appears they mean
> diff --git a/meta/classes/package_rpm.bbclass b/meta/classes/package_rpm.bbclass
> index bce5648..7c13d61 100644
> --- a/meta/classes/package_rpm.bbclass
> +++ b/meta/classes/package_rpm.bbclass
> @@ -329,7 +329,7 @@ python write_specfile () {
> translate_vers('RCONFLICTS', localdata)
>
> # Map the dependencies into their final form
> - mapping_rename_hook(localdata)
> + mapping_rename_hook(True, localdata)
>
> splitrdepends = strip_multilib_deps(localdata.getVar('RDEPENDS', True), d)
> splitrrecommends = strip_multilib_deps(localdata.getVar('RRECOMMENDS', 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),
prev parent reply other threads:[~2014-03-09 2:16 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-03-09 1:26 [PATCH V2] package: let dependency on a package name to be architecture specific Ming Liu
2014-03-09 1:48 ` Ming Liu
2014-03-09 2:16 ` Ming Liu [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=531BCEFF.6040403@windriver.com \
--to=ming.liu@windriver.com \
--cc=openembedded-core@lists.openembedded.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.