Thread: Build universal binary on Mac OS X 10.6?

Build universal binary on Mac OS X 10.6?

From
Israel Brewster
Date:
I am trying to create a static, universal (x86 and ppc at least - 64 bit architectures are optional) build of the PostgreSQL libraries on a Mac OS X 10.6 machine. The command line I am using is as follows:

CFLAGS="-arch i386 -arch ppc -arch x86_64" ./configure --disable-shared

The configure runs fine, as does the build until it gets to the following error:

gcc -no-cpp-precomp -arch i386 -arch ppc -arch x86_64 -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -fno-strict-aliasing -fwrapv -I../../../../src/include   -c -o heaptuple.o heaptuple.c
heaptuple.c: In function 'heap_fill_tuple':
heaptuple.c:196: error: duplicate case value
heaptuple.c:196: error: previously used here
heaptuple.c: In function 'heap_fill_tuple':
heaptuple.c:196: error: duplicate case value
heaptuple.c:196: error: previously used here
lipo: can't figure out the architecture type of: /var/tmp//ccKn3btt.out
make[4]: *** [heaptuple.o] Error 1
make[3]: *** [common-recursive] Error 2
make[2]: *** [access-recursive] Error 2
make[1]: *** [all] Error 2
make: *** [all] Error 2

I have tried both with PostgreSQL version 8.4.1 and 8.3.8 with the same result. I really just need the library for my apps to link against, I don't care if the server or client programs compile. What am I doing wrong here? How can I get this to work? Thanks.

-----------------------------------------------
Israel Brewster
Computer Support Technician II
Frontier Flying Service Inc.
5245 Airport Industrial Rd
Fairbanks, AK 99709
(907) 450-7250 x293
-----------------------------------------------


Attachment

Re: Build universal binary on Mac OS X 10.6?

From
Tom Lane
Date:
Israel Brewster <israel@frontierflying.com> writes:
> I am trying to create a static, universal (x86 and ppc at least - 64
> bit architectures are optional) build of the PostgreSQL libraries on a
> Mac OS X 10.6 machine.

I think what you're missing is that the header files generated by
configure are arch-sensitive.  You need to take steps to make sure that
each build reads the appropriate header declarations.  Check the
pgsql-hackers archives for previous discussions of building universal
binaries on Darwin --- I think the last one was mid-2008 or so.

> I have tried both with PostgreSQL version 8.4.1 and 8.3.8 with the
> same result.

My recollection is that you want 8.4 for this, previous releases would
have had even more hoops to jump through to get there.

            regards, tom lane

Re: Build universal binary on Mac OS X 10.6?

From
Dave Page
Date:
On Wed, Dec 2, 2009 at 1:14 AM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> Israel Brewster <israel@frontierflying.com> writes:
>> I am trying to create a static, universal (x86 and ppc at least - 64
>> bit architectures are optional) build of the PostgreSQL libraries on a
>> Mac OS X 10.6 machine.
>
> I think what you're missing is that the header files generated by
> configure are arch-sensitive.  You need to take steps to make sure that
> each build reads the appropriate header declarations.  Check the
> pgsql-hackers archives for previous discussions of building universal
> binaries on Darwin --- I think the last one was mid-2008 or so.
>
>> I have tried both with PostgreSQL version 8.4.1 and 8.3.8 with the
>> same result.
>
> My recollection is that you want 8.4 for this, previous releases would
> have had even more hoops to jump through to get there.

If you get it to work Israel, please report back to the list. I tried
briefly and failed completely at building a 3 way binary on one
machine. My next attempt was going to involve multiple build machines
and lipo...



--
Dave Page
EnterpriseDB UK: http://www.enterprisedb.com

Re: Build universal binary on Mac OS X 10.6?

From
Grzegorz Jaśkiewicz
Date:


On Tue, Dec 1, 2009 at 11:43 PM, Israel Brewster <israel@frontierflying.com> wrote:
I am trying to create a static, universal (x86 and ppc at least - 64 bit architectures are optional) build of the PostgreSQL libraries on a Mac OS X 10.6 machine. The command line I am using is as follows:

10.6 is intel only, so why do you even bother with PPC ?
 


--
GJ

