#!/bin/bash # Copyright 2014 Wolfgang Thaller. # # This file is part of Retro68. # # Retro68 is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Retro68 is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Retro68. If not, see . shopt -s nullglob function locateInterfaceThing() { local varname=$1 local name=$2 printf "Searching for %-25s" "$name..." local found=`find -L "$INTERFACES_DIR"/ -name ".*" -prune -o -name $name -print` if [ -n "$found" ]; then eval "$varname=\$found" echo ${found#$INTERFACES_DIR/} return 0 # success else echo "NOT FOUND" return 1 # failure fi } function explainInterfaces() { if [ "$INTERFACES_KIND" = "multiversal" ]; then echo "Apple's Universal Interfaces & Libraries will not be installed." echo "Continuing with the open-source Multiversal Interfaces." echo return fi echo "===============================================================================" if [ -z "$INTERFACES_KIND" ]; then echo "If you want to use Apple's Universal Interfaces & Libraries " echo "rather than the open-source Multiversal Interfaces, get a copy of" echo "version 3.x, and place it in the InterfacesAndLibraries directory inside" echo "the Retro68 source directory." else echo "Please get a copy of Apple's Universal Interfaces & Libraries, " echo "version 3.x, and place it in the InterfacesAndLibraries directory inside" echo "the Retro68 source directory." fi echo echo "The exact directory layout does not matter, but there has to be" echo " - a directory with C header files (usually \"CIncludes\")" echo " - a directory with Rez header files (usually \"RIncludes\")" echo " - (for 68K) a directory containing Interface.o (usually \"Libraries\")" echo " - (for PPC) a directory containing InterfaceLib (usually \"SharedLibraries\")" echo " - (for Carbon) Carbon.h and CarbonLib, in the same directories" echo echo "The Interfaces&Libraries folder from Apple's last MPW release (MPW 3.5 " echo "aka MPW GM 'Golden Master') is known to work." if [ -z "$INTERFACES_KIND" ]; then INTERFACES_KIND=multiversal echo echo "Continuing with the open-source Multiversal Interfaces." echo "===============================================================================" echo else echo "===============================================================================" exit 1 fi } function locateAndCheckInterfacesAndLibraries() { echo "Looking for various files in $INTERFACES_DIR/..." if locateInterfaceThing CONDITIONALMACROS_H ConditionalMacros.h; then CINCLUDES=`dirname "$CONDITIONALMACROS_H"` else echo "Could not find ConditionalMacros.h anywhere inside $INTERFACES_DIR" echo explainInterfaces return fi if locateInterfaceThing CONDITIONALMACROS_R ConditionalMacros.r; then RINCLUDES=`dirname "$CONDITIONALMACROS_R"` else echo "Could not find ConditionalMacros.r anywhere inside $INTERFACES_DIR" echo explainInterfaces return fi if [ $BUILD_68K != false ]; then if locateInterfaceThing INTERFACE_O Interface.o; then M68KLIBRARIES=`dirname "$INTERFACE_O"` elif locateInterfaceThing INTERFACELIB_68K libInterface.a; then M68KLIBRARIES=`dirname "$INTERFACELIB_68K"` else echo "Could not find Interface.o anywhere inside $INTERFACES_DIR" echo "(This file is required for 68K support only)" echo explainInterfaces return fi fi if [ $BUILD_PPC != false ]; then if locateInterfaceThing INTERFACELIB InterfaceLib; then SHAREDLIBRARIES=`dirname "$INTERFACELIB"` else SHAREDLIBRARIES="" echo "Could not find InterfaceLib, using included import libraries." fi if locateInterfaceThing OPENTRANSPORTAPPPPC OpenTransportAppPPC.o; then PPCLIBRARIES=`dirname "$OPENTRANSPORTAPPPPC"` else echo "Could not find OpenTransportAppPPC.o anywhere inside $INTERFACES_DIR" echo "(This file is required for OpenTransport on PPC only)" fi fi if [ $BUILD_CARBON != false ]; then if locateInterfaceThing CARBON_H Carbon.h; then carbondir=`dirname "$CARBON_H"` if [ "$carbondir" != "$CINCLUDES" ]; then echo "Carbon.h found, but not in the same directory as ConditionalMacros.h." echo "This is confusing." echo explainInterfaces return fi else echo "Could not find Carbon.h anywhere inside $INTERFACES_DIR" echo "(This file is required for Carbon support only)" echo explainInterfaces return fi if locateInterfaceThing CARBONLIB CarbonLib; then carbondir=`dirname "$CARBONLIB"` if [ "$carbondir" != "$SHAREDLIBRARIES" ]; then echo "CarbonLib found, but not in the same directory as InterfaceLib." echo "This is confusing." echo explainInterfaces return fi else echo "Could not find CarbonLib anywhere inside $INTERFACES_DIR" echo "(This file is required for Carbon support only)" echo explainInterfaces return fi fi if [ -z "$INTERFACES_KIND" ]; then INTERFACES_KIND=universal fi } function linkThings() { FROM="$1" TO="$2" PATTERN="$3" mkdir -p "$TO" (cd "$TO" && find "$FROM" -name "$PATTERN" -exec ln -s {} . \;) } function removeConflictingHeaders() { # On case-insensitive file systems, there will be some conflicts with # newlib. For now, universal interfaces get the right of way. rm -f "$1/Threads.h" # threads.h: does not currently work anyways rm -f "$1/Memory.h" # memory.h: non-standard aliasof string.h cp "$1/strings.h" "$1/bsdstrings.h" rm -f "$1/Strings.h" # strings.h: traditional bsd string functions } function unlinkThings() { for file in "$1/"*; do if [[ `readlink "$file"` == $2/* ]]; then rm "$file" fi done } function linkInterfacesAndLibraries() { linkThings "../$1/RIncludes" "$PREFIX/RIncludes" "*.r" if [ $BUILD_68K != false ]; then ln -sf ../RIncludes "$PREFIX/m68k-apple-macos/RIncludes" removeConflictingHeaders "$PREFIX/m68k-apple-macos/include" linkThings "../../$1/CIncludes" "$PREFIX/m68k-apple-macos/include" "*.h" linkThings "../../$1/lib68k" "$PREFIX/m68k-apple-macos/lib" "*.a" fi if [ $BUILD_PPC != false ]; then ln -sf ../RIncludes "$PREFIX/powerpc-apple-macos/RIncludes" removeConflictingHeaders "$PREFIX/powerpc-apple-macos/include" linkThings "../../$1/CIncludes" "$PREFIX/powerpc-apple-macos/include" "*.h" linkThings "../../$1/libppc" "$PREFIX/powerpc-apple-macos/lib" "*.a" fi } function unlinkInterfacesAndLibraries() { unlinkThings "$PREFIX/RIncludes" "../*/RIncludes" unlinkThings "$PREFIX/m68k-apple-macos/include" "../../*/CIncludes" unlinkThings "$PREFIX/powerpc-apple-macos/include" "../../*/CIncludes" unlinkThings "$PREFIX/m68k-apple-macos/lib" "../../*/lib68k" unlinkThings "$PREFIX/powerpc-apple-macos/lib" "../../*/libppc" rm -f "$PREFIX/m68k-apple-macos/RIncludes" rm -f "$PREFIX/powerpc-apple-macos/RIncludes" } function setup68KLibraries() { DEST=${1:-"$PREFIX/universal"} echo "Converting 68K static libraries..." mkdir -p "$DEST/lib68k" for macobj in "${M68KLIBRARIES}/"*.o; do if [ -r "$macobj" ]; then libname=`basename "$macobj"` libname=${libname%.o} printf " %30s => %-30s\n" ${libname}.o lib${libname}.a asm="$DEST/lib68k/$libname.s" obj="$DEST/lib68k/$libname.o" lib="$DEST/lib68k/lib${libname}.a" rm -f $lib if ConvertObj "$macobj" > "$asm"; then m68k-apple-macos-as "$asm" -o "$obj" m68k-apple-macos-ar cqs "$lib" "$obj" fi rm -f "$asm" fi done } function setupPPCLibraries() { DEST=${1:-"$PREFIX/universal"} mkdir -p "$DEST/libppc" case `ResInfo -n "$INTERFACELIB" 2> /dev/null || echo 0` in 0) if [ -n "$INTERFACELIB" ]; then echo "WARNING: Couldn't read resource fork for \"$INTERFACELIB\"." echo " Falling back to included import libraries." fi echo "Copying readymade PowerPC import libraries..." cp $PREFIX/multiversal/libppc/*.a $DEST/libppc/ ;; *) echo "Building PowerPC import libraries..." for shlib in "${SHAREDLIBRARIES}/"*; do libname=`basename "$shlib"` implib=lib${libname%.bin}.a printf " %30s => %-30s\n" ${libname} ${implib} MakeImport "$shlib" "$DEST/libppc/$implib" || true done ;; esac if [ -d "${PPCLIBRARIES}" ]; then echo "Copying static PPC libraries" for obj in "${PPCLIBRARIES}/"OpenT*.o "${PPCLIBRARIES}/CarbonAccessors.o" "${PPCLIBRARIES}/CursorDevicesGlue.o"; do if [ -r "$obj" ]; then # copy the library: cp "$obj" "$DEST/libppc/" basename=`basename "${obj%.o}"` # and wrap it in a .a archive for convenience lib="$DEST"/libppc/lib$basename.a rm -f "$lib" powerpc-apple-macos-ar cqs "$lib" "$obj" fi done fi } function setUpInterfacesAndLibraries() { DEST=${1:-"$PREFIX/universal"} rm -rf "$DEST" mkdir "$DEST" echo "Preparing CIncludes..." mkdir "$DEST/CIncludes" sh "$SRC/prepare-headers.sh" "$CINCLUDES" "$DEST/CIncludes" echo "Preparing RIncludes..." mkdir "$DEST/RIncludes" sh "$SRC/prepare-rincludes.sh" "$RINCLUDES" "$DEST/RIncludes" if [ $BUILD_68K != false ]; then setup68KLibraries "$DEST" fi if [ $BUILD_PPC != false ]; then setupPPCLibraries "$DEST" fi } function removeInterfacesAndLibraries() { unlinkInterfacesAndLibraries rm -rf "$PREFIX/universal" } if (return 0 2>/dev/null); then # We are being sourced from build-toolchain.sh true else # We are being run directly if [ $# -lt 2 ]; then echo "Usage: $0 /install/path /path/to/InterfacesAndLibraries" echo " $0 /install/path --remove" exit 1 fi PREFIX="$1" INTERFACES_DIR="$2" BUILD_68K=${3:-true} BUILD_PPC=${4:-true} BUILD_CARBON=${5:-true} SRC=$(cd `dirname $0` && pwd -P) export PATH="$PREFIX/bin:$PATH" if [ "${INTERFACES_DIR}" = "--remove" ]; then removeInterfacesAndLibraries elif [ "${INTERFACES_DIR}" = "--unlink" ]; then unlinkInterfacesAndLibraries elif [ "${INTERFACES_DIR}" = "--multiversal" ]; then unlinkInterfacesAndLibraries linkInterfacesAndLibraries "multiversal" elif [ "${INTERFACES_DIR}" = "--universal" ]; then unlinkInterfacesAndLibraries linkInterfacesAndLibraries "universal" else INTERFACES_KIND=universal locateAndCheckInterfacesAndLibraries removeInterfacesAndLibraries setUpInterfacesAndLibraries linkInterfacesAndLibraries "universal" fi fi