1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
#!/bin/sh
# gcc-uni.sh
# ----------
# By Matthew Leverton
#
# Builds a universal binary by a multi-step process to allow for individual
# options for both architectures. Its primary use is to be used as a wrapper
# for makefile based projects.
#
# Although untested, it should be able to build OS X 10.2 compatible builds.
# Note that you may need to install the various OS SDKs before this will
# work. gcc-3.3 is used for the PPC build. The active version of gcc is used
# for the Intel build. (Note that it must be at least version 4.)
#
# If the makefile has a CC variable, this is all that should be necessary:
#
# CC=/usr/bin/gcc-uni.sh
#
# set up defaults
mode=link
output=
cmd=
# check whether to use gcc or g++
# (using a symlink with g++ in name is recommended)
case "$0" in
*g++*)
gcc=g++
;;
*)
gcc=gcc
;;
esac
# which OSX to target (used for PPC)
OSX_TARGET=10.2
# which SDK to use (unused with PPC because gcc-3.3 doesn't know about it))
SDK_i386=/Developer/SDKs/MacOSX10.4u.sdk
SDK_PPC=
# i386 flags
CFLAGS_i386=" -isysroot $SDK_i386"
LDFLAGS_i386=" -isysroot $SDK_i386 -Wl,-syslibroot,$SDK_i386"
# ppc flags
CFLAGS_PPC=
LDFLAGS_PPC=
# Parse options:
# -arch switches are ignored
# looks for -c to enable the CFLAGS
# looks for -o to determine the name of the output
if [ $# -eq 0 ]; then
echo "This is a wrapper around gcc that builds universal binaries."
echo "It can only be used to compile or link."
exit 1
fi
# remember the arguments in case there's no output files
args=$*
while [ -n "$1" ]; do
case "$1" in
-arch)
shift
;;
-c)
mode=compile
cmd="$cmd -c"
;;
-o)
shift
output="$1"
;;
*)
cmd="$cmd $1"
;;
esac
shift
done
# if no output file, just pass the original command as-is and hope for the best
if [ -z "$output" ]; then
exec $gcc $args
fi
# figure out if we are compiling or linking
case "$mode" in
link)
FLAGS_i386="$LDFLAGS_i386"
FLAGS_PPC="$LDFLAGS_PPC"
;;
compile)
FLAGS_i386="$CFLAGS_i386"
FLAGS_PPC="$CFLAGS_PPC"
;;
*)
echo "internal error in gcc-uni.sh script"
exit 1
;;
esac
# TODO: use trap to cleanup
# build the i386 version
$gcc $cmd $FLAGS_i386 -arch i386 -o $output.i386
if [ $? -ne 0 ]; then
exit 1
fi
# build the PPC version
MACOSX_DEPLOYMENT_TARGET=$OSX_TARGET /usr/bin/$gcc-3.3 $cmd $FLAGS_PPC -arch ppc -o $output.ppc
if [ $? -ne 0 ]; then
rm -f $output.i386
exit 1
fi
# create the universal version
lipo -create $output.i386 $output.ppc -output $output
if [ $? -ne 0 ]; then
rm -f $output.i386 $output.ppc
exit 1
fi
# cleanup
rm -f $output.i386 $output.ppc
|