Re: Build universal binary on Mac OS X 10.6?

From
Dave Page
Date:
2009/12/2 Grzegorz Jaśkiewicz <gryzman@gmail.com>:
>
>
> On Tue, Dec 1, 2009 at 11:43 PM, Israel Brewster <israel@frontierflying.com>
> wrote:
>>
>> I am trying to create a static, universal (x86 and ppc at least - 64 bit
>> architectures are optional) build of the PostgreSQL libraries on a Mac OS X
>> 10.6 machine. The command line I am using is as follows:
>
> 10.6 is intel only, so why do you even bother with PPC ?

10.6 supports building of PPC binaries (in theory at least) for use on
older OSs,

--
Dave Page
EnterpriseDB UK: http://www.enterprisedb.com

Re: Build universal binary on Mac OS X 10.6?

From
Israel Brewster
Date:
On Dec 2, 2009, at 1:03 AM, Dave Page wrote:

> 2009/12/2 Grzegorz Jaśkiewicz <gryzman@gmail.com>:
>>
>>
>> On Tue, Dec 1, 2009 at 11:43 PM, Israel Brewster <israel@frontierflying.com
>> >
>> wrote:
>>>
>>> I am trying to create a static, universal (x86 and ppc at least -
>>> 64 bit
>>> architectures are optional) build of the PostgreSQL libraries on a
>>> Mac OS X
>>> 10.6 machine. The command line I am using is as follows:
>>
>> 10.6 is intel only, so why do you even bother with PPC ?
>
> 10.6 supports building of PPC binaries (in theory at least) for use on
> older OSs,

Exactly. If I was building for my own personal use, I wouldn't bother
with PPC, or even i386 - i'd just go with x86_64. However, as I am
developing software for wide distribution, I want it to be able to run
on as many machines/OS's as possible.

