build: add support for as-needed linking
PATCH 1/2 build: add support for as-needed linking
From: Gustavo Zacarias <[email protected]>
This option tells the linker to only link to the libraries containing symbols that are actually used.
It requires libtool patches to fully clean the needed chain, these are used by major distributions such as Debian and Gentoo.
https://wiki.debian.org/ToolChain/DSOLinking
https://wiki.gentoo.org/wiki/Project:Quality_Assurance/As-needed
Introduce a BR2_AS_NEEDED global enable option (default=no, marked as experimental) that generally disables the libtool patching and avoids the extra LDFLAGS (-Wl,--as-needed).
Also add a per-package PACKAGE_AS_NEEDED (default=yes) option to work around problematic packages that might not behave too well with as-needed linking.
For the libtool patching use a guess (automatic) method since version-matching doesn't work accurately with some packages that ship patched/modified ltmain.sh scripts, normally based on 2.4. In some of these cases the as-needed-v2.2.6.patch works, and in other cases the as-needed-v2.4.2.patch is necessary and the exact condition can't be found in a deterministic way. If for some reason none of the patches applies to a particular package this will only affect said package and shouldn't have any consequence even if passing -Wl,--as-needed LDFLAGS.
Example for a simple defconfig:
BR2_arm=y
BR2_AS_NEEDED=y
BR2_TOOLCHAIN_EXTERNAL=y
BR2_PACKAGE_GSTREAMER1=y
BR2_PACKAGE_GST1_PLUGINS_BAD=y
With as-needed disabled:
$ readelf -a libgstbadvideo-1.0.so|grep "(NEEDED)"|wc -l 10
With as-needed enabled:
$ readelf -a libgstbadvideo-1.0.so|grep "(NEEDED)"|wc -l 8
--- Config.in | 6 +++++ package/Makefile.in | 5 ++++ package/pkg-autotools.mk | 43 ++++++++++++++++++++++++++++++ support/libtool/as-needed-v1.5.26.patch | 46 +++++++++++++++++++++++++++++++++ support/libtool/as-needed-v1.5.patch | 38 +++++++++++++++++++++++++++ support/libtool/as-needed-v2.2.6.patch | 46 +++++++++++++++++++++++++++++++++ support/libtool/as-needed-v2.4.2.patch | 46 +++++++++++++++++++++++++++++++++ support/libtool/as-needed-v2.4.3.patch | 46 +++++++++++++++++++++++++++++++++ 8 files changed, 276 insertions(+) create mode 100644 support/libtool/as-needed-v1.5.26.patch create mode 100644 support/libtool/as-needed-v1.5.patch create mode 100644 support/libtool/as-needed-v2.2.6.patch create mode 100644 support/libtool/as-needed-v2.4.2.patch create mode 100644 support/libtool/as-needed-v2.4.3.patch
Config.in +6 -0
@@ -739,6 +739,12 @@ config BR2_REPRODUCIBLE This is labeled as an experimental feature, as not all packages behave properly to ensure reproducibility. +config BR2_AS_NEEDED + bool "Link target binaries/libraries as-needed (experimental)" + help + Tell the linker to link in the produced binary/library only + the libraries containing symbols that are actually used. + endmenu source "toolchain/Config.in"
package/Makefile.in +5 -0
@@ -144,6 +144,11 @@ TARGET_CXXFLAGS = $(TARGET_CFLAGS) TARGET_FCFLAGS = $(TARGET_ABI) $(TARGET_OPTIMIZATION) $(TARGET_DEBUGGING) TARGET_LDFLAGS = $(call qstrip,$(BR2_TARGET_LDFLAGS)) +# $(PKG)_AS_NEEDED gets expanded too early for ifeq usage, so use subst instead +ifeq ($(BR2_AS_NEEDED),y) +TARGET_LDFLAGS += -Wl,$(subst NO,--no,$(subst YES,-,$($(PKG)_AS_NEEDED)))-as-needed +endif + ifeq ($(BR2_BINFMT_FLAT),y) TARGET_CFLAGS += $(if $($(PKG)_FLAT_STACKSIZE),-Wl$(comma)-elf2flt=-s$($(PKG)_FLAT_STACKSIZE),\ -Wl$(comma)-elf2flt)
package/pkg-autotools.mk +43 -0
67 lines not on this page · raw message
support/libtool/as-needed-v1.5.26.patch new file +46 -0
46 lines not on this page · raw message
support/libtool/as-needed-v1.5.patch new file +38 -0
@@ -0,0 +1,38 @@ +Conveniently fetched from Gentoo, these are basically the same as used +by Debian. +https://gitweb.gentoo.org/repo/gentoo.git/tree/eclass/ELT-patches/as-needed + +Upstream status: unknown + +Signed-off-by: Gustavo Zacarias <[email protected]> + +--- a/ltmain.sh.orig 2006-03-29 15:45:36.000000000 +0200 ++++ b/ltmain.sh 2006-03-29 16:39:30.000000000 +0200 +@@ -1754,6 +1754,11 @@ + arg=`$echo "X$arg" | $Xsed -e "s/^ //"` + ;; + ++ -Wl,--as-needed|-Wl,--no-as-needed) ++ deplibs="$deplibs $arg" ++ continue ++ ;; ++ + -Wl,*) + args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'` + arg= +@@ -2094,6 +2099,15 @@ + lib= + found=no + case $deplib in ++ -Wl,--as-needed|-Wl,--no-as-needed) ++ if test "$linkmode,$pass" = "prog,link"; then ++ compile_deplibs="$deplib $compile_deplibs" ++ finalize_deplibs="$deplib $finalize_deplibs" ++ else ++ deplibs="$deplib $deplibs" ++ fi ++ continue ++ ;; + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs"
support/libtool/as-needed-v2.2.6.patch new file +46 -0
46 lines not on this page · raw message
support/libtool/as-needed-v2.4.2.patch new file +46 -0
46 lines not on this page · raw message
support/libtool/as-needed-v2.4.3.patch new file +46 -0
46 lines not on this page · raw message
Signature · 1 line
2.7.3
PATCH 2/2 docs/manual: document PKG_AS_NEEDED
From: Gustavo Zacarias <[email protected]>
--- docs/manual/adding-packages-autotools.txt | 4 ++++ 1 file changed, 4 insertions(+)
docs/manual/adding-packages-autotools.txt +4 -0
@@ -147,6 +147,10 @@ cases, typical packages will therefore only use a few of them. not. Valid values are +YES+ and +NO+. By default, the value is +YES+ +* +LIBFOO_AS_NEEDED+ tells wether as-needed linking should be enabled + or disabled. Valid values are +YES+ and +NO+. By default, the + value is +YES+ + * +LIBFOO_INSTALL_STAGING_OPTS+ contains the make options used to install the package to the staging directory. By default, the value is +DESTDIR=$(STAGING_DIR) install+, which is
Signature · 1 line
2.7.3
PATCH 1/2 build: add support for as-needed linking
In reply to gustavo.zacarias at free-electrons.comGustavo, All,
On 2016-07-17 12:05 -0300, gustavo.zacarias at free-electrons.com spake thusly:
Quoted 9 lines
From: Gustavo Zacarias <[email protected]>
This option tells the linker to only link to the libraries containing symbols that are actually used.
It requires libtool patches to fully clean the needed chain, these are used by major distributions such as Debian and Gentoo.
https://wiki.debian.org/ToolChain/DSOLinking
https://wiki.gentoo.org/wiki/Project:Quality_Assurance/As-needed
OK, I read both of the above, and I do understand the technicalities behind --as-needed.
However, I fail to see what it would bring to Buidlroot.
One key point of --as-needed is to not pull in an unneeded library into an executable, in case it does not need it, especially in the case that this library is a second-order depedency by way of another library, e.g.:
foo:
NEEDED: libbar.so
NEEDED: libbuz.so
libbar.so:
NEEDED: libbuz.so
but where foo does not use any symbol from libbuz.so. This purportedly allows to update second-order libraries (libbuz, above) when there is an ABI change in those libs, and only have to rebuild first-order libs (libbar, above) without to rebuild the executable itself.
Another key point is that the dynamic loader will not have to load unncessary libraries,thus reducing startup time.
However, I fail to see how that can be any usefull in the context of Buildroot.
First, we do not support partial updates, and only catter to full-system updates. Thus the first point is moot IMHO.
Second, the default behaviour of the dynamic linker is to do lazy binding, i.e. to only resolve sumbols at the time they are first needed, and thus only loading libraries to resolve a missing symbol (unless I'm mistaken...)
So, what would that bring to us?
Regards,
Yann E. MORIN.
Quoted 416 lines
Introduce a
BR2_AS_NEEDEDglobal enable option (default=no, marked as experimental) that generally disables the libtool patching and avoids the extra LDFLAGS (-Wl,--as-needed).Also add a per-package
PACKAGE_AS_NEEDED(default=yes) option to work around problematic packages that might not behave too well with as-needed linking.For the libtool patching use a guess (automatic) method since version-matching doesn't work accurately with some packages that ship patched/modified
ltmain.shscripts, normally based on 2.4. In some of these cases the as-needed-v2.2.6.patch works, and in other cases the as-needed-v2.4.2.patch is necessary and the exact condition can't be found in a deterministic way. If for some reason none of the patches applies to a particular package this will only affect said package and shouldn't have any consequence even if passing -Wl,--as-needed LDFLAGS.Example for a simple defconfig:
BR2_arm=y
BR2_AS_NEEDED=y
BR2_TOOLCHAIN_EXTERNAL=y
BR2_PACKAGE_GSTREAMER1=y
BR2_PACKAGE_GST1_PLUGINS_BAD=yWith as-needed disabled:
$ readelf -a libgstbadvideo-1.0.so|grep "(NEEDED)"|wc -l 10With as-needed enabled:
$ readelf -a libgstbadvideo-1.0.so|grep "(NEEDED)"|wc -l 8Signed-off-by Gustavo Zacarias <[email protected]>--- Config.in | 6 +++++ package/Makefile.in | 5 ++++ package/pkg-autotools.mk | 43 ++++++++++++++++++++++++++++++ support/libtool/as-needed-v1.5.26.patch | 46 +++++++++++++++++++++++++++++++++ support/libtool/as-needed-v1.5.patch | 38 +++++++++++++++++++++++++++ support/libtool/as-needed-v2.2.6.patch | 46 +++++++++++++++++++++++++++++++++ support/libtool/as-needed-v2.4.2.patch | 46 +++++++++++++++++++++++++++++++++ support/libtool/as-needed-v2.4.3.patch | 46 +++++++++++++++++++++++++++++++++ 8 files changed, 276 insertions(+) create mode 100644 support/libtool/as-needed-v1.5.26.patch create mode 100644 support/libtool/as-needed-v1.5.patch create mode 100644 support/libtool/as-needed-v2.2.6.patch create mode 100644 support/libtool/as-needed-v2.4.2.patch create mode 100644 support/libtool/as-needed-v2.4.3.patchConfig.in +6
-0@@ -739,6 +739,12 @@ config BR2_REPRODUCIBLE This is labeled as an experimental feature, as not all packages behave properly to ensure reproducibility. +config BR2_AS_NEEDED + bool "Link target binaries/libraries as-needed (experimental)" + help + Tell the linker to link in the produced binary/library only + the libraries containing symbols that are actually used. + endmenu source "toolchain/Config.in"package/Makefile.in +5
-0@@ -144,6 +144,11 @@ TARGET_CXXFLAGS = $(TARGET_CFLAGS) TARGET_FCFLAGS = $(TARGET_ABI) $(TARGET_OPTIMIZATION) $(TARGET_DEBUGGING) TARGET_LDFLAGS = $(call qstrip,$(BR2_TARGET_LDFLAGS)) +# $(PKG)_AS_NEEDED gets expanded too early for ifeq usage, so use subst instead +ifeq ($(BR2_AS_NEEDED),y) +TARGET_LDFLAGS += -Wl,$(subst NO,--no,$(subst YES,-,$($(PKG)_AS_NEEDED)))-as-needed +endif + ifeq ($(BR2_BINFMT_FLAT),y) TARGET_CFLAGS += $(if $($(PKG)_FLAT_STACKSIZE),-Wl$(comma)-elf2flt=-s$($(PKG)_FLAT_STACKSIZE),\ -Wl$(comma)-elf2flt)package/pkg-autotools.mk +43
-0@@ -55,6 +55,26 @@ define UPDATE_CONFIG_HOOK endef # +# Hook to patch libtool to make it work properly for as-needed linking +# +define LIBTOOL_AS_NEEDED_PATCH_HOOK + @$(call MESSAGE,"Patching libtool as-needed") + $(Q)for i in `find $($(PKG)_SRCDIR) -name ltmain.sh`; do \ + if patch -p1 --dry-run -f -s -d $${i%/*} <support/libtool/as-needed-v2.4.3.patch >/dev/null ; then\ + $(APPLY_PATCHES) $${i%/*} support/libtool as-needed-v2.4.3.patch; \ + elif patch -p1 --dry-run -f -s -d $${i%/*} <support/libtool/as-needed-v2.4.2.patch >/dev/null ; then\ + $(APPLY_PATCHES) $${i%/*} support/libtool as-needed-v2.4.2.patch; \ + elif patch -p1 --dry-run -f -s -d $${i%/*} <support/libtool/as-needed-v2.2.6.patch >/dev/null ; then\ + $(APPLY_PATCHES) $${i%/*} support/libtool as-needed-v2.2.6.patch; \ + elif patch -p1 --dry-run -f -s -d $${i%/*} <support/libtool/as-needed-v1.5.26.patch >/dev/null ; then\ + $(APPLY_PATCHES) $${i%/*} support/libtool as-needed-v1.5.26.patch; \ + elif patch -p1 --dry-run -f -s -d $${i%/*} <support/libtool/as-needed-v1.5.patch >/dev/null ; then\ + $(APPLY_PATCHES) $${i%/*} support/libtool as-needed-v1.5.patch; \ + fi \ + done +endef + +# # Hook to patch libtool to make it work properly for cross-compilation # define LIBTOOL_PATCH_HOOK@@ -111,6 +131,17 @@ endef define inner-autotools-package +# +# as-needed is only patched/enabled for target packages +# +ifndef $(2)_AS_NEEDED + ifeq ($(4),target) + $(2)_AS_NEEDED ?= YES + else + $(2)_AS_NEEDED ?= NO + endif +endif + ifndef $(2)_LIBTOOL_PATCH ifdef $(3)_LIBTOOL_PATCH $(2)_LIBTOOL_PATCH = $$($(3)_LIBTOOL_PATCH)@@ -244,6 +275,12 @@ $(2)_PRE_CONFIGURE_HOOKS += AUTORECONF_HOOK ifneq ($$($(2)_LIBTOOL_PATCH),NO) $(2)_PRE_CONFIGURE_HOOKS += LIBTOOL_PATCH_HOOK endif +# Don't patch packages that skip as-needed +ifeq ($(BR2_AS_NEEDED),y) +ifneq ($$($(2)_AS_NEEDED),NO) +$(2)_PRE_CONFIGURE_HOOKS += LIBTOOL_AS_NEEDED_PATCH_HOOK +endif +endif $(2)_DEPENDENCIES += host-automake host-autoconf host-libtool else # ! AUTORECONF = YES@@ -252,6 +289,12 @@ else # ! AUTORECONF = YES ifneq ($$($(2)_LIBTOOL_PATCH),NO) $(2)_POST_PATCH_HOOKS += LIBTOOL_PATCH_HOOK endif +# Don't patch packages that skip as-needed +ifeq ($(BR2_AS_NEEDED),y) +ifneq ($$($(2)_AS_NEEDED),NO) +$(2)_PRE_CONFIGURE_HOOKS += LIBTOOL_AS_NEEDED_PATCH_HOOK +endif +endif endifsupport/libtool/as-needed-v1.5.26.patch new file +46
-0@@ -0,0 +1,46 @@ +Conveniently fetched from Gentoo, these are basically the same as used +by Debian. +https://gitweb.gentoo.org/repo/gentoo.git/tree/eclass/ELT-patches/as-needed + +Upstream status: unknown + +Signed-off-by: Gustavo Zacarias <[email protected]> + +--- a/ltmain.sh.orig 2009-04-18 16:51:52.000000000 +0200 ++++ b/ltmain.sh 2009-04-18 16:55:05.000000000 +0200 +@@ -1812,10 +1812,15 @@ + done + IFS="$save_ifs" + arg=`$echo "X$arg" | $Xsed -e "s/^ //"` + ;; + ++ -Wl,--as-needed|-Wl,--no-as-needed) ++ deplibs="$deplibs $arg" ++ continue ++ ;; ++ + -Wl,*) + args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'` + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do +@@ -2152,10 +2157,19 @@ + fi + for deplib in $libs; do + lib= + found=no + case $deplib in ++ -Wl,--as-needed|-Wl,--no-as-needed) ++ if test "$linkmode,$pass" = "prog,link"; then ++ compile_deplibs="$deplib $compile_deplibs" ++ finalize_deplibs="$deplib $finalize_deplibs" ++ else ++ deplibs="$deplib $deplibs" ++ fi ++ continue ++ ;; + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + elsesupport/libtool/as-needed-v1.5.patch new file +38
-0@@ -0,0 +1,38 @@ +Conveniently fetched from Gentoo, these are basically the same as used +by Debian. +https://gitweb.gentoo.org/repo/gentoo.git/tree/eclass/ELT-patches/as-needed + +Upstream status: unknown + +Signed-off-by: Gustavo Zacarias <[email protected]> + +--- a/ltmain.sh.orig 2006-03-29 15:45:36.000000000 +0200 ++++ b/ltmain.sh 2006-03-29 16:39:30.000000000 +0200 +@@ -1754,6 +1754,11 @@ + arg=`$echo "X$arg" | $Xsed -e "s/^ //"` + ;; + ++ -Wl,--as-needed|-Wl,--no-as-needed) ++ deplibs="$deplibs $arg" ++ continue ++ ;; ++ + -Wl,*) + args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'` + arg= +@@ -2094,6 +2099,15 @@ + lib= + found=no + case $deplib in ++ -Wl,--as-needed|-Wl,--no-as-needed) ++ if test "$linkmode,$pass" = "prog,link"; then ++ compile_deplibs="$deplib $compile_deplibs" ++ finalize_deplibs="$deplib $finalize_deplibs" ++ else ++ deplibs="$deplib $deplibs" ++ fi ++ continue ++ ;; + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs"support/libtool/as-needed-v2.2.6.patch new file +46
-0@@ -0,0 +1,46 @@ +Conveniently fetched from Gentoo, these are basically the same as used +by Debian. +https://gitweb.gentoo.org/repo/gentoo.git/tree/eclass/ELT-patches/as-needed + +Upstream status: unknown + +Signed-off-by: Gustavo Zacarias <[email protected]> + +--- a/ltmain.sh.orig 2009-04-18 14:37:16.000000000 +0200 ++++ b/ltmain.sh 2009-04-18 14:40:08.000000000 +0200 +@@ -4721,10 +4721,15 @@ + IFS="$save_ifs" + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + ++ -Wl,--as-needed|-Wl,--no-as-needed) ++ deplibs="$deplibs $arg" ++ continue ++ ;; ++ + -Wl,*) + func_stripname '-Wl,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs="$IFS"; IFS=',' +@@ -5075,10 +5080,19 @@ + + for deplib in $libs; do + lib= + found=no + case $deplib in ++ -Wl,--as-needed|-Wl,--no-as-needed) ++ if test "$linkmode,$pass" = "prog,link"; then ++ compile_deplibs="$deplib $compile_deplibs" ++ finalize_deplibs="$deplib $finalize_deplibs" ++ else ++ deplibs="$deplib $deplibs" ++ fi ++ continue ++ ;; + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + elsesupport/libtool/as-needed-v2.4.2.patch new file +46
-0@@ -0,0 +1,46 @@ +Conveniently fetched from Gentoo, these are basically the same as used +by Debian. +https://gitweb.gentoo.org/repo/gentoo.git/tree/eclass/ELT-patches/as-needed + +Upstream status: unknown + +Signed-off-by: Gustavo Zacarias <[email protected]> + +--- a/ltmain.sh.orig 2012-08-19 10:18:57.929178597 +0200 ++++ b/ltmain.sh 2012-08-19 10:31:43.409388998 +0200 +@@ -5798,10 +5798,15 @@ + IFS="$save_ifs" + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + ++ -Wl,--as-needed|-Wl,--no-as-needed) ++ deplibs="$deplibs $arg" ++ continue ++ ;; ++ + -Wl,*) + func_stripname '-Wl,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs="$IFS"; IFS=',' +@@ -6158,10 +6163,19 @@ + + for deplib in $libs; do + lib= + found=no + case $deplib in ++ -Wl,--as-needed|-Wl,--no-as-needed) ++ if test "$linkmode,$pass" = "prog,link"; then ++ compile_deplibs="$deplib $compile_deplibs" ++ finalize_deplibs="$deplib $finalize_deplibs" ++ else ++ deplibs="$deplib $deplibs" ++ fi ++ continue ++ ;; + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs"support/libtool/as-needed-v2.4.3.patch new file +46
-0@@ -0,0 +1,46 @@ +Conveniently fetched from Gentoo, these are basically the same as used +by Debian. +https://gitweb.gentoo.org/repo/gentoo.git/tree/eclass/ELT-patches/as-needed + +Upstream status: unknown + +Signed-off-by: Gustavo Zacarias <[email protected]> + +--- a/ltmain.sh ++++ b/ltmain.sh +@@ -7225,10 +7225,15 @@ + IFS=$save_ifs + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + ++ -Wl,--as-needed|-Wl,--no-as-needed) ++ deplibs="$deplibs $arg" ++ continue ++ ;; ++ + -Wl,*) + func_stripname '-Wl,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs=$IFS; IFS=, +@@ -7609,10 +7614,19 @@ + + for deplib in $libs; do + lib= + found=false + case $deplib in ++ -Wl,--as-needed|-Wl,--no-as-needed) ++ if test "$linkmode,$pass" = "prog,link"; then ++ compile_deplibs="$deplib $compile_deplibs" ++ finalize_deplibs="$deplib $finalize_deplibs" ++ else ++ deplibs="$deplib $deplibs" ++ fi ++ continue ++ ;; + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs"Signature · 6 lines
2.7.3 _______________________________________________ buildroot mailing list buildroot at busybox.net http://lists.busybox.net/mailman/listinfo/buildroot
Signature · 6 lines
.-----------------.--------------------.------------------.--------------------. | Yann E. MORIN | Real-Time Embedded | /"\ ASCII RIBBON | Erics' conspiracy: | | +33 662 376 056 | Software Designer | \ / CAMPAIGN | ___ | | +33 223 225 172 `------------.-------: X AGAINST | \e/ There is no | | http://ymorin.is-a-geek.org/ | _/*\_ | / \ HTML MAIL | v conspiracy. | '------------------------------^-------^------------------^--------------------'
PATCH 1/2 build: add support for as-needed linking
Quoted 14 lines · Yann E. MORIN
OK, I read both of the above, and I do understand the technicalities behind --as-needed.
However, I fail to see what it would bring to Buidlroot.
One key point of --as-needed is to not pull in an unneeded library into an executable, in case it does not need it, especially in the case that this library is a second-order depedency by way of another library, e.g.:
foo:
NEEDED: libbar.so
NEEDED: libbuz.so
Quoted 7 lines
libbar.so:
NEEDED: libbuz.sobut where foo does not use any symbol from libbuz.so. This purportedly allows to update second-order libraries (libbuz, above) when there is an ABI change in those libs, and only have to rebuild first-order libs (libbar, above) without to rebuild the executable itself.
Hi Yann.
Indeed this is not the point of the new option.
Quoted 2 lines
Another key point is that the dynamic loader will not have to load unncessary libraries,thus reducing startup time.
But this is.
Quoted 5 lines
However, I fail to see how that can be any usefull in the context of Buildroot.
First, we do not support partial updates, and only catter to full-system updates. Thus the first point is moot IMHO.
Agreed.
Quoted 7 lines
Second, the default behaviour of the dynamic linker is to do lazy binding, i.e. to only resolve sumbols at the time they are first needed, and thus only loading libraries to resolve a missing symbol (unless I'm mistaken...)
So, what would that bring to us?
Yes, that's what lazy binding does... but it's still based on DT_NEEDED entries, hence instead of scanning 10 libraries at required time in my example it will only need to scan 8 to resolve required symbols. For more complex applications that use many nested libraries the savings can be bigger.
Example diff between non-as-needed gst-launch-1.0 and as-needed version:
libgstreamer-1.0.so.0
libgobject-2.0.so.0
-libgmodule-2.0.so.0
libglib-2.0.so.0
-librt.so.1
-libdl.so.2
libgcc_s.so.1
libpthread.so.0
libc.so.6
Most of the time even with lazy bindings any given binary will need to resolve symbols unless we are building statically.
Regards.
PATCH 1/2 build: add support for as-needed linking
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
"Gustavo" == Gustavo Zacarias <[email protected]> writes:
Hi,
Quoted 16 lines
Quoted 1 line
So, what would that bring to us?
Yes, that's what lazy binding does... but it's still based on
DT_NEEDEDentries, hence instead of scanning 10 libraries at required time in my example it will only need to scan 8 to resolve required symbols.
For more complex applications that use many nested libraries the savings can be bigger.
Example diff between non-as-needed gst-launch-1.0 and as-needed version:libgstreamer-1.0.so.0
libgobject-2.0.so.0
-libgmodule-2.0.so.0
libglib-2.0.so.0(quoted diff) +0
-2-librt.so.1 -libdl.so.2
Quoted 3 lines
libgcc_s.so.1
libpthread.so.0
libc.so.6
So what is E.G. the time differences when running
time gst-launch-1.0 fakesrc num-buffers=1 ! fakesink
on a "normal" machine with/without these patches?
(Notice that gstreamer searches plugins and creates cache file first time it is run).
Signature · 1 line
Bye, Peter Korsgaard
PATCH 1/2 build: add support for as-needed linking
In reply to gustavo.zacarias at free-electrons.comHello,
Quoted 18 lines · gustavo.zacarias at free-electrons.com
From: Gustavo Zacarias <[email protected]>
This option tells the linker to only link to the libraries containing symbols that are actually used.
It requires libtool patches to fully clean the needed chain, these are used by major distributions such as Debian and Gentoo.
https://wiki.debian.org/ToolChain/DSOLinking
https://wiki.gentoo.org/wiki/Project:Quality_Assurance/As-neededIntroduce a
BR2_AS_NEEDEDglobal enable option (default=no, marked as experimental) that generally disables the libtool patching and avoids the extra LDFLAGS (-Wl,--as-needed).Also add a per-package
PACKAGE_AS_NEEDED(default=yes) option to work around problematic packages that might not behave too well with as-needed linking.
Quoted 8 lines
For the libtool patching use a guess (automatic) method since version-matching doesn't work accurately with some packages that ship patched/modified
ltmain.shscripts, normally based on 2.4. In some of these cases the as-needed-v2.2.6.patch works, and in other cases the as-needed-v2.4.2.patch is necessary and the exact condition can't be found in a deterministic way. If for some reason none of the patches applies to a particular package this will only affect said package and shouldn't have any consequence even if passing -Wl,--as-needed LDFLAGS.
Just like Yann, I don't understand the usefulness of --as-needed support. If a library A is not using symbols from a library B it is linked against, why is library A linked against library B in the first place ?
The way you present it makes me understand that --as-needed is a workaround for broken package build systems, which end up producing binaries (programs or libraries) incorrect linked to too many libraries, that are in fact not all needed.
In addition to this, it is not really clear what are the benefits of having less NEEDED entries (i.e practical number of performance improvements). Since the complexity is quite huge for something that 1/ looks like a workaround and 2/ isn't associated to concrete performance improvements, I don't think we want to merge this at this point.
Of course, feel free to come back with some more details on why --as-needed is useful (why it's not a workaround, and prove it's really useful in practice).
Thanks a lot,
Thomas
Signature · 3 lines
Thomas Petazzoni, CTO, Free Electrons Embedded Linux and Kernel engineering http://free-electrons.com