Patchwork Drop --whole-archive and static libraries

login
register
mail settings
Submitter Andreas Färber
Date Dec. 13, 2009, 8:02 a.m.
Message ID <1260691332-6333-1-git-send-email-andreas.faerber@web.de>
Download mbox | patch
Permalink /patch/41021/
State New
Headers show

Comments

Andreas Färber - Dec. 13, 2009, 8:02 a.m.
From: Andreas Färber <afaerber@opensolaris.org>

Juan has donated a cool Makefile infrastructure that enables us to drop
static libraries completely:

Move shared obj-y definitions to Makefile.objs, prefixed common-, hw-, user-.

Link those object files directly.

Replace HWLIB by HWDIR, specifying only the directory.

Drop --whole-archive and ARLIBS in Makefiles and configure.

Drop GENERATED_HEADERS dependency in rules.mak, since this rebuilds all
common objects after generating a target-specific header. Add dependency
rules to Makefile and Makefile.target instead.

The early bird catches the bug or so...

Signed-off-by: Andreas Färber <afaerber@opensolaris.org>
Cc: Juan Quintela <quintela@trasno.org>
---
 Makefile        |  123 ++------------------------------------------
 Makefile.hw     |   33 +-----------
 Makefile.objs   |  156 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Makefile.target |   30 ++++++++---
 Makefile.user   |    9 +---
 configure       |   34 +------------
 rules.mak       |    4 +-
 7 files changed, 190 insertions(+), 199 deletions(-)
 create mode 100644 Makefile.objs
Andreas Färber - Dec. 19, 2009, 5:32 p.m.
Hello Anthony,

These two patches were already the fourth proposed solution to  
eliminate --whole-archive issues on Solaris. The last one was limited  
to CONFIG_SOLARIS, and if accepted a 0.12 candidate from my view; this  
one is a major rework of the build system to drop static libraries  
altogether, idea courtesy of Juan Quintela. Avi suggested an even  
bigger Makefile refactoring but for now Juan and me didn't spot an  
easy way to stuff everything into one Makefile.

Could you please tell us in which way you would like to see a solution  
so that we can get something merged?

Thanks,

Andreas

Am 13.12.2009 um 09:02 schrieb Andreas Färber:

> From: Andreas Färber <afaerber@opensolaris.org>
>
> Juan has donated a cool Makefile infrastructure that enables us to  
> drop
> static libraries completely:
>
> Move shared obj-y definitions to Makefile.objs, prefixed common-,  
> hw-, user-.
>
> Link those object files directly.
>
> Replace HWLIB by HWDIR, specifying only the directory.
>
> Drop --whole-archive and ARLIBS in Makefiles and configure.
>
> Drop GENERATED_HEADERS dependency in rules.mak, since this rebuilds  
> all
> common objects after generating a target-specific header. Add  
> dependency
> rules to Makefile and Makefile.target instead.
>
> The early bird catches the bug or so...
>
> Signed-off-by: Andreas Färber <afaerber@opensolaris.org>
> Cc: Juan Quintela <quintela@trasno.org>
> ---
> Makefile        |  123 ++------------------------------------------
> Makefile.hw     |   33 +-----------
> Makefile.objs   |  156 ++++++++++++++++++++++++++++++++++++++++++++++ 
> +++++++++
> Makefile.target |   30 ++++++++---
> Makefile.user   |    9 +---
> configure       |   34 +------------
> rules.mak       |    4 +-
> 7 files changed, 190 insertions(+), 199 deletions(-)
> create mode 100644 Makefile.objs
>
> diff --git a/Makefile b/Makefile
> index a662d96..c348ac8 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -66,7 +66,10 @@ SUBDIR_RULES=$(patsubst %,subdir-%, $(TARGET_DIRS))
> subdir-%: $(GENERATED_HEADERS)
> 	$(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C $* V="$(V)"  
> TARGET_DIR="$*/" all,)
>
> -$(filter %-softmmu,$(SUBDIR_RULES)): libqemu_common.a
> +include $(SRC_PATH)/Makefile.objs
> +
> +$(common-obj-y): $(GENERATED_HEADERS)
> +$(filter %-softmmu,$(SUBDIR_RULES)): $(common-obj-y)
>
> $(filter %-user,$(SUBDIR_RULES)): libuser.a
>
> @@ -81,124 +84,8 @@ ALL_SUBDIRS=$(TARGET_DIRS) $(patsubst %,pc-bios/ 
> %, $(ROMS))
>
> recurse-all: $(SUBDIR_RULES) $(ROMSUBDIR_RULES)
>
> - 
> #######################################################################
> -# QObject
> -qobject-obj-y = qint.o qstring.o qdict.o qlist.o qfloat.o qbool.o
> -qobject-obj-y += qjson.o json-lexer.o json-streamer.o json-parser.o
> -qobject-obj-y += qerror.o
> -
> - 
> #######################################################################
> -# block-obj-y is code used by both qemu system emulation and qemu-img
> -
> -block-obj-y = cutils.o cache-utils.o qemu-malloc.o qemu-option.o  
> module.o
> -block-obj-y += nbd.o block.o aio.o aes.o osdep.o
> -block-obj-$(CONFIG_POSIX) += posix-aio-compat.o
> -block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o
> -
> -block-nested-y += cow.o qcow.o vdi.o vmdk.o cloop.o dmg.o bochs.o  
> vpc.o vvfat.o
> -block-nested-y += qcow2.o qcow2-refcount.o qcow2-cluster.o qcow2- 
> snapshot.o
> -block-nested-y += parallels.o nbd.o
> -block-nested-$(CONFIG_WIN32) += raw-win32.o
> -block-nested-$(CONFIG_POSIX) += raw-posix.o
> -block-nested-$(CONFIG_CURL) += curl.o
> -
> -block-obj-y +=  $(addprefix block/, $(block-nested-y))
> -
> -net-obj-y = net.o
> -net-nested-y = queue.o checksum.o util.o
> -net-nested-y += socket.o
> -net-nested-y += dump.o
> -net-nested-$(CONFIG_POSIX) += tap.o
> -net-nested-$(CONFIG_LINUX) += tap-linux.o
> -net-nested-$(CONFIG_WIN32) += tap-win32.o
> -net-nested-$(CONFIG_BSD) += tap-bsd.o
> -net-nested-$(CONFIG_SOLARIS) += tap-solaris.o
> -net-nested-$(CONFIG_AIX) += tap-aix.o
> -net-nested-$(CONFIG_SLIRP) += slirp.o
> -net-nested-$(CONFIG_VDE) += vde.o
> -net-obj-y += $(addprefix net/, $(net-nested-y))
> -
> - 
> ######################################################################
> -# libqemu_common.a: Target independent part of system emulation. The
> -# long term path is to suppress *all* target specific code in case of
> -# system emulation, i.e. a single QEMU executable should support all
> -# CPUs and machines.
> -
> -obj-y = $(block-obj-y)
> -obj-y += $(net-obj-y)
> -obj-y += $(qobject-obj-y)
> -obj-y += readline.o console.o
> -
> -obj-y += tcg-runtime.o host-utils.o
> -obj-y += irq.o ioport.o
> -obj-$(CONFIG_PTIMER) += ptimer.o
> -obj-$(CONFIG_MAX7310) += max7310.o
> -obj-$(CONFIG_WM8750) += wm8750.o
> -obj-$(CONFIG_TWL92230) += twl92230.o
> -obj-$(CONFIG_TSC2005) += tsc2005.o
> -obj-$(CONFIG_LM832X) += lm832x.o
> -obj-$(CONFIG_TMP105) += tmp105.o
> -obj-$(CONFIG_STELLARIS_INPUT) += stellaris_input.o
> -obj-$(CONFIG_SSD0303) += ssd0303.o
> -obj-$(CONFIG_SSD0323) += ssd0323.o
> -obj-$(CONFIG_ADS7846) += ads7846.o
> -obj-$(CONFIG_MAX111X) += max111x.o
> -obj-$(CONFIG_DS1338) += ds1338.o
> -obj-y += i2c.o smbus.o smbus_eeprom.o
> -obj-y += eeprom93xx.o
> -obj-y += scsi-disk.o cdrom.o
> -obj-y += scsi-generic.o scsi-bus.o
> -obj-y += usb.o usb-hub.o usb-$(HOST_USB).o usb-hid.o usb-msd.o usb- 
> wacom.o
> -obj-y += usb-serial.o usb-net.o usb-bus.o
> -obj-$(CONFIG_SSI) += ssi.o
> -obj-$(CONFIG_SSI_SD) += ssi-sd.o
> -obj-$(CONFIG_SD) += sd.o
> -obj-y += bt.o bt-host.o bt-vhci.o bt-l2cap.o bt-sdp.o bt-hci.o bt- 
> hid.o usb-bt.o
> -obj-y += bt-hci-csr.o
> -obj-y += buffered_file.o migration.o migration-tcp.o qemu-sockets.o
> -obj-y += qemu-char.o aio.o savevm.o
> -obj-y += msmouse.o ps2.o
> -obj-y += qdev.o qdev-properties.o
> -obj-y += qemu-config.o block-migration.o
> -
> -obj-$(CONFIG_BRLAPI) += baum.o
> -obj-$(CONFIG_POSIX) += migration-exec.o migration-unix.o migration- 
> fd.o
> -
> audio/audio.o audio/fmodaudio.o: QEMU_CFLAGS += $(FMOD_CFLAGS)
>
> -audio-obj-y = audio.o noaudio.o wavaudio.o mixeng.o
> -audio-obj-$(CONFIG_SDL) += sdlaudio.o
> -audio-obj-$(CONFIG_OSS) += ossaudio.o
> -audio-obj-$(CONFIG_COREAUDIO) += coreaudio.o
> -audio-obj-$(CONFIG_ALSA) += alsaaudio.o
> -audio-obj-$(CONFIG_DSOUND) += dsoundaudio.o
> -audio-obj-$(CONFIG_FMOD) += fmodaudio.o
> -audio-obj-$(CONFIG_ESD) += esdaudio.o
> -audio-obj-$(CONFIG_PA) += paaudio.o
> -audio-obj-$(CONFIG_WINWAVE) += winwaveaudio.o
> -audio-obj-$(CONFIG_AUDIO_PT_INT) += audio_pt_int.o
> -audio-obj-$(CONFIG_AUDIO_WIN_INT) += audio_win_int.o
> -audio-obj-y += wavcapture.o
> -obj-y += $(addprefix audio/, $(audio-obj-y))
> -
> -obj-y += keymaps.o
> -obj-$(CONFIG_SDL) += sdl.o sdl_zoom.o x_keymap.o
> -obj-$(CONFIG_CURSES) += curses.o
> -obj-y += vnc.o acl.o d3des.o
> -obj-$(CONFIG_VNC_TLS) += vnc-tls.o vnc-auth-vencrypt.o
> -obj-$(CONFIG_VNC_SASL) += vnc-auth-sasl.o
> -obj-$(CONFIG_COCOA) += cocoa.o
> -obj-$(CONFIG_IOTHREAD) += qemu-thread.o
> -
> -slirp-obj-y = cksum.o if.o ip_icmp.o ip_input.o ip_output.o
> -slirp-obj-y += slirp.o mbuf.o misc.o sbuf.o socket.o tcp_input.o  
> tcp_output.o
> -slirp-obj-y += tcp_subr.o tcp_timer.o udp.o bootp.o tftp.o
> -obj-$(CONFIG_SLIRP) += $(addprefix slirp/, $(slirp-obj-y))
> -
> -# xen backend driver support
> -obj-$(CONFIG_XEN) += xen_backend.o xen_devconfig.o
> -obj-$(CONFIG_XEN) += xen_console.o xenfb.o xen_disk.o xen_nic.o
> -
> QEMU_CFLAGS+=$(CURL_CFLAGS)
>
> cocoa.o: cocoa.m
> @@ -229,8 +116,6 @@ curses.o: curses.c keymaps.h curses_keys.h
>
> bt-host.o: QEMU_CFLAGS += $(BLUEZ_CFLAGS)
>
> -libqemu_common.a: $(obj-y)
> -
> ######################################################################
>
> qemu-img.o: qemu-img-cmds.h
> diff --git a/Makefile.hw b/Makefile.hw
> index bd252f5..ff87ae4 100644
> --- a/Makefile.hw
> +++ b/Makefile.hw
> @@ -11,41 +11,12 @@ VPATH=$(SRC_PATH):$(SRC_PATH)/hw
>
> QEMU_CFLAGS+=-I.. -I$(SRC_PATH)/fpu
>
> -obj-y =
> -obj-y += loader.o
> -obj-y += virtio.o
> -obj-y += fw_cfg.o
> -obj-y += watchdog.o
> -obj-$(CONFIG_ECC) += ecc.o
> -obj-$(CONFIG_NAND) += nand.o
> +include $(SRC_PATH)/Makefile.objs
>
> -obj-$(CONFIG_M48T59) += m48t59.o
> -obj-$(CONFIG_ESCC) += escc.o
> -
> -# PCI watchdog devices
> -obj-y += wdt_i6300esb.o
> -
> -obj-y += msix.o
> -
> -# PCI network cards
> -obj-y += ne2000.o
> -
> -obj-$(CONFIG_SMC91C111) += smc91c111.o
> -obj-$(CONFIG_LAN9118) += lan9118.o
> -
> -# SCSI layer
> -obj-y += lsi53c895a.o
> -obj-$(CONFIG_ESP) += esp.o
> -
> -obj-y += dma-helpers.o sysbus.o isa-bus.o
> -obj-$(CONFIG_QDEV_ADDR) += qdev-addr.o
> -
> -all: $(HWLIB)
> +all: $(hw-obj-y)
> # Dummy command so that make thinks it has done something
> 	@true
>
> -$(HWLIB): $(obj-y)
> -
> clean:
> 	rm -f *.o *.d *.a *~
>
> diff --git a/Makefile.objs b/Makefile.objs
> new file mode 100644
> index 0000000..fd69717
> --- /dev/null
> +++ b/Makefile.objs
> @@ -0,0 +1,156 @@
> + 
> #######################################################################
> +# QObject
> +qobject-obj-y = qint.o qstring.o qdict.o qlist.o qfloat.o qbool.o
> +qobject-obj-y += qjson.o json-lexer.o json-streamer.o json-parser.o
> +qobject-obj-y += qerror.o
> +
> + 
> #######################################################################
> +# block-obj-y is code used by both qemu system emulation and qemu-img
> +
> +block-obj-y = cutils.o cache-utils.o qemu-malloc.o qemu-option.o  
> module.o
> +block-obj-y += nbd.o block.o aio.o aes.o osdep.o
> +block-obj-$(CONFIG_POSIX) += posix-aio-compat.o
> +block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o
> +
> +block-nested-y += cow.o qcow.o vdi.o vmdk.o cloop.o dmg.o bochs.o  
> vpc.o vvfat.o
> +block-nested-y += qcow2.o qcow2-refcount.o qcow2-cluster.o qcow2- 
> snapshot.o
> +block-nested-y += parallels.o nbd.o
> +block-nested-$(CONFIG_WIN32) += raw-win32.o
> +block-nested-$(CONFIG_POSIX) += raw-posix.o
> +block-nested-$(CONFIG_CURL) += curl.o
> +
> +block-obj-y +=  $(addprefix block/, $(block-nested-y))
> +
> +net-obj-y = net.o
> +net-nested-y = queue.o checksum.o util.o
> +net-nested-y += socket.o
> +net-nested-y += dump.o
> +net-nested-$(CONFIG_POSIX) += tap.o
> +net-nested-$(CONFIG_LINUX) += tap-linux.o
> +net-nested-$(CONFIG_WIN32) += tap-win32.o
> +net-nested-$(CONFIG_BSD) += tap-bsd.o
> +net-nested-$(CONFIG_SOLARIS) += tap-solaris.o
> +net-nested-$(CONFIG_AIX) += tap-aix.o
> +net-nested-$(CONFIG_SLIRP) += slirp.o
> +net-nested-$(CONFIG_VDE) += vde.o
> +net-obj-y += $(addprefix net/, $(net-nested-y))
> +
> + 
> ######################################################################
> +# libqemu_common.a: Target independent part of system emulation. The
> +# long term path is to suppress *all* target specific code in case of
> +# system emulation, i.e. a single QEMU executable should support all
> +# CPUs and machines.
> +
> +common-obj-y = $(block-obj-y)
> +common-obj-y += $(net-obj-y)
> +common-obj-y += $(qobject-obj-y)
> +common-obj-y += readline.o console.o
> +
> +common-obj-y += tcg-runtime.o host-utils.o
> +common-obj-y += irq.o ioport.o
> +common-obj-$(CONFIG_PTIMER) += ptimer.o
> +common-obj-$(CONFIG_MAX7310) += max7310.o
> +common-obj-$(CONFIG_WM8750) += wm8750.o
> +common-obj-$(CONFIG_TWL92230) += twl92230.o
> +common-obj-$(CONFIG_TSC2005) += tsc2005.o
> +common-obj-$(CONFIG_LM832X) += lm832x.o
> +common-obj-$(CONFIG_TMP105) += tmp105.o
> +common-obj-$(CONFIG_STELLARIS_INPUT) += stellaris_input.o
> +common-obj-$(CONFIG_SSD0303) += ssd0303.o
> +common-obj-$(CONFIG_SSD0323) += ssd0323.o
> +common-obj-$(CONFIG_ADS7846) += ads7846.o
> +common-obj-$(CONFIG_MAX111X) += max111x.o
> +common-obj-$(CONFIG_DS1338) += ds1338.o
> +common-obj-y += i2c.o smbus.o smbus_eeprom.o
> +common-obj-y += eeprom93xx.o
> +common-obj-y += scsi-disk.o cdrom.o
> +common-obj-y += scsi-generic.o scsi-bus.o
> +common-obj-y += usb.o usb-hub.o usb-$(HOST_USB).o usb-hid.o usb- 
> msd.o usb-wacom.o
> +common-obj-y += usb-serial.o usb-net.o usb-bus.o
> +common-obj-$(CONFIG_SSI) += ssi.o
> +common-obj-$(CONFIG_SSI_SD) += ssi-sd.o
> +common-obj-$(CONFIG_SD) += sd.o
> +common-obj-y += bt.o bt-host.o bt-vhci.o bt-l2cap.o bt-sdp.o bt- 
> hci.o bt-hid.o usb-bt.o
> +common-obj-y += bt-hci-csr.o
> +common-obj-y += buffered_file.o migration.o migration-tcp.o qemu- 
> sockets.o
> +common-obj-y += qemu-char.o savevm.o #aio.o
> +common-obj-y += msmouse.o ps2.o
> +common-obj-y += qdev.o qdev-properties.o
> +common-obj-y += qemu-config.o block-migration.o
> +
> +common-obj-$(CONFIG_BRLAPI) += baum.o
> +common-obj-$(CONFIG_POSIX) += migration-exec.o migration-unix.o  
> migration-fd.o
> +
> +audio-obj-y = audio.o noaudio.o wavaudio.o mixeng.o
> +audio-obj-$(CONFIG_SDL) += sdlaudio.o
> +audio-obj-$(CONFIG_OSS) += ossaudio.o
> +audio-obj-$(CONFIG_COREAUDIO) += coreaudio.o
> +audio-obj-$(CONFIG_ALSA) += alsaaudio.o
> +audio-obj-$(CONFIG_DSOUND) += dsoundaudio.o
> +audio-obj-$(CONFIG_FMOD) += fmodaudio.o
> +audio-obj-$(CONFIG_ESD) += esdaudio.o
> +audio-obj-$(CONFIG_PA) += paaudio.o
> +audio-obj-$(CONFIG_WINWAVE) += winwaveaudio.o
> +audio-obj-$(CONFIG_AUDIO_PT_INT) += audio_pt_int.o
> +audio-obj-$(CONFIG_AUDIO_WIN_INT) += audio_win_int.o
> +audio-obj-y += wavcapture.o
> +common-obj-y += $(addprefix audio/, $(audio-obj-y))
> +
> +common-obj-y += keymaps.o
> +common-obj-$(CONFIG_SDL) += sdl.o sdl_zoom.o x_keymap.o
> +common-obj-$(CONFIG_CURSES) += curses.o
> +common-obj-y += vnc.o acl.o d3des.o
> +common-obj-$(CONFIG_VNC_TLS) += vnc-tls.o vnc-auth-vencrypt.o
> +common-obj-$(CONFIG_VNC_SASL) += vnc-auth-sasl.o
> +common-obj-$(CONFIG_COCOA) += cocoa.o
> +common-obj-$(CONFIG_IOTHREAD) += qemu-thread.o
> +
> +slirp-obj-y = cksum.o if.o ip_icmp.o ip_input.o ip_output.o
> +slirp-obj-y += slirp.o mbuf.o misc.o sbuf.o socket.o tcp_input.o  
> tcp_output.o
> +slirp-obj-y += tcp_subr.o tcp_timer.o udp.o bootp.o tftp.o
> +common-obj-$(CONFIG_SLIRP) += $(addprefix slirp/, $(slirp-obj-y))
> +
> +# xen backend driver support
> +common-obj-$(CONFIG_XEN) += xen_backend.o xen_devconfig.o
> +common-obj-$(CONFIG_XEN) += xen_console.o xenfb.o xen_disk.o  
> xen_nic.o
> +
> + 
> ######################################################################
> +# libuser
> +
> +user-obj-y =
> +user-obj-y += envlist.o path.o
> +user-obj-y += tcg-runtime.o host-utils.o
> +user-obj-y += cutils.o cache-utils.o
> +
> + 
> ######################################################################
> +# libhw
> +
> +hw-obj-y =
> +hw-obj-y += loader.o
> +hw-obj-y += virtio.o
> +hw-obj-y += fw_cfg.o
> +hw-obj-y += watchdog.o
> +hw-obj-$(CONFIG_ECC) += ecc.o
> +hw-obj-$(CONFIG_NAND) += nand.o
> +
> +hw-obj-$(CONFIG_M48T59) += m48t59.o
> +hw-obj-$(CONFIG_ESCC) += escc.o
> +
> +# PCI watchdog devices
> +hw-obj-y += wdt_i6300esb.o
> +
> +hw-obj-y += msix.o
> +
> +# PCI network cards
> +hw-obj-y += ne2000.o
> +
> +hw-obj-$(CONFIG_SMC91C111) += smc91c111.o
> +hw-obj-$(CONFIG_LAN9118) += lan9118.o
> +
> +# SCSI layer
> +hw-obj-y += lsi53c895a.o
> +hw-obj-$(CONFIG_ESP) += esp.o
> +
> +hw-obj-y += dma-helpers.o sysbus.o isa-bus.o
> +hw-obj-$(CONFIG_QDEV_ADDR) += qdev-addr.o
> +
> diff --git a/Makefile.target b/Makefile.target
> index 7c1f30c..22a2f1e 100644
> --- a/Makefile.target
> +++ b/Makefile.target
> @@ -7,11 +7,14 @@ include ../config-host.mak
> include config-devices.mak
> include config-target.mak
> include $(SRC_PATH)/rules.mak
> +include $(HWDIR)/config.mak
>
> TARGET_PATH=$(SRC_PATH)/target-$(TARGET_BASE_ARCH)
> VPATH=$(SRC_PATH):$(TARGET_PATH):$(SRC_PATH)/hw
> QEMU_CFLAGS+= -I.. -I$(TARGET_PATH) -DNEED_CPU_H
>
> +include $(SRC_PATH)/Makefile.objs
> +
> ifdef CONFIG_USER_ONLY
> # user emulator name
> QEMU_PROG=qemu-$(TARGET_ARCH2)
> @@ -64,9 +67,9 @@ libobj-$(CONFIG_S390_DIS) += s390-dis.o
> libobj-$(CONFIG_SH4_DIS) += sh4-dis.o
> libobj-$(CONFIG_SPARC_DIS) += sparc-dis.o
>
> -# libqemu
> +$(libobj-y): $(GENERATED_HEADERS)
>
> -libqemu.a: $(libobj-y)
> +# libqemu
>
> translate.o: translate.c cpu.h
>
> @@ -106,7 +109,10 @@ obj-arm-y += arm-semi.o
>
> obj-m68k-y += m68k-sim.o m68k-semi.o
>
> -ARLIBS=../libuser/libuser.a libqemu.a
> +$(obj-y) $(obj-$(TARGET_BASE_ARCH)-y): $(GENERATED_HEADERS)
> +
> +obj-y += $(addprefix ../libuser/, $(user-obj-y))
> +obj-y += $(libobj-y)
>
> endif #CONFIG_LINUX_USER
>
> @@ -128,7 +134,10 @@ obj-y = main.o commpage.o machload.o mmap.o  
> signal.o syscall.o thunk.o \
>
> obj-i386-y += ioport-user.o
>
> -ARLIBS=../libuser/libuser.a libqemu.a
> +$(obj-y) $(obj-$(TARGET_BASE_ARCH)-y): $(GENERATED_HEADERS)
> +
> +obj-y += $(addprefix ../libuser/, $(user-obj-y))
> +obj-y += $(libobj-y)
>
> endif #CONFIG_DARWIN_USER
>
> @@ -145,7 +154,10 @@ obj-y = main.o bsdload.o elfload.o mmap.o  
> signal.o strace.o syscall.o \
>
> obj-i386-y += ioport-user.o
>
> -ARLIBS=../libuser/libuser.a libqemu.a
> +$(obj-y) $(obj-$(TARGET_BASE_ARCH)-y): $(GENERATED_HEADERS)
> +
> +obj-y += $(addprefix ../libuser/, $(user-obj-y))
> +obj-y += $(libobj-y)
>
> endif #CONFIG_BSD_USER
>
> @@ -303,13 +315,17 @@ vl.o: qemu-options.h
>
> monitor.o: qemu-monitor.h
>
> -ARLIBS=../libqemu_common.a libqemu.a $(HWLIB)
> +$(obj-y) $(obj-$(TARGET_BASE_ARCH)-y): $(GENERATED_HEADERS)
> +
> +obj-y += $(addprefix ../, $(common-obj-y))
> +obj-y += $(libobj-y)
> +obj-y += $(addprefix $(HWDIR)/, $(hw-obj-y))
>
> endif # CONFIG_SOFTMMU
>
> obj-$(CONFIG_GDBSTUB_XML) += gdbstub-xml.o
>
> -$(QEMU_PROG): $(obj-y) $(obj-$(TARGET_BASE_ARCH)-y) $(ARLIBS)
> +$(QEMU_PROG): $(obj-y) $(obj-$(TARGET_BASE_ARCH)-y)
> 	$(call LINK,$(obj-y) $(obj-$(TARGET_BASE_ARCH)-y))
>
>
> diff --git a/Makefile.user b/Makefile.user
> index 907e74b..4a8824d 100644
> --- a/Makefile.user
> +++ b/Makefile.user
> @@ -9,17 +9,12 @@ VPATH=$(SRC_PATH)
>
> QEMU_CFLAGS+=-I..
>
> -obj-y =
> -obj-y += envlist.o path.o
> -obj-y += tcg-runtime.o host-utils.o
> -obj-y += cutils.o cache-utils.o
> +include $(SRC_PATH)/Makefile.objs
>
> -all: libuser.a
> +all: $(user-obj-y)
> # Dummy command so that make thinks it has done something
> 	@true
>
> -libuser.a: $(obj-y)
> -
> clean:
> 	rm -f *.o *.d *.a *~
>
> diff --git a/configure b/configure
> index 273b6b7..6359401 100755
> --- a/configure
> +++ b/configure
> @@ -1707,37 +1707,6 @@ elif compile_prog "" "-lrt" ; then
>   LIBS="-lrt $LIBS"
> fi
>
> -# Determine what linker flags to use to force archive inclusion
> -check_linker_flags()
> -{
> -    w2=
> -    if test "$2" ; then
> -	w2=-Wl,$2
> -    fi
> -    compile_prog "" "-Wl,$1 ${w2}"
> -}
> -
> -cat > $TMPC << EOF
> -int main(void) { }
> -EOF
> -if check_linker_flags --whole-archive --no-whole-archive ; then
> -    # GNU ld
> -    arlibs_begin="-Wl,--whole-archive"
> -    arlibs_end="-Wl,--no-whole-archive"
> -elif check_linker_flags -z,allextract -z,defaultextract ; then
> -    # Solaris ld
> -    arlibs_begin="-Wl,-z,allextract"
> -    arlibs_end="-Wl,-z,defaultextract"
> -elif check_linker_flags -all_load ; then
> -    # Mac OS X
> -    arlibs_begin="-all_load"
> -    arlibs_end=""
> -else
> -    echo "Error: your linker does not support --whole-archive or -z."
> -    echo "Please report to qemu-devel@nongnu.org"
> -    exit 1
> -fi
> -
> if test "$darwin" != "yes" -a "$mingw32" != "yes" -a "$solaris" !=  
> yes -a \
>         "$aix" != "yes" ; then
>     libs_softmmu="-lutil $libs_softmmu"
> @@ -2427,7 +2396,7 @@ fi
> if test "$target_softmmu" = "yes" ; then
>   echo "CONFIG_SOFTMMU=y" >> $config_target_mak
>   echo "LIBS+=$libs_softmmu" >> $config_target_mak
> -  echo "HWLIB=../libhw$target_phys_bits/libqemuhw 
> $target_phys_bits.a" >> $config_target_mak
> +  echo "HWDIR=../libhw$target_phys_bits" >> $config_target_mak
>   echo "subdir-$target: subdir-libhw$target_phys_bits" >>  
> $config_host_mak
> fi
> if test "$target_user_only" = "yes" ; then
> @@ -2644,7 +2613,6 @@ for hwlib in 32 64; do
>   mkdir -p $d
>   rm -f $d/Makefile
>   ln -s $source_path/Makefile.hw $d/Makefile
> -  echo "HWLIB=libqemuhw$hwlib.a" > $d/config.mak
>   echo "QEMU_CFLAGS+=-DTARGET_PHYS_ADDR_BITS=$hwlib" >> $d/config.mak
> done
>
> diff --git a/rules.mak b/rules.mak
> index 5d9f684..9bcf9af 100644
> --- a/rules.mak
> +++ b/rules.mak
> @@ -14,7 +14,7 @@ MAKEFLAGS += -rR
> # Flags for dependency generation
> QEMU_DGFLAGS += -MMD -MP -MT $@
>
> -%.o: %.c $(GENERATED_HEADERS)
> +%.o: %.c
> 	$(call quiet-command,$(CC) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS)  
> -c -o $@ $<,"  CC    $(TARGET_DIR)$@")
>
> %.o: %.S
> @@ -23,7 +23,7 @@ QEMU_DGFLAGS += -MMD -MP -MT $@
> %.o: %.m
> 	$(call quiet-command,$(CC) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS)  
> -c -o $@ $<,"  OBJC  $(TARGET_DIR)$@")
>
> -LINK = $(call quiet-command,$(CC) $(QEMU_CFLAGS) $(CFLAGS) $ 
> (LDFLAGS) -o $@ $(1) $(ARLIBS_BEGIN) $(ARLIBS) $(ARLIBS_END) $ 
> (LIBS),"  LINK  $(TARGET_DIR)$@")
> +LINK = $(call quiet-command,$(CC) $(QEMU_CFLAGS) $(CFLAGS) $ 
> (LDFLAGS) -o $@ $(1) $(LIBS),"  LINK  $(TARGET_DIR)$@")
>
> %$(EXESUF): %.o
> 	$(call LINK,$^)
> -- 
> 1.6.5.3
>
>
>
Andreas Färber - Dec. 31, 2009, 2:10 p.m.
Am 13.12.2009 um 09:02 schrieb Andreas Färber:

> From: Andreas Färber <afaerber@opensolaris.org>
>
> Juan has donated a cool Makefile infrastructure that enables us to  
> drop
> static libraries completely:
>
> Move shared obj-y definitions to Makefile.objs, prefixed common-,  
> hw-, user-.
>
> Link those object files directly.
>
> Replace HWLIB by HWDIR, specifying only the directory.
>
> Drop --whole-archive and ARLIBS in Makefiles and configure.
>
> Drop GENERATED_HEADERS dependency in rules.mak, since this rebuilds  
> all
> common objects after generating a target-specific header. Add  
> dependency
> rules to Makefile and Makefile.target instead.

Patch cancelled. It is superseded by "Drop --whole-archive and static  
libraries" v2, at top-level. ;)

Patch

diff --git a/Makefile b/Makefile
index a662d96..c348ac8 100644
--- a/Makefile
+++ b/Makefile
@@ -66,7 +66,10 @@  SUBDIR_RULES=$(patsubst %,subdir-%, $(TARGET_DIRS))
 subdir-%: $(GENERATED_HEADERS)
 	$(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C $* V="$(V)" TARGET_DIR="$*/" all,)
 
-$(filter %-softmmu,$(SUBDIR_RULES)): libqemu_common.a
+include $(SRC_PATH)/Makefile.objs
+
+$(common-obj-y): $(GENERATED_HEADERS)
+$(filter %-softmmu,$(SUBDIR_RULES)): $(common-obj-y)
 
 $(filter %-user,$(SUBDIR_RULES)): libuser.a
 