That said, I did sort of get this to work. What I ended up doing was
building for each architecture separately (but on the same machine),
then using lipo to combine the resulting libraries. When I took all
but one architecture flag out of the configure string I used, it
worked- regardless of which architecture I left in. I haven't had a
chance to test this fully yet, but so far it seems to have worked -
lipo reports all three architectures (I didn't bother with ppc64), and
in the initial compile phase at least Qt is happy (still dealing with
other unrelated compile issues there). Apparently PostgreSQL will
happily build for any one of the platforms under Mac OS X 10.6, but
trying to build for multiple platforms at once gives it heartburn.
Given that, I tend to think there was something wrong with the way I
was trying to do it - something missing/wrong from the CFLAGS or
LDFLAGS or the like.

I'm somewhat curious though. I didn't have any difficulties making
universal builds of MySQL and SQLite by simply passing multiple -arch
flags to CFLAGS and LDFLAGS. It makes me wonder what PostgreSQL is
doing differently that causes problems? Thanks for the feedback and
advice!

>
> --
> Dave Page
> EnterpriseDB UK: http://www.enterprisedb.com
>
> --
> Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
> To make changes to your subscription:
> http://www.postgresql.org/mailpref/pgsql-general

-----------------------------------------------
Israel Brewster
Computer Support Technician II
Frontier Flying Service Inc.
5245 Airport Industrial Rd
Fairbanks, AK 99709
(907) 450-7250 x293
-----------------------------------------------




Attachment

Re: Build universal binary on Mac OS X 10.6?

From
Tom Lane
Date:
Israel Brewster <israel@frontierflying.com> writes:
> That said, I did sort of get this to work. What I ended up doing was
> building for each architecture separately (but on the same machine),
> then using lipo to combine the resulting libraries. When I took all
> but one architecture flag out of the configure string I used, it
> worked- regardless of which architecture I left in. I haven't had a
> chance to test this fully yet, but so far it seems to have worked -

The server executables will probably not work, except on the arch you
built on.  The client programs might accidentally fail to fail;
I'm not sure whether they contain any dependencies on the arch-specific
values that are extracted by configure.  You really need to create
pg_config.h contents that are correct for the specific arch you're
trying to compile for.  The last time I tried this, the only good way
to do that was by running configure on the particular architecture.
(Maybe 10.6 has got some cute way around that, but I doubt it.)

> I'm somewhat curious though. I didn't have any difficulties making
> universal builds of MySQL and SQLite by simply passing multiple -arch
> flags to CFLAGS and LDFLAGS.

Can't speak to SQLite, but I know quite well that mysql has got
essentially the same issues as PG with having arch-specific configure
output.  Have you actually tested those universal builds on any arch
except where you built them?

            regards, tom lane

Re: Build universal binary on Mac OS X 10.6?

From
Israel Brewster
Date:
On Dec 2, 2009, at 8:26 AM, Tom Lane wrote:

> Israel Brewster <israel@frontierflying.com> writes:
>> That said, I did sort of get this to work. What I ended up doing was
>> building for each architecture separately (but on the same machine),
>> then using lipo to combine the resulting libraries. When I took all
>> but one architecture flag out of the configure string I used, it
>> worked- regardless of which architecture I left in. I haven't had a
>> chance to test this fully yet, but so far it seems to have worked -
>
> The server executables will probably not work, except on the arch you
> built on.  The client programs might accidentally fail to fail;
> I'm not sure whether they contain any dependencies on the arch-
> specific
> values that are extracted by configure.  You really need to create
> pg_config.h contents that are correct for the specific arch you're
> trying to compile for.  The last time I tried this, the only good way
> to do that was by running configure on the particular architecture.
> (Maybe 10.6 has got some cute way around that, but I doubt it.)
>
>> I'm somewhat curious though. I didn't have any difficulties making
>> universal builds of MySQL and SQLite by simply passing multiple -arch
>> flags to CFLAGS and LDFLAGS.
>
> Can't speak to SQLite, but I know quite well that mysql has got
> essentially the same issues as PG with having arch-specific configure
> output.  Have you actually tested those universal builds on any arch
> except where you built them?

Well, I'm not trying to use the server or client programs from this
build - I just want the universal libraries for my programs. My point
in this last section, however, doesn't necessarily extend as far as
actual function, but rather is just with the build. MySQL and SQLite
build for multiple architectures quite happily, Postgres doesn't build
at all except for single architectures (the way I am trying at least).
Granted, it's entirely possible that the server/client built by MySQL
doesn't work on other platforms, but the build does - thus my curiosity.

FWIW, I have tested a program of mine linked against the multi-
architecture builds of the MySQL and SQLite libraries on other
platforms, and they do work. But then, I didn't need to do any fancy
work with multiple builds and lipo with them. Actually, back when I
was on Mac OS 10.5 I managed to get a universal build of Postgres 8.2
that worked - there's an old thread of mine from when I was having
problems with that as well. But I'm trying to get updated here, and
seem to be running into all new problems :-)

>
>             regards, tom lane

-----------------------------------------------
Israel Brewster
Computer Support Technician II
Frontier Flying Service Inc.
5245 Airport Industrial Rd
Fairbanks, AK 99709
(907) 450-7250 x293
-----------------------------------------------




Attachment

Re: Build universal binary on Mac OS X 10.6?

From
Tom Lane
Date:
Israel Brewster <israel@frontierflying.com> writes:
> Well, I'm not trying to use the server or client programs from this
> build - I just want the universal libraries for my programs. My point
> in this last section, however, doesn't necessarily extend as far as
> actual function, but rather is just with the build. MySQL and SQLite
> build for multiple architectures quite happily, Postgres doesn't build
> at all except for single architectures (the way I am trying at least).

Well, it's been done.  Searching the PG archives for prior discussions
I find
http://archives.postgresql.org/pgsql-hackers/2008-07/msg00884.php
which describes success with multiple -arch flags in CFLAGS plus
hand creation of relevant .h files.  The first few steps in the
older recipe here
http://archives.postgresql.org/pgsql-general/2008-02/msg00200.php
show a reasonably plausible way to mechanically generate the required
.h files, although I wonder whether it's right in detail --- over here
http://archives.postgresql.org/pgsql-hackers/2008-07/msg00898.php
I had found out that you also need --host if you want to fool configure
into generating .h files for a different architecture.  On the whole
I'd still recommend building the reference .h files on the actual target
arch rather than trusting cross-compile to create them correctly.

            regards, tom lane

