Cross-compiling LLVM on Mac OS X

Hello,

I’ve spent the past day or so attempting to get LLVM’s libraries built as a Mac OS X-style universal binary, the first step of which is to get them built for each component architecture (i386, x86_64, ppc, and ppc64).

The first two are straightforward as I am working on an x86_64 Mac (running Mac OS X 10.6, which corresponds to Darwin 10), but building ppc binaries has thus far eluded me. My attempts have been made with 2.6 and trunk with identical results.

I have been using this command to configure it:

./configure --enable-optimized --enable-jit --build=x86_64-apple-darwin10 --host=powerpc-apple-darwin10

(Note that using darwin9 or just darwin doesn’t change matters.)

The configuration succeeds (up to a point—see below), and then I make it (using the system’s included make command, which apparently is GNU Make 3.81). make fails immediately with this message:

configure: error: Already configured in /Users/rob/Developer/External/llvm-trunk
make[1]: *** No targets specified and no makefile found. Stop.
make: *** [cross-compile-build-tools] Error 1

Looking at the cross-compile-build-tools rule in the Makefile, I see that it checks for a Makefile in the BuildTools directory, and if there is none, it goes in there and runs the source directory’s configure script—at which point the configure script errors because it was already configured in the source directory.

I’m assuming I must be doing something wrong with the configuration, but I don’t know enough about make in general and llvm’s build system specifically to comment on whether the cross-compile-build-tools rule might be broken.

Thank you in advance for any light you can shed on this issue!

Sincerely,
Rob

P.S. One extra fly in the ointment is that I’m building against the Mac OS X 10.5 SDK on a 10.6 machine, to accomplish which I am setting CFLAGS to -isysroot /Developer/SDKs/MacOSX10.5.sdk -mmacosx-version-min=10.5. Omitting this doesn’t change the result, however.

Rob Rix <rob@monochromeindustries.com> writes:

[snip]

If your problem persists, maybe CMake can do the job:

http://www.llvm.org/docs/CMake.html

configure: error: Already configured in /Users/rob/Developer/External/llvm-trunk
make[1]: *** No targets specified and no makefile found. Stop.
make: *** [cross-compile-build-tools] Error 1

You're going to need multiple configures and multiple build directories to do it that way. You may want to try just setting your CXXFLAGS to "-arch i386 -arch ppc -arch x86_64" or something.

Out of curiosity, why are you trying to build ToT 3-way FAT for OSX? It's already built like that on the system.

-eric

(My apologies for the double e-mail, Eric; I neglected to reply to the list.)

configure: error: Already configured in /Users/rob/Developer/External/llvm-trunk
make[1]: *** No targets specified and no makefile found. Stop.
make: *** [cross-compile-build-tools] Error 1

You're going to need multiple configures and multiple build directories to do it that way. You may want to try just setting your CXXFLAGS to "-arch i386 -arch ppc -arch x86_64" or something.

I’m actually doing that presently with CFLAGS, but hadn’t considered the necessity of doing it with CXXFLAGS as well. Thank you!

Out of curiosity, why are you trying to build ToT 3-way FAT for OSX? It's already built like that on the system.

I wasn’t aware of that. Are you referring to libLLVMCore.a & friends, or LLVM GCC? I wasn’t able to find the libraries in question in /usr/lib, /Developer, /System, or anywhere else I looked and searched. I am building a universal framework which needs to embed these libraries.

Thanks very much,
Rob

You may also want to search for 'ifdef UNIVERSAL' in Makefile.rules,
there is some builtin support in the Makefile for this.

- Daniel

configure really doesn't know about it. It's still the target architecture. You'll just be adding more.

Let the build go and see where you get. Also, you need more than a single -arch flag. As I said before -arch ppc -arch i386 -arch x86_64.

Daniel's comments are also good.

-eric

The configure script’s output says, near the top:

checking target architecture... x86_64

So it seems that the Makefile is preferring the configure script’s reckoning to the CFLAGS/CXXFLAGS variables at present.

configure really doesn't know about it. It's still the target architecture. You'll just be adding more.

Let the build go and see where you get. Also, you need more than a single -arch flag. As I said before -arch ppc -arch i386 -arch x86_64.

This results in x86_64 binaries only, unfortunately. However…