@@ -81,124 +84,8 @@  ALL_SUBDIRS=$(TARGET_DIRS) $(patsubst %,pc-bios/%, $(ROMS))
 
 recurse-all: $(SUBDIR_RULES) $(ROMSUBDIR_RULES)
 
-#######################################################################
-# QObject
-qobject-obj-y = qint.o qstring.o qdict.o qlist.o qfloat.o qbool.o
-qobject-obj-y += qjson.o json-lexer.o json-streamer.o json-parser.o
-qobject-obj-y += qerror.o
-
-#######################################################################
-# block-obj-y is code used by both qemu system emulation and qemu-img
-
-block-obj-y = cutils.o cache-utils.o qemu-malloc.o qemu-option.o module.o
-block-obj-y += nbd.o block.o aio.o aes.o osdep.o
-block-obj-$(CONFIG_POSIX) += posix-aio-compat.o
-block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o
-
-block-nested-y += cow.o qcow.o vdi.o vmdk.o cloop.o dmg.o bochs.o vpc.o vvfat.o
-block-nested-y += qcow2.o qcow2-refcount.o qcow2-cluster.o qcow2-snapshot.o
-block-nested-y += parallels.o nbd.o
-block-nested-$(CONFIG_WIN32) += raw-win32.o
-block-nested-$(CONFIG_POSIX) += raw-posix.o
-block-nested-$(CONFIG_CURL) += curl.o
-
-block-obj-y +=  $(addprefix block/, $(block-nested-y))
-
-net-obj-y = net.o
-net-nested-y = queue.o checksum.o util.o
-net-nested-y += socket.o
-net-nested-y += dump.o
-net-nested-$(CONFIG_POSIX) += tap.o
-net-nested-$(CONFIG_LINUX) += tap-linux.o
-net-nested-$(CONFIG_WIN32) += tap-win32.o
-net-nested-$(CONFIG_BSD) += tap-bsd.o
-net-nested-$(CONFIG_SOLARIS) += tap-solaris.o
-net-nested-$(CONFIG_AIX) += tap-aix.o
-net-nested-$(CONFIG_SLIRP) += slirp.o
-net-nested-$(CONFIG_VDE) += vde.o
-net-obj-y += $(addprefix net/, $(net-nested-y))
-
-######################################################################
-# libqemu_common.a: Target independent part of system emulation. The
-# long term path is to suppress *all* target specific code in case of
-# system emulation, i.e. a single QEMU executable should support all
-# CPUs and machines.
-
-obj-y = $(block-obj-y)
-obj-y += $(net-obj-y)
-obj-y += $(qobject-obj-y)
-obj-y += readline.o console.o
-
-obj-y += tcg-runtime.o host-utils.o
-obj-y += irq.o ioport.o
-obj-$(CONFIG_PTIMER) += ptimer.o
-obj-$(CONFIG_MAX7310) += max7310.o
-obj-$(CONFIG_WM8750) += wm8750.o
-obj-$(CONFIG_TWL92230) += twl92230.o
-obj-$(CONFIG_TSC2005) += tsc2005.o
-obj-$(CONFIG_LM832X) += lm832x.o
-obj-$(CONFIG_TMP105) += tmp105.o
-obj-$(CONFIG_STELLARIS_INPUT) += stellaris_input.o
-obj-$(CONFIG_SSD0303) += ssd0303.o
-obj-$(CONFIG_SSD0323) += ssd0323.o
-obj-$(CONFIG_ADS7846) += ads7846.o
-obj-$(CONFIG_MAX111X) += max111x.o
-obj-$(CONFIG_DS1338) += ds1338.o
-obj-y += i2c.o smbus.o smbus_eeprom.o
-obj-y += eeprom93xx.o
-obj-y += scsi-disk.o cdrom.o
-obj-y += scsi-generic.o scsi-bus.o
-obj-y += usb.o usb-hub.o usb-$(HOST_USB).o usb-hid.o usb-msd.o usb-wacom.o
-obj-y += usb-serial.o usb-net.o usb-bus.o
-obj-$(CONFIG_SSI) += ssi.o
-obj-$(CONFIG_SSI_SD) += ssi-sd.o
-obj-$(CONFIG_SD) += sd.o
-obj-y += bt.o bt-host.o bt-vhci.o bt-l2cap.o bt-sdp.o bt-hci.o bt-hid.o usb-bt.o
-obj-y += bt-hci-csr.o
-obj-y += buffered_file.o migration.o migration-tcp.o qemu-sockets.o
-obj-y += qemu-char.o aio.o savevm.o
-obj-y += msmouse.o ps2.o
-obj-y += qdev.o qdev-properties.o
-obj-y += qemu-config.o block-migration.o
-
-obj-$(CONFIG_BRLAPI) += baum.o
-obj-$(CONFIG_POSIX) += migration-exec.o migration-unix.o migration-fd.o
-
 audio/audio.o audio/fmodaudio.o: QEMU_CFLAGS += $(FMOD_CFLAGS)
 
