diff mbox series

[scarthgap] classes-global/license: create -lic package from PKGD, not D

Message ID 20260827140542.669897-1-roman.nazarenko@leica-geosystems.com
State New
Headers show
Series [scarthgap] classes-global/license: create -lic package from PKGD, not D | expand

Commit Message

roman.nazarenko@leica-geosystems.com Aug. 27, 2026, 2:05 p.m. UTC
From: Roman Nazarenko <roman.nazarenko@leica-geosystems.com>

do_package and do_populate_sysroot are siblings - both are only ordered
"after do_install" - so they run concurrently. With
LICENSE_CREATE_PACKAGE=1, perform_packagecopy:prepend wrote the
LIC_FILES_CHKSUM texts straight into ${D}${datadir}/licenses/${PN}/,
mutating the very tree do_populate_sysroot stages with find|cpio:

  | DEBUG: Executing shell function sysroot_stage_all
  | cpio: ./licenses/libmodule/LICENSE: Cannot stat: No such file or directory
  | WARNING: exit code 2 from a shell command.

copy_license_files() removes and re-links an already existing
destination, so a file can be listed by find and gone by the time cpio
stats it.

Write into ${PKGD} from a perform_packagecopy:append instead. By then
${D} is complete and untouched, and ${PKGD} is a private copy that
do_populate_sysroot never reads. Package contents, on-target paths and
ownership are unchanged - do_package is a fakeroot task, so the
os.chown() in copy_license_files() still applies. As a side effect the
license texts stop being staged into every target recipe's sysroot,
which they had no business being in.

The stale comment about do_install:append goes away with the change,
taking the find_license_filesa typo with it.

This changes perform_packagecopy, so do_package basehashes change for
every recipe; expect a one-time repackage.

Signed-off-by: Roman Nazarenko <roman.nazarenko@leica-geosystems.com>
---
 meta/classes-global/license.bbclass | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

Comments

