[openwrt/openwrt] build: add support for fixing up library soname

LEDE Commits lede-commits at lists.infradead.org
Sun Feb 14 13:42:13 EST 2021


nbd pushed a commit to openwrt/openwrt.git, branch master:
https://git.openwrt.org/b12288fa69b171f7c9405518c9bed3581a06f7ce

commit b12288fa69b171f7c9405518c9bed3581a06f7ce
Author: Felix Fietkau <nbd at nbd.name>
AuthorDate: Fri Feb 12 09:56:56 2021 +0100

    build: add support for fixing up library soname
    
    This makes it possible to declare a package ABI_VERSION independent from the
    upstream soname by setting PKG_ABI_VERSION in the package makefile.
    The library filename is fixed up for files installed to packages and to the
    staging dir. References to the original from executables within the same
    package are also fixed up
    
    Signed-off-by: Felix Fietkau <nbd at nbd.name>
---
 include/package-ipkg.mk    |  5 ++++
 include/package.mk         |  2 ++
 rules.mk                   |  6 ++++
 scripts/set-abi-version.sh | 73 ++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 86 insertions(+)

diff --git a/include/package-ipkg.mk b/include/package-ipkg.mk
index ead4b5742c..fb1b7549fb 100644
--- a/include/package-ipkg.mk
+++ b/include/package-ipkg.mk
@@ -152,6 +152,7 @@ ifeq ($(DUMP),)
 	mkdir -p $(PKG_BUILD_DIR)/.pkgdir/$(1)
 	$(call Package/$(1)/install,$(PKG_BUILD_DIR)/.pkgdir/$(1))
 	$(call Package/$(1)/install_lib,$(PKG_BUILD_DIR)/.pkgdir/$(1))
+	$(if $(PKG_ABI_VERSION),$(SET_ABI_VERSION) "$(PKG_ABI_VERSION)" "$(PKG_BUILD_DIR)/.pkgdir/$(1)" "$(STAGING_DIR)/packages/$(STAGING_FILES_LIST)")
 	touch $$@
 
     $(STAGING_DIR_ROOT)/stamp/.$(1)_installed: $(PKG_BUILD_DIR)/.pkgdir/$(1).installed
@@ -191,11 +192,15 @@ $(_endef)
     $$(IPKG_$(1)) : export DESCRIPTION=$$(Package/$(1)/description)
     $$(IPKG_$(1)) : export PATH=$$(TARGET_PATH_PKG)
     $$(IPKG_$(1)) : export PKG_SOURCE_DATE_EPOCH:=$(PKG_SOURCE_DATE_EPOCH)
+    ifdef Build/InstallDev
+      $$(IPKG_$(1)): $(STAMP_INSTALLED)
+    endif
     $(PKG_INFO_DIR)/$(1).provides $$(IPKG_$(1)): $(STAMP_BUILT) $(INCLUDE_DIR)/package-ipkg.mk
 	@rm -rf $$(IDIR_$(1)); \
 		$$(call remove_ipkg_files,$(1),$$(call opkg_package_files,$(call gen_ipkg_wildcard,$(1))))
 	mkdir -p $(PACKAGE_DIR) $$(IDIR_$(1))/CONTROL $(PKG_INFO_DIR)
 	$(call Package/$(1)/install,$$(IDIR_$(1)))
+	$(if $(PKG_ABI_VERSION),$(SET_ABI_VERSION) "$(PKG_ABI_VERSION)" "$$(IDIR_$(1))" "$(STAGING_DIR)/packages/$(STAGING_FILES_LIST)")
 	$(if $(Package/$(1)/install-overlay),mkdir -p $(PACKAGE_DIR) $$(IDIR_$(1))/rootfs-overlay)
 	$(call Package/$(1)/install-overlay,$$(IDIR_$(1))/rootfs-overlay)
 	-find $$(IDIR_$(1)) -name 'CVS' -o -name '.svn' -o -name '.#*' -o -name '*~'| $(XARGS) rm -rf
diff --git a/include/package.mk b/include/package.mk
index d38d52908e..0f1dd5cc50 100644
--- a/include/package.mk
+++ b/include/package.mk
@@ -178,6 +178,7 @@ Build/Exports=$(Build/Exports/Default)
 define Build/CoreTargets
   STAMP_PREPARED:=$$(STAMP_PREPARED)
   STAMP_CONFIGURED:=$$(STAMP_CONFIGURED)
