tools/elfutils: do not use ar to list library objects
authorMichael Pratt <mcpratt@pm.me>
Thu, 13 Jun 2024 19:40:57 +0000 (15:40 -0400)
committerRobert Marko <robimarko@gmail.com>
Wed, 19 Jun 2024 09:22:13 +0000 (11:22 +0200)
The use of ar to list the archive members in a library
in order to include them in another library is not portable.

On BSD and macOS, ar will also list
the special archive member "__.SYMDEF"
which is not a compiled object, rather it is
part of the metadata prepended to the library by ranlib.

Fix this by writing the list of unique objects used
to create the library into a separate "manifest" file
when the library is created, which will be read later
when the Makefiles of other subdirectories are ran.

Extend this to all other libraries whether or not they are linked
to another library for a shared object that is installed
so that it is possible for any of the libraries
to be statically built with more objects.

The use of the wildcard function to ignore the
special archive members which are only metadata
is no longer needed to prevent build errors.

Not using the wildcard function is preferred,
since errors should be caught during the build
instead of when linking something else or at runtime.

Signed-off-by: Michael Pratt <mcpratt@pm.me>
Link: https://github.com/openwrt/openwrt/pull/15690
Signed-off-by: Robert Marko <robimarko@gmail.com>
tools/elfutils/patches/100-portability.patch

index ee9560a3444e9b8c5010447570a870d9fbf91f94..b3bddd0c88024a8157f5f4db7cbbf54889d906bc 100644 (file)
  libelf_so_LDLIBS += -lpthread
  endif
  
-+libelf_a_LIBADD = $(foreach dep,$(libelf_so_DEPS:.so=.a) $(LIBS:.so=.a),$(if $(findstring a,$(suffix $(dep))),$(wildcard $(addprefix $(dir $(dep)),$(shell $(AR) t $(dep)))),$(dep)))
++libelf_a_LIBADD = $(foreach dep,$(libelf_so_DEPS:.so=.a) $(LIBS:.so=.a),$(if $(findstring a,$(suffix $(dep))),$(addprefix $(dir $(dep)),$(shell cat $(basename $(dep)).manifest)),$(dep)))
 +
  libelf_so_LIBS = libelf_pic.a
  libelf.so: $(srcdir)/libelf.map $(libelf_so_LIBS) $(libelf_so_DEPS)
  
  uninstall: uninstall-am
        rm -f $(DESTDIR)$(libdir)/libelf-$(PACKAGE_VERSION).so