-audio-obj-y = audio.o noaudio.o wavaudio.o mixeng.o
-audio-obj-$(CONFIG_SDL) += sdlaudio.o
-audio-obj-$(CONFIG_OSS) += ossaudio.o
-audio-obj-$(CONFIG_COREAUDIO) += coreaudio.o
-audio-obj-$(CONFIG_ALSA) += alsaaudio.o
-audio-obj-$(CONFIG_DSOUND) += dsoundaudio.o
-audio-obj-$(CONFIG_FMOD) += fmodaudio.o
-audio-obj-$(CONFIG_ESD) += esdaudio.o
-audio-obj-$(CONFIG_PA) += paaudio.o
-audio-obj-$(CONFIG_WINWAVE) += winwaveaudio.o
-audio-obj-$(CONFIG_AUDIO_PT_INT) += audio_pt_int.o
-audio-obj-$(CONFIG_AUDIO_WIN_INT) += audio_win_int.o
-audio-obj-y += wavcapture.o
-obj-y += $(addprefix audio/, $(audio-obj-y))
-
-obj-y += keymaps.o
-obj-$(CONFIG_SDL) += sdl.o sdl_zoom.o x_keymap.o
-obj-$(CONFIG_CURSES) += curses.o
-obj-y += vnc.o acl.o d3des.o
-obj-$(CONFIG_VNC_TLS) += vnc-tls.o vnc-auth-vencrypt.o
-obj-$(CONFIG_VNC_SASL) += vnc-auth-sasl.o
-obj-$(CONFIG_COCOA) += cocoa.o
-obj-$(CONFIG_IOTHREAD) += qemu-thread.o
-
-slirp-obj-y = cksum.o if.o ip_icmp.o ip_input.o ip_output.o
-slirp-obj-y += slirp.o mbuf.o misc.o sbuf.o socket.o tcp_input.o tcp_output.o
-slirp-obj-y += tcp_subr.o tcp_timer.o udp.o bootp.o tftp.o
-obj-$(CONFIG_SLIRP) += $(addprefix slirp/, $(slirp-obj-y))
-
-# xen backend driver support
-obj-$(CONFIG_XEN) += xen_backend.o xen_devconfig.o
-obj-$(CONFIG_XEN) += xen_console.o xenfb.o xen_disk.o xen_nic.o
-
 QEMU_CFLAGS+=$(CURL_CFLAGS)
 
 cocoa.o: cocoa.m