Re: Build universal binary on Mac OS X 10.6?

From
Israel Brewster
Date:
On Dec 2, 2009, at 5:16 PM, Tom Lane wrote:

> Israel Brewster <israel@frontierflying.com> writes:
>> Well, I'm not trying to use the server or client programs from this
>> build - I just want the universal libraries for my programs. My point
>> in this last section, however, doesn't necessarily extend as far as
>> actual function, but rather is just with the build. MySQL and SQLite
>> build for multiple architectures quite happily, Postgres doesn't
>> build
>> at all except for single architectures (the way I am trying at
>> least).
>
> Well, it's been done.

On 10.5. By myself among others. Thus the reason I think there is
something wrong about the way I am going about this, and thus my
question to this list. If I didn't think it was possible, I wouldn't
bother asking how to do it :-)

> Searching the PG archives for prior discussions
> I find
> http://archives.postgresql.org/pgsql-hackers/2008-07/msg00884.php
> which describes success with multiple -arch flags in CFLAGS plus
> hand creation of relevant .h files.

Thanks for the link. It explains why I wasn't finding anything in my
searches - I was searching for "OS X", while the post references
"Darwin". I'll keep that distinction in mind in the future - may help
me solve my problems on my own, without needing outside help :-) That
said, the post hilights a few  points:

1) From the second paragraph of that post:
> If you add something like "-arch i386 -arch ppc" to CFLAGS and build
> normally, you get real working multiarch binaries and libraries.
Which is exactly the problem that started this whole thread - on 10.6,
you DON'T (or at least I don't) get "real working multiarch binaries
and libraries". In fact, you don't get anything - the compile fails.
Already we see that this post does not address my issue in any form,
as it references a successful compile resulting in unusable binaries-
not a failed compile, which is what I am dealing with.

The post goes on to say that "if you only do that, only the arch you
build on will work", but as I have already pointed out, I don't care -
I just need the libraries. My app already runs fine on multiple
platforms, I just need the multi-arch libraries to link against. From
a Mac OS X 10.6 build machine - I already have it working just fine on
a 10.5 build machine (with no header hacking), albeit with Postgres 8.2.

2) The post explains quite elegantly my point about Postgres being
more difficult to create a universal binary with than other programs.
I have compiled Qt, MySQL, SQLite, and several of my own programs for
all four architectures, and never once needed to hack around with
header files to get it to work. See, for example, this: <
http://www.malisphoto.com/tips/mysql-on-os-x.html#Anchor-Build 
  >. A Single configure command, with the right arguments, creates a 4-
way universal binary of MySQL on Mac OS X.

That said, this really isn't an issue for me - I mean, it's not like
I'm rebuilding Postgres every day or anything, so If I need to hack
around with headers or whatever to get the build to work, that's fine.
However, see point 1 - apparently the headers aren't the issue,
because according to the posts you linked, incorrect headers result in
non-functioning binaries, NOT in a failed build (it explicitly said
the build itself worked).

> [snip] On the whole
> I'd still recommend building the reference .h files on the actual
> target
> arch rather than trusting cross-compile to create them correctly.

If I was simply trying to build the Postgres server and/or client to
run on my machines, I would agree. However, as that is not what I am
doing (I'm not using the client or server portions of the build at
all) this is simply not an option, for two reasons. First, it would
require that I have four different machines to build on: ppc 32 and 64
bit, and Intel 32 and 64 bit. I could probably get away with two (ppc
and intel 32 bit) but regardless it would still require multiple build
machines, and that will never happen.

Secondly, even if I had the machines, it wouldn't help me achieve what
I need - a single, universal binary build of my application that can
run on as many Mac OS X machines as possible. There is no way I am
going to be distributing different binaries of my application for
different machine architectures. That might be fine for your average
Linux/Unix user, perhaps even for your average PosgreSQL database
admin- but not for the general public  to whom my app is targeted.
Most of my target audience is going to go "machine type? I dunno...
it's a mac". So I need to distribute an application that will run on a
"mac" regardless of what chip is inside. For that, I need a single,
universal, build of the Postgres libraries. Doing multiple builds on
multiple machines is, quite simply, not an option.