Yoann Congal Aug. 27, 2026, 3:16 p.m. UTC | #1
On Thu Aug 27, 2026 at 4:05 PM CEST, roman.nazarenko via lists.openembedded.org wrote:
> From: Roman Nazarenko <roman.nazarenko@leica-geosystems.com>
>
> do_package and do_populate_sysroot are siblings - both are only ordered
> "after do_install" - so they run concurrently. With
> LICENSE_CREATE_PACKAGE=1, perform_packagecopy:prepend wrote the
> LIC_FILES_CHKSUM texts straight into ${D}${datadir}/licenses/${PN}/,
> mutating the very tree do_populate_sysroot stages with find|cpio:
>
>   | DEBUG: Executing shell function sysroot_stage_all
>   | cpio: ./licenses/libmodule/LICENSE: Cannot stat: No such file or directory
>   | WARNING: exit code 2 from a shell command.
>
> copy_license_files() removes and re-links an already existing
> destination, so a file can be listed by find and gone by the time cpio
> stats it.
>
> Write into ${PKGD} from a perform_packagecopy:append instead. By then
> ${D} is complete and untouched, and ${PKGD} is a private copy that
> do_populate_sysroot never reads. Package contents, on-target paths and
> ownership are unchanged - do_package is a fakeroot task, so the
> os.chown() in copy_license_files() still applies. As a side effect the
> license texts stop being staged into every target recipe's sysroot,
> which they had no business being in.
>
> The stale comment about do_install:append goes away with the change,
> taking the find_license_filesa typo with it.
>
> This changes perform_packagecopy, so do_package basehashes change for
> every recipe; expect a one-time repackage.
>
> Signed-off-by: Roman Nazarenko <roman.nazarenko@leica-geosystems.com>
> ---
>  meta/classes-global/license.bbclass | 9 +++++----
>  1 file changed, 5 insertions(+), 4 deletions(-)
>
> diff --git a/meta/classes-global/license.bbclass b/meta/classes-global/license.bbclass
> index 6e0de5f414..f2d83c227c 100644
> --- a/meta/classes-global/license.bbclass
> +++ b/meta/classes-global/license.bbclass
> @@ -45,14 +45,15 @@ python do_populate_lic() {
>  }
>  
>  PSEUDO_IGNORE_PATHS .= ",${@','.join(((d.getVar('COMMON_LICENSE_DIR') or '') + ' ' + (d.getVar('LICENSE_PATH') or '') + ' ' + d.getVar('COREBASE') + '/meta/COPYING').split())}"
> -# it would be better to copy them in do_install:append, but find_license_filesa is python
> -python perform_packagecopy:prepend () {
> +# Write into PKGD, not D: do_populate_sysroot stages D concurrently and races
> +# with the remove-then-relink in copy_license_files().
> +python perform_packagecopy:append () {
>      enabled = oe.data.typed_value('LICENSE_CREATE_PACKAGE', d)
>      if d.getVar('CLASSOVERRIDE') == 'class-target' and enabled:
>          lic_files_paths = find_license_files(d)
>  
> -        # LICENSE_FILES_DIRECTORY starts with '/' so os.path.join cannot be used to join D and LICENSE_FILES_DIRECTORY
> -        destdir = d.getVar('D') + os.path.join(d.getVar('LICENSE_FILES_DIRECTORY'), d.getVar('PN'))
> +        # LICENSE_FILES_DIRECTORY starts with '/' so os.path.join cannot be used to join PKGD and LICENSE_FILES_DIRECTORY
> +        destdir = d.getVar('PKGD') + os.path.join(d.getVar('LICENSE_FILES_DIRECTORY'), d.getVar('PN'))

Hello,

It looks like this patch could apply to master (at a really quick
glance).

We have a "master-first" policy which prevent me from merging anything
to scarthgap if there is no wrynose&master equivalent.

Depending on the situation, you will need to send master&wrynose patches
before I can review this patch.

Regards,
>          copy_license_files(lic_files_paths, destdir)
>          add_package_and_files(d)
>  }
diff mbox series

Patch

diff --git a/meta/classes-global/license.bbclass b/meta/classes-global/license.bbclass
index 6e0de5f414..f2d83c227c 100644
--- a/meta/classes-global/license.bbclass
+++ b/meta/classes-global/license.bbclass
@@ -45,14 +45,15 @@  python do_populate_lic() {
 }
 
 PSEUDO_IGNORE_PATHS .= ",${@','.join(((d.getVar('COMMON_LICENSE_DIR') or '') + ' ' + (d.getVar('LICENSE_PATH') or '') + ' ' + d.getVar('COREBASE') + '/meta/COPYING').split())}"
-# it would be better to copy them in do_install:append, but find_license_filesa is python
-python perform_packagecopy:prepend () {
+# Write into PKGD, not D: do_populate_sysroot stages D concurrently and races
+# with the remove-then-relink in copy_license_files().
+python perform_packagecopy:append () {
     enabled = oe.data.typed_value('LICENSE_CREATE_PACKAGE', d)
     if d.getVar('CLASSOVERRIDE') == 'class-target' and enabled:
         lic_files_paths = find_license_files(d)
 
-        # LICENSE_FILES_DIRECTORY starts with '/' so os.path.join cannot be used to join D and LICENSE_FILES_DIRECTORY
-        destdir = d.getVar('D') + os.path.join(d.getVar('LICENSE_FILES_DIRECTORY'), d.getVar('PN'))
+        # LICENSE_FILES_DIRECTORY starts with '/' so os.path.join cannot be used to join PKGD and LICENSE_FILES_DIRECTORY
+        destdir = d.getVar('PKGD') + os.path.join(d.getVar('LICENSE_FILES_DIRECTORY'), d.getVar('PN'))
         copy_license_files(lic_files_paths, destdir)
         add_package_and_files(d)
 }