Pino Toscano
2019-Dec-19 13:54 UTC
[Libguestfs] [PATCH] daemon: reorder internal static libs to fix linking
Move the interal static libraries as the last items in the list of libraries of guestfsd, to make sure their symbols are used for all the other libraries. This is because GCC resolves the symbols looking at the arguments from the beginning to the end of the command line. This currently does not cause failures, however it "just works" because of the tricky situation set up. The situation is the following: 1) common/utils contains few utility sources: one of them is utils.c, which contains various functions -- for example guestfs_int_free_string_list and guestfs_int_drive_name --, it is built as utils.o, and bundled in the static library libutils.a 2) common/mlutils builds a OCaml library with bindings for some utility functions in libutils.a, in particular guestfs_int_drive_name (but not guestfs_int_free_string_list); there are two versions of this library, one OCaml library (dllmlcutils.so) that links with libutils.a, and one static library (libmlcutils.a), which cannot specify the libraries it links to (as it is static) 3) when the daemon is linked, the command line was the following (simplified): $ gcc [...] -o guestfsd guestfsd-9p.o other_daemon_object.o [...] \ ../common/utils/.libs/libutils.a [...] -lmlcutils [...] Some of the objects of the daemon itself use guestfs_int_free_string_list, and thus the compiler opens libutils.a (it is after the objects in the command line) and picks utils.o, which contains also guestfs_int_drive_name (not used directly in the daemon); when linking later on with libmlcutils.a, the symbols for this static library (like guestfs_int_drive_name) are already resolved, and thus all the symbols are resolved, and the linking succeeds This fragile situation can be easily broken by moving e.g. guestfs_int_drive_name out of common/utils/utils.c to a new source (say utils2.c) still built as part of libutils.a: since nothing before -lmlcutils actually needs to pick utils2.o from libutils.a for symbols, then GCC will not be able to resolve all the symbols in libmlcutils.a. As solution, move libutils.a (and other internal static libraries) as last libraries to link guestfsd to: this way, GCC knows where to find all the symbols needed by all the objects and libraries specified in the command line. --- daemon/Makefile.am | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/daemon/Makefile.am b/daemon/Makefile.am index ab3019cc1..25948dbe9 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -217,9 +217,6 @@ guestfsd_LDFLAGS = \ -L../bundled/ocaml-augeas \ -L../common/mlpcre guestfsd_LDADD = \ - ../common/errnostring/liberrnostring.la \ - ../common/protocol/libprotocol.la \ - ../common/utils/libutils.la \ camldaemon.o \ $(ACL_LIBS) \ $(CAP_LIBS) \ @@ -236,7 +233,10 @@ guestfsd_LDADD = \ $(TSK_LIBS) \ $(RPC_LIBS) \ $(YARA_LIBS) \ - $(OCAML_LIBS) + $(OCAML_LIBS) \ + ../common/errnostring/liberrnostring.la \ + ../common/protocol/libprotocol.la \ + ../common/utils/libutils.la guestfsd_CPPFLAGS = \ -DCAML_NAME_SPACE \ -- 2.24.1
Richard W.M. Jones
2020-Jan-09 13:35 UTC
Re: [Libguestfs] [PATCH] daemon: reorder internal static libs to fix linking
On Thu, Dec 19, 2019 at 02:54:16PM +0100, Pino Toscano wrote:> Move the interal static libraries as the last items in the list of > libraries of guestfsd, to make sure their symbols are used for all the > other libraries. This is because GCC resolves the symbols looking at > the arguments from the beginning to the end of the command line. > This currently does not cause failures, however it "just works" because > of the tricky situation set up. > > The situation is the following: > > 1) common/utils contains few utility sources: one of them is utils.c, > which contains various functions -- for example > guestfs_int_free_string_list and guestfs_int_drive_name --, it is built > as utils.o, and bundled in the static library libutils.a > > 2) common/mlutils builds a OCaml library with bindings for some utility > functions in libutils.a, in particular guestfs_int_drive_name (but not > guestfs_int_free_string_list); there are two versions of this library, > one OCaml library (dllmlcutils.so) that links with libutils.a, and one > static library (libmlcutils.a), which cannot specify the libraries it > links to (as it is static) > > 3) when the daemon is linked, the command line was the following > (simplified): > $ gcc [...] -o guestfsd guestfsd-9p.o other_daemon_object.o [...] \ > ../common/utils/.libs/libutils.a [...] -lmlcutils [...] > Some of the objects of the daemon itself use > guestfs_int_free_string_list, and thus the compiler opens libutils.a > (it is after the objects in the command line) and picks utils.o, which > contains also guestfs_int_drive_name (not used directly in the daemon); > when linking later on with libmlcutils.a, the symbols for this static > library (like guestfs_int_drive_name) are already resolved, and thus > all the symbols are resolved, and the linking succeeds > > This fragile situation can be easily broken by moving e.g. > guestfs_int_drive_name out of common/utils/utils.c to a new source (say > utils2.c) still built as part of libutils.a: since nothing before > -lmlcutils actually needs to pick utils2.o from libutils.a for symbols, > then GCC will not be able to resolve all the symbols in libmlcutils.a. > > As solution, move libutils.a (and other internal static libraries) as > last libraries to link guestfsd to: this way, GCC knows where to find > all the symbols needed by all the objects and libraries specified in > the command line. > --- > daemon/Makefile.am | 8 ++++---- > 1 file changed, 4 insertions(+), 4 deletions(-) > > diff --git a/daemon/Makefile.am b/daemon/Makefile.am > index ab3019cc1..25948dbe9 100644 > --- a/daemon/Makefile.am > +++ b/daemon/Makefile.am > @@ -217,9 +217,6 @@ guestfsd_LDFLAGS = \ > -L../bundled/ocaml-augeas \ > -L../common/mlpcre > guestfsd_LDADD = \ > - ../common/errnostring/liberrnostring.la \ > - ../common/protocol/libprotocol.la \ > - ../common/utils/libutils.la \ > camldaemon.o \ > $(ACL_LIBS) \ > $(CAP_LIBS) \ > @@ -236,7 +233,10 @@ guestfsd_LDADD = \ > $(TSK_LIBS) \ > $(RPC_LIBS) \ > $(YARA_LIBS) \ > - $(OCAML_LIBS) > + $(OCAML_LIBS) \ > + ../common/errnostring/liberrnostring.la \ > + ../common/protocol/libprotocol.la \ > + ../common/utils/libutils.laGood find, ACK. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com libguestfs lets you edit virtual machines. Supports shell scripting, bindings from many languages. http://libguestfs.org
Apparently Analagous Threads
- Re-attaching a package environment drops the attributes
- [PATCH 1/2] utils: Add a test of the guestfs_int_drive_name function.
- [PATCH v2 0/2] utils: Add guestfs_int_drive_index and unit test.
- [PATCH v2 3/3] daemon: Restore PCRE regular expressions in OCaml code.
- [PATCH] common/options: Change drv struct to store drive index instead of device name.