#!/bin/sh # gcc_select [-n] [-force] [2 | 3 | 3.x | 4.x ] [-h | --help] [-v | --version] # [-l | --list] [-root] # # # Switch the default gcc to any of 2.x, 3.x, or 4.x. # # 2 Select gcc 2.95.2 as the default compiler. # 3 Select gcc 3.1 as the default compiler. # 3.x Select gcc 3.x as the default compiler. # 4.x Select gcc 4.x as the default compiler. # -force Ensure the links are correct for the specified version. # even if the one specified is the current version. # -h Display this help info. # --help Same as -h. # -n Show commands to do selection but do not execute them. # -root Skip 'root' check and assume you have root access. # -v Display gcc_select version number. # --version Same as -v. # -l Display available compiler versions. # --list Same as -l. # # This script will switch the current compiler installation around # among 2.x, 3.x, and 4.x (or echo the commands to do it if -n is used). # The current version is displayed if no arguments are specified. # # Note, for documentation completeness, there are three additional options. # # -dstroot dir Install the sym links in a /usr directory within the # specified dir or the dir itself if it specifies a usr # directory (e.g., /foo/bar/usr). -dstroot /usr is # allowed, in which case, the sytem is changed to the # requested compiler, i.e., the same effect as not # specifying it at all. # --wrap SCRIPT Forces all possible mechanisms for invoking the # compiler to be diverted from /usr/bin/NAME to # /usr/bin/NAME.real, and /usr/bin/NAME will become # a symbolic link to SCRIPT. Will fail if binaries # are already diverted. # --unwrap Restores diversions created by --wrap. # # These are special options NOT for general use. They are deliberately # omitted from the --help info. They are intended for internal build # procedures. # # Copyright Apple Computer, Inc. 2002, 2003, 2004, 2005 ####################################################################### GCC_SELECT_VERSION="2.14" ####################################################################### # List of headers in & underneath /usr/include that need to be symlinked # to a compiler-specific version. symlink_hdrs0="stdint.h" # List of libraries in /usr/lib and /usr/local/lib that need to be # symlinked to a compiler-specific version. symlink_libs="libcc_dynamic.a \ libcc_kext.a \ libgcc.a \ libcc.a \ libstdc++.a \ libsupc++.a" symlink_local_libs="libcc_noc++.a" # List of directories (underneath /usr) containing a 'default' # symlink that must be adjusted to correspond to the default compiler. default_dirs="include/gcc/darwin \ libexec/gcc/darwin/i386 \ libexec/gcc/darwin/ppc \ lib/gcc/darwin" ####################################################################### # ## gcc_select's main control function # switch_it() { local f who status argc=$# cwd="`/bin/pwd`" local n="\n`echo "usage: ${0##*/}" | sed -e 's/./ /g'`" local usage="${0##*/} [-n] [-force] [2 | 3 | 3.x | 4.x ] [-h | --help] [-v | --version]$n [-l | --list] [-root]" # # Collect the arguments... # dashn= switchto_cc=0 switchto_cc_driver=0 forced= list_versions= usr="/usr" installing= show_help= root= wrapper= unwrap=0 while [ $# -gt 0 ] ; do case $1 in 2* | -2* | 3* | -3* | 4.* | -4.* ) if [[ "$switchto_cc" != "0" && "$switchto_cc" != "$1" ]]; then echo -e "usage: $usage" echo " Inconsistent compiler versions specified." exit 1 fi switchto_cc=$1 shift ;; -force | --force) forced=1 shift ;; -l | -list | --list) list_versions=1 shift ;; -h | --help | -help | -\?) show_help=1 shift ;; -n) dashn="echo -e ""\040" shift ;; -dstroot | --dstroot) shift usr="`echo "$1" | sed -e 's,/$,,'`" if [ "${usr##*/}" != "usr" ]; then usr="$usr/usr" fi installing=1 shift ;; -wrap | --wrap) if [ $unwrap -ne 0 ]; then echo "Cannot specify both --wrap and --unwrap." exit 1 fi shift if [ -z "$1" ]; then cat < 3.3 ]; then $dashn rm -f $usr/lib/gcc/darwin/default $dashn rm -f $usr/lib/libcc_dynamic.a fi # Set up header symlinks... $dashn mkdir -p $usr/include for header in $symlink_hdrs0; do $dashn rm -f $usr/include/$header if [ -e /usr/include/gcc/darwin/default/$header ]; then $dashn ln -sf gcc/darwin/default/$header $usr/include/$header fi done # Set up man page symlinks... # NB: The crufty /usr/bin/cpp script utilizes the # /usr/libexec/gcc/darwin/{i386,ppc}/default/cpp binary to do its work. # Hence, it makes sense to symlink the cpp man page to the current compiler # default. $dashn mkdir -p $usr/share/man/man1 for manpage in c++ g++ gcc gcov cpp; do $dashn rm -f $usr/share/man/man1/$manpage.1 if [ -e /usr/share/man/man1/$manpage$switchto_cc_driver.1 ]; then $dashn ln -sf $manpage$switchto_cc_driver.1 $usr/share/man/man1/$manpage.1 fi done $dashn rm -rf $usr/share/man/man1/cc.1 if [ -e /usr/share/man/man1/gcc.1 ]; then $dashn ln -sf gcc.1 $usr/share/man/man1/cc.1 fi # # We determine which compiler is currently installed by looking at # the version number it displays when we do a cc -v... # if [ ! "$installing" ]; then if [ "$dashn" == "" ]; then actual_ver="`cc -v 2>&1 | grep -i 'gcc version'`" current_cc="`echo \"$actual_ver\" | sed -e 's/.*gcc version \([^ ]*\).*/\1/'`" if [[ ! "$current_cc" == 2* && ! "$current_cc" == 3* && ! "$current_cc" == 4* ]]; then echo "Error trying to determine current cc version (got $current_cc)" exit 1 fi echo "Default compiler has been set to:" echo "$actual_ver" fi else echo "$(basename $0): SYMLINKS UNDER '$usr'" echo "$(basename $0): NOW POINT AT gcc$switchto_cc_driver ($switchto_cc)" fi exit 0 } #---------------------------------------------------------------------# # ## show_list info1 info2 item1 ... - display a list of items ## ## This outputs an error message about a list of "bad" items. The ## format is: ## ## info1 ## info2 ## item1 ## - - - ## ## The info2 line is not output if it is null. # show_list() { local info1="$1" local info2="$2" shift 2 if [ ${#@} -gt 0 ]; then echo "$info1" if [ "$info2" != "" ]; then echo "$info2" fi for f; do echo " $f" done fi } ####################################################################### ### main() ############################################################ ####################################################################### os_version=$(sw_vers -productVersion | awk -F. '{ printf "%02d%02d%02d", $1, $2, $3 }') if [ $os_version -lt 100200 ]; then echo "You must be using MacOS X 10.2 (Jaguar) or later." exit 1 fi switch_it "$@"