@@ -229,8 +116,6 @@  curses.o: curses.c keymaps.h curses_keys.h
 
 bt-host.o: QEMU_CFLAGS += $(BLUEZ_CFLAGS)
 
-libqemu_common.a: $(obj-y)
-
 ######################################################################
 
 qemu-img.o: qemu-img-cmds.h
diff --git a/Makefile.hw b/Makefile.hw
index bd252f5..ff87ae4 100644
--- a/Makefile.hw
+++ b/Makefile.hw
@@ -11,41 +11,12 @@  VPATH=$(SRC_PATH):$(SRC_PATH)/hw
 
 QEMU_CFLAGS+=-I.. -I$(SRC_PATH)/fpu
 
-obj-y =
-obj-y += loader.o
-obj-y += virtio.o
-obj-y += fw_cfg.o
-obj-y += watchdog.o
-obj-$(CONFIG_ECC) += ecc.o
-obj-$(CONFIG_NAND) += nand.o
+include $(SRC_PATH)/Makefile.objs
 
-obj-$(CONFIG_M48T59) += m48t59.o
-obj-$(CONFIG_ESCC) += escc.o
-
-# PCI watchdog devices
-obj-y += wdt_i6300esb.o
-
-obj-y += msix.o
-
-# PCI network cards
-obj-y += ne2000.o
-
-obj-$(CONFIG_SMC91C111) += smc91c111.o
-obj-$(CONFIG_LAN9118) += lan9118.o
-
-# SCSI layer
-obj-y += lsi53c895a.o
-obj-$(CONFIG_ESP) += esp.o
-
-obj-y += dma-helpers.o sysbus.o isa-bus.o
-obj-$(CONFIG_QDEV_ADDR) += qdev-addr.o
-
-all: $(HWLIB)
+all: $(hw-obj-y)
 # Dummy command so that make thinks it has done something
 	@true
 
-$(HWLIB): $(obj-y)
-
 clean:
 	rm -f *.o *.d *.a *~
 