I thank you for the time you have taken trying to explain this to me,
and I apologize if I am being dense or stubborn. I'm not trying to be
difficult, it just feels to me that your posts don't address my issue,
that of a failed compile on 10.6. Rather, it feels like you are stuck
on the fact that the generated binaries won't work on other platforms,
which as I stated I don't care about. Again, I apologize if I am
missing your point or being a nusance - I don't want to be difficult,
I just want to get this working. Thanks for your time and patience.

>             regards, tom lane

-----------------------------------------------
Israel Brewster
Computer Support Technician II
Frontier Flying Service Inc.
5245 Airport Industrial Rd
Fairbanks, AK 99709
(907) 450-7250 x293
-----------------------------------------------




Attachment

Re: Build universal binary on Mac OS X 10.6?

From
Tom Lane
Date:
Israel Brewster <israel@frontierflying.com> writes:
> 1) From the second paragraph of that post:
>> If you add something like "-arch i386 -arch ppc" to CFLAGS and build
>> normally, you get real working multiarch binaries and libraries.
> Which is exactly the problem that started this whole thread - on 10.6,
> you DON'T (or at least I don't) get "real working multiarch binaries
> and libraries". In fact, you don't get anything - the compile fails.
> Already we see that this post does not address my issue in any form,

The reason it's failing is that you continue to ignore the important
point: you need arch-specific header files.

I tried this on current sources and found that the failure occurs in
code like this:

#if SIZEOF_DATUM == 8
...
        switch (attlen) \
        { \
            case sizeof(char): \
                ...
            case sizeof(int16): \
                ...
            case sizeof(int32): \
                ...
            case sizeof(Datum): \
                ...
...
#else                            /* SIZEOF_DATUM != 8 */

Since I configured on a 64-bit Mac, the generated header file
sets SIZEOF_DATUM to 8.  When this code is fed to the 32-bit
compiler, it thinks sizeof(Datum) is 4, so it spits up on the
duplicated case values.  Had it been fed the correct header file for
a 32-bit machine, it would have gone to the other part of the #if
(which doesn't have the intended-to-be-for-8-bytes case branch).

I don't really recall whether I hit this in the experiment I did
last year.  It's possible, maybe even likely, that the code was
different then and happened not to have any compiler-visible
inconsistencies when the header was wrong for the target arch.
That doesn't change the fact that it'd fail at runtime whether
the compiler could detect a problem or not.

There's really no way around building the correct header files
if you want a usable multiarch library.

            regards, tom lane

Re: Build universal binary on Mac OS X 10.6?

From
Israel Brewster
Date:
On Dec 3, 2009, at 10:54 AM, Tom Lane wrote:

> Israel Brewster <israel@frontierflying.com> writes:
>> 1) From the second paragraph of that post:
>>> If you add something like "-arch i386 -arch ppc" to CFLAGS and build
>>> normally, you get real working multiarch binaries and libraries.
>> Which is exactly the problem that started this whole thread - on
>> 10.6,
>> you DON'T (or at least I don't) get "real working multiarch binaries
>> and libraries". In fact, you don't get anything - the compile fails.
>> Already we see that this post does not address my issue in any form,
>
> The reason it's failing is that you continue to ignore the important
> point: you need arch-specific header files.

So it WAS just me being dense. Figures :P Your explanation makes
perfect sense now, thanks. Although in my defense, everything that I
read up till now implied that the compile should work, it would just
be the generated binaries that wouldn't (how else do you interpret
that quite I included?). However with your explanation, it makes sense
why the compile would fail. Again, my apologies.

So what it boils down to, if I now understand you correctly, is that
(since you obviously can only have one set of headers per build) the
only way to make this work is pretty much exactly what I ended up
doing: build for each architecture separately (even  if on the same
machine) and then lipo the results together. I can live with that.

Then the reason this is necessary on Postgres, and not with other
software I have dealt with is that Postgres has 64 bit specific code,
while the others don't? I know my code doesn't. Or maybe I was just
doing 32 bit builds of the others, and so never ran into this sort of
thing. Hmm. Oh well, it works. My profuse thanks for the explanations
and bearing with me.

