echo -e
"\033[36m$1\033[0m" echo -e
"\033[91mError: $1\033[0m" 1>
&2 echo -e
"\033[33mWarning: $1\033[0m" 1>
&2 # Logs the given commands output to $LOG_FILE while IFS='' read -r
line
; do echo "[ERROR]: $line" >>
${LOG_FILE}; done while IFS='' read -r
line
; do echo "[INFO]: $line" >>
${LOG_FILE}; done ) >
>
(stampLog
) 2>
>
(stampErr
) # Checks to make sure the listed tools are installed, and errors if one is not if !
which
$tool &>
/dev/null
; then error
"Missing required tool $tool." if $missing; then exit 1; fi # Checks if the current directory has a config.status file, or if the options # passed include --configure if [ -f
config.status
]; then needsconfig=false
; fi if $FORCE_CONFIGURE; then # Downloads the source code to the package if it is not already found in the if [ -d
"$ROOTDIR/source/$1" ]; then return 0; fi quiet
pushd "$ROOTDIR/source" # Work out the file extension from the name for zxt
in ".tar.gz" ".tgz" ".tar.bz2" ".tbz",
".tar",
".zip"; do if expr
"$2" :
'.*'${zxt//./\.}'$' >
/dev/null
; then error
"Couldn't autodetect file type of $2 for $1" status
"Downloading source for package $1" # Extract the source to a fixed directory name status
"Extracting source for package $1" # Zip is a pain in the ass. We have to decide whether to make a # directory and extract into it, or otherwise extract the archive # and then rename the parent directory. error
"Too lazy to unzip package $1" # Count the number of parent directories there are IFS="/" read -a
firstfile
<
<
(tar
t
${tarflags}f
"$1$ext" | head
-n
1) levels=(${#firstfile[@]} -
1) # Extract to the source directory tar
x
${tarflags}f
"$1$ext" --strip-components
$levels -C
"$1" # Clean up and resume previous operation if [ -f
"$1$ext" ]; then rm
-f
"$1$ext"; fi # Tries to execute a command silently, and catches the error if it fails. ${@:1} &>
/dev/null
|| true # fwdpatch <patchfile> <opts> # Patches files without modifying their access or modified times. We do this so # that we don't upset Make when we patch and unpatch on the fly. # Figure out which direction we're going in if [ "$opt" = "-R" ]; then # Get the list of files that will be changed file=$(expr
"$line" :
'^patching file \(.*\)$') if [ "$file" !
= "" ]; then patchfiles
[${#patchfiles[*]}]="$file" done <
<
(patch
-fi
"$1" --dry-run
${@:2}) for file
in $patchfiles; do access
[${#access[*]}]=$(date
-r
$(stat
-f
"%a" "$file") +%Y%m%d%H%M.%S
) modify
[${#modify[*]}]=$(date
-r
$(stat
-f
"%m" "$file") +%Y%m%d%H%M.%S
) # Go ahead and apply the patch if [ ${#patchfiles[@]} -eq
1 ]; then status
"$mode patch $(basename
\"$1\") to 1 file" status
"$mode patch $(basename
\"$1\") to ${#patchfiles[@]} files" # Go back and reset the times on all the files while [ "$index" -lt
${#patchfiles[@]} ]; do touch
-at
${access[$index]} ${patchfiles[$index]} touch
-mt
${modify[$index]} ${patchfiles[$index]} # revpatch <patchfile> <opts> # Reverses a patch. You should always do this when finished building, so the # developer always works on the unpatched code. # xcompile <CFLAGS> <LDFLAGS> <configure command> <files to combine> # Cycles through supported host configurations and builds, then lipo-ing them all together. # ensure we don't have old object files laying around # first check that we, in fact, have declared arches to build against # if not, just do a native build. if ${NATIVE_BUILD} ; then status
"...configuring for native host" log
${3} --prefix
="$ROOTDIR/build" status
"...making and installing for native host" log
make
-j
$NUMBER_OF_CORES # we're done now, exit early # Things are simpler if we only have one arch to build, too. elif [[ 1 == ${#ARCHS[@]} ]] ; then status
"...configuring for ${ARCH[0]} Only" log
${3} --host
="${HOSTS[0]}" --build
="${HOSTS[0]}" \ --prefix
="$ROOTDIR/build" status
"...making and installing for ${ARCH[0]} Only" log
make
-j
$NUMBER_OF_CORES # we're done now, exit early quiet
mkdir
"${ROOTDIR}/sandbox" for (( i=0; i<
${#HOSTS[@]}; i++
)) ; do status
"...configuring for ${HOSTS[i]}" quiet
mkdir
"${ROOTDIR}/sandbox/root-${ARCHS[i]}" export CFLAGS="${1} -arch ${ARCHS[i]}" export LDFLAGS="${2} -arch ${ARCHS[i]}" log
${3} --host
="${HOSTS[i]}" --build
="${HOSTS[i]}" \ --prefix
="${ROOTDIR}/sandbox/root-${ARCHS[i]}" status
"...making and installing for ${HOSTS[i]}" log
make
-j
$NUMBER_OF_CORES # change library location and for ARCH
in ${ARCHS[@]} ; do if [[ ${ext} == 'dylib' ]] ; then install_name_tool
-id
"${ROOTDIR}/build/${FILE}" \ "${ROOTDIR}/sandbox/root-${ARCH}/${FILE}" lipoFiles="${lipoFiles} ${ROOTDIR}/sandbox/root-${ARCH}/${FILE}" status
"combine ${lipoFiles} to build/${FILE}" lipo
-create
${lipoFiles} -output
"${ROOTDIR}/build/${FILE}" local files="${ROOTDIR}/sandbox/root-${ARCHS[0]}/include/*" log
cp
-R
${f} "${ROOTDIR}/build/include" cp
-R
"${ROOTDIR}/sandbox/root-${ARCHS[0]}/bin/" \ #copy pkgconfig files and modify prefix if [ -d
"${ROOTDIR}/sandbox/root-${ARCHS[0]}/lib/pkgconfig" ] ; then local files="${ROOTDIR}/sandbox/root-${ARCHS[0]}/lib/pkgconfig/*" status
"patching pkgconfig file: ${f}" local basename=`basename
${f}` local SEDREP=`echo $ROOTDIR | awk
'{gsub("\\\\\/", "\\\\\\/");print}'` local SEDPAT="s/^prefix=.*/prefix=${SEDREP}\\/build/" sed
-e
"${SEDPAT}" "${f}" >
"${ROOTDIR}/build/lib/pkgconfig/${basename}" #copy .la files and modify local files="${ROOTDIR}/sandbox/root-${ARCHS[0]}/lib/*.la" status
"patching .la file: ${f}" local basename=`basename
${f}` local SEDREP=`echo $ROOTDIR | awk
'{gsub("\\\\\/", "\\\\\\/");print}'` local SEDPAT="s/^libdir=.*/libdir=\'${SEDREP}\\/build\\/lib\'/" sed
-e
"${SEDPAT}" "${f}" >
"${ROOTDIR}/build/lib/${basename}" local files="${ROOTDIR}/sandbox/root-${ARCHS[0]}/lib/*" log
cp
-a
${f} "${ROOTDIR}/build/lib" quiet
rm
-rf
"${ROOTDIR}/sandbox" # xconfigure <CFLAGS> <LDFLAGS> <configure command> <headers to mux> # Cycles through supported host configurations and muxes platform-dependant # This ensures that we don't have type mismatches and compile time overflows. # just do a native configure if no archs are given if ${NATIVE_BUILD} ; then status
"...configuring for native host" for (( i=0; i<
${#HOSTS[@]}; i++
)) ; do status
"...for ${HOSTS[i]}" export CFLAGS="${1} -arch ${ARCHS[i]}" export LDFLAGS="${2} -arch ${ARCHS[i]}" CONFIG_CMD="${3} --host=${HOSTS[i]} --build=${HOSTS[i]}" #only do this for more than 1 arch if [[ 1 <
${#ARCHS[@]} ]] ; then local base=${FILE:0:${#FILE}-${#ext}-1} mv
${FILE} ${base}-
${ARCHS[i]}.
${ext} #only do this for more than 1 arch if [[ 1 <
${#ARCHS[@]} ]] ; then # reconfigure *again* to set C and LD Flags right # Yes, it's an ugly hack, and should probably be replaced with status
"...for universal build" export CFLAGS="${1} ${ARCH_FLAGS}" export LDFLAGS="${2} ${ARCH_FLAGS}" local self_host=`gcc
-dumpmachine
` status
"Muxing ${FILE}..." local base=${FILE:0:${#FILE}-${#ext}-1} for (( i=0; i<
${#ARCHS[@]}; i++
)) ; do status
"...for ${ARCHS[i]}" echo "#if defined (__${ARCHS[i]}__)" >
${FILE} echo "#elif defined (__${ARCHS[i]}__)" >>
${FILE} cat
${base}-
${ARCHS[i]}.
${ext} >>
${FILE} echo "#error This isn't a recognized platform." >>
${FILE} status
"...${FILE} muxed"