Guido van Rossum | 060f24c | 1998-12-18 15:37:14 +0000 | [diff] [blame^] | 1 | #! /bin/sh |
| 2 | # |
| 3 | # Fake "ar" to build the Python shared library on BeOS. This "ar" |
| 4 | # manipulates a .ar-libname file listing all the objects and regenerates |
| 5 | # the shared lib every time it's called. This is probably only suitable |
| 6 | # for things that get built like Python, and you'll probably have to make |
| 7 | # some small modifications here and there. |
| 8 | # |
| 9 | # This stupid hackery is necessary due to the brain-damaged __declspec() |
| 10 | # semantics on x86; on PowerPC, we could just build a static library |
| 11 | # and turn that into a shared library using an exports list. On x86, you'd |
| 12 | # need to use a fake table of pointers to every symbol you wanted to |
| 13 | # export, otherwise you'd end up with an empty shared lib. This is |
| 14 | # progress? |
| 15 | # |
| 16 | # Called via: |
| 17 | # |
| 18 | # ar-fake cr lib-name objects |
| 19 | # ar-fake d lib-name objects |
| 20 | # |
| 21 | # This fake "ar" DOES NOT support any other POSIX "ar" commands! DO NOT |
| 22 | # expect it to behave very intelligently, it's designed to build Python, |
| 23 | # not any old shared lib. |
| 24 | |
| 25 | AR_COMMAND=$1 ; shift |
| 26 | AR_LIB=$1 ; shift |
| 27 | AR_LIB_NAME=$(basename $AR_LIB) |
| 28 | AR_SO_LIB_NAME=${AR_LIB_NAME/.a/.so} |
| 29 | AR_LIB_PATH=${AR_LIB/$AR_LIB_NAME/} |
| 30 | if [ "$AR_LIB_PATH" = "" ] ; then |
| 31 | AR_LIB_PATH="." |
| 32 | fi |
| 33 | AR_CRUD=${AR_LIB_PATH}/.ar-${AR_LIB_NAME} |
| 34 | |
| 35 | AR_CWD=$(pwd) |
| 36 | |
| 37 | # Function to tell is if the arg is an absolute path. Use it like this: |
| 38 | # |
| 39 | # if is_abs pathname ; then ... |
| 40 | is_abs() { |
| 41 | if [ "$1" != "$(echo $1 | sed -e "s,^/,,")" ] ; then |
| 42 | return 0 |
| 43 | fi |
| 44 | return 1 |
| 45 | } |
| 46 | |
| 47 | # Function to build the shared library. It does the right thing for |
| 48 | # PowerPC or x86 systems running BeOS. |
| 49 | build_lib() { |
| 50 | LIB=$1 ; shift |
| 51 | SO_NAME=$1 ; shift |
| 52 | CRUD_NAME=$1 ; shift |
| 53 | |
| 54 | # maybe too much... |
| 55 | EXTRA_LIBS="-lroot -lbe -lnet" |
| 56 | |
| 57 | case $BE_HOST_CPU in |
| 58 | ppc) |
| 59 | AR_CC="mwcc -xms -export pragma -nodup" |
| 60 | GLUE_LOC=/boot/develop/lib/ppc |
| 61 | AR_GLUE="${GLUE_LOC}/glue-noinit.a ${GLUE_LOC}/init_term_dyn.o ${GLUE_LOC}/start_dyn.o" |
| 62 | ;; |
| 63 | |
| 64 | x86) |
| 65 | AR_CC="gcc -nostart -Wl,-soname=${SO_NAME}" |
| 66 | AR_GLUE= |
| 67 | ;; |
| 68 | |
| 69 | *) |
| 70 | # Send me the mystery system (soo-pah aitch!), then we'll talk... |
| 71 | echo "No, no, no... $0 doesn't support $BE_HOST_CPU" |
| 72 | exit 2 |
| 73 | ;; |
| 74 | esac |
| 75 | |
| 76 | # Build a list of the objects... |
| 77 | PARTS="" |
| 78 | while read OBJ_FILE OBJ_PATH ; do |
| 79 | PARTS="$PARTS ${OBJ_PATH}${OBJ_FILE}" |
| 80 | done < $CRUD_NAME |
| 81 | |
| 82 | $AR_CC -o ${LIB%.a}.so $PARTS $AR_GLUE $EXTRA_LIBS > /dev/null 2>&1 |
| 83 | |
| 84 | return 0 |
| 85 | } |
| 86 | |
| 87 | # Make a backup of the old AR_CRUD file, just to be nice, and clean up |
| 88 | # any of our temp files that may be laying around. |
| 89 | if [ -e $AR_CRUD ] ; then |
| 90 | mv -f $AR_CRUD ${AR_CRUD}.old |
| 91 | cp ${AR_CRUD}.old $AR_CRUD |
| 92 | else |
| 93 | touch $AR_CRUD |
| 94 | fi |
| 95 | |
| 96 | if [ -e ${AR_CRUD}.grepper ] ; then |
| 97 | rm -f ${AR_CRUD}.grepper |
| 98 | fi |
| 99 | |
| 100 | case $AR_COMMAND in |
| 101 | cr) |
| 102 | # Add the extra bits to the $AR_CRUD file. |
| 103 | for OBJECT in "$@" ; do |
| 104 | OBJ_NAME=$(basename $OBJECT) |
| 105 | OBJ_PATH=${OBJECT%$OBJ_NAME} |
| 106 | if ! is_abs $OBJ_PATH ; then |
| 107 | OBJ_PATH=${AR_CWD}/${OBJECT} |
| 108 | OBJ_PATH=${OBJ_PATH%$OBJ_NAME} |
| 109 | fi |
| 110 | |
| 111 | # If this is already in there, we have to blow it away so |
| 112 | # we can replace it with the new one. |
| 113 | if egrep -q "^$OBJ_NAME " $AR_CRUD ; then |
| 114 | egrep -v "^$OBJ_NAME " < $AR_CRUD > ${AR_CRUD}.grepper |
| 115 | mv -f ${AR_CRUD}.grepper $AR_CRUD |
| 116 | fi |
| 117 | |
| 118 | echo $OBJ_NAME $OBJ_PATH >> $AR_CRUD |
| 119 | done |
| 120 | |
| 121 | # Now build a library from the files. |
| 122 | build_lib $AR_LIB $AR_SO_LIB_NAME $AR_CRUD |
| 123 | ;; |
| 124 | |
| 125 | d) |
| 126 | # Remove files from the $AR_CRUD file. This isn't terribly |
| 127 | # efficient. |
| 128 | for OBJECT in "$@" ; do |
| 129 | OBJ_NAME=$(basename $OBJECT) |
| 130 | OBJ_PATH=${OBJECT%$OBJ_NAME} |
| 131 | if ! is_abs $OBJ_PATH ; then |
| 132 | OBJ_PATH=${AR_CWD}/${OBJECT} |
| 133 | OBJ_PATH=${OBJ_PATH%$OBJ_NAME} |
| 134 | fi |
| 135 | |
| 136 | # Strip the objects from the list, if they're in there. |
| 137 | egrep -v "^$OBJ_NAME " < $AR_CRUD > ${AR_CRUD}.grepper |
| 138 | mv -f ${AR_CRUD}.grepper $AR_CRUD |
| 139 | done |
| 140 | |
| 141 | # Now build a library from the remaining objects. |
| 142 | build_lib $AR_LIB $AR_SO_LIB_NAME $AR_CRUD |
| 143 | ;; |
| 144 | |
| 145 | *) |
| 146 | echo "$0 error:" |
| 147 | echo " Unsupported command: $AR_COMMAND" |
| 148 | exit 1 |
| 149 | ;; |
| 150 | esac |
| 151 | |
| 152 | # If we make it here, all went well. Hopefully. |
| 153 | exit 0 |