Skip to content

Commit e0ea3d7

Browse files
GeorgeSapkinrobimarko
authored andcommitted
build: fix apk packaging and ABI-versioning
The updated logic for the APK dependencies and provides is as follows: - If ABI version is defined: - package is named `package_name-ABI_version` - package implicitly provides `package_name-ABI_version=package_version` this implies that only one version of a package per ABI can be installed at the same time - additionally provide `package_name` so multiple packages can be looked up by its base name - for each `provides`, provide `provide-ABI_version=package_version` this implies that only one version of a provide can be installed at the same time - else if ABI version is _not_ defined - package is named `package_name` - package implicitly provides `package_name=package_version` this implies that only one version of a package can be installed at the same time - if `alternatives` is defined - for each `provides`, provide `provide` this implies that multiple versions of a provide can be installed at the same time - else if `alternatives` is _not_ defined - for each `provides`, provide `provide=package_version` this implies that only one version of a provide can be installed at the same time Both cases a package can be looked up by its base name. ABI version `alternatives`, `conffiles`, `conffiles_static`, `list` and `rusers` files so multiple versions of the same ABI package can be installed side by side, and so they don't overwrite each other's packaging files. ABI version `EXTRA_DEPENDS` so dependencies can be correctly looked up using the existing OpenWrt semantics without the ABI specified. This is needed since ABI-versioned libraries no longer provide `package_name=package_version`, so that they can be installed side by side. Remove duplicate dependencies when `EXTRA_DEPENDS` specifies a versioned one that is already in `DEPENDS`. ABI is defined ------------------------------------------------------------------------ `libsqlite3` has `PROVIDES` set to `libfake` and has two different ABI versions installed. `libfake` is just an example to demonstrate the mechanics, as the library can already be depended upon using e.g. `libsqlite3-0=3.51.0-r1`. Note the ABI-versioned lists. ``` root@OpenWrt:/tmp# apk add --allow-untrusted ./libsqlite3-0-3.51.0-r1.apk (1/1) Installing libsqlite3-0 (3.51.0-r1) libsqlite3-0-3.51.0-r1.post-install: Executing script... OK: 22 MiB in 157 packages root@OpenWrt:/tmp# apk add --allow-untrusted ./libsqlite3-1-4.00.0-r1.apk (1/1) Installing libsqlite3-1 (4.00.0-r1) libsqlite3-1-4.00.0-r1.post-install: Executing script... OK: 23 MiB in 158 packages root@OpenWrt:/tmp# apk query --fields name,version,contents,provides libsqlite3-0 libsqlite3-1 Name: libsqlite3-0 Version: 3.51.0-r2 Provides: libfake-0=3.51.0-r2 libsqlite3 Contents: lib/apk/packages/libsqlite3-0.list usr/lib/libsqlite3.so.0 usr/lib/libsqlite3.so.3.51.0 Name: libsqlite3-1 Version: 4.00.0-r1 Provides: libfake-1=4.00.0-r1 libsqlite3 Contents: lib/apk/packages/libsqlite3-1.list usr/lib/libsqlite3.so.1 usr/lib/libsqlite3.so.4.00.0 root@OpenWrt:/tmp# ls -lh /usr/lib/libsqlite3.so.* lrwxrwxrwx 1 root root 20 Nov 20 00:23 /usr/lib/libsqlite3.so.0 -> libsqlite3.so.3.51.0 lrwxrwxrwx 1 root root 20 Nov 20 00:27 /usr/lib/libsqlite3.so.1 -> libsqlite3.so.4.00.0 -rwxr-xr-x 1 root root 1.0M Nov 6 18:19 /usr/lib/libsqlite3.so.3.51.0 -rwxr-xr-x 1 root root 1.0M Nov 6 18:19 /usr/lib/libsqlite3.so.4.00.0 ``` ABI is not defined ------------------------------------------------------------------------ Both `avahi-dbus-daemon` and `avahi-nodbus-daemon` provide `avahi-daemon`, but have no ABI specified. This results in `avahi-daemon=0.8-r11` provides for both packages and only one being able to be installed at the same time: ``` root@OpenWrt:/tmp# apk add --allow-untrusted ./avahi-nodbus-daemon-0.8-r11.apk (1/4) Installing libavahi-nodbus-support (0.8-r10) libavahi-nodbus-support-0.8-r10.post-install: Executing script... (2/4) Installing libdaemon (0.14-r5) libdaemon-0.14-r5.post-install: Executing script... (3/4) Installing libexpat (2.7.3-r1) libexpat-2.7.3-r1.post-install: Executing script... (4/4) Installing avahi-nodbus-daemon (0.8-r11) avahi-nodbus-daemon-0.8-r11.post-install: Executing script... 23 MiB in 160 packages root@OpenWrt:/tmp# apk query --fields provides avahi-nodbus-daemon Provides: avahi-daemon=0.8-r11 root@OpenWrt:/tmp# apk add --allow-untrusted ./avahi-dbus-daemon-0.8-r11.apk ERROR: unable to select packages: avahi-dbus-daemon-0.8-r11: conflicts: avahi-nodbus-daemon-0.8-r11[avahi-daemon=0.8-r11] satisfies: world[avahi-dbus-daemon><Q1R111s+ke9Vf+eCxDHX2BZVUK54Q=] avahi-nodbus-daemon-0.8-r11: conflicts: avahi-dbus-daemon-0.8-r11[avahi-daemon=0.8-r11] satisfies: world[avahi-nodbus-daemon><Q1BAu7nLI2MgRabpveLTGO2ksQz7E=] ``` Provides and alternatives ------------------------------------------------------------------------ Both `uclient-fetch` and `wget-nossl` provide `wget` and specify alternatives, so provides are not versioned and both packages can be installed at the same time: ``` root@OpenWrt:/tmp# apk query --fields name,version,contents,provides uclient-fetch wget-nossl Name: uclient-fetch Version: 2025.10.03~dc909ca7-r1 Provides: wget Contents: bin/uclient-fetch lib/apk/packages/uclient-fetch.alternatives lib/apk/packages/uclient-fetch.list Name: wget-nossl Version: 1.25.0-r1 Provides: gnu-wget wget Contents: lib/apk/packages/wget-nossl.alternatives lib/apk/packages/wget-nossl.list usr/libexec/wget-nossl ``` Fixes: openwrt/openwrt#20582 Fixes: openwrt/openwrt#20802 Signed-off-by: George Sapkin <[email protected]> Link: openwrt/openwrt#20819 (cherry picked from commit 1802997) Link: openwrt/openwrt#21253 Signed-off-by: Robert Marko <[email protected]>
1 parent 2da3942 commit e0ea3d7

