Patchwork [3/3] Workaround --whole-archive on Solaris

login
register
mail settings
Submitter Andreas Färber
Date Dec. 12, 2009, 7:10 p.m.
Message ID <1260645057-19819-4-git-send-email-andreas.faerber@web.de>
Download mbox | patch
Permalink /patch/40990/
State New
Headers show

Comments

Andreas Färber - Dec. 12, 2009, 7:10 p.m.
From: Andreas Färber <afaerber@opensolaris.org>

On OpenSolaris, neither --whole-archive nor -z allextract
appear to work as expected, causing runtime errors. For example:

qemu: could not open disk image [...]

Fix this by extracting archives and linking their object files individually.

libqemu_common.a contains object files from different subdirectories,
leading to name clashes, e.g., nbd.o vs. block/nbd.o.

Archive a renamed copy of the affected files instead, this avoids
duplicating %.c -> %.o compilation rules. Two dashes are used for the copy
to avoid name clashes between, e.g., block-qcow.c and block/qcow.c.

Contain this behavior to Solaris to avoid speed regressions on Linux.

Signed-off-by: Andreas Färber <afaerber@opensolaris.org>
Cc: Palle Lyckegaard <palle@lyckegaard.dk>
Cc: Ben Taylor <bentaylor.solx86@gmail.com>
---
 Makefile  |   14 ++++++++++++++
 rules.mak |    4 ++++
 2 files changed, 18 insertions(+), 0 deletions(-)
Andreas Färber - Dec. 12, 2009, 11:07 p.m.
Am 12.12.2009 um 21:57 schrieb Juan Quintela:

> Andreas Färber <andreas.faerber@web.de> wrote:
>> From: Andreas Färber <afaerber@opensolaris.org>
>>
>> On OpenSolaris, neither --whole-archive nor -z allextract
>> appear to work as expected, causing runtime errors. For example:
>>
>> qemu: could not open disk image [...]
>>
>> Fix this by extracting archives and linking their object files  
>> individually.
>>
>> libqemu_common.a contains object files from different subdirectories,
>> leading to name clashes, e.g., nbd.o vs. block/nbd.o.
>>
>> Archive a renamed copy of the affected files instead, this avoids
>> duplicating %.c -> %.o compilation rules. Two dashes are used for  
>> the copy
>> to avoid name clashes between, e.g., block-qcow.c and block/qcow.c.
>>
>> Contain this behavior to Solaris to avoid speed regressions on Linux.
>
> I just wonder.  If we are:
> a- linking all archives (that is the whole point)
> b- some OS's need to unpack the library due to broken ld (or whatever)
>
> why don't we do the right thing?

Maybe because, if we are honest, we have lengthy discussions about  
sticking to ISO/ANSI/POSIX malloc behavior when it affects customers  
on The OS, but silently ignore some "fringe" OS breaking after  
choosing a convenient but non-standard GCC mechanism? ;)

> just put the objects in some directory, and not create the library in
> the 1st place?  It is a static library, not a dynamic one, and we want
> everything in the 1st place.

The trick is knowing which "everything" we want today!

> I think that this is a saner approach that having two ways (well
> currently several ways) of linking all archives.
>
> What do you people think?

Certainly I would prefer having one shared linking mechanism.

The three separate Makefiles (Makefile, Makefile.hw, Makefile.target)  
that govern which objects are to be compiled pose the problem.
In the end, we need some mechanism to get the right set of objects  
into Makefile.target. Previous attempts were
(i) writing object file paths to a file (me not satisfied), or
(ii) printing them from within make (Avi objected), and now
(iii) extracting them from archives (Juan objected for Linux).

Juan, being our Makefile inventor, what about
(iv) moving the assembling of some of the obj-y variables to a shared  
file included by all three Makefiles?
Would that work? If we had, e.g., common-obj-y and libhw{32,64}-obj-y  
accessible in Makefile.target, we could use them for both dependency  
modelling and linking.

Regards,
Andreas
Andreas Färber - Dec. 13, 2009, 8:16 a.m.
Am 13.12.2009 um 00:07 schrieb Andreas Färber:

>
> Am 12.12.2009 um 21:57 schrieb Juan Quintela:
>
>> Andreas Färber <andreas.faerber@web.de> wrote:
>>> From: Andreas Färber <afaerber@opensolaris.org>
>>>
>>> On OpenSolaris, neither --whole-archive nor -z allextract
>>> appear to work as expected, causing runtime errors. For example:
>>>
>>> qemu: could not open disk image [...]
>>>
>>> Fix this by extracting archives and linking their object files  
>>> individually.
>>>
>>> libqemu_common.a contains object files from different  
>>> subdirectories,
>>> leading to name clashes, e.g., nbd.o vs. block/nbd.o.
>>>
>>> Archive a renamed copy of the affected files instead, this avoids
>>> duplicating %.c -> %.o compilation rules. Two dashes are used for  
>>> the copy
>>> to avoid name clashes between, e.g., block-qcow.c and block/qcow.c.
>>>
>>> Contain this behavior to Solaris to avoid speed regressions on  
>>> Linux.
>>
>> I just wonder.  If we are:
>> a- linking all archives (that is the whole point)
>> b- some OS's need to unpack the library due to broken ld (or  
>> whatever)
>>
>> why don't we do the right thing?

