diff mbox series

[RFC,master] populate_sdk_base: Add SDKIMAGE_INSTALL_COMPLEMENTARY_HARD_DEPENDS_ONLY

Message ID 20240927132040.200122-1-claus.stovgaard@gmail.com
State New
Headers show
Series [RFC,master] populate_sdk_base: Add SDKIMAGE_INSTALL_COMPLEMENTARY_HARD_DEPENDS_ONLY | expand

Commit Message

Claus Stovgaard Sept. 27, 2024, 1:20 p.m. UTC
SDKIMAGE_INSTALL_COMPLEMENTARY_HARD_DEPENDS_ONLY is a new variable to
enable installation of recommended complementary packages in the classic
sdk. Use it to get populate_sdk behave like Kirkstone and earlier.

As installing complementary recommended packages is known to cause bugs
it was disabled. Though it can be usefull when having dummy packages
with DEPENDS to create SDK's. Use this variable with caution.

Signed-off-by: Claus Stovgaard <claus.stovgaard@gmail.com>
---
 documentation/ref-manual/variables.rst        | 7 +++++++
 meta/classes-recipe/populate_sdk_base.bbclass | 1 +
 meta/conf/documentation.conf                  | 1 +
 meta/lib/oe/package_manager/__init__.py       | 4 ++--
 meta/lib/oe/package_manager/deb/sdk.py        | 4 +++-
 meta/lib/oe/package_manager/ipk/sdk.py        | 4 +++-
 meta/lib/oe/package_manager/rpm/sdk.py        | 6 ++++--
 7 files changed, 21 insertions(+), 6 deletions(-)

Comments

Claus Stovgaard Oct. 1, 2024, 9:30 a.m. UTC | #1
On Fri, 2024-09-27 at 15:20 +0200, Claus Stovgaard wrote:
> SDKIMAGE_INSTALL_COMPLEMENTARY_HARD_DEPENDS_ONLY is a new variable to
> enable installation of recommended complementary packages in the
> classic
> sdk. Use it to get populate_sdk behave like Kirkstone and earlier.
> 
> As installing complementary recommended packages is known to cause
> bugs
> it was disabled. Though it can be usefull when having dummy packages
> with DEPENDS to create SDK's. Use this variable with caution.
> 
> Signed-off-by: Claus Stovgaard <claus.stovgaard@gmail.com>

I got a comment on IRC about splitting it up into documentation part
for yocto-doc mailing list and implementation, so will wait some days
more, and then split it up and send as normal patches if there is no
other comments.


/Claus


