2014-12-24 10:52:24 +01:00
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
|
|
|
##
|
|
|
|
## A minimalistic MacPorts Packet Manager for OSXCross,
|
|
|
|
## based on: https://github.com/maci0/pmmacports.
|
|
|
|
## Please see README.MACPORTS for more.
|
|
|
|
## License: GPLv2.
|
|
|
|
##
|
|
|
|
|
|
|
|
set -e
|
|
|
|
export LC_ALL=C
|
|
|
|
pushd "${0%/*}" &>/dev/null
|
|
|
|
|
|
|
|
MIRROR="$OSXCROSS_MACPORTS_MIRROR"
|
|
|
|
|
|
|
|
if [ -z "$MIRROR" ]; then
|
|
|
|
MIRROR="http://packages.macports.org"
|
|
|
|
fi
|
|
|
|
|
|
|
|
PUBKEYURL="https://svn.macports.org/repository/"
|
|
|
|
PUBKEYURL+="macports/trunk/base/macports-pubkey.pem"
|
|
|
|
|
|
|
|
# Darwin's antique OpenSSL does not support the SHA-2 family
|
|
|
|
PUBKEYRMD160="d3a22f5be7184d6575afcc1be6fdb82fd25562e8"
|
|
|
|
PUBKEYSHA1="214baa965af76ff71187e6c1ac91c559547f48ab"
|
|
|
|
|
|
|
|
if [ -n "$OSXCROSS_MACPORTS_ENABLE_HTTPS" ]; then
|
|
|
|
MIRROR=$(echo $MIRROR | sed 's/http:/https:/g')
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ -z "$BASHPID" ]; then
|
|
|
|
BASHPID=$(sh -c 'echo $PPID')
|
|
|
|
fi
|
|
|
|
|
|
|
|
errorMsg()
|
|
|
|
{
|
|
|
|
echo "$@" 1>&2
|
|
|
|
}
|
|
|
|
|
|
|
|
verboseMsg()
|
|
|
|
{
|
|
|
|
if [ -n "$VERBOSE" ]; then
|
|
|
|
errorMsg "$@"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
verbosePlaceHolder()
|
|
|
|
{
|
|
|
|
if [ -n "$VERBOSE" ]; then
|
|
|
|
errorMsg ""
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
require()
|
|
|
|
{
|
|
|
|
set +e
|
|
|
|
which $1 &>/dev/null
|
|
|
|
if [ $? -ne 0 ]; then
|
|
|
|
errorMsg "$1 is required"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
set -e
|
|
|
|
}
|
|
|
|
|
|
|
|
PLATFORM=$(uname -s)
|
|
|
|
|
|
|
|
if [ -z "$MACOSX_DEPLOYMENT_TARGET" ]; then
|
|
|
|
errorMsg "You must set MACOSX_DEPLOYMENT_TARGET first."
|
|
|
|
errorMsg "Please see README.MACPORTS."
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
unsupportedDepTarget()
|
|
|
|
{
|
|
|
|
errorMsg "unsupported deployment target"
|
|
|
|
exit 1
|
|
|
|
}
|
|
|
|
|
|
|
|
require "wget"
|
|
|
|
require "openssl"
|
|
|
|
|
|
|
|
case $MACOSX_DEPLOYMENT_TARGET in
|
|
|
|
10.6* ) OSXVERSION="darwin_10" ;;
|
|
|
|
10.7* ) OSXVERSION="darwin_11" ;;
|
|
|
|
10.8* ) OSXVERSION="darwin_12" ;;
|
|
|
|
10.9* ) OSXVERSION="darwin_13" ;;
|
|
|
|
10.10* ) OSXVERSION="darwin_14" ;;
|
|
|
|
* ) unsupportedDepTarget ;;
|
|
|
|
esac
|
|
|
|
|
|
|
|
require "osxcross-conf"
|
|
|
|
eval $(osxcross-conf)
|
|
|
|
|
|
|
|
if [ -z "$OSXCROSS_TARGET_DIR" ]; then
|
|
|
|
errorMsg "OSXCROSS_TARGET_DIR should be set"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
ROOT="$OSXCROSS_TARGET_DIR/macports"
|
|
|
|
|
|
|
|
if [ ! -d "$ROOT" ]; then
|
|
|
|
echo "creating macports directory: $ROOT"
|
|
|
|
mkdir -p $ROOT
|
|
|
|
fi
|
|
|
|
|
|
|
|
PUBKEY="$ROOT/mp-pubkey.pem"
|
|
|
|
INSTALLDB="$ROOT/INSTALLED"
|
|
|
|
CACHE="$ROOT/cache"
|
|
|
|
INSTALL="$ROOT/pkgs"
|
|
|
|
TMP="$ROOT/tmp"
|
|
|
|
LASTPKGNAME=""
|
|
|
|
|
|
|
|
LOCKDIR="/tmp/osxcross-macports-lock"
|
|
|
|
LOCKPID="$LOCKDIR/pid"
|
|
|
|
|
|
|
|
checkLock()
|
|
|
|
{
|
|
|
|
if mkdir $LOCKDIR 2>/dev/null; then
|
|
|
|
echo $BASHPID > $LOCKPID
|
|
|
|
else
|
|
|
|
pid=$(cat $LOCKPID 2>/dev/null) || { errorMsg "remove $LOCKDIR"; exit 1; }
|
|
|
|
if [ $? -eq 0 -a "$(ps -p $pid -o comm=)" == "bash" ]; then
|
|
|
|
errorMsg "locked by pid $pid"
|
|
|
|
else
|
|
|
|
errorMsg "dead lockdir detected! please remove '$LOCKDIR' by hand."
|
|
|
|
fi
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
createDir()
|
|
|
|
{
|
|
|
|
if [ ! -d $2 ]; then
|
|
|
|
echo "creating $1 directory: $2"
|
|
|
|
mkdir -p $2
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
checkLock
|
|
|
|
|
|
|
|
createDir "cache" $CACHE
|
|
|
|
createDir "install" $INSTALL
|
|
|
|
createDir "tmp" $TMP
|
|
|
|
|
|
|
|
getFileStdout()
|
|
|
|
{
|
|
|
|
verbosePlaceHolder
|
|
|
|
local xargs=""
|
|
|
|
[ -z "$VERBOSE" ] && xargs+="--quiet"
|
|
|
|
wget "$1" -O- $xargs
|
|
|
|
#verbosePlaceHolder
|
|
|
|
}
|
|
|
|
|
|
|
|
getFile()
|
|
|
|
{
|
|
|
|
verbosePlaceHolder
|
|
|
|
local xargs=""
|
|
|
|
if [ $# -ge 2 ]; then
|
|
|
|
xargs+="-O $2 "
|
|
|
|
else
|
|
|
|
xargs+="-P $CACHE "
|
|
|
|
fi
|
|
|
|
[ -z "$VERBOSE" ] && xargs+="--quiet"
|
|
|
|
wget -c "$1" $xargs
|
|
|
|
#verbosePlaceHolder
|
|
|
|
}
|
|
|
|
|
|
|
|
verifyFileIntegrity()
|
|
|
|
{
|
|
|
|
local file="$1"
|
|
|
|
|
|
|
|
if [ ! -e "$PUBKEY" ]; then
|
|
|
|
echo "getting macports public key ..."
|
|
|
|
getFile $PUBKEYURL "$PUBKEY"
|
|
|
|
fi
|
|
|
|
|
|
|
|
local rmd160=$(openssl rmd160 "$PUBKEY" | awk '{print $2}')
|
|
|
|
local sha1=$(openssl sha1 "$PUBKEY" | awk '{print $2}')
|
|
|
|
|
|
|
|
if [ "$rmd160" != "$PUBKEYRMD160" -o "$sha1" != "$PUBKEYSHA1" ]; then
|
|
|
|
errorMsg "invalid macports public key (hash check failed)"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
verboseMsg "verifying file integrity ..."
|
|
|
|
|
|
|
|
set +e
|
|
|
|
|
|
|
|
openssl dgst -ripemd160 -verify "$PUBKEY" -signature \
|
|
|
|
"$CACHE/$file.rmd160" "$CACHE/$file" 1>/dev/null
|
|
|
|
|
|
|
|
if [ $? -ne 0 ]; then
|
|
|
|
errorMsg "file integrity check failed ($CACHE/$file)"
|
|
|
|
exit 2
|
|
|
|
fi
|
|
|
|
|
|
|
|
set -e
|
|
|
|
}
|
|
|
|
|
|
|
|
getPkgUrl()
|
|
|
|
{
|
|
|
|
local pkgname="$1"
|
|
|
|
local pkgs
|
|
|
|
local pkg
|
|
|
|
|
|
|
|
set +e
|
|
|
|
|
|
|
|
pkgs=$(getFileStdout "$MIRROR/$pkgname/?C=M;O=A" | \
|
|
|
|
grep -o -E 'href="([^"#]+)"' | \
|
|
|
|
cut -d'"' -f2 | grep '.tbz2$')
|
|
|
|
|
|
|
|
local ec=$?
|
|
|
|
|
|
|
|
set -e
|
|
|
|
|
|
|
|
if [ $ec -ne 0 ]; then
|
|
|
|
errorMsg "no package found"
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
|
|
|
|
verboseMsg " candidates for $pkgname:"
|
|
|
|
|
|
|
|
for p in $pkgs; do
|
|
|
|
verboseMsg " $p"
|
|
|
|
done
|
|
|
|
|
|
|
|
local pkg=$(echo "$pkgs" | grep $OSXVERSION | uniq | tail -n1)
|
|
|
|
|
|
|
|
verboseMsg " selected: $pkg"
|
|
|
|
|
|
|
|
if [ -z "$pkg" ]; then
|
|
|
|
verboseMsg -n " "
|
|
|
|
errorMsg "no suitable version found for $OSXVERSION"
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
|
|
|
|
echo "$MIRROR/$pkgname/$pkg"
|
|
|
|
}
|
|
|
|
|
|
|
|
pkgInstalled()
|
|
|
|
{
|
|
|
|
local pkgname="$1"
|
|
|
|
|
|
|
|
if [ ! -e "$INSTALLDB" ]; then
|
|
|
|
echo 0
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
|
|
|
|
set +e
|
|
|
|
grep -x "$pkgname" "$INSTALLDB" &>/dev/null
|
|
|
|
local status=$?
|
|
|
|
set -e
|
|
|
|
|
|
|
|
if [ $status -eq 0 ]; then
|
|
|
|
echo 1
|
|
|
|
else
|
|
|
|
echo 0
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
installPkg()
|
|
|
|
{
|
|
|
|
local pkgname="$1"
|
|
|
|
|
|
|
|
LASTPKGNAME=$pkgname
|
|
|
|
|
|
|
|
if [ $(pkgInstalled $pkgname) -eq 1 ]; then
|
|
|
|
continue
|
|
|
|
fi
|
|
|
|
|
|
|
|
echo "searching package $pkgname ..."
|
|
|
|
|
|
|
|
local pkgurl=$(getPkgUrl "$pkgname")
|
|
|
|
local pkgfile=$(echo "$pkgurl" | awk -F'/' '{print $NF}')
|
|
|
|
|
|
|
|
if [ -z "$pkgurl" ]; then
|
2014-12-26 11:17:38 +01:00
|
|
|
local oldpkgname=$pkgname
|
|
|
|
local tmp=$(echo "$pkgname" | awk -F'-' '{print $NF}')
|
|
|
|
[ -n "$tmp" ] && pkgname=${pkgname/-$tmp/}
|
2014-12-24 10:52:24 +01:00
|
|
|
|
|
|
|
if [ "$pkgname" != "$oldpkgname" ]; then
|
|
|
|
echo "trying $pkgname instead ..."
|
|
|
|
else
|
|
|
|
[ -n "$UPGRADE" ] && return
|
|
|
|
exit 3
|
|
|
|
fi
|
|
|
|
|
|
|
|
installPkg $pkgname
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
|
|
|
|
echo "getting $pkgfile ..."
|
|
|
|
getFile "$pkgurl"
|
|
|
|
|
|
|
|
verboseMsg "getting $pkgname.rmd160 ..."
|
|
|
|
getFile "$pkgurl.rmd160"
|
|
|
|
|
|
|
|
verifyFileIntegrity "$pkgfile"
|
|
|
|
|
|
|
|
pushd $TMP &>/dev/null
|
|
|
|
|
|
|
|
echo "installing $pkgname ..."
|
|
|
|
verboseMsg " extracting $pkgfile ..."
|
|
|
|
tar xf "$CACHE/$pkgfile"
|
|
|
|
|
|
|
|
if [ -d opt/local ]; then
|
|
|
|
verboseMsg " fixing permissions ..."
|
|
|
|
find opt/local -type d -exec chmod 770 {} \;
|
|
|
|
find opt/local -type f -exec chmod 660 {} \;
|
|
|
|
if [ -d opt/local/lib ]; then
|
|
|
|
if [ -n "$STATIC" ]; then
|
|
|
|
verboseMsg " "
|
|
|
|
echo "removing dylibs ..."
|
|
|
|
find opt/local/lib -name "*.dylib" -exec rm {} \;
|
|
|
|
else
|
|
|
|
find opt/local/lib -type f -name "*.dylib" -exec chmod +x {} \;
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
set +e
|
|
|
|
cp -r opt $INSTALL
|
|
|
|
local status=$?
|
|
|
|
set -e
|
|
|
|
if [ $status -eq 1 ]; then
|
|
|
|
errorMsg "removing broken symlinks ..."
|
|
|
|
find -L . -type l -exec rm {} \;
|
|
|
|
cp -r opt $INSTALL
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
|
|
|
local pkgdeps=$(grep '@pkgdep' \+CONTENTS | cut -d\ -f2 | \
|
|
|
|
rev | cut -f2-100 -d\- | rev)
|
|
|
|
|
|
|
|
popd &>/dev/null # TMP
|
|
|
|
rm -rf $TMP/*
|
|
|
|
|
|
|
|
for pkgdep in $pkgdeps; do
|
|
|
|
installPkg $pkgdep
|
|
|
|
done
|
|
|
|
|
|
|
|
echo "$pkgname" >> "$INSTALLDB"
|
|
|
|
}
|
|
|
|
|
|
|
|
installPkgs()
|
|
|
|
{
|
|
|
|
local packages="$1"
|
|
|
|
|
|
|
|
for pkgname in $packages; do
|
|
|
|
if [ $(pkgInstalled $pkgname) == "1" ]; then
|
|
|
|
errorMsg "$pkgname is already installed"
|
|
|
|
continue
|
|
|
|
fi
|
|
|
|
installPkg $pkgname
|
|
|
|
echo "installed $pkgname"
|
|
|
|
rm -f $INSTALL/+*
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
|
|
|
updateSearchCache()
|
|
|
|
{
|
|
|
|
pushd $CACHE &>/dev/null
|
|
|
|
|
|
|
|
echo "generating index cache (this may take several minutes ...)"
|
|
|
|
getFile $MIRROR $CACHE/packages
|
|
|
|
|
|
|
|
cat packages | grep -o -E 'href="([^"#]+)"' | cut -d'"' -f2 | \
|
|
|
|
sed 's/.\{1\}$//' | uniq | sort > INDEXCACHE
|
|
|
|
|
|
|
|
rm -f packages
|
|
|
|
echo "generated index cache for $(cat INDEXCACHE | wc -l) packages"
|
|
|
|
|
|
|
|
popd &>/dev/null
|
|
|
|
}
|
|
|
|
|
|
|
|
searchPkg()
|
|
|
|
{
|
|
|
|
local pkg="$1"
|
|
|
|
|
|
|
|
pushd $CACHE &>/dev/null
|
|
|
|
|
|
|
|
if [ ! -e INDEXCACHE ]; then
|
|
|
|
updateSearchCache
|
|
|
|
fi
|
|
|
|
|
|
|
|
local packages=$(grep -i "$pkg" INDEXCACHE)
|
|
|
|
|
|
|
|
if [ -z "$packages" ]; then
|
|
|
|
echo "no matching packages found for $1"
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
|
|
|
|
for pkg in $packages; do
|
|
|
|
echo $pkg
|
|
|
|
done
|
|
|
|
|
|
|
|
popd &>/dev/null
|
|
|
|
}
|
|
|
|
|
|
|
|
_exit()
|
|
|
|
{
|
|
|
|
local ec=$?
|
|
|
|
if [ $ec -ne 0 ]; then
|
|
|
|
if [ -n "$LASTPKGNAME" ]; then
|
|
|
|
errorMsg "failed to install $LASTPKGNAME, try with '-v'"
|
|
|
|
fi
|
|
|
|
if [ $ec -eq 3 ]; then
|
|
|
|
errorMsg -n "use '$(basename $0) fake-install <pkgname>' to "
|
|
|
|
errorMsg "fake install non-existing packages"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
|
|
|
rm -rf $LOCKDIR
|
|
|
|
}
|
|
|
|
|
|
|
|
showFlags()
|
|
|
|
{
|
|
|
|
if [ -n "$OSXCROSS_TARGET" ]; then
|
|
|
|
PKG_CONFIG="x86_64-apple-${OSXCROSS_TARGET}-pkg-config"
|
|
|
|
else
|
|
|
|
PKG_CONFIG="pkg-config"
|
|
|
|
fi
|
|
|
|
|
|
|
|
$PKG_CONFIG $1 $2
|
|
|
|
}
|
|
|
|
|
|
|
|
showCFLAGS()
|
|
|
|
{
|
|
|
|
showFlags "--cflags" $1
|
|
|
|
}
|
|
|
|
|
|
|
|
showLDFLAGS()
|
|
|
|
{
|
|
|
|
showFlags "--libs" $1
|
|
|
|
}
|
|
|
|
|
|
|
|
upgrade()
|
|
|
|
{
|
|
|
|
if [ ! -e $INSTALLDB ]; then
|
|
|
|
if [ -e $INSTALLDB.old ]; then
|
|
|
|
echo "restoring old installation database"
|
|
|
|
mv $INSTALLDB.old $INSTALLDB
|
|
|
|
else
|
|
|
|
errorMsg "no install database"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
|
|
|
local PKGS=$(cat $INSTALLDB)
|
|
|
|
mv $INSTALLDB $INSTALLDB.old
|
|
|
|
|
|
|
|
UPGRADE=1
|
|
|
|
rm -rf $INSTALL
|
2014-12-24 14:06:30 +01:00
|
|
|
createDir "" $INSTALL 1>/dev/null
|
2014-12-24 10:52:24 +01:00
|
|
|
|
|
|
|
for pkg in $PKGS; do
|
|
|
|
installPkg $pkg
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
|
|
|
clearCache()
|
|
|
|
{
|
|
|
|
rm -rf $CACHE
|
|
|
|
}
|
|
|
|
|
|
|
|
removeDylibs()
|
|
|
|
{
|
|
|
|
find $INSTALL -name "*.dylib" -exec rm {} \;
|
|
|
|
}
|
|
|
|
|
|
|
|
showHelpText()
|
|
|
|
{
|
|
|
|
errorMsg "Please see README.MACPORTS"
|
|
|
|
}
|
|
|
|
|
|
|
|
main()
|
|
|
|
{
|
|
|
|
local args
|
|
|
|
local cmd
|
|
|
|
|
|
|
|
for opt in $@; do
|
|
|
|
if [[ $opt == -* ]]; then
|
|
|
|
if [ $opt == "-v" -o $opt == "--verbose" ]; then
|
|
|
|
VERBOSE=1
|
|
|
|
elif [ $opt == "-v=2" -o $opt == "--verbose=2" ]; then
|
|
|
|
set -x
|
|
|
|
VERBOSE=1
|
|
|
|
elif [ $opt == "-s" -o $opt == "--static" ]; then
|
|
|
|
STATIC=1
|
|
|
|
elif [ $opt == "-c" -o $opt == "--cflags" ]; then
|
|
|
|
showCFLAGS $2
|
|
|
|
exit
|
|
|
|
elif [ $opt == "-l" -o $opt == "--ldflags" ]; then
|
|
|
|
showLDFLAGS $2
|
|
|
|
exit
|
|
|
|
elif [ $opt == "-h" -o $opt == "--help" ]; then
|
|
|
|
showHelpText
|
|
|
|
exit
|
|
|
|
else
|
|
|
|
errorMsg "unknown option: $opt"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
else
|
|
|
|
if [ -z "$cmd" ]; then
|
|
|
|
cmd="$opt"
|
|
|
|
else
|
|
|
|
args+="$opt "
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
|
|
|
|
if [ -z "$cmd" ]; then
|
|
|
|
errorMsg "no command given"
|
|
|
|
showHelpText
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
case "$cmd" in
|
|
|
|
update*cache )
|
|
|
|
updateSearchCache
|
|
|
|
exit
|
|
|
|
;;
|
|
|
|
|
|
|
|
upgrade )
|
|
|
|
upgrade
|
|
|
|
exit
|
|
|
|
;;
|
|
|
|
|
|
|
|
clear*cache )
|
|
|
|
clearCache
|
|
|
|
echo "done"
|
|
|
|
exit
|
|
|
|
;;
|
|
|
|
|
|
|
|
remove*dylibs )
|
|
|
|
removeDylibs
|
|
|
|
echo "done"
|
|
|
|
exit
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
|
|
|
|
local packages="$args"
|
|
|
|
|
|
|
|
if [ -z "$packages" ]; then
|
|
|
|
errorMsg "no package name given"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
case "$cmd" in
|
|
|
|
install )
|
|
|
|
installPkgs "$packages"
|
|
|
|
;;
|
|
|
|
|
|
|
|
fake*install )
|
|
|
|
for pkgname in $args; do
|
|
|
|
if [ $(pkgInstalled $pkgname) -eq 0 ]; then
|
|
|
|
echo $pkgname >> $INSTALLDB
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
|
|
|
|
echo "done"
|
|
|
|
;;
|
|
|
|
|
|
|
|
search )
|
|
|
|
for pkgname in $args; do
|
|
|
|
searchPkg $pkgname
|
|
|
|
done
|
|
|
|
;;
|
|
|
|
|
|
|
|
* )
|
|
|
|
showHelpText
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
}
|
|
|
|
|
|
|
|
trap '' TERM
|
|
|
|
trap '' INT
|
|
|
|
|
|
|
|
trap _exit EXIT
|
|
|
|
|
|
|
|
main "$@"
|