>> just put the objects in some directory, and not create the library in
>> the 1st place?  It is a static library, not a dynamic one, and we  
>> want
>> everything in the 1st place.
>
> The trick is knowing which "everything" we want today!
>
>> I think that this is a saner approach that having two ways (well
>> currently several ways) of linking all archives.
>>
>> What do you people think?

> Juan, being our Makefile inventor, what about
> (iv) moving the assembling of some of the obj-y variables to a  
> shared file included by all three Makefiles?

I've tested some softmmus on OpenSolaris/amd64 and it appears to work!  
Don't have a test environment for all the user emulators though.

Andreas
Avi Kivity - Dec. 13, 2009, 10:21 a.m.
On 12/13/2009 01:07 AM, Andreas Färber wrote:
>
> Certainly I would prefer having one shared linking mechanism.
>
> The three separate Makefiles (Makefile, Makefile.hw, Makefile.target) 
> that govern which objects are to be compiled pose the problem.
> In the end, we need some mechanism to get the right set of objects 
> into Makefile.target. Previous attempts were
> (i) writing object file paths to a file (me not satisfied), or
> (ii) printing them from within make (Avi objected), and now
> (iii) extracting them from archives (Juan objected for Linux).

Out of the three above, I prefer (ii) despite my objection.

>
> Juan, being our Makefile inventor, what about
> (iv) moving the assembling of some of the obj-y variables to a shared 
> file included by all three Makefiles?
> Would that work? If we had, e.g., common-obj-y and libhw{32,64}-obj-y 
> accessible in Makefile.target, we could use them for both dependency 
> modelling and linking.

But out of the four, I prefer this.

In fact, why not have one large makefile, with different targets called 
for different subdirectories?

Patch

diff --git a/Makefile b/Makefile
index a662d96..cb57c61 100644
--- a/Makefile
+++ b/Makefile
@@ -102,7 +102,14 @@  block-nested-$(CONFIG_WIN32) += raw-win32.o
 block-nested-$(CONFIG_POSIX) += raw-posix.o
 block-nested-$(CONFIG_CURL) += curl.o
 
+ifneq ($(CONFIG_SOLARIS),y)
 block-obj-y +=  $(addprefix block/, $(block-nested-y))
+else
+block-obj-y +=  $(addprefix block--, $(block-nested-y))
+
+block--%.o: block/%.o
+	$(call quiet-command,cp $< $@,"  CP    $(TARGET_DIR)$@")
+endif
 
 net-obj-y = net.o
 net-nested-y = queue.o checksum.o util.o
@@ -116,7 +123,14 @@  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
+ifneq ($(CONFIG_SOLARIS),y)
 net-obj-y += $(addprefix net/, $(net-nested-y))
+else
+net-obj-y += $(addprefix net--, $(net-nested-y))
+
+net--%.o: net/%.o
+	$(call quiet-command,cp $< $@,"  CP    $(TARGET_DIR)$@")
+endif
 
 ######################################################################
 # libqemu_common.a: Target independent part of system emulation. The
diff --git a/rules.mak b/rules.mak
index 5d9f684..d0e3a2d 100644
--- a/rules.mak
+++ b/rules.mak
@@ -23,7 +23,11 @@  QEMU_DGFLAGS += -MMD -MP -MT $@
 %.o: %.m
 	$(call quiet-command,$(CC) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) -c -o $@ $<,"  OBJC  $(TARGET_DIR)$@")
 
+ifeq ($(CONFIG_SOLARIS),y)
+LINK = $(call quiet-command,{ rm -rf .tmpobjs;mkdir .tmpobjs$(foreach arlib,$(ARLIBS),;(mkdir .tmpobjs/$(notdir $(arlib));cd .tmpobjs/$(notdir $(arlib)) && ar x ../../$(arlib)));$(CC) $(QEMU_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ $(1) $(foreach arlib,$(ARLIBS),$(foreach obj,$(shell $(AR) t $(arlib)),.tmpobjs/$(notdir $(arlib))/$(obj))) $(LIBS);},"  LINK  $(TARGET_DIR)$@")
+else
 LINK = $(call quiet-command,$(CC) $(QEMU_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ $(1) $(ARLIBS_BEGIN) $(ARLIBS) $(ARLIBS_END) $(LIBS),"  LINK  $(TARGET_DIR)$@")
+endif
 
 %$(EXESUF): %.o
 	$(call LINK,$^)