From a420e535d5549809ca384136d889c2c4d65ea571 Mon Sep 17 00:00:00 2001 From: Pino Toscano Date: Thu, 19 Dec 2019 13:10:41 +0100 Subject: [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 \