diff options
author | Viktor Szakats <vszakats@users.noreply.github.com> | 2017-03-12 15:26:40 (GMT) |
---|---|---|
committer | Viktor Szakats <vszakats@users.noreply.github.com> | 2017-03-13 12:39:25 (GMT) |
commit | 466e24cf4e515faf7db1433083be4ca498f8d481 (patch) | |
tree | 352e87554c1c2957b16c81dceb6c79c7adf4d8a8 /tools/mxe-get | |
parent | a3ac9460ce1be67dace11784e174ba2d69703d7d (diff) | |
download | mxe-466e24cf4e515faf7db1433083be4ca498f8d481.zip mxe-466e24cf4e515faf7db1433083be4ca498f8d481.tar.gz mxe-466e24cf4e515faf7db1433083be4ca498f8d481.tar.bz2 |
add bash script to install packages on non-Linux systems
*BSD systems are currently supported and macOS actually tested.
Ref: https://github.com/mxe/mxe/issues/1708
Diffstat (limited to 'tools/mxe-get')
-rwxr-xr-x | tools/mxe-get | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/tools/mxe-get b/tools/mxe-get new file mode 100755 index 0000000..f1cdb9f --- /dev/null +++ b/tools/mxe-get @@ -0,0 +1,165 @@ +#!/usr/bin/env bash + +# The MIT License (MIT) +# ===================== +# +# Copyright (c) 2017 Viktor Szakats <https://vszakats.net/> +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +set -ue + +usage() { + echo "Download and unpack a list of MXE binary packages along with their +dependencies, securely. + +Usage: $(basename "$0") [package ...] + +Environment: + +MXE_HOME Configure directory where packages will be installed. + Default: ~/mxe +MXE_DONT_INSTALL Comma/space separated list of package names to skip + installing. Useful to exclude unnecessary dependencies. + *-linux-gnu-*, mxe-requirements, mxe-source packages + are excluded automatically. + +Required: ar (BSD), gpg (2.x), curl, openssl, awk, sed, tar, gzip + +Author: Viktor Szakats <https://vszakats.net/>" +} + +mxe_curl() { + curl -fsS --connect-timeout 15 --retry 3 "$@" +} + +mxe_get_pkg() { + + if [[ "$1" =~ ^(mxe-(i686|x86\-64)-(w64|unknown)-(mingw32|linux-gnu)(\.shared|\.static)?)-(.*)$ ]]; then + + repo="${BASH_REMATCH[1]}" # mxe-x86-64-w64-mingw32.shared + plat="${BASH_REMATCH[4]}" # mingw32 | linux-gnu + name="${BASH_REMATCH[6]}" # harfbuzz + + # skip native packages + if [ ! "${plat}" = 'linux-gnu' ]; then + + # skip packages on the don't install list + if [[ ! "${name}" =~ ^("${MXE_DONT_INSTALL//[, ]/|}")$ ]]; then + + idid="${repo}-${name}" # package id for internal purposes + if [[ ! "${done}" = *"|${idid}|"* ]]; then # avoid installing the same package twice + done="${done} |${idid}|" # add to list of install packages + + ctrl="$(awk "/^Package: ${repo}-${name}$/,/^SHA256: /" Packages)" # control section for this package + + debp="$(echo "${ctrl}" | sed -n -E 's,^Filename: (.+)$,\1,p')" # .deb path + vers="$(echo "${ctrl}" | sed -n -E 's,^Version: (.+)$,\1,p')" # package version + hash="$(echo "${ctrl}" | sed -n -E 's,^SHA256: ([0-9a-fA-F]{64})$,\1,p')" # .deb hash + deps="$(echo "${ctrl}" | sed -n -E 's,^Depends: (.+)$,\1,p')" # .deb dependencies + + echo "! Version: ${vers}" + url="${base}/${debp}" + echo "! Downloading... '${url}'" + if mxe_curl "${url}" -o pack.bin; then + + hash_fl="$(openssl dgst -sha256 pack.bin \ + | sed -n -E 's,.+= ([0-9a-fA-F]{64}),\1,p')" + + if [ "${hash_fl}" = "${hash}" ]; then + if ar -x pack.bin data.tar.xz && \ + tar --strip-components 4 -xf data.tar.xz; then + subd="$(echo "$(pwd)/usr/${repo}" \ + | sed -e 's|^mxe-||' -e 's|x86-64|x86_64|' -e "s|${HOME}|~|")" + echo "! Verified OK. Unpacked into: '${subd}'" # ~/mxe/usr/mxe-x86_64-w64-mingw32.shared + else + echo "! Error: Unpacking: '${url}'" + fi + rm -f data.tar.xz + else + echo "! Error: Verifying package checksum: '${url}'" + echo "! Expected: ${hash}" + echo "! Actual: ${hash_fl}" + fi + rm -f pack.bin + + for i in ${deps//,/}; do + mxe_get_pkg "$i" # recurse + done + else + echo "! Error: Cannot find file in file list: '${repo}-${name}_*'" + fi + fi + fi + fi + elif [ ! "$1" = 'mxe-requirements' ] && \ + [ ! "$1" = 'mxe-source' ]; then + echo "! Error: Cannot parse package name: '$1'" + fi +} + +if [ $# -eq 0 ]; then + usage + exit +fi + +[ -z "${MXE_DONT_INSTALL+x}" ] && MXE_DONT_INSTALL='gcc' +[ -z "${MXE_HOME+x}" ] && MXE_HOME="${HOME}/mxe" + +mkdir -p "${MXE_HOME}" +( + cd "${MXE_HOME}" || exit + + # APT root + base='http://pkg.mxe.cc/repos/apt/debian' + + alias gpg='gpg --batch --keyserver-options timeout=15 --keyid-format LONG' + + echo "! Downloading and verifying MXE package list..." + mxe_curl \ + -O "${base}/dists/wheezy/Release.gpg" \ + -O "${base}/dists/wheezy/Release" + gpg -q --keyserver hkps://keyserver.ubuntu.com --recv-keys 'D43A795B73B16ABE9643FE1AFD8FFF16DB45C6AB' + gpg --verify-options show-primary-uid-only --verify Release.gpg Release || exit 1 + mxe_curl \ + -O "${base}/dists/wheezy/main/binary-amd64/Packages.gz" + openssl dgst -sha256 Packages.gz \ + | grep -q "$(sed -E -n 's,^ ([0-9a-fA-F]{64}) [0-9]* main/binary-amd64/Packages.gz$,\1,p' Release)" || exit 1 + gzip -f -d Packages.gz + + echo "! Downloading and verifying MXE package(s)..." + done='' + while [ $# -gt 0 ]; do + echo "! Installing MXE package '$1'" + mxe_get_pkg "$1" + shift + done + echo "! Installed:${done//|/}" + + if [ -n "${done}" ]; then + echo '! Retargeting symlinks...' + find . -type l -name '*' | while IFS= read -r f; do + # TOFIX: readlink may need to be adapted for non-macOS systems + ln -f -s "$(readlink "${f}" | sed "s|/usr/lib/mxe|$(pwd)|")" "${f}" + done + fi + + echo '! Done.' +) |