File tree

1 file changed

+57
-22
lines changed

1 file changed

+57
-22
lines changed

include/package-pack.mk

Lines changed: 57 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -199,11 +199,49 @@ endif
199199
$(call locked,$(CP) $(PKG_BUILD_DIR)/.pkgdir/$(1)/. $(STAGING_DIR_ROOT)/,root-copy)
200200
touch $$@
201201

202-
Package/$(1)/DEPENDS := $$(call mergelist,$$(foreach dep,$$(filter-out @%,$$(IDEPEND_$(1))),$$(dep)$$(call GetABISuffix,$$(dep))))
202+
Package/$(1)/DEPENDS := $$(foreach dep,$$(filter-out @%,$$(IDEPEND_$(1))),$$(dep)$$(call GetABISuffix,$$(dep)))
203203
ifneq ($$(EXTRA_DEPENDS),)
204-
Package/$(1)/DEPENDS := $$(EXTRA_DEPENDS)$$(if $$(Package/$(1)/DEPENDS),$$(comma) $$(Package/$(1)/DEPENDS))
204+
ifeq ($(CONFIG_USE_APK),)
205+
Package/$(1)/DEPENDS := $$(call mergelist,$$(Package/$(1)/DEPENDS))
206+
Package/$(1)/DEPENDS := $$(EXTRA_DEPENDS)$$(if $$(Package/$(1)/DEPENDS),$$(comma) $$(Package/$(1)/DEPENDS))
207+
else
208+
_SEP := __COMMA_SEP__
209+
_SPACE := __SPACE_SEP__
210+
_DEPENDS := $$(Package/$(1)/DEPENDS)
211+
_EXTRA_DEPENDS_ABI :=
212+
_DEP_ITEMS := $$(subst $$(_SEP),$$(space),$$(subst $$(space),$$(_SPACE),$$(subst $$(comma),$$(_SEP),$$(EXTRA_DEPENDS))))
213+
214+
$$(foreach dep,$$(_DEP_ITEMS), \
215+
$$(eval _CUR_DEP := $$(subst $$(_SPACE),$$(space),$$(strip $$(dep)))) \
216+
$$(eval _PKG_NAME := $$(word 1,$$(_CUR_DEP))) \
217+
$$(if $$(findstring $$(paren_left), $$(_PKG_NAME)), \
218+
$$(error "Unsupported extra dependency format: no space before '(': $$(_CUR_DEP)")) \
219+
) \
220+
$$(eval _ABI_SUFFIX := $$(call GetABISuffix,$$(_PKG_NAME))) \
221+
$$(eval _PKG_NAME_ABI := $$(_PKG_NAME)$$(_ABI_SUFFIX)) \
222+
$$(eval _VERSION_CONSTRAINT := $$(word 2,$$(_CUR_DEP))) \
223+
$$(if $$(_VERSION_CONSTRAINT), \
224+
$$(eval _EXTRA_DEP := $$(_PKG_NAME_ABI) $$(_VERSION_CONSTRAINT)), \
225+
$$(error "Extra dependencies must have version constraints. $$(_PKG_NAME) seems to be unversioned.") \
226+
) \
227+
$$(if $$(_EXTRA_DEPENDS_ABI), \
228+
$$(eval _EXTRA_DEPENDS_ABI := $$(_EXTRA_DEPENDS_ABI)$$(comma)$$(_EXTRA_DEP)), \
229+
$$(eval _EXTRA_DEPENDS_ABI := $$(_EXTRA_DEP)) \
230+
) \
231+
$$(if $$(_DEPENDS), \
232+
$$(eval _DEPENDS := $$(filter-out $$(_PKG_NAME_ABI),$$(_DEPENDS))) \
233+
) \
234+
)
235+
236+
_DEPENDS := $$(call mergelist,$$(_DEPENDS))
237+
Package/$(1)/DEPENDS := $$(_EXTRA_DEPENDS_ABI)$$(if $$(_DEPENDS),$$(comma) $$(_DEPENDS))
238+
endif
239+
else
240+
Package/$(1)/DEPENDS := $$(call mergelist,$$(Package/$(1)/DEPENDS))
205241
endif
206242