> I don't really recall whether I hit this in the experiment I did
> last year.  It's possible, maybe even likely, that the code was
> different then and happened not to have any compiler-visible
> inconsistencies when the header was wrong for the target arch.

Or perhaps the 10.6 compiler has better error checking than the 10.5?
That would explain why the build would succeed on 10.5 (but give
unusable binaries for other platforms) but die on 10.6.

> That doesn't change the fact that it'd fail at runtime whether
> the compiler could detect a problem or not.

Well, the libraries I created in the past from the 8.2 code work just
fine on both PPC 32 bit and Intel 64 bit. But then, that was 8.2. The
code probably changed between 8.2 and 8.4 though :-D. Thanks again!

>
> There's really no way around building the correct header files
> if you want a usable multiarch library.
>
>             regards, tom lane

-----------------------------------------------
Israel Brewster
Computer Support Technician II
Frontier Flying Service Inc.
5245 Airport Industrial Rd
Fairbanks, AK 99709
(907) 450-7250 x293
-----------------------------------------------




Attachment

Re: Build universal binary on Mac OS X 10.6?

From
Tom Lane
Date:
Israel Brewster <israel@frontierflying.com> writes:
> So what it boils down to, if I now understand you correctly, is that
> (since you obviously can only have one set of headers per build) the
> only way to make this work is pretty much exactly what I ended up
> doing: build for each architecture separately (even  if on the same
> machine) and then lipo the results together. I can live with that.

You can, but you don't have to.  The alternative is to generate the
machine-specific headers, set them up to be pulled in with #ifdefs,
and then do one compile run with multiple -arch switches.  This does
not work for pre-8.4 PG sources but does with 8.4.  The one post
I pointed you to shows a script for setting up the headers that way.
(It also talks about using lipo because it predated 8.4, but you
can skip that part of the recipe.)

> Then the reason this is necessary on Postgres, and not with other
> software I have dealt with is that Postgres has 64 bit specific code,
> while the others don't?

The others are just accidentally failing to fail at the build stage.
I'm still pretty suspicious about whether the executables actually
work on arches other than where you built.  I am one hundred percent
certain that MySQL has arch-dependent headers just like we do (because
I have to cope with them when I build Red Hat's mysql packages).  It's
possible that SQLite manages to avoid generating any arch-specific
source code during its build process, but I rather doubt it.

Given that you only care about client libraries and not servers, it
might be that the breakage doesn't really affect you --- the server
side is much more likely to need the sort of tricks that lead to
generating arch-dependent headers.  But I wouldn't trust them an
inch unless I'd tested them pretty thoroughly.  It would be much
safer to build with correct headers.

>> I don't really recall whether I hit this in the experiment I did
>> last year.  It's possible, maybe even likely, that the code was
>> different then and happened not to have any compiler-visible
>> inconsistencies when the header was wrong for the target arch.

> Or perhaps the 10.6 compiler has better error checking than the 10.5?

Actually, I think I know what the difference is: 10.5 didn't have any
support for x86_64 did it?  If configure was generating declarations for
32-bit, at least the one particular bit of code we looked at would have
compiled happily on either word size --- and then failed at runtime on
64-bit because it was missing a needed case branch.  But again, I think
that's server-only code.

            regards, tom lane

Re: Build universal binary on Mac OS X 10.6?

From
Dave Page
Date:
On Thu, Dec 3, 2009 at 8:39 PM, Israel Brewster
<israel@frontierflying.com> wrote:
>
> Well, the libraries I created in the past from the 8.2 code work just fine
> on both PPC 32 bit and Intel 64 bit. But then, that was 8.2. The code
> probably changed between 8.2 and 8.4 though :-D. Thanks again!

When I was first writing the build script that Tom referenced earlier,
I too made the mistake of not creating arch-specific config headers. I
found that the build worked fine, and even initdb ran and I could
start the server and login. pgAdmin then promptly fell over because it
tried to use a view which had been mis-compiled (in postgres, not by
gcc) as it was treating my ppc box as a little-endian platform. Of
course, the build worked fine on an intel box.

So it's entirely possible that libpq may be working OK, whilst the
server is broken horribly.

--
Dave Page
EnterpriseDB UK: http://www.enterprisedb.com