[openwrt/openwrt] build: add support for virtual provides
LEDE Commits
lede-commits at lists.infradead.org
Wed Dec 31 09:16:55 PST 2025
robimarko pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/5ed650acbfd9cfbfd6a381df7db060c9153bacfc
commit 5ed650acbfd9cfbfd6a381df7db060c9153bacfc
Author: George Sapkin <george at sapk.in>
AuthorDate: Thu Dec 25 15:32:29 2025 +0200
build: add support for virtual provides
Allow defining virtual provides using the PROVIDES field by prefixing
them with @, e.g.:
PROVIDES:=@ca-certs
Virtual provides don't own the provided name and multiple packages with
the same virtual provides can be installed side-by-side. Packages must
still take care not to override each other's files.
Add an implicit self-provide to packages. apk can't handle self
provides, be it versioned or virtual, so opt for a suffix instead. This
allows several variants to provide the same virtual package without
adding extra provides to the default one, e.g. wget implicitly provides
wget-any and is marked as default, so wget-ssl can explicitly provide
@wget-any as well.
Filter out virtual provides when generating metadata.
Filter out virtual provides prefix and self provide where appropriate.
Signed-off-by: George Sapkin <george at sapk.in>
Link: https://github.com/openwrt/openwrt/pull/21288
Signed-off-by: Robert Marko <robimarko at gmail.com>
---
include/package-pack.mk | 46 +++++++++++++++++++++++++++++++++++++++++-----
include/package.mk | 7 +++++++
scripts/metadata.pm | 3 +++
3 files changed, 51 insertions(+), 5 deletions(-)
diff --git a/include/package-pack.mk b/include/package-pack.mk
index 7080b8362b..853832d90f 100644
--- a/include/package-pack.mk
+++ b/include/package-pack.mk
@@ -78,6 +78,25 @@ define FixupDependencies
$(call AddDependency,$(1),$$(DEPS))
endef
+# Format provide and add ABI and version if it's not a virtual provide marked
+# with an @.
+#
+# 1: provide name
+# 2: provide version
+# 3: (optional) ABI preformatted by FormatABISuffix
+define AddProvide
+$(if $(filter @%,$(1)),$(patsubst @%,%,$(1)),$(1)$(3)=$(2))
+endef
+
+# Remove virtual provides prefix and self. apk doesn't like it when packages
+# specify a redundant provide pointing to self.
+#
+# 1: package name
+# 2: list of provides
+define SanitizeProvides
+$(filter-out $(1),$(patsubst @%,%,$(2)))
+endef
+
# Format provides both for apk and control
#
# - If ABI version is defined:
@@ -108,16 +127,33 @@ endef
# this implies that only one version of a provide can be installed at the
# same time
#
+# - Both with and without an ABI, if a provide starts with an @, treat it as a
+# virtual provide, that doesn't own the name by not appending version.
+# Multiple packages with the same virtual provides can be installed
+# side-by-side.
+#
+# - apk doesn't like it when packages specify a redundant provide pointing to
+# self. Filter it out, but keep virtual self provides, in the form of
+# @${package_name}-any.
+#
+# - Packages implicitly add a virtual @${package_name}-any provide in Package.
+#
# 1: package name
# 2: package version
# 3: list of provides
# 4: list of alternatives
define FormatProvides
$(strip $(if $(ABIV_$(1)), \
- $(1) $(foreach provide,$(3), $(provide)$(ABIV_$(1))=$(2)), \
+ $(1) $(foreach provide, \
+ $(filter-out $(1),$(3)), \
+ $(call AddProvide,$(provide),$(2),$(ABIV_$(1))) \
+ ), \
$(if $(4), \
- $(3), \
- $(foreach provide,$(3), $(provide)=$(2)) \
+ $(filter-out $(1),$(3)), \
+ $(foreach provide, \
+ $(filter-out $(1),$(3)), \
+ $(call AddProvide,$(provide),$(2)) \
+ ) \
) \
))
endef
@@ -237,7 +273,7 @@ endif
$(if $(ABI_VERSION),echo '$(ABI_VERSION)' | cmp -s - $(PKG_INFO_DIR)/$(1).version || { \
mkdir -p $(PKG_INFO_DIR); \
echo '$(ABI_VERSION)' > $(PKG_INFO_DIR)/$(1).version; \
- $(foreach pkg,$(filter-out $(1),$(PROVIDES)), \
+ $(foreach pkg,$(call SanitizeProvides,$(1),$(PROVIDES)), \
cp $(PKG_INFO_DIR)/$(1).version $(PKG_INFO_DIR)/$(pkg).version; \
) \
} )
@@ -336,7 +372,7 @@ endif
fi; \
done; $(Package/$(1)/extra_provides) \
) | sort -u > $(PKG_INFO_DIR)/$(1).provides
- $(if $(PROVIDES), at for pkg in $(filter-out $(1),$(PROVIDES)); do cp $(PKG_INFO_DIR)/$(1).provides $(PKG_INFO_DIR)/$$$$pkg.provides; done)
+ $(if $(PROVIDES), at for pkg in $(call SanitizeProvides,$(1),$(PROVIDES)); do cp $(PKG_INFO_DIR)/$(1).provides $(PKG_INFO_DIR)/$$$$pkg.provides; done)
$(CheckDependencies)
$(RSTRIP) $$(IDIR_$(1))
diff --git a/include/package.mk b/include/package.mk
index 5392bdf465..087e374ea9 100644
--- a/include/package.mk
+++ b/include/package.mk
@@ -332,6 +332,13 @@ define BuildPackage
$(eval $(Package/Default))
$(eval $(Package/$(1)))
+ # Add an implicit self-provide. apk can't handle self provides, be it
+ # versioned or virtual, so opt for a suffix instead. This allows several
+ # variants to provide the same virtual package without adding extra provides
+ # to the default one, e.g. wget implicitly provides wget-any and is marked as
+ # default, so wget-ssl can explicitly provide @wget-any as well.
+ PROVIDES+=@$(1)-any
+
ifdef DESCRIPTION
$$(error DESCRIPTION:= is obsolete, use Package/PKG_NAME/description)
endif
diff --git a/scripts/metadata.pm b/scripts/metadata.pm
index dec9e62dff..6cb63608d2 100644
--- a/scripts/metadata.pm
+++ b/scripts/metadata.pm
@@ -263,6 +263,9 @@ sub parse_package_metadata($) {
/^Default: \s*(.+)\s*$/ and $pkg->{default} = $1;
/^Provides: \s*(.+)\s*$/ and do {
my @vpkg = split /\s+/, $1;
+ foreach (@vpkg) {
+ s/^@//;
+ }
@{$pkg->{provides}} = ($pkg->{name}, @vpkg);
foreach my $vpkg (@vpkg) {
next if ($vpkg eq $pkg->{name});
More information about the lede-commits
mailing list