> ---
>  documentation/ref-manual/variables.rst        | 7 +++++++
>  meta/classes-recipe/populate_sdk_base.bbclass | 1 +
>  meta/conf/documentation.conf                  | 1 +
>  meta/lib/oe/package_manager/__init__.py       | 4 ++--
>  meta/lib/oe/package_manager/deb/sdk.py        | 4 +++-
>  meta/lib/oe/package_manager/ipk/sdk.py        | 4 +++-
>  meta/lib/oe/package_manager/rpm/sdk.py        | 6 ++++--
>  7 files changed, 21 insertions(+), 6 deletions(-)
> 
> diff --git a/documentation/ref-manual/variables.rst
> b/documentation/ref-manual/variables.rst
> index 32c9e7407d..44ec6d59a6 100644
> --- a/documentation/ref-manual/variables.rst
> +++ b/documentation/ref-manual/variables.rst
> @@ -7658,6 +7658,13 @@ system and gives an overview of their function
> and contents.
>  
>           $ bitbake -c populate_sdk imagename
>  
> +   :term:`SDKIMAGE_INSTALL_COMPLEMENTARY_HARD_DEPENDS_ONLY`
> +      Set to '0' to install recommended complementary packages as
> part of populate_sdk.
> +      Used to make the clasical sdk behave like Kirkstone and
> earlier yocto releases.
> +      Complementary recommended packages was disabled for default
> because of long standing
> +      bugs where RDEPENDS from -dev packages causes problems in sdk.
> Example with conflict
> +      for main openssh and dropbear packages. Use with caution.
> +
>     :term:`SDKMACHINE`
>        The machine for which the SDK is built. In other words, the
> SDK is built
>        such that it runs on the target you specify with the
> :term:`SDKMACHINE`
> diff --git a/meta/classes-recipe/populate_sdk_base.bbclass
> b/meta/classes-recipe/populate_sdk_base.bbclass
> index 16013d5872..09e9c5b61c 100644
> --- a/meta/classes-recipe/populate_sdk_base.bbclass
> +++ b/meta/classes-recipe/populate_sdk_base.bbclass
> @@ -37,6 +37,7 @@ def complementary_globs(featurevar, d):
>  SDKIMAGE_FEATURES ??= "dev-pkgs dbg-pkgs src-pkgs
> ${@bb.utils.contains('DISTRO_FEATURES', 'api-documentation', 'doc-
> pkgs', '', d)}"
>  SDKIMAGE_INSTALL_COMPLEMENTARY =
> '${@complementary_globs("SDKIMAGE_FEATURES", d)}'
>  SDKIMAGE_INSTALL_COMPLEMENTARY[vardeps] += "SDKIMAGE_FEATURES"
> +SDKIMAGE_INSTALL_COMPLEMENTARY_HARD_DEPENDS_ONLY ??= "1"
>  
>  PACKAGE_ARCHS:append:task-populate-sdk = " sdk-provides-dummy-
> target"
>  SDK_PACKAGE_ARCHS += "sdk-provides-dummy-${SDKPKGSUFFIX}"
> diff --git a/meta/conf/documentation.conf
> b/meta/conf/documentation.conf
> index 3f130120c0..84e2fef688 100644
> --- a/meta/conf/documentation.conf
> +++ b/meta/conf/documentation.conf
> @@ -376,6 +376,7 @@ SDK_DIR[doc] = "The parent directory used by the
> OpenEmbedded build system when
>  SDK_NAME[doc] = "The base name for SDK output files."
>  SDK_OUTPUT[doc] = "The location used by the OpenEmbedded build
> system when creating SDK output."
>  SDKIMAGE_FEATURES[doc] = "Equivalent to IMAGE_FEATURES. However,
> this variable applies to the SDK generated from an image using the
> command 'bitbake -c populate_sdk imagename'."
> +SDKIMAGE_INSTALL_COMPLEMENTARY_HARD_DEPENDS_ONLY[doc] = "Set to
> something else than '1' to install recommended complementary packages
> as part of sdk. Used to make populate_sdk behave like Kirkstone and
> earlier"
>  SDKMACHINE[doc] = "Specifies the architecture (i.e. i686 or x86_64)
> for which to build SDK and ADT items."
>  SECTION[doc] = "The section in which packages should be categorized.
> Package management utilities can make use of this variable."
>  SELECTED_OPTIMIZATION[doc] = "The variable takes the value of
> FULL_OPTIMIZATION unless DEBUG_BUILD = '1'. In this case, the value
> of DEBUG_OPTIMIZATION is used."
> diff --git a/meta/lib/oe/package_manager/__init__.py
> b/meta/lib/oe/package_manager/__init__.py
> index d3b2317894..50e78c4017 100644
> --- a/meta/lib/oe/package_manager/__init__.py
> +++ b/meta/lib/oe/package_manager/__init__.py
> @@ -344,7 +344,7 @@ class PackageManager(object, metaclass=ABCMeta):
>                           "'%s' returned %d:\n%s" %
>                           (' '.join(cmd), e.returncode,
> e.output.decode("utf-8")))
>  
> -    def install_complementary(self, globs=None):
> +    def install_complementary(self, globs=None,
> hard_depends_only=True):
>          """
>          Install complementary packages based upon the list of
> currently installed
>          packages e.g. locales, *-dev, *-dbg, etc. Note: every
> backend needs to
> @@ -399,7 +399,7 @@ class PackageManager(object, metaclass=ABCMeta):
>                  bb.note("Installing complementary packages ... %s
> (skipped already provided packages %s)" % (
>                      ' '.join(install_pkgs),
>                      ' '.join(skip_pkgs)))
> -                self.install(install_pkgs, hard_depends_only=True)
> +                self.install(install_pkgs,
> hard_depends_only=hard_depends_only)
>              except subprocess.CalledProcessError as e:
>                  bb.fatal("Could not compute complementary packages
> list. Command "
>                           "'%s' returned %d:\n%s" %
> diff --git a/meta/lib/oe/package_manager/deb/sdk.py
> b/meta/lib/oe/package_manager/deb/sdk.py
> index 6f3005053e..6232c47f4a 100644
> --- a/meta/lib/oe/package_manager/deb/sdk.py
> +++ b/meta/lib/oe/package_manager/deb/sdk.py
> @@ -65,7 +65,9 @@ class PkgSdk(Sdk):
>          bb.note("Installing TARGET packages")
>          self._populate_sysroot(self.target_pm, self.target_manifest)
>  
> -       
> self.target_pm.install_complementary(self.d.getVar('SDKIMAGE_INSTALL_
> COMPLEMENTARY'))
> +        hard_depends_only =
> (self.d.getVar('SDKIMAGE_INSTALL_COMPLEMENTARY_HARD_DEPENDS_ONLY') ==
> '1')
> +       
> self.target_pm.install_complementary(self.d.getVar('SDKIMAGE_INSTALL_
> COMPLEMENTARY'),
> +            hard_depends_only)
>  
>          self.target_pm.run_pre_post_installs()
>  
> diff --git a/meta/lib/oe/package_manager/ipk/sdk.py
> b/meta/lib/oe/package_manager/ipk/sdk.py
> index 3acd55f548..e8663523df 100644
> --- a/meta/lib/oe/package_manager/ipk/sdk.py
> +++ b/meta/lib/oe/package_manager/ipk/sdk.py
> @@ -61,7 +61,9 @@ class PkgSdk(Sdk):
>          bb.note("Installing TARGET packages")
>          self._populate_sysroot(self.target_pm, self.target_manifest)
>  
> -       
> self.target_pm.install_complementary(self.d.getVar('SDKIMAGE_INSTALL_
> COMPLEMENTARY'))
> +        hard_depends_only =
> (self.d.getVar('SDKIMAGE_INSTALL_COMPLEMENTARY_HARD_DEPENDS_ONLY') ==
> '1')
> +       
> self.target_pm.install_complementary(self.d.getVar('SDKIMAGE_INSTALL_
> COMPLEMENTARY'),
> +            hard_depends_only)
>  
>          env_bkp = os.environ.copy()
>          os.environ['PATH'] =
> self.d.expand("${COREBASE}/scripts/nativesdk-intercept") + \
> diff --git a/meta/lib/oe/package_manager/rpm/sdk.py
> b/meta/lib/oe/package_manager/rpm/sdk.py
> index ea79fe050b..a3f505c023 100644
> --- a/meta/lib/oe/package_manager/rpm/sdk.py
> +++ b/meta/lib/oe/package_manager/rpm/sdk.py
> @@ -65,8 +65,10 @@ class PkgSdk(Sdk):
>          bb.note("Installing TARGET packages")
>          self._populate_sysroot(self.target_pm, self.target_manifest)
>  
> -       
> self.target_pm.install_complementary(self.d.getVar('SDKIMAGE_INSTALL_
> COMPLEMENTARY'))
> -
> +        hard_depends_only =
> (self.d.getVar('SDKIMAGE_INSTALL_COMPLEMENTARY_HARD_DEPENDS_ONLY') ==
> '1')
> +       
> self.target_pm.install_complementary(self.d.getVar('SDKIMAGE_INSTALL_
> COMPLEMENTARY'),
> +            hard_depends_only)
> +        
>          env_bkp = os.environ.copy()
>          os.environ['PATH'] =
> self.d.expand("${COREBASE}/scripts/nativesdk-intercept") + \
>                               os.pathsep + os.environ["PATH"]
Richard Purdie Oct. 1, 2024, 9:53 a.m. UTC | #2
On Fri, 2024-09-27 at 15:20 +0200, Claus Stovgaard via
lists.openembedded.org wrote:
> SDKIMAGE_INSTALL_COMPLEMENTARY_HARD_DEPENDS_ONLY is a new variable to
> enable installation of recommended complementary packages in the classic
> sdk. Use it to get populate_sdk behave like Kirkstone and earlier.
> 
> As installing complementary recommended packages is known to cause bugs
> it was disabled. Though it can be usefull when having dummy packages
> with DEPENDS to create SDK's. Use this variable with caution.
> 
> Signed-off-by: Claus Stovgaard <claus.stovgaard@gmail.com>

The commit message needs improvement since I can't tell what this
means/does.

What was the behaviour in kirkstone and how did it change? Why/when
would I need it?

What is a "hard depends"?

I don't have an opinion on whether should do something like this or not
as yet, mainly as I can't tell what it is doing. Can you explain it
without reference to "behaviour in kirkstone"?

I also have an aversion to "1" as a magic value. Have a look at
bb.utils.to_boolean() for that.

Cheers,

Richard
Claus Stovgaard Oct. 7, 2024, 9:08 p.m. UTC | #3
On Tue, 2024-10-01 at 10:53 +0100, Richard Purdie wrote:
> On Fri, 2024-09-27 at 15:20 +0200, Claus Stovgaard via
> lists.openembedded.org wrote:
> > SDKIMAGE_INSTALL_COMPLEMENTARY_HARD_DEPENDS_ONLY is a new variable
> > to
> > enable installation of recommended complementary packages in the
> > classic
> > sdk. Use it to get populate_sdk behave like Kirkstone and earlier.
> > 
> > As installing complementary recommended packages is known to cause
> > bugs
> > it was disabled. Though it can be usefull when having dummy
> > packages
> > with DEPENDS to create SDK's. Use this variable with caution.
> > 
> > Signed-off-by: Claus Stovgaard <claus.stovgaard@gmail.com>
> 
> The commit message needs improvement since I can't tell what this
> means/does.
> 
> What was the behaviour in kirkstone and how did it change? Why/when
> would I need it?
> 
> What is a "hard depends"?
> 
> I don't have an opinion on whether should do something like this or
> not
> as yet, mainly as I can't tell what it is doing. Can you explain it
> without reference to "behaviour in kirkstone"?
> 
> I also have an aversion to "1" as a magic value. Have a look at
> bb.utils.to_boolean() for that.
> 

Thanks for your comments.

I will try to improve the commit message, and split the documentation
part out from the rest.

The issue it tries to solve is the one described here.
https://lists.openembedded.org/g/openembedded-core/topic/108100662#msg203745

In short - with this commit

https://git.yoctoproject.org/poky/patch/?id=4705dd264681d908f144dd4d9bf1f6175f68d8b9
the behaviour of complementary package handling changed ignore
RRECOMMENDS.

This was changed to fix some long standing bugs for RDEPENDS from -dev
packages.

Though as the complementary handling of including packages from
RRECOMMENDS is needed in some situations the purpose of this patch is
to change from hardcoded disabled to be a configurable option.

A prime example for where we need the installation of packages in
RRECOMMENDS, and not ignore it is for generating a SDK with all
dependencies for an application.

E.g. if we have a dummy recipe with packages in DEPENDS, the packages
listed in DEPENDS will end in RRECOMMENDS. See process_depchains in
package.py for the pkg_adddeprrecs method, and not be installed in the
SDK. Using the variable introduced with this patch, will install
packages from RRECOMMENDS in the SDK, and we have a classic SDK with
all the packages from DEPENDS and ready to be used for the application.

Hope it make better sense for you now, and I will try to describe it
better in the commit message.

Regards
Claus


> Cheers,
> 
> Richard
Alexander Kanavin Oct. 8, 2024, 9:17 a.m. UTC | #4
On Mon, 7 Oct 2024 at 23:08, Claus Stovgaard via
lists.openembedded.org
<claus.stovgaard=gmail.com@lists.openembedded.org> wrote:
> A prime example for where we need the installation of packages in
> RRECOMMENDS, and not ignore it is for generating a SDK with all
> dependencies for an application.
>
> E.g. if we have a dummy recipe with packages in DEPENDS, the packages
> listed in DEPENDS will end in RRECOMMENDS. See process_depchains in
> package.py for the pkg_adddeprrecs method, and not be installed in the
> SDK. Using the variable introduced with this patch, will install
> packages from RRECOMMENDS in the SDK, and we have a classic SDK with
> all the packages from DEPENDS and ready to be used for the application.

But DEPENDS isn't meant to generate SDK dependencies. It's purpose is
to pull things into sysroots in a plain yocto build.

You need RDEPENDS for that if I'm not mistaken.

Alex
Claus Stovgaard Oct. 8, 2024, 11:24 a.m. UTC | #5
On Tue, 2024-10-08 at 11:17 +0200, Alexander Kanavin wrote:
> On Mon, 7 Oct 2024 at 23:08, Claus Stovgaard via
> lists.openembedded.org
> <claus.stovgaard=gmail.com@lists.openembedded.org> wrote:
> > A prime example for where we need the installation of packages in
> > RRECOMMENDS, and not ignore it is for generating a SDK with all
> > dependencies for an application.
> > 
> > E.g. if we have a dummy recipe with packages in DEPENDS, the
> > packages
> > listed in DEPENDS will end in RRECOMMENDS. See process_depchains in
> > package.py for the pkg_adddeprrecs method, and not be installed in
> > the
> > SDK. Using the variable introduced with this patch, will install
> > packages from RRECOMMENDS in the SDK, and we have a classic SDK
> > with
> > all the packages from DEPENDS and ready to be used for the
> > application.
> 
> But DEPENDS isn't meant to generate SDK dependencies. It's purpose is
> to pull things into sysroots in a plain yocto build.
> 
> You need RDEPENDS for that if I'm not mistaken.
> 
> Alex

It is a build time dependency as I see it.

if foo.bb is setting DEPENDS to include "bar baz and qux" to indicate
it need it for compilation.

When foo is added to an image, and we then populate_sdk for this image
I expect that the SDK includes the dev packages of bar baz and qux to
be able to compile foo with it.

This has working until now as the SDK installed the recommended
packages.

The key is that process_depchains in package.py make the
recommendation. From the comment

<snip>
def process_depchains(pkgfiles, d):
    """
    For a given set of prefix and postfix modifiers, make those
packages
    RRECOMMENDS on the corresponding packages for its RDEPENDS.

    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.
</snip>

I will start on creating an example on my github account showing the
issue better if it is not yet clear.

Claus
Alexander Kanavin Oct. 8, 2024, 11:42 a.m. UTC | #6
On Tue, 8 Oct 2024 at 13:24, <claus.stovgaard@gmail.com> wrote:

> It is a build time dependency as I see it.
>
> if foo.bb is setting DEPENDS to include "bar baz and qux" to indicate
> it need it for compilation.
>
> When foo is added to an image, and we then populate_sdk for this image
> I expect that the SDK includes the dev packages of bar baz and qux to
> be able to compile foo with it.
>
> This has working until now as the SDK installed the recommended
> packages.
>
> The key is that process_depchains in package.py make the
> recommendation. From the comment
>
> <snip>
> def process_depchains(pkgfiles, d):
>     """
>     For a given set of prefix and postfix modifiers, make those
> packages
>     RRECOMMENDS on the corresponding packages for its RDEPENDS.
>
>     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.
> </snip>
>
> I will start on creating an example on my github account showing the
> issue better if it is not yet clear.

I still don't understand why the standard SDK population mechanism
doesn't work for you. It does pull in -dev for everything that is in
the image, so where does this break down?

Alex
Claus Stovgaard Oct. 10, 2024, 9:01 p.m. UTC | #7
On Tue, 2024-10-08 at 13:42 +0200, Alexander Kanavin wrote:
> > On Tue, 8 Oct 2024 at 13:24, <claus.stovgaard@gmail.com> wrote:
> > 
> > > > It is a build time dependency as I see it.
> > > > 
> > > > if foo.bb is setting DEPENDS to include "bar baz and qux" to
> > > > indicate
> > > > it need it for compilation.
> > > > 
> > > > When foo is added to an image, and we then populate_sdk for
> > > > this
> > > > image
> > > > I expect that the SDK includes the dev packages of bar baz and
> > > > qux
> > > > to
> > > > be able to compile foo with it.
> > > > 
> > > > This has working until now as the SDK installed the recommended
> > > > packages.
> > > > 
> > > > The key is that process_depchains in package.py make the
> > > > recommendation. From the comment
> > > > 
> > > > <snip>
> > > > def process_depchains(pkgfiles, d):
> > > >     """
> > > >     For a given set of prefix and postfix modifiers, make those
> > > > packages
> > > >     RRECOMMENDS on the corresponding packages for its RDEPENDS.
> > > > 
> > > >     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.
> > > > </snip>
> > > > 
> > > > I will start on creating an example on my github account
> > > > showing
> > > > the
> > > > issue better if it is not yet clear.
> > 
> > I still don't understand why the standard SDK population mechanism
> > doesn't work for you. It does pull in -dev for everything that is
> > in
> > the image, so where does this break down?
> > 
> > Alex


I have made a small example on github - in the sdk_example branch
https://github.com/frosteyes/yocto-master/tree/fe/sdk_example

In short it has a layer named meta-fe.
This contains a small app named fe-app (just a program with boost
dependency), and a dummy-fe-app as placeholder for the same
dependencies.

https://github.com/frosteyes/yocto-master/tree/fe/sdk_example/meta-fe/recipes-application/fe-app

Next their is two images. image-amp-base based on core-image-minimal,
just adding dummy-fe-app, and a image-fe starting from the base image,
but removing the dummy-fe-app and adding the fe-app instead.

Think of this as a pattern, where you have several dummy packages, and
that the dependency includes a significant number of packages like
boost, qt packages, gstreamer, etc.

Until know this pattern have worked great for having a base sdk /
image, able to be shared to an application team, so they have something
to code against when upgrading, so their is breaking changes of the
application.

It is based around that the SDK installed the recommends packages, as
the list of packages ends in the recommends section of the RPM
packages.

yocto@yocto:~/./deploy/rpm/core2_64$ rpm -q --recommends dummy-fe-app-
dev*
boost-dev
dummy-fe-app = git-r0

But as the dummy package only contain a text file and no binary, the
rpm --requires only list the default rpmlib and not all the files
located for the binary of fe-app.

Hope it make it more clear what workflow their is broken with the
change, and why my patch suggest to making it a configurable option.

Will update the patch (split out documentation and better commit
message) and send v1 of the patch.

/Claus
Alexander Kanavin Oct. 11, 2024, 8:51 a.m. UTC | #8
On Thu, 10 Oct 2024 at 23:01, Claus Stovgaard <claus.stovgaard@gmail.com> wrote:

> Hope it make it more clear what workflow their is broken with the
> change, and why my patch suggest to making it a configurable option.

Thanks, this is much clearer now. I do wonder if we really need all
the complication of having an extra variable (that isn't tested). Can
the dummy app recipe be written such that it takes the list of
DEPENDS, and adds everything in it to RDEPENDS, with -dev suffix?

Alex
Claus Stovgaard Oct. 12, 2024, 9:41 a.m. UTC | #9
On Fri, 2024-10-11 at 10:51 +0200, Alexander Kanavin wrote:
> On Thu, 10 Oct 2024 at 23:01, Claus Stovgaard <
> claus.stovgaard@gmail.com> wrote:
> 
> > Hope it make it more clear what workflow their is broken with the
> > change, and why my patch suggest to making it a configurable
> > option.
> 
> Thanks, this is much clearer now. I do wonder if we really need all
> the complication of having an extra variable (that isn't tested). Can
> the dummy app recipe be written such that it takes the list of
> DEPENDS, and adds everything in it to RDEPENDS, with -dev suffix?
> 

Thanks, I was looking into using the RDEPENDS of the dev package, and
after some work I came up with below section.

<snip>
python package_depchains:append() {
    pn = d.getVar('PN')
    recommends = d.getVar('RRECOMMENDS:' + pn + '-dev' )

    # Append the recommends to the RDEPENDS, so it end in requires for
the package
    d.appendVar('RDEPENDS:' + pn + '-dev', recommends)
}
</snip>

This also works pretty well, but I am hitting some problems with
packages like sqlite3 and googletest (gtest).

sqlite3 is becaues the resulting package is not named sqlite3-dev but
libsqlite3-dev
googletest_git.bb provides gmock/gtest so the package would not be
named gtest-dev but googletest-dev

I am working more with it, and I think there might be a solution in
sight. Though if you have any ideas please share.

Regards
Claus
Alexander Kanavin Oct. 12, 2024, 12:18 p.m. UTC | #10
On Sat, 12 Oct 2024 at 11:41, <claus.stovgaard@gmail.com> wrote:
> I am working more with it, and I think there might be a solution in
> sight. Though if you have any ideas please share.

I think you need to run it through package name translation function,
the same one that package.bbclass is using to do 'debian-style library
package renaming'. I can't remember what it's called though.

Alex
Claus Stovgaard Oct. 31, 2024, 12:55 p.m. UTC | #11
On Sat, 2024-10-12 at 14:18 +0200, Alexander Kanavin wrote:
> On Sat, 12 Oct 2024 at 11:41, <claus.stovgaard@gmail.com> wrote:
> > I am working more with it, and I think there might be a solution in
> > sight. Though if you have any ideas please share.
> 
> I think you need to run it through package name translation function,
> the same one that package.bbclass is using to do 'debian-style
> library
> package renaming'. I can't remember what it's called though.
> 
> Alex

Hi Alex and others reading this thread.

I ended up thinking my direction with using the RECOMMENDS was wrong.
When I was working with the problem, I figured out that my problem was
that my dummy package does not correctly fits with the automatically
runtime dependency part of Yocto, as there is no shlibdeps or pcdeps,
and depchains only handle dev and dbg packages.

So my solution ended up being a base class, just copying from DEPENDS
to RDEPENDS.

See
https://github.com/frosteyes/yocto-master/blob/fe/sdk_example/meta-fe/classes/dummy-package.bbclass


For specfic packages like sqlite3 and cli11 I handle it before
inheriting the class. Someething like

<snip>
# sqlite3 needs specific handling, as it package the dev package
# as libsqlite3-dev and not sqlite3-dev
DEPENDS:remove = "sqlite3"
RDEPENDS:${PN} += "libsqlite3"

# cli11 is header only, meaning there is no library to depend on. This
# means that the package itself does not depend on cli11, and by that
# cli11 is not automatically added to RDEPENDS so only add dev
# package runtime dependency.
DEPENDS:remove = "cli11"
RDEPENDS:${PN}-dev += "cli11-dev"

inherit dummy-package
</snip>

I was looking into some kind of verification that a dev package exist.
But it does not work on the parsing step.

Anyone knows of a solution for this?

# Verify a -dev package exist, or skip and warn that it need special
handling
	recipename = oe.packagedata.recipename(dep + '-dev', d)
        if not recipename:
		bb.warn("dummy-package: %s (Skipping DEPENDS: %s -
needs customs handling, no %s-dev exist)" % (pn, dep, dep) )
            continue


Maybe it would be better to move the function from an anonymous
function on parsing, to a function before the packaging task or
similar. If we can verify that a correct dev package exist.

Any inputs is welcome.

Also just to share for others to use.

/Claus
diff mbox series

Patch

diff --git a/documentation/ref-manual/variables.rst b/documentation/ref-manual/variables.rst
index 32c9e7407d..44ec6d59a6 100644
--- a/documentation/ref-manual/variables.rst
+++ b/documentation/ref-manual/variables.rst
@@ -7658,6 +7658,13 @@  system and gives an overview of their function and contents.
 
          $ bitbake -c populate_sdk imagename
 
+   :term:`SDKIMAGE_INSTALL_COMPLEMENTARY_HARD_DEPENDS_ONLY`
+      Set to '0' to install recommended complementary packages as part of populate_sdk.
+      Used to make the clasical sdk behave like Kirkstone and earlier yocto releases.
+      Complementary recommended packages was disabled for default because of long standing
+      bugs where RDEPENDS from -dev packages causes problems in sdk. Example with conflict
+      for main openssh and dropbear packages. Use with caution.
+
    :term:`SDKMACHINE`
       The machine for which the SDK is built. In other words, the SDK is built
       such that it runs on the target you specify with the :term:`SDKMACHINE`
diff --git a/meta/classes-recipe/populate_sdk_base.bbclass b/meta/classes-recipe/populate_sdk_base.bbclass
index 16013d5872..09e9c5b61c 100644
--- a/meta/classes-recipe/populate_sdk_base.bbclass
+++ b/meta/classes-recipe/populate_sdk_base.bbclass
@@ -37,6 +37,7 @@  def complementary_globs(featurevar, d):
 SDKIMAGE_FEATURES ??= "dev-pkgs dbg-pkgs src-pkgs ${@bb.utils.contains('DISTRO_FEATURES', 'api-documentation', 'doc-pkgs', '', d)}"
 SDKIMAGE_INSTALL_COMPLEMENTARY = '${@complementary_globs("SDKIMAGE_FEATURES", d)}'
 SDKIMAGE_INSTALL_COMPLEMENTARY[vardeps] += "SDKIMAGE_FEATURES"
+SDKIMAGE_INSTALL_COMPLEMENTARY_HARD_DEPENDS_ONLY ??= "1"
 
 PACKAGE_ARCHS:append:task-populate-sdk = " sdk-provides-dummy-target"
 SDK_PACKAGE_ARCHS += "sdk-provides-dummy-${SDKPKGSUFFIX}"
diff --git a/meta/conf/documentation.conf b/meta/conf/documentation.conf
index 3f130120c0..84e2fef688 100644
--- a/meta/conf/documentation.conf
+++ b/meta/conf/documentation.conf
@@ -376,6 +376,7 @@  SDK_DIR[doc] = "The parent directory used by the OpenEmbedded build system when
 SDK_NAME[doc] = "The base name for SDK output files."
 SDK_OUTPUT[doc] = "The location used by the OpenEmbedded build system when creating SDK output."
 SDKIMAGE_FEATURES[doc] = "Equivalent to IMAGE_FEATURES. However, this variable applies to the SDK generated from an image using the command 'bitbake -c populate_sdk imagename'."
+SDKIMAGE_INSTALL_COMPLEMENTARY_HARD_DEPENDS_ONLY[doc] = "Set to something else than '1' to install recommended complementary packages as part of sdk. Used to make populate_sdk behave like Kirkstone and earlier"
 SDKMACHINE[doc] = "Specifies the architecture (i.e. i686 or x86_64) for which to build SDK and ADT items."
 SECTION[doc] = "The section in which packages should be categorized. Package management utilities can make use of this variable."
 SELECTED_OPTIMIZATION[doc] = "The variable takes the value of FULL_OPTIMIZATION unless DEBUG_BUILD = '1'. In this case, the value of DEBUG_OPTIMIZATION is used."
diff --git a/meta/lib/oe/package_manager/__init__.py b/meta/lib/oe/package_manager/__init__.py
index d3b2317894..50e78c4017 100644
--- a/meta/lib/oe/package_manager/__init__.py
+++ b/meta/lib/oe/package_manager/__init__.py
@@ -344,7 +344,7 @@  class PackageManager(object, metaclass=ABCMeta):
                          "'%s' returned %d:\n%s" %
                          (' '.join(cmd), e.returncode, e.output.decode("utf-8")))
 
-    def install_complementary(self, globs=None):
+    def install_complementary(self, globs=None, hard_depends_only=True):
         """
         Install complementary packages based upon the list of currently installed
         packages e.g. locales, *-dev, *-dbg, etc. Note: every backend needs to
@@ -399,7 +399,7 @@  class PackageManager(object, metaclass=ABCMeta):
                 bb.note("Installing complementary packages ... %s (skipped already provided packages %s)" % (
                     ' '.join(install_pkgs),
                     ' '.join(skip_pkgs)))
-                self.install(install_pkgs, hard_depends_only=True)
+                self.install(install_pkgs, hard_depends_only=hard_depends_only)
             except subprocess.CalledProcessError as e:
                 bb.fatal("Could not compute complementary packages list. Command "
                          "'%s' returned %d:\n%s" %
diff --git a/meta/lib/oe/package_manager/deb/sdk.py b/meta/lib/oe/package_manager/deb/sdk.py
index 6f3005053e..6232c47f4a 100644
--- a/meta/lib/oe/package_manager/deb/sdk.py
+++ b/meta/lib/oe/package_manager/deb/sdk.py
@@ -65,7 +65,9 @@  class PkgSdk(Sdk):
         bb.note("Installing TARGET packages")
         self._populate_sysroot(self.target_pm, self.target_manifest)
 
-        self.target_pm.install_complementary(self.d.getVar('SDKIMAGE_INSTALL_COMPLEMENTARY'))
+        hard_depends_only = (self.d.getVar('SDKIMAGE_INSTALL_COMPLEMENTARY_HARD_DEPENDS_ONLY') == '1')
+        self.target_pm.install_complementary(self.d.getVar('SDKIMAGE_INSTALL_COMPLEMENTARY'),
+            hard_depends_only)
 
         self.target_pm.run_pre_post_installs()
 
diff --git a/meta/lib/oe/package_manager/ipk/sdk.py b/meta/lib/oe/package_manager/ipk/sdk.py
index 3acd55f548..e8663523df 100644
--- a/meta/lib/oe/package_manager/ipk/sdk.py
+++ b/meta/lib/oe/package_manager/ipk/sdk.py
@@ -61,7 +61,9 @@  class PkgSdk(Sdk):
         bb.note("Installing TARGET packages")
         self._populate_sysroot(self.target_pm, self.target_manifest)
 
-        self.target_pm.install_complementary(self.d.getVar('SDKIMAGE_INSTALL_COMPLEMENTARY'))
+        hard_depends_only = (self.d.getVar('SDKIMAGE_INSTALL_COMPLEMENTARY_HARD_DEPENDS_ONLY') == '1')
+        self.target_pm.install_complementary(self.d.getVar('SDKIMAGE_INSTALL_COMPLEMENTARY'),
+            hard_depends_only)
 
         env_bkp = os.environ.copy()
         os.environ['PATH'] = self.d.expand("${COREBASE}/scripts/nativesdk-intercept") + \
diff --git a/meta/lib/oe/package_manager/rpm/sdk.py b/meta/lib/oe/package_manager/rpm/sdk.py
index ea79fe050b..a3f505c023 100644
--- a/meta/lib/oe/package_manager/rpm/sdk.py
+++ b/meta/lib/oe/package_manager/rpm/sdk.py
@@ -65,8 +65,10 @@  class PkgSdk(Sdk):
         bb.note("Installing TARGET packages")
         self._populate_sysroot(self.target_pm, self.target_manifest)
 
-        self.target_pm.install_complementary(self.d.getVar('SDKIMAGE_INSTALL_COMPLEMENTARY'))
-
+        hard_depends_only = (self.d.getVar('SDKIMAGE_INSTALL_COMPLEMENTARY_HARD_DEPENDS_ONLY') == '1')
+        self.target_pm.install_complementary(self.d.getVar('SDKIMAGE_INSTALL_COMPLEMENTARY'),
+            hard_depends_only)
+        
         env_bkp = os.environ.copy()
         os.environ['PATH'] = self.d.expand("${COREBASE}/scripts/nativesdk-intercept") + \
                              os.pathsep + os.environ["PATH"]