+@@ -135,4 +132,10 @@ uninstall: uninstall-am
+ EXTRA_DIST = libelf.map
++EXTRA_libelf_a_DEPENDENCIES = libelf.manifest
++
++libelf.manifest: $(libelf_a_OBJECTS)
++      echo $^ > $@
++
++MOSTLYCLEANFILES = $(EXTRA_libelf_a_DEPENDENCIES)
+ CLEANFILES += $(am_libelf_pic_a_OBJECTS) libelf.so libelf.so.$(VERSION)
 --- a/backends/i386_auxv.c
 +++ b/backends/i386_auxv.c
 @@ -48,5 +48,4 @@ EBLHOOK(auxv_info) (GElf_Xword a_type, c
  
  uninstall: uninstall-am
        rm -f $(DESTDIR)$(libdir)/libdw-$(PACKAGE_VERSION).so
-@@ -134,19 +129,21 @@ uninstall: uninstall-am
+@@ -133,24 +128,31 @@ uninstall: uninstall-am
+       rm -f $(DESTDIR)$(libdir)/libdw.so
        rmdir --ignore-fail-on-non-empty $(DESTDIR)$(includedir)/elfutils
  
- libdwfl_objects = $(shell $(AR) t ../libdwfl/libdwfl.a)
--libdw_a_LIBADD = $(addprefix ../libdwfl/,$(libdwfl_objects))
-+libdw_a_LIBADD = $(wildcard $(addprefix ../libdwfl/,$(libdwfl_objects)))
+-libdwfl_objects = $(shell $(AR) t ../libdwfl/libdwfl.a)
++libdwfl_objects = $(shell cat ../libdwfl/libdwfl.manifest)
+ libdw_a_LIBADD = $(addprefix ../libdwfl/,$(libdwfl_objects))
  
- libdwelf_objects = $(shell $(AR) t ../libdwelf/libdwelf.a)
--libdw_a_LIBADD += $(addprefix ../libdwelf/,$(libdwelf_objects))
-+libdw_a_LIBADD += $(wildcard $(addprefix ../libdwelf/,$(libdwelf_objects)))
+-libdwelf_objects = $(shell $(AR) t ../libdwelf/libdwelf.a)
++libdwelf_objects = $(shell cat ../libdwelf/libdwelf.manifest)
+ libdw_a_LIBADD += $(addprefix ../libdwelf/,$(libdwelf_objects))
  
- libebl_objects = $(shell $(AR) t ../libebl/libebl.a)
--libdw_a_LIBADD += $(addprefix ../libebl/,$(libebl_objects))
-+libdw_a_LIBADD += $(wildcard $(addprefix ../libebl/,$(libebl_objects)))
+-libebl_objects = $(shell $(AR) t ../libebl/libebl.a)
++libebl_objects = $(shell cat ../libebl/libebl.manifest)
+ libdw_a_LIBADD += $(addprefix ../libebl/,$(libebl_objects))
  
- backends_objects = $(shell $(AR) t ../backends/libebl_backends.a)
--libdw_a_LIBADD += $(addprefix ../backends/,$(backends_objects))
-+libdw_a_LIBADD += $(wildcard $(addprefix ../backends/,$(backends_objects)))
+-backends_objects = $(shell $(AR) t ../backends/libebl_backends.a)
++backends_objects = $(shell cat ../backends/libebl_backends.manifest)
+ libdw_a_LIBADD += $(addprefix ../backends/,$(backends_objects))
  
- libcpu_objects = $(shell $(AR) t ../libcpu/libcpu.a)
--libdw_a_LIBADD += $(addprefix ../libcpu/,$(libcpu_objects))
-+libdw_a_LIBADD += $(wildcard $(addprefix ../libcpu/,$(libcpu_objects)))
-+
-+libdw_a_LIBADD += $(foreach dep,$(libdw_so_DEPS:.so=.a) $(LIBS:.so=.a),$(if $(findstring a,$(suffix $(dep))),$(wildcard $(addprefix $(dir $(dep)),$(shell $(AR) t $(dep)))),$(dep)))
+-libcpu_objects = $(shell $(AR) t ../libcpu/libcpu.a)
++libcpu_objects = $(shell cat ../libcpu/libcpu.manifest)
+ libdw_a_LIBADD += $(addprefix ../libcpu/,$(libcpu_objects))
  
++libdw_a_LIBADD += $(foreach dep,$(libdw_so_DEPS:.so=.a) $(LIBS:.so=.a),$(if $(findstring a,$(suffix $(dep))),$(addprefix $(dir $(dep)),$(shell cat $(basename $(dep)).manifest)),$(dep)))
++
  noinst_HEADERS = libdwP.h memory-access.h dwarf_abbrev_hash.h \
                 dwarf_sig8_hash.h cfi.h encoded-value.h
+ EXTRA_DIST = libdw.map
+-MOSTLYCLEANFILES = $(am_libdw_pic_a_OBJECTS) libdw.so libdw.so.$(VERSION)
++EXTRA_libdw_a_DEPENDENCIES = libdw.manifest
++
++libdw.manifest: $(libdw_a_OBJECTS)
++      echo $^ > $@
++
++MOSTLYCLEANFILES = $(am_libdw_pic_a_OBJECTS) $(EXTRA_libdw_a_DEPENDENCIES) libdw.so libdw.so.$(VERSION)
+--- a/backends/Makefile.am
++++ b/backends/Makefile.am
+@@ -119,4 +119,9 @@ am_libebl_backends_pic_a_OBJECTS = $(lib
+ noinst_HEADERS = libebl_CPU.h common-reloc.c linux-core-note.c x86_corenote.c
+ EXTRA_DIST = $(modules:=_reloc.def)
+-MOSTLYCLEANFILES = $(am_libebl_backends_pic_a_OBJECTS)
++EXTRA_libebl_backends_a_DEPENDENCIES = libebl_backends.manifest
++
++libebl_backends.manifest: $(libebl_backends_a_OBJECTS)
++      echo $^ > $@
++
++MOSTLYCLEANFILES = $(am_libebl_backends_pic_a_OBJECTS) $(EXTRA_libebl_backends_a_DEPENDENCIES)
+--- a/libcpu/Makefile.am
++++ b/libcpu/Makefile.am
+@@ -101,6 +101,11 @@ bpf_disasm_CFLAGS = -Wno-format-nonliter
+ EXTRA_DIST = defs/i386
+-MOSTLYCLEANFILES = $(am_libcpu_pic_a_OBJECTS)
++EXTRA_libcpu_a_DEPENDENCIES = libcpu.manifest
++
++libcpu.manifest: $(libcpu_a_OBJECTS)
++      echo $^ > $@
++
++MOSTLYCLEANFILES = $(am_libcpu_pic_a_OBJECTS) $(EXTRA_libcpu_a_DEPENDENCIES)
+ CLEANFILES += $(foreach P,i386 x86_64,$P_defs $P.mnemonics)
+ MAINTAINERCLEANFILES = $(foreach P,i386 x86_64, $P_dis.h)
+--- a/libdwelf/Makefile.am
++++ b/libdwelf/Makefile.am
+@@ -54,4 +54,10 @@ libeu = ../lib/libeu.a
+ libdwelf_pic_a_SOURCES =
+ am_libdwelf_pic_a_OBJECTS = $(libdwelf_a_SOURCES:.c=.os)
++EXTRA_libdwelf_a_DEPENDENCIES = libdwelf.manifest
++
++libdwelf.manifest: $(libdwelf_a_OBJECTS)
++      echo $^ > $@
++
++MOSTLYCLEANFILES = $(EXTRA_libdwelf_a_DEPENDENCIES)
+ CLEANFILES += $(am_libdwelf_pic_a_OBJECTS)
+--- a/libdwfl/Makefile.am
++++ b/libdwfl/Makefile.am
+@@ -93,4 +93,10 @@ am_libdwfl_pic_a_OBJECTS = $(libdwfl_a_S
+ noinst_HEADERS = libdwflP.h
++EXTRA_libdwfl_a_DEPENDENCIES = libdwfl.manifest
++
++libdwfl.manifest: $(libdwfl_a_OBJECTS)
++      echo $^ > $@
++
++MOSTLYCLEANFILES = $(EXTRA_libdwfl_a_DEPENDENCIES)
+ CLEANFILES += $(am_libdwfl_pic_a_OBJECTS)
+--- a/libebl/Makefile.am
++++ b/libebl/Makefile.am
+@@ -61,4 +61,9 @@ am_libebl_pic_a_OBJECTS = $(libebl_a_SOU
+ noinst_HEADERS = libebl.h libeblP.h ebl-hooks.h
+-MOSTLYCLEANFILES = $(am_libebl_pic_a_OBJECTS)
++EXTRA_libebl_a_DEPENDENCIES = libebl.manifest
++
++libebl.manifest: $(libebl_a_OBJECTS)
++      echo $^ > $@
++
++MOSTLYCLEANFILES = $(am_libebl_pic_a_OBJECTS) $(EXTRA_libebl_a_DEPENDENCIES)
+--- a/lib/Makefile.am
++++ b/lib/Makefile.am
+@@ -41,3 +41,10 @@ noinst_HEADERS = fixedsizehash.h libeu.h
+                eu-config.h color.h printversion.h bpf.h \
+                atomics.h stdatomic-fbsd.h dynamicsizehash_concurrent.h
+ EXTRA_DIST = dynamicsizehash.c dynamicsizehash_concurrent.c
++
++EXTRA_libeu_a_DEPENDENCIES = libeu.manifest
++
++libeu.manifest: $(libeu_a_OBJECTS)
++      echo $^ > $@
++
++MOSTLYCLEANFILES = $(EXTRA_libeu_a_DEPENDENCIES)
 --- a/libasm/Makefile.am
 +++ b/libasm/Makefile.am
 @@ -33,8 +33,6 @@ AM_CPPFLAGS += -I$(top_srcdir)/libelf -I
  libasm_so_LDLIBS += -lpthread
  endif
  
-+libasm_a_LIBADD = $(foreach dep,$(libasm_so_DEPS:.so=.a) $(LIBS:.so=.a),$(if $(findstring a,$(suffix $(dep))),$(wildcard $(addprefix $(dir $(dep)),$(shell $(AR) t $(dep)))),$(dep)))
++libasm_a_LIBADD = $(foreach dep,$(libasm_so_DEPS:.so=.a) $(LIBS:.so=.a),$(if $(findstring a,$(suffix $(dep))),$(addprefix $(dir $(dep)),$(shell cat $(basename $(dep)).manifest)),$(dep)))
 +
  libasm_so_LIBS = libasm_pic.a
  libasm.so: $(srcdir)/libasm.map $(libasm_so_LIBS) $(libasm_so_DEPS)
  
  uninstall: uninstall-am
        rm -f $(DESTDIR)$(libdir)/libasm-$(PACKAGE_VERSION).so
+@@ -86,4 +83,10 @@ uninstall: uninstall-am
+ noinst_HEADERS = libasmP.h symbolhash.h
+ EXTRA_DIST = libasm.map
++EXTRA_libasm_a_DEPENDENCIES = libasm.manifest
++
++libasm.manifest: $(libasm_a_OBJECTS)
++      echo $^ > $@
++
++MOSTLYCLEANFILES = $(EXTRA_libasm_a_DEPENDENCIES)
+ CLEANFILES += $(am_libasm_pic_a_OBJECTS) libasm.so libasm.so.$(VERSION)
 --- a/debuginfod/Makefile.am
 +++ b/debuginfod/Makefile.am
 @@ -77,7 +77,6 @@ debuginfod_find_LDADD = $(libdw) $(libel
  libdebuginfod_so_LDLIBS =
  else
  libdebuginfod_so_LDLIBS = -lpthread $(libcurl_LIBS) $(fts_LIBS) $(libelf)
-+libdebuginfod_a_LIBADD = $(foreach dep,$(wildcard $(libdebuginfod_so_LDLIBS:.so=.a)) $(LIBS:.so=.a),$(if $(findstring a,$(suffix $(dep))),$(wildcard $(addprefix $(dir $(dep)),$(shell $(AR) t $(dep)))),$(dep)))
++libdebuginfod_a_LIBADD = $(foreach dep,$(wildcard $(libdebuginfod_so_LDLIBS:.so=.a)) $(LIBS:.so=.a),$(if $(findstring a,$(suffix $(dep))),$(addprefix $(dir $(dep)),$(shell cat $(basename $(dep)).manifest)),$(dep)))
  endif
  $(LIBDEBUGINFOD_SONAME): $(srcdir)/libdebuginfod.map $(libdebuginfod_so_LIBS)
        $(AM_V_CCLD)$(LINK) $(dso_LDFLAGS) -o $@ \
  
  uninstall: uninstall-am
        rm -f $(DESTDIR)$(libdir)/libdebuginfod-$(PACKAGE_VERSION).so
+@@ -126,7 +122,13 @@ uninstall: uninstall-am
+ endif
+ EXTRA_DIST = libdebuginfod.map
+-MOSTLYCLEANFILES = $(am_libdebuginfod_pic_a_OBJECTS) $(LIBDEBUGINFOD_SONAME)
++
++EXTRA_libdebuginfod_a_DEPENDENCIES = libdebuginfod.manifest
++
++libdebuginfod.manifest: $(libdebuginfod_a_OBJECTS)
++      echo $^ > $@
++
++MOSTLYCLEANFILES = $(am_libdebuginfod_pic_a_OBJECTS) $(LIBDEBUGINFOD_SONAME) $(EXTRA_libdebuginfod_a_DEPENDENCIES)
+ CLEANFILES += $(am_libdebuginfod_pic_a_OBJECTS) libdebuginfod.so
+ # automake std-options override: arrange to pass LD_LIBRARY_PATH
 --- a/tests/Makefile.am
 +++ b/tests/Makefile.am
 @@ -50,7 +50,7 @@ check_PROGRAMS = arextract arsymtest new