diff --git a/Makefile.objs b/Makefile.objs
new file mode 100644
index 0000000..fd69717
--- /dev/null
+++ b/Makefile.objs
@@ -0,0 +1,156 @@ 
+#######################################################################
+# QObject
+qobject-obj-y = qint.o qstring.o qdict.o qlist.o qfloat.o qbool.o
+qobject-obj-y += qjson.o json-lexer.o json-streamer.o json-parser.o
+qobject-obj-y += qerror.o
+
+#######################################################################
+# block-obj-y is code used by both qemu system emulation and qemu-img
+
+block-obj-y = cutils.o cache-utils.o qemu-malloc.o qemu-option.o module.o
+block-obj-y += nbd.o block.o aio.o aes.o osdep.o
+block-obj-$(CONFIG_POSIX) += posix-aio-compat.o
+block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o
+
+block-nested-y += cow.o qcow.o vdi.o vmdk.o cloop.o dmg.o bochs.o vpc.o vvfat.o
+block-nested-y += qcow2.o qcow2-refcount.o qcow2-cluster.o qcow2-snapshot.o
+block-nested-y += parallels.o nbd.o
+block-nested-$(CONFIG_WIN32) += raw-win32.o
+block-nested-$(CONFIG_POSIX) += raw-posix.o
+block-nested-$(CONFIG_CURL) += curl.o
+
+block-obj-y +=  $(addprefix block/, $(block-nested-y))
+
+net-obj-y = net.o
+net-nested-y = queue.o checksum.o util.o
+net-nested-y += socket.o
+net-nested-y += dump.o
+net-nested-$(CONFIG_POSIX) += tap.o
+net-nested-$(CONFIG_LINUX) += tap-linux.o
+net-nested-$(CONFIG_WIN32) += tap-win32.o
+net-nested-$(CONFIG_BSD) += tap-bsd.o
+net-nested-$(CONFIG_SOLARIS) += tap-solaris.o
+net-nested-$(CONFIG_AIX) += tap-aix.o
+net-nested-$(CONFIG_SLIRP) += slirp.o
+net-nested-$(CONFIG_VDE) += vde.o
+net-obj-y += $(addprefix net/, $(net-nested-y))
+
+######################################################################
+# libqemu_common.a: Target independent part of system emulation. The
+# long term path is to suppress *all* target specific code in case of
+# system emulation, i.e. a single QEMU executable should support all
+# CPUs and machines.
+
+common-obj-y = $(block-obj-y)
+common-obj-y += $(net-obj-y)
+common-obj-y += $(qobject-obj-y)
+common-obj-y += readline.o console.o
+
+common-obj-y += tcg-runtime.o host-utils.o
+common-obj-y += irq.o ioport.o
+common-obj-$(CONFIG_PTIMER) += ptimer.o
+common-obj-$(CONFIG_MAX7310) += max7310.o
+common-obj-$(CONFIG_WM8750) += wm8750.o
+common-obj-$(CONFIG_TWL92230) += twl92230.o
+common-obj-$(CONFIG_TSC2005) += tsc2005.o
+common-obj-$(CONFIG_LM832X) += lm832x.o
+common-obj-$(CONFIG_TMP105) += tmp105.o
+common-obj-$(CONFIG_STELLARIS_INPUT) += stellaris_input.o
+common-obj-$(CONFIG_SSD0303) += ssd0303.o
+common-obj-$(CONFIG_SSD0323) += ssd0323.o
+common-obj-$(CONFIG_ADS7846) += ads7846.o
+common-obj-$(CONFIG_MAX111X) += max111x.o
+common-obj-$(CONFIG_DS1338) += ds1338.o
+common-obj-y += i2c.o smbus.o smbus_eeprom.o
+common-obj-y += eeprom93xx.o
+common-obj-y += scsi-disk.o cdrom.o
+common-obj-y += scsi-generic.o scsi-bus.o
+common-obj-y += usb.o usb-hub.o usb-$(HOST_USB).o usb-hid.o usb-msd.o usb-wacom.o
+common-obj-y += usb-serial.o usb-net.o usb-bus.o
+common-obj-$(CONFIG_SSI) += ssi.o
+common-obj-$(CONFIG_SSI_SD) += ssi-sd.o
+common-obj-$(CONFIG_SD) += sd.o
+common-obj-y += bt.o bt-host.o bt-vhci.o bt-l2cap.o bt-sdp.o bt-hci.o bt-hid.o usb-bt.o
+common-obj-y += bt-hci-csr.o
+common-obj-y += buffered_file.o migration.o migration-tcp.o qemu-sockets.o
+common-obj-y += qemu-char.o savevm.o #aio.o
+common-obj-y += msmouse.o ps2.o
+common-obj-y += qdev.o qdev-properties.o
+common-obj-y += qemu-config.o block-migration.o
+
+common-obj-$(CONFIG_BRLAPI) += baum.o
+common-obj-$(CONFIG_POSIX) += migration-exec.o migration-unix.o migration-fd.o
+
+audio-obj-y = audio.o noaudio.o wavaudio.o mixeng.o
+audio-obj-$(CONFIG_SDL) += sdlaudio.o
+audio-obj-$(CONFIG_OSS) += ossaudio.o
+audio-obj-$(CONFIG_COREAUDIO) += coreaudio.o
+audio-obj-$(CONFIG_ALSA) += alsaaudio.o
+audio-obj-$(CONFIG_DSOUND) += dsoundaudio.o
+audio-obj-$(CONFIG_FMOD) += fmodaudio.o
+audio-obj-$(CONFIG_ESD) += esdaudio.o
+audio-obj-$(CONFIG_PA) += paaudio.o
+audio-obj-$(CONFIG_WINWAVE) += winwaveaudio.o
+audio-obj-$(CONFIG_AUDIO_PT_INT) += audio_pt_int.o
+audio-obj-$(CONFIG_AUDIO_WIN_INT) += audio_win_int.o
+audio-obj-y += wavcapture.o
+common-obj-y += $(addprefix audio/, $(audio-obj-y))
+
+common-obj-y += keymaps.o
+common-obj-$(CONFIG_SDL) += sdl.o sdl_zoom.o x_keymap.o
+common-obj-$(CONFIG_CURSES) += curses.o
+common-obj-y += vnc.o acl.o d3des.o
+common-obj-$(CONFIG_VNC_TLS) += vnc-tls.o vnc-auth-vencrypt.o
+common-obj-$(CONFIG_VNC_SASL) += vnc-auth-sasl.o
+common-obj-$(CONFIG_COCOA) += cocoa.o
+common-obj-$(CONFIG_IOTHREAD) += qemu-thread.o
+
+slirp-obj-y = cksum.o if.o ip_icmp.o ip_input.o ip_output.o
+slirp-obj-y += slirp.o mbuf.o misc.o sbuf.o socket.o tcp_input.o tcp_output.o
+slirp-obj-y += tcp_subr.o tcp_timer.o udp.o bootp.o tftp.o
+common-obj-$(CONFIG_SLIRP) += $(addprefix slirp/, $(slirp-obj-y))
+
+# xen backend driver support
+common-obj-$(CONFIG_XEN) += xen_backend.o xen_devconfig.o
+common-obj-$(CONFIG_XEN) += xen_console.o xenfb.o xen_disk.o xen_nic.o
+
+######################################################################
+# libuser
+
+user-obj-y =
+user-obj-y += envlist.o path.o
+user-obj-y += tcg-runtime.o host-utils.o
+user-obj-y += cutils.o cache-utils.o
+
+######################################################################
+# libhw
+
+hw-obj-y =
+hw-obj-y += loader.o
+hw-obj-y += virtio.o
+hw-obj-y += fw_cfg.o
+hw-obj-y += watchdog.o
+hw-obj-$(CONFIG_ECC) += ecc.o
+hw-obj-$(CONFIG_NAND) += nand.o
+
+hw-obj-$(CONFIG_M48T59) += m48t59.o
+hw-obj-$(CONFIG_ESCC) += escc.o
+
+# PCI watchdog devices
+hw-obj-y += wdt_i6300esb.o
+
+hw-obj-y += msix.o
+
+# PCI network cards
+hw-obj-y += ne2000.o
+
+hw-obj-$(CONFIG_SMC91C111) += smc91c111.o
+hw-obj-$(CONFIG_LAN9118) += lan9118.o
+
+# SCSI layer
+hw-obj-y += lsi53c895a.o
+hw-obj-$(CONFIG_ESP) += esp.o
+
+hw-obj-y += dma-helpers.o sysbus.o isa-bus.o
+hw-obj-$(CONFIG_QDEV_ADDR) += qdev-addr.o
+
diff --git a/Makefile.target b/Makefile.target
index 7c1f30c..22a2f1e 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -7,11 +7,14 @@  include ../config-host.mak
 include config-devices.mak
 include config-target.mak
 include $(SRC_PATH)/rules.mak
+include $(HWDIR)/config.mak
 
 TARGET_PATH=$(SRC_PATH)/target-$(TARGET_BASE_ARCH)
 VPATH=$(SRC_PATH):$(TARGET_PATH):$(SRC_PATH)/hw
 QEMU_CFLAGS+= -I.. -I$(TARGET_PATH) -DNEED_CPU_H
 
+include $(SRC_PATH)/Makefile.objs
+
 ifdef CONFIG_USER_ONLY
 # user emulator name
 QEMU_PROG=qemu-$(TARGET_ARCH2)