243+
$$(info $(1) fused dependencies: $$(Package/$(1)/DEPENDS))
244+
207245
$(_define) Package/$(1)/CONTROL
208246
Package: $(1)$$(ABIV_$(1))
209247
Version: $(VERSION)
@@ -320,7 +358,7 @@ else
320358
echo "[ -s "\$$$${IPKG_INSTROOT}/lib/functions.sh" ] || exit 0"; \
321359
echo ". \$$$${IPKG_INSTROOT}/lib/functions.sh"; \
322360
echo 'export root="$$$${IPKG_INSTROOT}"'; \
323-
echo 'export pkgname="$(1)"'; \
361+
echo 'export pkgname="$(1)$$(ABIV_$(1))"'; \
324362
echo "add_group_and_user"; \
325363
echo "default_postinst"; \
326364
[ ! -f $$(ADIR_$(1))/postinst-pkg ] || sed -z 's/^\s*#!/#!/' "$$(ADIR_$(1))/postinst-pkg"; \
@@ -345,34 +383,34 @@ else
345383
echo "[ -s "\$$$${IPKG_INSTROOT}/lib/functions.sh" ] || exit 0"; \
346384
echo ". \$$$${IPKG_INSTROOT}/lib/functions.sh"; \
347385
echo 'export root="$$$${IPKG_INSTROOT}"'; \
348-
echo 'export pkgname="$(1)"'; \
386+
echo 'export pkgname="$(1)$$(ABIV_$(1))"'; \
349387
echo "default_prerm"; \
350388
[ ! -f $$(ADIR_$(1))/prerm-pkg ] || sed -z 's/^\s*#!/#!/' "$$(ADIR_$(1))/prerm-pkg"; \
351389
) > $$(ADIR_$(1))/pre-deinstall;
352390

353391
[ ! -f $$(ADIR_$(1))/postrm ] || sed -zi 's/^\s*#!/#!/' "$$(ADIR_$(1))/postrm";
354392

