kickaha: (Default)
[personal profile] kickaha
Alright, I'm going bonkers. In the middle of porting a Linux app to MacOS X 10.4, and I've run into what seems to be a very common problem: converting the build system for dynamic libraries. There is no end of 'helpful' advice running around, 99.9% of which seems to boil down to "Try everything" or "Use this magic sequence, it works for some people, nobody knows why". The last .1% seems to be posts of "Got it working! Thanks!" *with no explanation of how*. Bastards.

The build system I'm struggling with is... byzantine. Multiple layers of Makefiles with embedded Perl, custom scripts that don't really *do* much that I can see, other than add obfuscation, etc, etc.

In other words, a pretty normal Linux project. :)

So here's the setup:

1) .o files being archived into .a libs.
2) .a libs being gathered into .dylibs.
3) binaries being built on dylibs.

Simple, no?

The gcc/ld link flags for the linux build are:

CFLAGS throughout are the same: -pipe -Wreturn-type -march=i686 -fPIC -Wunused -Wformat -Wall -Wno-parentheses -Wno-switch -Wno-sign-compare -Wno-unused-parameter

.c%.o:
g++ $(CFLAGS) -o foo.o foo.c

.o%.a:
ar cr foo.a *.o

.a%.dylib:
g++ -L/usr/local/lib -L. -lfoo -o libbar.so -Wl,--enable-new-dtags -shared -Wl,--whole-archive ../lib/[.a libs here] -Wl,--no-whole-archive

No, I don't know why they switch back to --no-whole-archive, I just report what they do.

.dylib%a.out:
g++ $(CFLAGS) -L../dll -Wl,-rpath-link,../dll -L. -o my_executable ../main.c -lMyLib1 -lMyLib2


--------
The analogous (I thought) flags for OS X's build chain are: (first two are the same)

.c%.o:
g++ $(CFLAGS) -o foo.o foo.c

.o%.a:
ar cr foo.a *.o

.a%.dylib:
g++ -L/usr/local/lib -L. -lfoo -o libbar.dylib -dynamiclib -all_load -single_module -flat_namespace -force_flat_namespace -bind_at_load ../lib/[.a libs here]

-shared -> -dynamiclib
--whole-archive -> -all_load
because it's not a MacOS X app -> -single_module -flat_namespace -force_flat_namespace
who the hell knows, see 99.9% reference above -> -bind_at_load

.dylib%a.out:
g++ $(CFLAGS) -fvisibility=default -L../dll -L. -o my_executable ../main.c -lMyLib1 -lMyLib2

The -fvisibility is to make sure that 'older style' auto-export of symbols in dylibs is done.

Of course, this doesn't work, it can't find the second level dependent libraries...

/usr/bin/ld: warning can't open dynamic library: libMyLib3.dylib referenced from: ../dll/libMyLib1.dylib (checking for undefined symbols may be affected) (No such file or directory, errno = 2)
/usr/bin/ld: Undefined symbols:
_FirstUndefSym referenced from libMyLib1 expected to be defined in libMyLib3.dylib

I did an 'export DYLD_LIBRARY_PATH = $(DLLDIR)', *and* set it in the shell. Neither worked. I need a replacement for that -rpath up in the Linux build line, apparently.

Looking through the Makefiles, ranlib is never being invoked directly, but shouldn't that be handled by passing everything through gcc??

I'm getting another 'undefined symbol' error from a .a library that obviously *HAS* the symbol in it (two .o files, one defines, one uses, apparently the one using is bitching... in the *same library* - grr), but let's take this one step at a time.


On writing this up, I'm wondering if the -fvisibility flag should be in the .a%.dylib command...

Have you considered ritual suicide?

Date: 2007-10-04 08:10 pm (UTC)
From: [identity profile] sfeldon.livejournal.com
(I'm serious. Not about suggesting seppuku, but about that being the best suggestion _I_ have.)

Re: Have you considered ritual suicide?

Date: 2007-10-04 08:36 pm (UTC)
From: [identity profile] kickaha.livejournal.com
Heh, you're not the first to suggest that with this problem, probably won't be the last.

I mean for god's sake, it's just a linker. HOW HARD COULD IT BE???



sigh

Re: Have you considered ritual suicide?

Date: 2007-10-04 09:07 pm (UTC)
From: [identity profile] sfeldon.livejournal.com
Um. . . Relationship co-efficient between how hard a problem should be and how hard it is: precisely 0. I have a closet full of "easy problems" I'm still seeking solutions to. Usually the hard ones are . . . more tractable. :)

(no subject)

Date: 2007-10-04 09:42 pm (UTC)
From: [identity profile] code-slave.livejournal.com
Have you made offerings to the appropriate gods?
Sumerian *and* Babylonian?!

Assuming, of course, you have found the Keymaster *and* the Gatekeeper!
(If someone asks you if you are a SysAdmin, you say, "YES!".)

Perhaps you should go ahead and cross the streams!
;-)


Yeah - not helpful - but i thought it might be good for some amusement. *hugs*

(no subject)

Date: 2007-10-04 10:12 pm (UTC)
From: [identity profile] actsofcreation.livejournal.com
Have you considered converting to using libtool?

(no subject)

Date: 2007-10-04 10:53 pm (UTC)
From: [identity profile] kickaha.livejournal.com
I assume you mean the gnu libtool, and not the NeXT-derived libtool that ships with OS X...

glibtool is in there as well, actually, but since the build system for the Linux sides of things doesn't use it, I'd be porting anyway, just to a tool that's not as well integrated with the platform. :\

(no subject)

Date: 2007-10-05 02:18 am (UTC)
From: [identity profile] ssandv.livejournal.com
I assume you've seen the "Recursive Make considered harmful" article? ;)

Not that it'll help you much, but it'll make you at least feel like you're doing the right thing when you end up with a monolithic 500 block uber-makefile. (Not that we have one or anything, or that it invokes a perl wrapper for a VHDL compiler or that I get to maintain it. No, nothing like that.)

One thing I *do* know is that make -n is your very good friend when things are not working the way you think they should. (though that sounds like it might be more useful for problem #2)

(no subject)

Date: 2007-10-05 02:30 am (UTC)
From: [identity profile] kickaha.livejournal.com
Yeah, and I stumbled across $(warning foo) today too, which is something I've been wanting for, oh, a long time.

This build system is just unreal - otoh, it runs on several, um, extremely different platforms, and has good reuse of core rules. It just takes some wading through to figure out what the hell is going on.

I'm convinced that the make execution flow is correct, it's just the &*(%@# linker flags I need to hammer into shape. :p

(no subject)

Date: 2007-10-06 12:20 am (UTC)
From: [identity profile] ssandv.livejournal.com
If it makes (haha) you feel any better, you know that perl wrapper I mentioned? I get to rewrite it nearly from scratch. Turns out the guy who wrote it thought that basically doing @foo=`$command`; prettyprint @foo;, making the wrapper the head of the process group, and passing signals to the group via %SIG{FOO} => sub { kill -$$ }; was good enough...but the zombies say otherwise. Yeah, I signed on to a test position to learn to use fork, exec, and %SIG{} in perl. Really I did. *headdesk*. If nothing else, misery loves company, right?

(no subject)

Date: 2007-10-06 05:11 am (UTC)
From: [identity profile] kickaha.livejournal.com
Indeed. :/

Profile

kickaha: (Default)
kickaha

January 2020

S M T W T F S
   1234
5678 91011
12131415161718
19202122232425
262728293031 

Style Credit

Expand Cut Tags

No cut tags