Compiling as 32bit on MacOSX

G

Gregory Ewing

I'm getting my Python environment set up on a new
Snow Leopard machine, and I'd like to compile everything
in 32 bit mode for the time being, because some of the
extensions I need use APIs that aren't available in
64 bit.

Is there some environment variable or config setting
that will make gcc compile 32 bit binaries by default?
Setting CFLAGS isn't very reliable, since the build
systems of some libraries don't seem to take notice
of it.
 
J

Jason Swails

Try setting the compiler itself as "gcc -m32"

--
Jason Swails
Quantum Theory Project,
University of Florida
Ph.D. Graduate Student
352-392-4032
 
M

MRAB

I'm getting my Python environment set up on a new
Snow Leopard machine, and I'd like to compile everything
in 32 bit mode for the time being, because some of the
extensions I need use APIs that aren't available in
64 bit.

Is there some environment variable or config setting
that will make gcc compile 32 bit binaries by default?
Setting CFLAGS isn't very reliable, since the build
systems of some libraries don't seem to take notice
of it.
Not MacOSX, but might help:

http://www.cyberciti.biz/tips/compile-32bit-application-using-gcc-64-bit-linux.html
 
P

Philip Semanchuk

I'm getting my Python environment set up on a new
Snow Leopard machine, and I'd like to compile everything
in 32 bit mode for the time being, because some of the
extensions I need use APIs that aren't available in
64 bit.

Is there some environment variable or config setting
that will make gcc compile 32 bit binaries by default?
Setting CFLAGS isn't very reliable, since the build
systems of some libraries don't seem to take notice
of it.

Hi Greg,
Are you talking about compiling Python itself or extensions?
 
N

Ned Deily

I'm getting my Python environment set up on a new
Snow Leopard machine, and I'd like to compile everything
in 32 bit mode for the time being, because some of the
extensions I need use APIs that aren't available in
64 bit.

Is there some environment variable or config setting
that will make gcc compile 32 bit binaries by default?
Setting CFLAGS isn't very reliable, since the build
systems of some libraries don't seem to take notice
of it.

It varies. Projects that use one of the Apple-supplied gcc's (4.2 or
4.0) generally use the -arch parameter.

For Python itself on 10.6, there isn't a standard configure option to
build just for i386 (Intel 32-bit). The two easiest choices are to
either build for 32-bit only which results in a i386 and ppc universal
build:

../configure MACOSX_DEPLOYMENT_TARGET=10.6
--with-universal-archs="32-bit"
--enable-universalsdk=/Developer/SDKs/MacOSX10.6.sdk

or tweak the configure options a bit which *should* result in an
i386-only build (at least for 2.7 and 3.2):

../configure MACOSX_DEPLOYMENT_TARGET=10.6 CFLAGS="-arch i386"
LDFLAGS="-arch i386"

If you want backwards compatibility, add or change the sdk and
deployment target values ("10.5" "MacOSX10.5.sdk" or "10.4"
"MacOSX10.4u.sdk" along with GCC=/usr/bin/gcc-4.0). For a framework
build, throw in --enable-framework.

Distutils should ensure that the right settings will get passed on to
any extension module builds.
 
G

Gregory Ewing

Philip said:
Hi Greg,
Are you talking about compiling Python itself or extensions?

I've managed to get Python itself compiled as 32 bit,
and that also seems to take care of extensions built
using 'python setup.py ...'.

I'm mainly concerned about non-Python libraries that
get wrapped by the extensions, of which I've built up
quite a collection over the years. Currently I'm having
to keep a careful eye out when building them to make
sure they don't get compiled with the wrong architecture,
since gcc's natural inclination is to default to 64 bit
whenever it's available.

So I was wondering if there was some way of globally
changing that default that doesn't rely on compiler
options getting passed correctly through the many and
varied layers of build technology that one comes across.
But from what I've seen so far, it seems not.
 
G

Gregory Ewing

Jason said:
Try setting the compiler itself as "gcc -m32"

You mean by setting CC? That's a cunning plan -- I'll
give it a try.

On a related note, according to the man page for Apple's
gcc, you're supposed to be able to use both '-arch i386'
and '-arch x86_64' at the same time and get fat binaries.
That would actually be my preferred option, because then
I wouldn't have to go back and rebuild all my libraries
if I decide to switch to 64 bit in the future.

But I can't seem to get it to work -- it just uses the
last architecture specified. Has anyone successfully done
this? Is there some trick to it that I've missed?
 
D

Diez B. Roggisch

Gregory Ewing said:
I've managed to get Python itself compiled as 32 bit,
and that also seems to take care of extensions built
using 'python setup.py ...'.

I'm mainly concerned about non-Python libraries that
get wrapped by the extensions, of which I've built up
quite a collection over the years. Currently I'm having
to keep a careful eye out when building them to make
sure they don't get compiled with the wrong architecture,
since gcc's natural inclination is to default to 64 bit
whenever it's available.

So I was wondering if there was some way of globally
changing that default that doesn't rely on compiler
options getting passed correctly through the many and
varied layers of build technology that one comes across.
But from what I've seen so far, it seems not.

If all you have is a fat-binary, you can still work with that using the
lipo-tool to remove those architectures you are not interested in.