355-
if [ -n "$(USERID)" ]; then echo $(USERID) > $$(IDIR_$(1))/lib/apk/packages/$(1).rusers; fi;
356-
if [ -n "$(ALTERNATIVES)" ]; then echo $(ALTERNATIVES) > $$(IDIR_$(1))/lib/apk/packages/$(1).alternatives; fi;
357-
(cd $$(IDIR_$(1)) && find . -type f,l -printf "/%P\n" | sort > $(TMP_DIR)/$(1).list && mv $(TMP_DIR)/$(1).list $$(IDIR_$(1))/lib/apk/packages/$(1).list)
393+
if [ -n "$(USERID)" ]; then echo $(USERID) > $$(IDIR_$(1))/lib/apk/packages/$(1)$$(ABIV_$(1)).rusers; fi;
394+
if [ -n "$(ALTERNATIVES)" ]; then echo $(ALTERNATIVES) > $$(IDIR_$(1))/lib/apk/packages/$(1)$$(ABIV_$(1)).alternatives; fi;
395+
(cd $$(IDIR_$(1)) && find . -type f,l -printf "/%P\n" | sort > $(TMP_DIR)/$(1).list && mv $(TMP_DIR)/$(1).list $$(IDIR_$(1))/lib/apk/packages/$(1)$$(ABIV_$(1)).list)
358396
# Move conffiles to IDIR and build conffiles_static with csums
359397
if [ -f $$(ADIR_$(1))/conffiles ]; then \
360-
mv -f $$(ADIR_$(1))/conffiles $$(IDIR_$(1))/lib/apk/packages/$(1).conffiles; \
361-
for file in $$$$(cat $$(IDIR_$(1))/lib/apk/packages/$(1).conffiles); do \
398+
mv -f $$(ADIR_$(1))/conffiles $$(IDIR_$(1))/lib/apk/packages/$(1)$$(ABIV_$(1)).conffiles; \
399+
for file in $$$$(cat $$(IDIR_$(1))/lib/apk/packages/$(1)$$(ABIV_$(1)).conffiles); do \
362400
[ -f $$(IDIR_$(1))/$$$$file ] || continue; \
363401
csum=$$$$($(MKHASH) sha256 $$(IDIR_$(1))/$$$$file); \
364-
echo $$$$file $$$$csum >> $$(IDIR_$(1))/lib/apk/packages/$(1).conffiles_static; \
402+
echo $$$$file $$$$csum >> $$(IDIR_$(1))/lib/apk/packages/$(1)$$(ABIV_$(1)).conffiles_static; \
365403
done; \
366404
fi
367405

368406
# Some package (base-files) manually append stuff to conffiles
369407
# Append stuff from it and delete the CONTROL directory since everything else should be migrated
370408
if [ -f $$(IDIR_$(1))/CONTROL/conffiles ]; then \
371-
echo $$$$(IDIR_$(1))/CONTROL/conffiles >> $$(IDIR_$(1))/lib/apk/packages/$(1).conffiles; \
409+
echo $$$$(IDIR_$(1))/CONTROL/conffiles >> $$(IDIR_$(1))/lib/apk/packages/$(1)$$(ABIV_$(1)).conffiles; \
372410
for file in $$$$(cat $$(IDIR_$(1))/CONTROL/conffiles); do \
373411
[ -f $$(IDIR_$(1))/$$$$file ] || continue; \
374412
csum=$$$$($(MKHASH) sha256 $$(IDIR_$(1))/$$$$file); \
375-
echo $$$$file $$$$csum >> $$(IDIR_$(1))/lib/apk/packages/$(1).conffiles_static; \
413+
echo $$$$file $$$$csum >> $$(IDIR_$(1))/lib/apk/packages/$(1)$$(ABIV_$(1)).conffiles_static; \
376414
done; \
377415
rm -rf $$(IDIR_$(1))/CONTROL/conffiles; \
378416
fi
@@ -394,16 +432,13 @@ else
394432
--info "origin:$(SOURCE)" \
395433
--info "url:$(URL)" \
396434
--info "maintainer:$(MAINTAINER)" \
397-
--info "provides:$$(foreach prov,\
398-
$$(filter-out $(1)$$(ABIV_$(1)), \
399-
$(PROVIDES)$$(if $$(ABIV_$(1)), \
400-
$(1)=$(VERSION) $(foreach provide, \
401-
$(PROVIDES), \
402-
$(provide)$$(ABIV_$(1))=$(VERSION) \
403-
) \
404-
) \
405-
), \
406-
$$(prov) )" \
435+
--info "provides:$$(if $$(ABIV_$(1)), \
436+
$(1) $(foreach provide,$(PROVIDES), $(provide)$$(ABIV_$(1))=$(VERSION)), \
437+
$(if $(ALTERNATIVES), \
438+
$(PROVIDES), \
439+
$(foreach provide,$(PROVIDES), $(provide)=$(VERSION)) \
440+
) \
441+
)" \
407442
$(if $(DEFAULT_VARIANT),--info "provider-priority:100",$(if $(PROVIDES),--info "provider-priority:1")) \
408443
$$(APK_SCRIPTS_$(1)) \
409444
--info "depends:$$(foreach depends,$$(subst $$(comma),$$(space),$$(subst $$(space),,$$(subst $$(paren_right),,$$(subst $$(paren_left),,$$(Package/$(1)/DEPENDS))))),$$(depends))" \

0 commit comments

Comments
 (0)