Daniel's comments are also good.

…success!

export UNIVERSAL=true
export UNIVERSAL_ARCH="i386 x86_64 ppc ppc64"
export UNIVERSAL_SDK_PATH=/Developer/SDKs/MacOSX10.5.sdk/
export CFLAGS="-mmacosx-version-min=10.5"
export CXXFLAGS="-mmacosx-version-min=10.5"

./configure --enable-optimized --enable-jit --enable-targets=x86,x86_64,powerpc
make libs-only

I suspect the problem with my earlier attempts was that I was exporting the environment variables in question to configure, but not to make. Regardless, this is nicely intention-revealing and very easy.

Thanks very much for your help, everyone; if no one objects, I will make a page on the LLVM wiki about fat builds for OS X.

Sincerely,
Rob

Daniel's comments are also good.

…success!

Looks like I spoke a bit too soon. Everything works as far as the fat binaries are concerned, except that -mmacosx-version-min is set to the host’s OS version, not that of the SDK, causing errors when it tries to link against 10.6’s versions of libraries instead of 10.5’s.

This patch appears to solve that; it uses the OS version from the SDK path for -mmacosx-version-min if UNIVERSAL_SDK_PATH is specified.

Makefile.rules.patch (1.04 KB)

Sorry to resurrect an ancient thread, but...

For our application we need to build llvm libraries on OSX as universal ppc/i386 binaries, against the 10.4 SDK, using the 2.6 stable release of LLVM.

I've followed the comments that people have made previously, including Rob Rix's makefile patch and the following command line incantations, but the build is failing:

#configure:
sudo make clean
export MACOSX_DEPLOYMENT_TARGET=10.4
export UNIVERSAL=true
export UNIVERSAL_ARCH="i386 ppc"
export UNIVERSAL_SDK_PATH=/Developer/SDKs/MacOSX10.4u.sdk/
export CFLAGS="-mmacosx-version-min=10.4"
export CXXFLAGS="-mmacosx-version-min=10.4"
./configure --enable-optimized --enable-jit --enable-targets=x86,powerpc

# modifications to config.h for 10.4:
edit include/llvm/Config/config.h
# comment out HAVE_BACKTRACE 1
# comment out HAVE_EXECINFO_H 1

#make:
export MACOSX_DEPLOYMENT_TARGET=10.4
export UNIVERSAL=true
export UNIVERSAL_ARCH="i386 ppc"
export UNIVERSAL_SDK_PATH=/Developer/SDKs/MacOSX10.4u.sdk/
export CFLAGS="-mmacosx-version-min=10.4"
export CXXFLAGS="-mmacosx-version-min=10.4"
make libs-only

The error is as follows:

llvm[2]: Compiling TableGenBackend.cpp for Release build
g++ -I/Users/grahamwakefield/Source/llvm-2.6_ub/include -I/Users/grahamwakefield/Source/llvm-2.6_ub/utils/TableGen -D_DEBUG -D_GNU_SOURCE -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -O3 -fno-common -Woverloaded-virtual -mmacosx-version-min=10.4 -mmacosx-version-min=10.4 -pedantic -Wno-long-long -Wall -W -Wno-unused-parameter -Wwrite-strings -arch i386 -arch ppc -isysroot /Developer/SDKs/MacOSX10.4u.sdk/ -c TableGenBackend.cpp -o /Users/grahamwakefield/Source/llvm-2.6_ub/utils/TableGen/Release/TableGenBackend.o
llvm[2]: Linking Release executable tblgen (without symbols)
ld: library not found for -lffi
collect2: ld returned 1 exit status
ld: library not found for -lffi
collect2: ld returned 1 exit status
lipo: can't open input file: /var/folders/O+/O+BZljw+HB8GMWwKGSQWs++++TI/-Tmp-//cczAl73O.out (No such file or directory)
make[2]: *** [/Users/grahamwakefield/Source/llvm-2.6_ub/Release/bin/tblgen] Error 1
make[1]: *** [TableGen/.makeall] Error 2
make: *** [all] Error 1

I thought that it meant that I need a universal libffi, but the libffi.dylib I have in /usr/lib is a fat binary (according to file).

Any suggestions for what to try next would be very much appreciated!