586 lines
14 KiB
Bash
586 lines
14 KiB
Bash
#!/usr/bin/env sh
|
|
|
|
##
|
|
## Installs package dependencies and builds the application.
|
|
##
|
|
|
|
# Don't exit if some command fails.
|
|
set +e
|
|
# Disable file globbing.
|
|
set -f
|
|
|
|
# Boolean variables are true if non-empty and false otherwise.
|
|
|
|
# Command to install packages.
|
|
PKGCMD=
|
|
# Args to pass to $PKGCMD.
|
|
PKGARGS=
|
|
# Required packages.
|
|
PACKAGES=
|
|
# Whether package installation requires root permissions.
|
|
PKG_INSTALL_AS_ROOT=true
|
|
# Whether to skip package installation altogether.
|
|
PKG_INSTALL_SKIP=
|
|
# Whether to force package installation, even if it does not seem
|
|
# necessary.
|
|
PKG_INSTALL_FORCE=
|
|
# Only test if the OS is handled by this script.
|
|
DRY_RUN=
|
|
# If and where to install the program.
|
|
INSTALL_DIR=
|
|
# Whether we can install packages.
|
|
OS_IS_HANDLED=true
|
|
# Which OSs installer to use
|
|
OS=
|
|
|
|
## +-----------------------------------------------------------+
|
|
## * Utility Functions
|
|
## +-----------------------------------------------------------+
|
|
|
|
usage()
|
|
{
|
|
cat <<EOF
|
|
usage:$(basename "$0") [--help|-n|-i DIR|[-d -D]|[--os OS]]
|
|
|
|
-n Don't do anything, but check if this OS is handled.
|
|
|
|
-i DIR Install the program in the given directory.
|
|
|
|
-d Force dependency installattion.
|
|
|
|
-D Skip dependency installattion.
|
|
|
|
--os OS Use the given OS's installer
|
|
|
|
--help Display this message.
|
|
|
|
EOF
|
|
exit "$1"
|
|
}
|
|
|
|
# Search for command $1 in PATH. Print its absolute filename.
|
|
which()
|
|
{
|
|
if [ -z "$1" ]; then
|
|
return 1
|
|
fi
|
|
command -v "$1"
|
|
}
|
|
|
|
# Quote $@ for the shell.
|
|
quote()
|
|
{
|
|
quoted=
|
|
for arg; do
|
|
qarg=$(printf "%s" "$arg" | sed -e 's/[|&;<>()$\`"'\'' ]/\\&/g')
|
|
if [ -z "$quoted" ]; then
|
|
quoted=$qarg
|
|
else
|
|
quoted="$quoted $qarg"
|
|
fi
|
|
done
|
|
printf "%s" "$quoted"
|
|
}
|
|
|
|
# Attempt to exec $@ as root.
|
|
exec_privileged() {
|
|
if [ -z "$1" ]; then
|
|
echo "internal error: command is empty"
|
|
exit 2
|
|
fi
|
|
if [ -w / ]; then
|
|
"$@"
|
|
elif which sudo >/dev/null 2>&1; then
|
|
sudo -- "$@"
|
|
retval=$?
|
|
sudo -k
|
|
return $retval
|
|
elif which su >/dev/null 2>&1; then
|
|
su -c "$(quote "$@")"
|
|
else
|
|
echo "No such program: sudo or su"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Test if $1 is in PATH or exit with a failure status.
|
|
assert_program()
|
|
{
|
|
if ! which "$1" >/dev/null 2>&1; then
|
|
echo "No such program: $1"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Source filename $1 and echo variable $2.
|
|
source_var()
|
|
{
|
|
if ! [ -f "$1" ] || ! [ -r "$1" ] || [ -z "$2" ]; then
|
|
return 1
|
|
fi
|
|
# shellcheck source=/dev/null
|
|
. "$1"
|
|
eval "printf '%s\n' \$$2"
|
|
return 0
|
|
}
|
|
|
|
exit_success()
|
|
{
|
|
echo "==========================="
|
|
echo " Build succeeded. :O) "
|
|
echo "==========================="
|
|
exit 0
|
|
}
|
|
|
|
exit_fail()
|
|
{
|
|
echo "==========================="
|
|
echo " Build failed. ;o( "
|
|
echo "==========================="
|
|
if [ -z "$PKG_INSTALL_FORCE" ]; then
|
|
echo "Note: maybe try the '-d' option."
|
|
fi
|
|
exit 1
|
|
}
|
|
|
|
# Return 0, if all required packages seem to be installed.
|
|
have_packages_installed()
|
|
{
|
|
{
|
|
which pkg-config || return 1
|
|
if ! [ -f configure ];then
|
|
which autoreconf || return 1
|
|
which automake || return 1
|
|
fi
|
|
for lib in libpng glib-2.0 poppler poppler-glib zlib; do
|
|
pkg-config --exists $lib || return 1
|
|
done
|
|
which make || return 1
|
|
which gcc || which cc || return 1
|
|
[ $? -eq 0 ] || return 1
|
|
return 0
|
|
} >/dev/null 2>&1
|
|
}
|
|
|
|
handle_options()
|
|
{
|
|
while [ $# -gt 0 ]; do
|
|
case $1 in
|
|
--help) usage 0;;
|
|
-n) DRY_RUN=true;;
|
|
-d) PKG_INSTALL_FORCE=true ;;
|
|
-D) PKG_INSTALL_SKIP=true ;;
|
|
-i)
|
|
shift
|
|
[ $# -gt 0 ] || usage 1
|
|
if [ "${1%%/}" != "${PWD%%/}" ]; then
|
|
INSTALL_DIR=$1
|
|
fi ;;
|
|
--os)
|
|
shift
|
|
[ $# -gt 0 ] || usage 1
|
|
OS="$1"
|
|
;;
|
|
*) usage 1 ;;
|
|
esac
|
|
shift
|
|
done
|
|
if [ -n "$PKG_INSTALL_SKIP" ] && [ -n "$PKG_INSTALL_FORCE" ]; then
|
|
usage 1
|
|
fi
|
|
}
|
|
|
|
## +-----------------------------------------------------------+
|
|
## * OS Functions
|
|
## +-----------------------------------------------------------+
|
|
|
|
# Archlinux
|
|
os_arch() {
|
|
if ! [ -e "/etc/arch-release" ]; then
|
|
return 1;
|
|
fi
|
|
PKGCMD=pacman
|
|
PKGARGS="-S --needed"
|
|
PACKAGES="base-devel libpng zlib poppler-glib"
|
|
return 0;
|
|
}
|
|
|
|
# CentOS
|
|
os_centos() {
|
|
if ! [ -e "/etc/centos-release" ]; then
|
|
return 1
|
|
fi
|
|
PKGCMD=yum
|
|
if yum help install-n >/dev/null 2>&1; then
|
|
PKGARGS=install-n
|
|
else
|
|
PKGARGS=install
|
|
fi
|
|
PACKAGES="autoconf
|
|
automake
|
|
gcc
|
|
libpng-devel
|
|
make
|
|
pkgconfig
|
|
poppler-devel
|
|
poppler-glib-devel
|
|
zlib-devel"
|
|
return 0
|
|
}
|
|
|
|
# FreeBSD
|
|
os_freebsd() {
|
|
if ! which uname >/dev/null 2>&1 || [ "$(uname -s)" != "FreeBSD" ]; then
|
|
return 1
|
|
fi
|
|
PKGCMD=pkg
|
|
PKGARGS=install
|
|
PACKAGES="autotools poppler-glib png pkgconf"
|
|
return 0
|
|
}
|
|
|
|
# OpenBSD
|
|
os_openbsd() {
|
|
if ! which uname >/dev/null 2>&1 || [ "$(uname -s)" != "OpenBSD" ]; then
|
|
return 1
|
|
fi
|
|
PKGCMD=pkg_add
|
|
PKGARGS="-uU"
|
|
PACKAGES="autoconf%2.69 automake%1.15 poppler poppler-utils png"
|
|
export AUTOCONF_VERSION=2.69
|
|
export AUTOMAKE_VERSION=1.15
|
|
return 0
|
|
}
|
|
|
|
# Fedora
|
|
os_fedora() {
|
|
if ! [ -e "/etc/fedora-release" ]; then
|
|
return 1
|
|
fi
|
|
PKGCMD=dnf
|
|
PKGARGS=install
|
|
PACKAGES="autoconf
|
|
automake
|
|
gcc
|
|
libpng-devel
|
|
make
|
|
poppler-devel
|
|
poppler-glib-devel
|
|
zlib-devel"
|
|
VERSION=$(source_var /etc/os-release VERSION_ID)
|
|
if [ -n "$VERSION" ] && [ "$VERSION" -ge 26 ]; then
|
|
PACKAGES="$PACKAGES pkgconf"
|
|
else
|
|
PACKAGES="$PACKAGES pkgconfig"
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
# Debian/Ubuntu
|
|
os_debian() {
|
|
if ! [ -e "/etc/debian_version" ]; then
|
|
return 1
|
|
fi
|
|
PACKAGES="autoconf
|
|
automake
|
|
gcc
|
|
libpng-dev
|
|
libpoppler-dev
|
|
libpoppler-glib-dev
|
|
libz-dev
|
|
make
|
|
pkg-config"
|
|
PKGCMD=apt-get
|
|
PKGARGS="install -y"
|
|
return 0
|
|
}
|
|
|
|
# Msys2
|
|
os_msys2() {
|
|
if [ -z "$MSYSTEM" ] || ! [ -r "/etc/profile" ]; then
|
|
return 1
|
|
fi
|
|
case $MSYSTEM in
|
|
MINGW64)
|
|
PACKAGES="base-devel
|
|
autoconf
|
|
automake
|
|
mingw-w64-x86_64-libpng
|
|
mingw-w64-x86_64-poppler
|
|
mingw-w64-x86_64-imagemagick
|
|
mingw-w64-x86_64-toolchain
|
|
mingw-w64-x86_64-openssl
|
|
mingw-w64-x86_64-zlib" ;;
|
|
MINGW32)
|
|
PACKAGES="base-devel
|
|
autoconf
|
|
automake
|
|
mingw-w64-i686-libpng
|
|
mingw-w64-i686-poppler
|
|
mingw-w64-i686-imagemagick
|
|
mingw-w64-i686-toolchain
|
|
mingw-w64-i686-openssl
|
|
mingw-w64-i686-zlib" ;;
|
|
MSYS)
|
|
case $(uname -m) in
|
|
x86_64)
|
|
MSYSTEM=MINGW64 ;;
|
|
*)
|
|
MSYSTEM=MINGW32 ;;
|
|
esac
|
|
export MSYSTEM
|
|
# shellcheck source=/dev/null
|
|
. /etc/profile
|
|
eval "exec $(quote "$0" "$@")" ;;
|
|
*)
|
|
echo "Unrecognized MSYSTEM value: $MSYSTEM"
|
|
exit 1 ;;
|
|
esac
|
|
PKGCMD=pacman
|
|
PKGARGS="-S --needed"
|
|
PKG_INSTALL_AS_ROOT=
|
|
return 0
|
|
}
|
|
|
|
# MacOS
|
|
os_macos() {
|
|
if ! which uname >/dev/null 2>&1 || [ "$(uname -s)" != "Darwin" ]; then
|
|
return 1
|
|
elif which brew >/dev/null 2>&1; then
|
|
PKGCMD=brew
|
|
PKGARGS=install
|
|
PACKAGES="pkg-config poppler autoconf automake"
|
|
PKG_INSTALL_AS_ROOT=
|
|
# brew installs libffi as keg-only, meaning we need to set
|
|
# PKG_CONFIG_PATH manually so configure can find it
|
|
export PKG_CONFIG_PATH="${PKG_CONFIG_PATH}:$(brew --prefix libffi)/lib/pkgconfig/"
|
|
elif which port >/dev/null 2>&1; then
|
|
PKGCMD=port
|
|
PKGARGS=install
|
|
PACKAGES="pkgconfig poppler autoconf automake libpng"
|
|
else
|
|
return 1
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
# NixOS
|
|
os_nixos() {
|
|
# Already in the nix-shell.
|
|
if [ -n "$AUTOBUILD_NIX_SHELL" ]; then
|
|
return 0
|
|
fi
|
|
if ! which nix-shell >/dev/null 2>&1; then
|
|
return 1
|
|
fi
|
|
if [ -n "$DRY_RUN" ]; then
|
|
return 0
|
|
fi
|
|
if ! nix-instantiate --eval -E "<nixpkgs>" &>/dev/null; then
|
|
echo "File 'nixpkgs' was not found in the Nix path. Using NixOS/nixpkgs"
|
|
NIX_PATH="nixpkgs=https://github.com/nixos/nixpkgs/archive/master.tar.gz:$NIX_PATH"
|
|
fi
|
|
command="AUTOBUILD_NIX_SHELL=true"
|
|
command="$command;export AUTOBUILD_NIX_SHELL"
|
|
command="$command;$(quote "$0" "$@")"
|
|
exec nix-shell --pure --run "$command" \
|
|
-p automake autoconf pkgconfig libpng zlib poppler
|
|
}
|
|
|
|
# Gentoo
|
|
os_gentoo() {
|
|
if ! [ -e "/etc/gentoo-release" ]; then
|
|
return 1
|
|
fi
|
|
PKGCMD=emerge
|
|
PKGARGS=--noreplace
|
|
PACKAGES="app-text/poppler
|
|
dev-util/pkgconf
|
|
media-libs/libpng
|
|
sys-devel/autoconf
|
|
sys-devel/automake
|
|
sys-devel/gcc
|
|
sys-devel/make
|
|
sys-libs/glibc
|
|
sys-libs/zlib"
|
|
return 0
|
|
}
|
|
|
|
# Void
|
|
os_void() {
|
|
if [ -f "/etc/os-release" ]; then
|
|
. /etc/os-release
|
|
if [ "$NAME" != "void" ]; then
|
|
return 1
|
|
fi
|
|
else
|
|
return 1
|
|
fi
|
|
PACKAGES="autoconf
|
|
automake
|
|
libpng-devel
|
|
poppler-devel
|
|
poppler-glib-devel
|
|
zlib-devel
|
|
make
|
|
pkgconf"
|
|
PKGCMD=xbps-install
|
|
PKGARGS="-Sy"
|
|
return 0
|
|
}
|
|
|
|
# openSUSE (TODO: add support for micro versions)
|
|
os_opensuse() {
|
|
if [ -f "/etc/os-release" ]; then
|
|
. /etc/os-release
|
|
if [ "$ID" != "opensuse-leap" ] && [ "$ID" != "opensuse-tumbleweed" ]; then
|
|
return 1
|
|
fi
|
|
else
|
|
return 1
|
|
fi
|
|
PACKAGES="make
|
|
automake
|
|
autoconf
|
|
gcc
|
|
libpng16-devel
|
|
libpng16-compat-devel
|
|
zlib-devel
|
|
libpoppler-devel
|
|
libpoppler-glib-devel
|
|
glib2-devel
|
|
pkgconf"
|
|
PKGCMD=zypper
|
|
PKGARGS="install"
|
|
return 0
|
|
}
|
|
|
|
# By Parameter --os
|
|
os_argument() {
|
|
[ -z "$OS" ] && return 1
|
|
case $OS in
|
|
macos) os_macos "$@";;
|
|
freebsd) os_freebsd "$@";;
|
|
arch) os_arch "$@";;
|
|
centos) os_centos "$@";;
|
|
openbsd) os_openbsd "$@";;
|
|
fedora) os_fedora "$@";;
|
|
debian) os_debian "$@";;
|
|
gentoo) os_gentoo "$@";;
|
|
msys2) os_msys2 "$@";;
|
|
nixos) os_nixos "$@";;
|
|
void) os_void "$@";;
|
|
opensuse) os_opensuse "$@";;
|
|
*) echo "Invalid --os argument: $OS"
|
|
exit 1
|
|
esac || {
|
|
echo "Unable to install on this system as $OS"
|
|
exit 1
|
|
}
|
|
}
|
|
|
|
## +-----------------------------------------------------------+
|
|
## * Figure out were we are, install deps and build the program
|
|
## +-----------------------------------------------------------+
|
|
|
|
handle_options "$@"
|
|
|
|
os_argument "$@" || \
|
|
os_macos "$@" || \
|
|
os_freebsd "$@" || \
|
|
os_arch "$@" || \
|
|
os_centos "$@" || \
|
|
os_openbsd "$@" || \
|
|
os_fedora "$@" || \
|
|
os_debian "$@" || \
|
|
os_gentoo "$@" || \
|
|
os_msys2 "$@" || \
|
|
os_nixos "$@" || \
|
|
os_void "$@" || \
|
|
os_opensuse "$@" || \
|
|
{
|
|
OS_IS_HANDLED=
|
|
if [ -z "$DRY_RUN" ]; then
|
|
echo "Failed to recognize this system, trying to continue."
|
|
fi
|
|
}
|
|
|
|
if [ -n "$DRY_RUN" ]; then
|
|
[ -n "$OS_IS_HANDLED" ]
|
|
exit $?
|
|
fi
|
|
|
|
if [ -n "$PKGCMD" ];then
|
|
echo "---------------------------"
|
|
echo " Installing packages "
|
|
echo "---------------------------"
|
|
if [ -n "$PKG_INSTALL_SKIP" ]; then
|
|
echo "Skipping package installation (as requested)"
|
|
elif [ -z "$PKG_INSTALL_FORCE" ] && have_packages_installed; then
|
|
echo "Skipping package installation (already installed)"
|
|
else
|
|
assert_program "$PKGCMD"
|
|
echo "$PKGCMD $PKGARGS $PACKAGES"
|
|
if [ -n "$PKG_INSTALL_AS_ROOT" ]; then
|
|
exec_privileged $PKGCMD $PKGARGS $PACKAGES
|
|
else
|
|
$PKGCMD $PKGARGS $PACKAGES
|
|
fi
|
|
fi
|
|
echo
|
|
fi
|
|
|
|
# Try to be in the correct directory.
|
|
if which dirname >/dev/null 2>&1; then
|
|
cd "$(dirname "$0")" || {
|
|
echo "Failed to change into the source directory"
|
|
exit 1
|
|
}
|
|
fi
|
|
|
|
echo "---------------------------"
|
|
echo " Configuring and compiling "
|
|
echo "---------------------------"
|
|
|
|
# Create the configure script.
|
|
if ! [ -f ./configure ]; then
|
|
assert_program autoreconf
|
|
echo "autoreconf -i"
|
|
autoreconf -i
|
|
[ -f ./configure ] || exit_fail
|
|
fi
|
|
|
|
# Build the program.
|
|
if [ -n "$INSTALL_DIR" ]; then
|
|
prefix=--bindir=$INSTALL_DIR
|
|
fi
|
|
|
|
echo "./configure -q $prefix && make clean && make -s"
|
|
eval "./configure -q $(quote "$prefix") && make clean && make -s || exit_fail"
|
|
echo
|
|
if [ -n "$INSTALL_DIR" ]; then
|
|
echo "---------------------------"
|
|
echo " Installing "
|
|
echo "---------------------------"
|
|
echo make -s install
|
|
if mkdir -p -- "$INSTALL_DIR" && [ -w "$INSTALL_DIR" ]; then
|
|
make install || exit_fail
|
|
else
|
|
exec_privileged make install || exit_fail
|
|
fi
|
|
# Copy dynamic libraries on windows.
|
|
if [ -f epdfinfo.exe ]; then
|
|
assert_program awk
|
|
assert_program ldd
|
|
for dll in $(ldd epdfinfo.exe | awk '/\/mingw/ {print $3}'); do
|
|
cp -u "$dll" "$INSTALL_DIR"
|
|
done
|
|
fi
|
|
echo
|
|
fi
|
|
exit_success
|
|
|
|
# Local Variables:
|
|
# compile-command: "shellcheck autobuild"
|
|
# End:
|