build: replace weak symbols with a static library
authorPaolo Bonzini <pbonzini@redhat.com>
Fri, 16 Nov 2012 17:35:27 +0000 (18:35 +0100)
committerBlue Swirl <blauwirbel@gmail.com>
Sun, 18 Nov 2012 19:19:23 +0000 (19:19 +0000)
Weak symbols were a nice idea, but they turned out not to be a good one.
Toolchain support is just too sparse, in particular llvm-gcc is totally
broken.

This patch uses a surprisingly low-tech approach: a static library.
Symbols in a static library are always overridden by symbols in an
object file.  Furthermore, if you place each function in a separate
source file, object files for unused functions will not be taken in.
This means that each function can use all the dependencies that it needs
(especially QAPI stuff such as error_setg).

Thus, all stubs are placed in separate object files and put together in
a static library.  The library then is linked to all programs.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Tested-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Tested-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
18 files changed:
Makefile
Makefile.objs
Makefile.target
compiler.h
osdep.c
oslib-win32.c
qemu-sockets.c
qmp.c
rules.mak
stubs/Makefile.objs [new file with mode: 0644]
stubs/arch-query-cpu-def.c [new file with mode: 0644]
stubs/fd-register.c [new file with mode: 0644]
stubs/fdset-add-fd.c [new file with mode: 0644]
stubs/fdset-find-fd.c [new file with mode: 0644]
stubs/fdset-get-fd.c [new file with mode: 0644]
stubs/fdset-remove-fd.c [new file with mode: 0644]
stubs/get-fd.c [new file with mode: 0644]
stubs/set-fd-handler.c [new file with mode: 0644]

index 81c660f9f432a3072af8e308dec0b18125e7cb26..b8301a2521439edbeb5970089ccf488c4b9385e6 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -157,6 +157,12 @@ version.o: $(SRC_PATH)/version.rc config-host.h
        $(call quiet-command,$(WINDRES) -I. -o $@ $<,"  RC    $(TARGET_DIR)$@")
 
 version-obj-$(CONFIG_WIN32) += version.o
+
+######################################################################
+# Build library with stubs
+
+libqemustub.a: $(stub-obj-y)
+
 ######################################################################
 # Support building shared library libcacard
 
@@ -183,13 +189,13 @@ tools-obj-y = $(oslib-obj-y) $(trace-obj-y) qemu-tool.o qemu-timer.o \
        main-loop.o iohandler.o error.o
 tools-obj-$(CONFIG_POSIX) += compatfd.o
 
-qemu-img$(EXESUF): qemu-img.o $(tools-obj-y) $(block-obj-y)
-qemu-nbd$(EXESUF): qemu-nbd.o $(tools-obj-y) $(block-obj-y)
-qemu-io$(EXESUF): qemu-io.o cmd.o $(tools-obj-y) $(block-obj-y)
+qemu-img$(EXESUF): qemu-img.o $(tools-obj-y) $(block-obj-y) libqemustub.a
+qemu-nbd$(EXESUF): qemu-nbd.o $(tools-obj-y) $(block-obj-y) libqemustub.a
+qemu-io$(EXESUF): qemu-io.o cmd.o $(tools-obj-y) $(block-obj-y) libqemustub.a
 
 qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o
 
-vscclient$(EXESUF): $(libcacard-y) $(oslib-obj-y) $(trace-obj-y) libcacard/vscclient.o
+vscclient$(EXESUF): $(libcacard-y) $(oslib-obj-y) $(trace-obj-y) libcacard/vscclient.o libqemustub.a
        $(call quiet-command,$(CC) $(LDFLAGS) -o $@ $^ $(libcacard_libs) $(LIBS),"  LINK  $@")
 
 fsdev/virtfs-proxy-helper$(EXESUF): fsdev/virtfs-proxy-helper.o fsdev/virtio-9p-marshal.o oslib-posix.o $(trace-obj-y)
@@ -232,7 +238,7 @@ $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
 QGALIB_GEN=$(addprefix qga/qapi-generated/, qga-qapi-types.h qga-qapi-visit.h qga-qmp-commands.h)
 $(qga-obj-y) qemu-ga.o: $(QGALIB_GEN)
 