@@ -64,9 +67,9 @@  libobj-$(CONFIG_S390_DIS) += s390-dis.o
 libobj-$(CONFIG_SH4_DIS) += sh4-dis.o
 libobj-$(CONFIG_SPARC_DIS) += sparc-dis.o
 
-# libqemu
+$(libobj-y): $(GENERATED_HEADERS)
 
-libqemu.a: $(libobj-y)
+# libqemu
 
 translate.o: translate.c cpu.h
 
@@ -106,7 +109,10 @@  obj-arm-y += arm-semi.o
 
 obj-m68k-y += m68k-sim.o m68k-semi.o
 
-ARLIBS=../libuser/libuser.a libqemu.a
+$(obj-y) $(obj-$(TARGET_BASE_ARCH)-y): $(GENERATED_HEADERS)
+
+obj-y += $(addprefix ../libuser/, $(user-obj-y))
+obj-y += $(libobj-y)
 
 endif #CONFIG_LINUX_USER
 
@@ -128,7 +134,10 @@  obj-y = main.o commpage.o machload.o mmap.o signal.o syscall.o thunk.o \
 
 obj-i386-y += ioport-user.o
 
-ARLIBS=../libuser/libuser.a libqemu.a
+$(obj-y) $(obj-$(TARGET_BASE_ARCH)-y): $(GENERATED_HEADERS)
+
+obj-y += $(addprefix ../libuser/, $(user-obj-y))
+obj-y += $(libobj-y)
 
 endif #CONFIG_DARWIN_USER
 
@@ -145,7 +154,10 @@  obj-y = main.o bsdload.o elfload.o mmap.o signal.o strace.o syscall.o \
 
 obj-i386-y += ioport-user.o
 
-ARLIBS=../libuser/libuser.a libqemu.a
+$(obj-y) $(obj-$(TARGET_BASE_ARCH)-y): $(GENERATED_HEADERS)
+
+obj-y += $(addprefix ../libuser/, $(user-obj-y))
+obj-y += $(libobj-y)
 
 endif #CONFIG_BSD_USER
 
@@ -303,13 +315,17 @@  vl.o: qemu-options.h
 
 monitor.o: qemu-monitor.h
 
-ARLIBS=../libqemu_common.a libqemu.a $(HWLIB)
+$(obj-y) $(obj-$(TARGET_BASE_ARCH)-y): $(GENERATED_HEADERS)
+
+obj-y += $(addprefix ../, $(common-obj-y))
+obj-y += $(libobj-y)
+obj-y += $(addprefix $(HWDIR)/, $(hw-obj-y))
 
 endif # CONFIG_SOFTMMU
 
 obj-$(CONFIG_GDBSTUB_XML) += gdbstub-xml.o
 
-$(QEMU_PROG): $(obj-y) $(obj-$(TARGET_BASE_ARCH)-y) $(ARLIBS)
+$(QEMU_PROG): $(obj-y) $(obj-$(TARGET_BASE_ARCH)-y)
 	$(call LINK,$(obj-y) $(obj-$(TARGET_BASE_ARCH)-y))
 
 
diff --git a/Makefile.user b/Makefile.user
index 907e74b..4a8824d 100644
--- a/Makefile.user
+++ b/Makefile.user
@@ -9,17 +9,12 @@  VPATH=$(SRC_PATH)
 
 QEMU_CFLAGS+=-I..
 
-obj-y =
-obj-y += envlist.o path.o
-obj-y += tcg-runtime.o host-utils.o
-obj-y += cutils.o cache-utils.o
+include $(SRC_PATH)/Makefile.objs
 
-all: libuser.a
+all: $(user-obj-y)
 # Dummy command so that make thinks it has done something
 	@true
 
-libuser.a: $(obj-y)
-
 clean:
 	rm -f *.o *.d *.a *~
 
diff --git a/configure b/configure
index 273b6b7..6359401 100755
--- a/configure
+++ b/configure
@@ -1707,37 +1707,6 @@  elif compile_prog "" "-lrt" ; then
   LIBS="-lrt $LIBS"
 fi
 
-# Determine what linker flags to use to force archive inclusion
-check_linker_flags()
-{
-    w2=
-    if test "$2" ; then
-	w2=-Wl,$2
-    fi
-    compile_prog "" "-Wl,$1 ${w2}"
-}
-
-cat > $TMPC << EOF
-int main(void) { }
-EOF
-if check_linker_flags --whole-archive --no-whole-archive ; then
-    # GNU ld
-    arlibs_begin="-Wl,--whole-archive"
-    arlibs_end="-Wl,--no-whole-archive"
-elif check_linker_flags -z,allextract -z,defaultextract ; then
-    # Solaris ld
-    arlibs_begin="-Wl,-z,allextract"
-    arlibs_end="-Wl,-z,defaultextract"
-elif check_linker_flags -all_load ; then
-    # Mac OS X
-    arlibs_begin="-all_load"
-    arlibs_end=""
-else
-    echo "Error: your linker does not support --whole-archive or -z."
-    echo "Please report to qemu-devel@nongnu.org"
-    exit 1
-fi
-
 if test "$darwin" != "yes" -a "$mingw32" != "yes" -a "$solaris" != yes -a \
         "$aix" != "yes" ; then
     libs_softmmu="-lutil $libs_softmmu"
@@ -2427,7 +2396,7 @@  fi
 if test "$target_softmmu" = "yes" ; then
   echo "CONFIG_SOFTMMU=y" >> $config_target_mak
   echo "LIBS+=$libs_softmmu" >> $config_target_mak
-  echo "HWLIB=../libhw$target_phys_bits/libqemuhw$target_phys_bits.a" >> $config_target_mak
+  echo "HWDIR=../libhw$target_phys_bits" >> $config_target_mak
   echo "subdir-$target: subdir-libhw$target_phys_bits" >> $config_host_mak
 fi
 if test "$target_user_only" = "yes" ; then
@@ -2644,7 +2613,6 @@  for hwlib in 32 64; do
   mkdir -p $d
   rm -f $d/Makefile
   ln -s $source_path/Makefile.hw $d/Makefile
-  echo "HWLIB=libqemuhw$hwlib.a" > $d/config.mak
   echo "QEMU_CFLAGS+=-DTARGET_PHYS_ADDR_BITS=$hwlib" >> $d/config.mak
 done
 
diff --git a/rules.mak b/rules.mak
index 5d9f684..9bcf9af 100644
--- a/rules.mak
+++ b/rules.mak
@@ -14,7 +14,7 @@  MAKEFLAGS += -rR
 # Flags for dependency generation
 QEMU_DGFLAGS += -MMD -MP -MT $@
 
-%.o: %.c $(GENERATED_HEADERS)
+%.o: %.c
 	$(call quiet-command,$(CC) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) -c -o $@ $<,"  CC    $(TARGET_DIR)$@")
 
 %.o: %.S
@@ -23,7 +23,7 @@  QEMU_DGFLAGS += -MMD -MP -MT $@
 %.o: %.m
 	$(call quiet-command,$(CC) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) -c -o $@ $<,"  OBJC  $(TARGET_DIR)$@")
 
-LINK = $(call quiet-command,$(CC) $(QEMU_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ $(1) $(ARLIBS_BEGIN) $(ARLIBS) $(ARLIBS_END) $(LIBS),"  LINK  $(TARGET_DIR)$@")
+LINK = $(call quiet-command,$(CC) $(QEMU_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ $(1) $(LIBS),"  LINK  $(TARGET_DIR)$@")
 
 %$(EXESUF): %.o
 	$(call LINK,$^)