+  PKG_ABI_VERSION:=$$(PKG_ABI_VERSION)
 
   $(if $(QUILT),$(Build/Quilt))
   $(call Build/Autoclean)
@@ -236,6 +237,7 @@ define Build/CoreTargets
 			"$(STAGING_DIR)/packages/$(STAGING_FILES_LIST)" \
 			"$(STAGING_DIR)"; \
 	fi
+	$(if $(PKG_ABI_VERSION),$(SET_ABI_VERSION) "$(PKG_ABI_VERSION)" $(TMP_DIR)/stage-$(PKG_DIR_NAME))
 	if [ -d $(TMP_DIR)/stage-$(PKG_DIR_NAME) ]; then \
 		(cd $(TMP_DIR)/stage-$(PKG_DIR_NAME); find ./ > $(TMP_DIR)/stage-$(PKG_DIR_NAME).files); \
 		$(call locked, \
diff --git a/rules.mk b/rules.mk
index cbe1b0cb4c..c6bd7327c5 100644
--- a/rules.mk
+++ b/rules.mk
@@ -339,6 +339,10 @@ else
     $(SCRIPT_DIR)/rstrip.sh
 endif
 
+SET_ABI_VERSION= \
+    PATCHELF="$(STAGING_DIR_HOST)/bin/patchelf" \
+	$(SCRIPT_DIR)/set-abi-version.sh
+
 ifeq ($(CONFIG_IPV6),y)
   DISABLE_IPV6:=
 else
@@ -428,6 +432,8 @@ $(shell \
 )
 endef
 
+abi_version_str = $(subst -,,$(subst _,,$(subst .,,$(1))))
+
 COMMITCOUNT = $(if $(DUMP),0,$(call commitcount))
 AUTORELEASE = $(if $(DUMP),0,$(call commitcount,1))
 
diff --git a/scripts/set-abi-version.sh b/scripts/set-abi-version.sh
new file mode 100755
index 0000000000..a61c842c6d
--- /dev/null
+++ b/scripts/set-abi-version.sh
@@ -0,0 +1,73 @@
+#!/usr/bin/env bash
+# 
+# Copyright (C) 2020 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+SELF=${0##*/}
+
+[ -n "$PATCHELF" ] || {
+  echo "$SELF: patchelf command not defined (PATCHELF variable not set)"
+  exit 1
+}
+
+ABI_VER="$1"
+PATCH_DIR="$2"
+REF_LIST="$3"
+
+[ -n "$ABI_VER" -a -n "$PATCH_DIR" ] || {
+	echo "$SELF: no ABI version or files/directories specified"
+	echo "usage: $SELF <VERSION> [<PATH>...]"
+	exit 1
+}
+
+cmd() {
+	echo "$@" >&2
+	"$@" || exit 1
+}
+
+gen_lib_list() {
+	while read F; do
+		F="${F##*/}"
+		case "$F" in
+			lib*.so*);;
+			*) continue;;
+		esac
+		echo -n "$F:"
+	done < "$REF_LIST"
+}
+
+find "$PATCH_DIR" -type f -a -name 'lib*.so*' | \
+(
+	while read F; do
+		NEW_F="${F%%.so*}.so.$ABI_VER"
+		NEW_NAME="${NEW_F##*/}"
+		[ "$NEW_F" != "$F" ] || continue
+		cmd mv "$F" "$NEW_F"
+		[ "$REF_LIST" ] || cmd ln -s "$NEW_NAME" "$F"
+		cmd $PATCHELF --set-soname "$NEW_NAME" "$NEW_F"
+	done
+)
+
+[ -n "$REF_LIST" ] || exit 0
+
+LIBS="$(gen_lib_list)"
+LIBS="${LIBS%%:}"
+find "$PATCH_DIR" -type f -a -exec file {} \; | \
+  sed -n -e 's/^\(.*\):.*ELF.*\(executable\|relocatable\|shared object\).*,.*/\1:\2/p' | \
+(
+	IFS=":"
+	while read F S; do
+		$PATCHELF --print-needed "$F" | while read L; do
+			BASE_L="${L%%.so*}"
+			for lib in $LIBS; do
+				base_lib="${lib%%.so*}"
+				[ "$BASE_L" = "$base_lib" ] || continue
+				[ "$l" = "$lib" ] && continue
+				cmd $PATCHELF --replace-needed "$L" "$lib" "$F"
+			done
+		done
+	done
+	true
+)



More information about the lede-commits mailing list