-qemu-ga$(EXESUF): qemu-ga.o $(qga-obj-y) $(oslib-obj-y) $(trace-obj-y) $(qapi-obj-y) $(qobject-obj-y) $(version-obj-y)
+qemu-ga$(EXESUF): qemu-ga.o $(qga-obj-y) $(oslib-obj-y) $(trace-obj-y) $(qapi-obj-y) $(qobject-obj-y) $(version-obj-y) libqemustub.a
 
 QEMULIBS=libuser libdis libdis-user
 
index dc1e69991495e12a140bd9d07c9a0fead2f3a4a7..3c7abca43300c96cf4b85613f8ecbecb15b81d73 100644 (file)
@@ -1,3 +1,7 @@
+#######################################################################
+# Stub library, linked in tools
+stub-obj-y = stubs/
+
 #######################################################################
 # Target-independent parts used in system and user emulation
 universal-obj-y =
@@ -239,6 +243,7 @@ vl.o: QEMU_CFLAGS+=$(SDL_CFLAGS)
 QEMU_CFLAGS+=$(GLIB_CFLAGS)
 
 nested-vars += \
+       stub-obj-y \
        qga-obj-y \
        qom-obj-y \
        qapi-obj-y \
index 3822bc5ac3f073964e7ad60f0b656c2aa12b6824..8b658c0d13ca0a721ce57b8d3efe21ca7d9b83c9 100644 (file)
@@ -162,12 +162,12 @@ endif #CONFIG_LINUX_USER
 
 ifdef QEMU_PROGW
 # The linker builds a windows executable. Make also a console executable.
-$(QEMU_PROGW): $(all-obj-y)
+$(QEMU_PROGW): $(all-obj-y) ../libqemustub.a
        $(call LINK,$^)
 $(QEMU_PROG): $(QEMU_PROGW)
        $(call quiet-command,$(OBJCOPY) --subsystem console $(QEMU_PROGW) $(QEMU_PROG),"  GEN   $(TARGET_DIR)$(QEMU_PROG)")
 else
-$(QEMU_PROG): $(all-obj-y)
+$(QEMU_PROG): $(all-obj-y) ../libqemustub.a
        $(call LINK,$^)
 endif
 
index 55d7d74775e02f7d3b30c2d771d0292b3779620d..2f7998b6c121dd2223dbb42a40a7f030729b55a7 100644 (file)
 #   define __printf__ __gnu_printf__
 #  endif
 # endif