Diez
 
N

Ned Deily

On a related note, according to the man page for Apple's
gcc, you're supposed to be able to use both '-arch i386'
and '-arch x86_64' at the same time and get fat binaries.
That would actually be my preferred option, because then
I wouldn't have to go back and rebuild all my libraries
if I decide to switch to 64 bit in the future.

But I can't seem to get it to work -- it just uses the
last architecture specified. Has anyone successfully done
this? Is there some trick to it that I've missed?

You'll also need to specify the appropriate SDK using Apple's gcc
-sysroot option.
 
P

Philip Semanchuk

I've managed to get Python itself compiled as 32 bit,
and that also seems to take care of extensions built
using 'python setup.py ...'.

I'm mainly concerned about non-Python libraries that
get wrapped by the extensions, of which I've built up
quite a collection over the years. Currently I'm having
to keep a careful eye out when building them to make
sure they don't get compiled with the wrong architecture,
since gcc's natural inclination is to default to 64 bit
whenever it's available.

So I was wondering if there was some way of globally
changing that default that doesn't rely on compiler
options getting passed correctly through the many and
varied layers of build technology that one comes across.
But from what I've seen so far, it seems not.

If CFLAGS isn't doing the trick for you, then I don't know what to suggest. Maybe some libs also need LDFLAGS='-arch i386 -arch x86_64'?

FYI, the `file` command will give you information about whether or not a binary is 32-bit, 64-bit or both.

$ file shlib/libreadline.6.1.dylib
shlib/libreadline.6.1.dylib: Mach-O universal binary with 2 architectures
shlib/libreadline.6.1.dylib (for architecture i386): Mach-O dynamically linked shared library i386
shlib/libreadline.6.1.dylib (for architecture x86_64): Mach-O 64-bit dynamically linked shared library x86_64


Good luck
Philip
 
G

Gregory Ewing

Ned said:
You'll also need to specify the appropriate SDK using Apple's gcc
-sysroot option.

Are you sure? I'm not asking for ppc + i386, I'm
asking for i386 + x86_64. I can get either of these
individually without switching SDKs.
 
N

Ned Deily

Are you sure? I'm not asking for ppc + i386, I'm
asking for i386 + x86_64. I can get either of these
individually without switching SDKs.

Well, you'd need it if you want backward compatibility (with an older
ABI) but, no, you wouldn't need -sysroot just to produce i386 and x86_64
on a 64-bit capable machine running 10.6.

Getting back to your previous post: "But I can't seem to get it to work
-- it just uses the last architecture specified." Perhaps you're
calling ld(1) directly? To link multiple-arch executables (etc), the
Apple gcc driver does the dirty work of calling ld multiple times and
lipo-ing the results. See the Apple ld(1) man page.
 
G

Gregory Ewing

Ned said:
Perhaps you're
calling ld(1) directly? To link multiple-arch executables (etc), the
Apple gcc driver does the dirty work of calling ld multiple times and
lipo-ing the results.

Is this something that only works at link time, then? The
gcc man page says:

"Multiple options work, and
direct the compiler to produce "universal" binaries including
object code for each architecture specified with -arch."

From this I was hoping to be able to do

gcc -arch i386 -arch x86_64 -c foo.c

and get dual-architecture .o files that could then be linked
into dual-architecture libraries. But if I do the above, I
just get an x86_64 .o file.

Are you saying that I need to compile separate sets of .o
files and then combine them at link time? That sounds like
an awkward thing to retrofit onto a library's existing
build system.
 
N

Ned Deily

Gregory Ewing said:
Is this something that only works at link time, then? The
gcc man page says:

"Multiple options work, and
direct the compiler to produce "universal" binaries including
object code for each architecture specified with -arch."

From this I was hoping to be able to do

gcc -arch i386 -arch x86_64 -c foo.c

and get dual-architecture .o files that could then be linked
into dual-architecture libraries. But if I do the above, I
just get an x86_64 .o file.

Are you saying that I need to compile separate sets of .o
files and then combine them at link time? That sounds like
an awkward thing to retrofit onto a library's existing
build system.

No, it's supported both at compile and link time. Here's a compile on
10.6:

$ /usr/bin/gcc --version
i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5664)
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is
NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.

$ /usr/bin/gcc -arch i386 -arch x86_64 -c foo.c
$ file foo.o
foo.o: Mach-O universal binary with 2 architectures
foo.o (for architecture i386): Mach-O object i386
foo.o (for architecture x86_64): Mach-O 64-bit object x86_64

BTW, if, for some reason, you *do* need to extract a particular
architecture from a multi-arch file, you can use lipo to do it:

$ lipo foo.o -output foo_32.o -extract i386
$ lipo foo.o -output foo_64.o -extract x86_64
$ file foo_32.o
foo_32.o: Mach-O universal binary with 1 architecture
foo_32.o (for architecture i386): Mach-O object i386
$ file foo_64.o
foo_64.o: Mach-O universal binary with 1 architecture
foo_64.o (for architecture x86_64): Mach-O 64-bit object x86_64
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,186
Members
46,743
Latest member
WoodrowMea

Latest Threads

Top