-# if defined(__APPLE__)
-#  define QEMU_WEAK_ALIAS(newname, oldname) \
-        static typeof(oldname) weak_##newname __attribute__((unused, weakref(#oldname)))
-#  define QEMU_WEAK_REF(newname, oldname) (weak_##newname ? weak_##newname : oldname)
-# else
-#  define QEMU_WEAK_ALIAS(newname, oldname) \
-        typeof(oldname) newname __attribute__((weak, alias (#oldname)))
-#  define QEMU_WEAK_REF(newname, oldname) newname
-# endif
 #else
 #define GCC_ATTR /**/
 #define GCC_FMT_ATTR(n, m)
-#define QEMU_WEAK_ALIAS(newname, oldname) \
-        _Pragma("weak " #newname "=" #oldname)
 #endif
 
 #endif /* COMPILER_H */
diff --git a/osdep.c b/osdep.c
index 2f7a49159a65e9da08c37c82f071e880100ed2cd..3a63d26e75c0556a0d9e718a6c3281b904f61447 100644 (file)
--- a/osdep.c
+++ b/osdep.c
@@ -54,38 +54,6 @@ static bool fips_enabled = false;
 
 static const char *qemu_version = QEMU_VERSION;
 
-static int default_fdset_get_fd(int64_t fdset_id, int flags)
-{
-    return -1;
-}
-QEMU_WEAK_ALIAS(monitor_fdset_get_fd, default_fdset_get_fd);
-#define monitor_fdset_get_fd \
-    QEMU_WEAK_REF(monitor_fdset_get_fd, default_fdset_get_fd)
-
-static int default_fdset_dup_fd_add(int64_t fdset_id, int dup_fd)
-{
-    return -1;
-}
-QEMU_WEAK_ALIAS(monitor_fdset_dup_fd_add, default_fdset_dup_fd_add);
-#define monitor_fdset_dup_fd_add \
-    QEMU_WEAK_REF(monitor_fdset_dup_fd_add, default_fdset_dup_fd_add)
-
-static int default_fdset_dup_fd_remove(int dup_fd)
-{
-    return -1;
-}
-QEMU_WEAK_ALIAS(monitor_fdset_dup_fd_remove, default_fdset_dup_fd_remove);
-#define monitor_fdset_dup_fd_remove \
-    QEMU_WEAK_REF(monitor_fdset_dup_fd_remove, default_fdset_dup_fd_remove)
-
-static int default_fdset_dup_fd_find(int dup_fd)
-{
-    return -1;
-}
-QEMU_WEAK_ALIAS(monitor_fdset_dup_fd_find, default_fdset_dup_fd_find);
-#define monitor_fdset_dup_fd_find \
-    QEMU_WEAK_REF(monitor_fdset_dup_fd_remove, default_fdset_dup_fd_find)
-
 int socket_set_cork(int fd, int v)
 {
 #if defined(SOL_TCP) && defined(TCP_CORK)
index 326a2bddb364680d1f3b3934e40963eef7d27ae1..51b33e8b2017bd1f5db2105b590cc8e1058022b5 100644 (file)
 #include "trace.h"
 #include "qemu_socket.h"
 
-static void default_qemu_fd_register(int fd)
-{
-}
-QEMU_WEAK_ALIAS(qemu_fd_register, default_qemu_fd_register);
-#define qemu_fd_register \
-    QEMU_WEAK_REF(qemu_fd_register, default_qemu_fd_register)
-
 void *qemu_oom_check(void *ptr)
 {
     if (ptr == NULL) {
index abcd791cb687520a485f9e751ead736db9c59815..cfed9c5a5bd9e14b68015a1be2f909eabfa73cc6 100644 (file)
@@ -61,28 +61,6 @@ static QemuOptsList dummy_opts = {
     },
 };
 
-static int default_monitor_get_fd(Monitor *mon, const char *name, Error **errp)
-{
-    error_setg(errp, "only QEMU supports file descriptor passing");
-    return -1;
-}
-QEMU_WEAK_ALIAS(monitor_get_fd, default_monitor_get_fd);
-#define monitor_get_fd \
-    QEMU_WEAK_REF(monitor_get_fd, default_monitor_get_fd)
-
-static int default_qemu_set_fd_handler2(int fd,
-                                        IOCanReadHandler *fd_read_poll,
-                                        IOHandler *fd_read,
-                                        IOHandler *fd_write,
-                                        void *opaque)
-
-{
-    abort();
-}
-QEMU_WEAK_ALIAS(qemu_set_fd_handler2, default_qemu_set_fd_handler2);
-#define qemu_set_fd_handler2 \
-    QEMU_WEAK_REF(qemu_set_fd_handler2, default_qemu_set_fd_handler2)
-
 static int inet_getport(struct addrinfo *e)
 {
     struct sockaddr_in *i4;
diff --git a/qmp.c b/qmp.c
index 13e83a59e0972736a986c3b3762e6e555e868bdf..e3a7f0b21771aaf94f503f31c683bbcd5a4ff55f 100644 (file)
--- a/qmp.c
+++ b/qmp.c
@@ -471,15 +471,6 @@ DevicePropertyInfoList *qmp_device_list_properties(const char *typename,
     return prop_list;
 }
 
-static CpuDefinitionInfoList *default_arch_query_cpu_definitions(Error **errp)
-{
-    error_set(errp, QERR_NOT_SUPPORTED);
-    return NULL;
-}
-QEMU_WEAK_ALIAS(arch_query_cpu_definitions, default_arch_query_cpu_definitions);
-#define arch_query_cpu_definitions \
-    QEMU_WEAK_REF(arch_query_cpu_definitions, default_arch_query_cpu_definitions)
-
 CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
 {
     return arch_query_cpu_definitions(errp);
index 1b173aa9812661c5e850ba86714b2b389e1d44f5..d0b04e44f544ee8434b8f5f9628d2cc7ecfcdf6d 100644 (file)
--- a/rules.mak
+++ b/rules.mak
@@ -31,7 +31,7 @@ endif
 %.o: %.m
        $(call quiet-command,$(OBJCC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) -c -o $@ $<,"  OBJC  $(TARGET_DIR)$@")
 
-LINK = $(call quiet-command,$(CC) $(QEMU_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ $(sort $(1)) $(LIBS),"  LINK  $(TARGET_DIR)$@")
+LINK = $(call quiet-command,$(CC) $(QEMU_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ $(sort $(filter %.o, $1)) $(filter-out %.o, $1) $(LIBS),"  LINK  $(TARGET_DIR)$@")
 
 %$(EXESUF): %.o
        $(call LINK,$^)
diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
new file mode 100644 (file)
index 0000000..035b29a
--- /dev/null
@@ -0,0 +1,8 @@
+stub-obj-y += arch-query-cpu-def.o
+stub-obj-y += fdset-add-fd.o
+stub-obj-y += fdset-find-fd.o
+stub-obj-y += fdset-get-fd.o
+stub-obj-y += fdset-remove-fd.o
+stub-obj-y += get-fd.o
+stub-obj-y += set-fd-handler.o
+stub-obj-$(CONFIG_WIN32) += fd-register.o
diff --git a/stubs/arch-query-cpu-def.c b/stubs/arch-query-cpu-def.c
new file mode 100644 (file)
index 0000000..47b5246
--- /dev/null
@@ -0,0 +1,9 @@
+#include "qemu-common.h"
+#include "arch_init.h"
+#include "qerror.h"
+
+CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
+{
+    error_set(errp, QERR_NOT_SUPPORTED);
+    return NULL;
+}
diff --git a/stubs/fd-register.c b/stubs/fd-register.c
new file mode 100644 (file)
index 0000000..813b6dd
--- /dev/null
@@ -0,0 +1,6 @@
+#include "qemu-common.h"
+#include "main-loop.h"
+
+void qemu_fd_register(int fd)
+{
+}
diff --git a/stubs/fdset-add-fd.c b/stubs/fdset-add-fd.c
new file mode 100644 (file)
index 0000000..09fe2a8
--- /dev/null
@@ -0,0 +1,7 @@
+#include "qemu-common.h"
+#include "monitor.h"
+
+int monitor_fdset_dup_fd_add(int64_t fdset_id, int dup_fd)
+{
+    return -1;
+}
diff --git a/stubs/fdset-find-fd.c b/stubs/fdset-find-fd.c
new file mode 100644 (file)
index 0000000..f82baa0
--- /dev/null
@@ -0,0 +1,7 @@
+#include "qemu-common.h"
+#include "monitor.h"
+
+int monitor_fdset_dup_fd_find(int dup_fd)
+{
+    return -1;
+}
diff --git a/stubs/fdset-get-fd.c b/stubs/fdset-get-fd.c
new file mode 100644 (file)
index 0000000..4106cf9
--- /dev/null
@@ -0,0 +1,7 @@
+#include "qemu-common.h"
+#include "monitor.h"
+
+int monitor_fdset_get_fd(int64_t fdset_id, int flags)
+{
+    return -1;
+}
diff --git a/stubs/fdset-remove-fd.c b/stubs/fdset-remove-fd.c
new file mode 100644 (file)
index 0000000..861b312
--- /dev/null
@@ -0,0 +1,7 @@
+#include "qemu-common.h"
+#include "monitor.h"
+
+int monitor_fdset_dup_fd_remove(int dupfd)
+{
+    return -1;
+}
diff --git a/stubs/get-fd.c b/stubs/get-fd.c
new file mode 100644 (file)
index 0000000..3561ab6
--- /dev/null
@@ -0,0 +1,8 @@
+#include "qemu-common.h"
+#include "monitor.h"
+
+int monitor_get_fd(Monitor *mon, const char *name, Error **errp)
+{
+    error_setg(errp, "only QEMU supports file descriptor passing");
+    return -1;
+}
diff --git a/stubs/set-fd-handler.c b/stubs/set-fd-handler.c
new file mode 100644 (file)
index 0000000..4807b5d
--- /dev/null
@@ -0,0 +1,11 @@
+#include "qemu-common.h"
+#include "main-loop.h"
+
+int qemu_set_fd_handler2(int fd,
+                         IOCanReadHandler *fd_read_poll,
+                         IOHandler *fd_read,
+                         IOHandler *fd_write,
+                         void *opaque)
+{
+    abort();
+}