dotemacs

My Emacs configuration
git clone git://git.entf.net/dotemacs
Log | Files | Refs | LICENSE

autobuild (12959B)


      1 #!/usr/bin/env sh
      2 
      3 ##
      4 ## Installs package dependencies and builds the application.
      5 ##
      6 
      7 # Don't exit if some command fails.
      8 set +e
      9 # Disable file globbing.
     10 set -f
     11 
     12 # Boolean variables are true if non-empty and false otherwise.
     13 
     14 # Command to install packages.
     15 PKGCMD=
     16 # Args to pass to $PKGCMD.
     17 PKGARGS=
     18 # Required packages.
     19 PACKAGES=
     20 # Whether package installation requires root permissions.
     21 PKG_INSTALL_AS_ROOT=true
     22 # Whether to skip package installation altogether.
     23 PKG_INSTALL_SKIP=
     24 # Whether to force package installation, even if it does not seem
     25 # necessary.
     26 PKG_INSTALL_FORCE=
     27 # Only test if the OS is handled by this script.
     28 DRY_RUN=
     29 # If and where to install the program.
     30 INSTALL_DIR=
     31 # Whether we can install packages.
     32 OS_IS_HANDLED=true
     33 # Which OSs installer to use
     34 OS=
     35 
     36 ## +-----------------------------------------------------------+
     37 ## * Utility Functions
     38 ## +-----------------------------------------------------------+
     39 
     40 usage()
     41 {
     42     cat <<EOF
     43 usage:$(basename "$0") [--help|-n|-i DIR|[-d -D]|[--os OS]]
     44 
     45     -n       Don't do anything, but check if this OS is handled.
     46 
     47     -i DIR   Install the program in the given directory.
     48 
     49     -d       Force dependency installattion.
     50 
     51     -D       Skip dependency installattion.
     52 
     53     --os OS  Use the given OS's installer
     54 
     55     --help   Display this message.
     56 
     57 EOF
     58     exit "$1"
     59 }
     60 
     61 # Search for command $1 in PATH. Print its absolute filename.
     62 which()
     63 {
     64     if [ -z "$1" ]; then
     65         return 1
     66     fi
     67     command -v "$1"
     68 }
     69 
     70 # Quote $@ for the shell.
     71 quote()
     72 {
     73     quoted=
     74     for arg; do
     75         qarg=$(printf "%s" "$arg" | sed -e 's/[|&;<>()$\`"'\'' 	]/\\&/g')
     76         if [ -z "$quoted" ]; then
     77             quoted=$qarg
     78         else
     79             quoted="$quoted $qarg"
     80         fi
     81     done
     82     printf "%s" "$quoted"
     83 }
     84 
     85 # Attempt to exec $@ as root.
     86 exec_privileged() {
     87     if [ -z "$1" ]; then
     88         echo "internal error: command is empty"
     89         exit 2
     90     fi
     91     if [ -w / ]; then
     92         "$@"
     93     elif which sudo >/dev/null 2>&1; then
     94         sudo -- "$@"
     95         retval=$?
     96         sudo -k
     97         return $retval
     98     elif which su >/dev/null 2>&1; then
     99         su -c "$(quote "$@")"
    100     else
    101         echo "No such program: sudo or su"
    102         exit 1
    103     fi
    104 }
    105 
    106 # Test if $1 is in PATH or exit with a failure status.
    107 assert_program()
    108 {
    109     if ! which "$1" >/dev/null 2>&1; then
    110         echo "No such program: $1"
    111         exit 1
    112     fi
    113 }
    114 
    115 # Source filename $1 and echo variable $2.
    116 source_var()
    117 {
    118     if ! [ -f "$1" ] || ! [ -r "$1" ] || [ -z "$2" ]; then
    119         return 1
    120     fi
    121     # shellcheck source=/dev/null
    122     . "$1"
    123     eval "printf '%s\n' \$$2"
    124     return 0
    125 }
    126 
    127 exit_success()
    128 {
    129     echo "==========================="
    130     echo "   Build succeeded. :O)    "
    131     echo "==========================="
    132     exit 0
    133 }
    134 
    135 exit_fail()
    136 {
    137     echo "==========================="
    138     echo "     Build failed.  ;o(    "
    139     echo "==========================="
    140     if [ -z "$PKG_INSTALL_FORCE" ]; then
    141         echo "Note: maybe try the '-d' option."
    142     fi
    143     exit 1
    144 }
    145 
    146 # Return 0, if all required packages seem to be installed.
    147 have_packages_installed()
    148 {
    149     {
    150         which pkg-config || return 1
    151         if ! [ -f configure ];then
    152             which autoreconf || return 1
    153             which automake || return 1
    154         fi
    155         for lib in libpng glib-2.0 poppler poppler-glib zlib; do
    156             pkg-config --exists $lib || return 1
    157         done
    158         which make || return 1
    159         which gcc || which cc || return 1
    160         which g++ || which c++ || return 1
    161         c++ $(pkg-config --cflags poppler) -o /dev/null -E install_test.cpp 2>/dev/null
    162         [ $? -eq 0 ] || return 1
    163         return 0
    164     } >/dev/null 2>&1
    165 }
    166 
    167 handle_options()
    168 {
    169     while [ $# -gt 0 ]; do
    170         case $1 in
    171             --help) usage 0;;
    172             -n) DRY_RUN=true;;
    173             -d) PKG_INSTALL_FORCE=true ;;
    174             -D) PKG_INSTALL_SKIP=true ;;
    175             -i)
    176                 shift
    177                 [ $# -gt 0 ] || usage 1
    178                 if [ "${1%%/}" != "${PWD%%/}" ]; then
    179                     INSTALL_DIR=$1
    180                 fi ;;
    181             --os)
    182                 shift
    183                 [ $# -gt 0 ] || usage 1
    184                 OS="$1"
    185                 ;;
    186             *) usage 1 ;;
    187         esac
    188         shift
    189     done
    190     if [ -n "$PKG_INSTALL_SKIP" ] && [ -n "$PKG_INSTALL_FORCE" ]; then
    191         usage 1
    192     fi
    193 }
    194 
    195 ## +-----------------------------------------------------------+
    196 ## * OS Functions
    197 ## +-----------------------------------------------------------+
    198 
    199 # Archlinux
    200 os_arch() {
    201     if ! [ -e "/etc/arch-release" ]; then
    202         return 1;
    203     fi
    204     PKGCMD=pacman
    205     PKGARGS="-S --needed"
    206     PACKAGES="base-devel libpng zlib poppler-glib"
    207     return 0;
    208 }
    209 
    210 # CentOS
    211 os_centos() {
    212     if ! [ -e "/etc/centos-release" ]; then
    213         return 1
    214     fi
    215     PKGCMD=yum
    216     if yum help install-n >/dev/null 2>&1; then
    217         PKGARGS=install-n
    218     else
    219         PKGARGS=install
    220     fi
    221     PACKAGES="autoconf
    222               automake
    223               gcc
    224               gcc-c++
    225               libpng-devel
    226               make
    227               pkgconfig
    228               poppler-devel
    229               poppler-glib-devel
    230               zlib-devel"
    231     return 0
    232 }
    233 
    234 # FreeBSD
    235 os_freebsd() {
    236     if ! which uname >/dev/null 2>&1 || [ "$(uname -s)" != "FreeBSD" ]; then
    237         return 1
    238     fi
    239     PKGCMD=pkg
    240     PKGARGS=install
    241     PACKAGES="autotools poppler-glib png pkgconf"
    242     return 0
    243 }
    244 
    245 # OpenBSD
    246 os_openbsd() {
    247     if ! which uname >/dev/null 2>&1 || [ "$(uname -s)" != "OpenBSD" ]; then
    248         return 1
    249     fi
    250     PKGCMD=pkg_add
    251     PKGARGS="-uU"
    252     PACKAGES="autoconf-2.69p2 automake-1.15.1 poppler poppler-utils png"
    253     export AUTOCONF_VERSION=2.69
    254     export AUTOMAKE_VERSION=1.15
    255     if whereis clang++ ;then
    256         export CXX=clang++
    257     elif whereis eg++ ;then
    258         export CXX=eg++
    259     else
    260         export CXX=eg++
    261         PACKAGES="${PACKAGES} g++"
    262     fi
    263     export CXXFLAGS="-std=c++11 -I/usr/local/include/poppler -I/usr/local/include"
    264     return 0
    265 }
    266 
    267 # Fedora
    268 os_fedora() {
    269     if ! [ -e "/etc/fedora-release" ]; then
    270         return 1
    271     fi
    272     PKGCMD=dnf
    273     PKGARGS=install
    274     PACKAGES="autoconf
    275               automake
    276               gcc
    277               gcc-c++
    278               libpng-devel
    279               make
    280               poppler-devel
    281               poppler-glib-devel
    282               zlib-devel"
    283     VERSION=$(source_var /etc/os-release VERSION_ID)
    284     if [ -n "$VERSION" ] && [ "$VERSION" -ge 26 ]; then
    285         PACKAGES="$PACKAGES pkgconf"
    286     else
    287         PACKAGES="$PACKAGES pkgconfig"
    288     fi
    289     return 0
    290 }
    291 
    292 # Debian/Ubuntu
    293 os_debian() {
    294     if ! [ -e "/etc/debian_version" ]; then
    295         return 1
    296     fi
    297     PACKAGES="autoconf
    298               automake
    299               g++
    300               gcc
    301               libpng-dev
    302               libpoppler-dev
    303               libpoppler-glib-dev
    304               libpoppler-private-dev
    305               libz-dev
    306               make
    307               pkg-config"
    308     PKGCMD=apt-get
    309     PKGARGS="install -y"
    310     return 0
    311 }
    312 
    313 # Msys2
    314 os_msys2() {
    315     if [ -z "$MSYSTEM" ] || ! [ -r "/etc/profile" ]; then
    316         return 1
    317     fi
    318     case $MSYSTEM in
    319         MINGW64)
    320             PACKAGES="base-devel
    321                       mingw-w64-x86_64-libpng
    322                       mingw-w64-x86_64-poppler
    323                       mingw-w64-x86_64-toolchain
    324                       mingw-w64-x86_64-zlib" ;;
    325         MINGW32)
    326             PACKAGES="base-devel
    327                       mingw-w64-i686-libpng
    328                       mingw-w64-i686-poppler
    329                       mingw-w64-i686-toolchain
    330                       mingw-w64-i686-zlib" ;;
    331         MSYS)
    332             case $(uname -m) in
    333                 x86_64)
    334                     MSYSTEM=MINGW64 ;;
    335                 *)
    336                     MSYSTEM=MINGW32 ;;
    337             esac
    338             export MSYSTEM
    339             # shellcheck source=/dev/null
    340             . /etc/profile
    341             eval "exec $(quote "$0" "$@")" ;;
    342         *)
    343             echo "Unrecognized MSYSTEM value: $MSYSTEM"
    344             exit 1 ;;
    345     esac
    346     PKGCMD=pacman
    347     PKGARGS="-S --needed"
    348     PKG_INSTALL_AS_ROOT=
    349     return 0
    350 }
    351 
    352 # MacOS
    353 os_macos() {
    354     if ! which uname >/dev/null 2>&1 || [ "$(uname -s)" != "Darwin" ]; then
    355         return 1
    356     elif which brew >/dev/null 2>&1; then
    357         PKGCMD=brew
    358         PKGARGS=install
    359         PACKAGES="pkg-config poppler automake"
    360         PKG_INSTALL_AS_ROOT=
    361         # homebrew install libffi as keg-only, meaning we need to set
    362         # PKG_CONFIG_PATH manually so configure can find it
    363         export PKG_CONFIG_PATH="$(brew --prefix libffi)/lib/pkgconfig/"
    364     elif which port >/dev/null 2>&1; then
    365         PKGCMD=port
    366         PKGARGS=install
    367         PACKAGES="pkgconfig poppler automake libpng"
    368     else
    369         return 1
    370     fi
    371     return 0
    372 }
    373 
    374 # NixOS
    375 os_nixos() {
    376     # Already in the nix-shell.
    377     if [ -n "$AUTOBUILD_NIX_SHELL" ]; then
    378         return 0
    379     fi
    380     if ! which nix-shell >/dev/null 2>&1; then
    381         return 1
    382     fi
    383     if [ -n "$DRY_RUN" ]; then
    384         return 0
    385     fi
    386     command="AUTOBUILD_NIX_SHELL=true"
    387     command="$command;export AUTOBUILD_NIX_SHELL"
    388     command="$command;$(quote "$0" "$@")"
    389     exec nix-shell --pure --command "$command" \
    390          -p gcc gnumake automake autoconf pkgconfig libpng zlib poppler
    391 }
    392 
    393 # Gentoo
    394 os_gentoo() {
    395     if ! [ -e "/etc/gentoo-release" ]; then
    396         return 1
    397     fi
    398     PKGCMD=emerge
    399     PKGARGS=--noreplace
    400     PACKAGES="app-text/poppler
    401               dev-util/pkgconfig
    402               media-libs/libpng
    403               sys-devel/autoconf
    404               sys-devel/automake
    405               sys-devel/gcc
    406               sys-devel/make
    407               sys-libs/zlib"
    408     return 0
    409 }
    410 
    411 # By Parameter --os
    412 os_argument() {
    413     [ -z "$OS" ] && return 1
    414     case $OS in
    415         macos)   os_macos   "$@";;
    416         freebsd) os_freebsd "$@";;
    417         arch)    os_arch    "$@";;
    418         centos)  os_centos  "$@";;
    419         openbsd) os_openbsd "$@";;
    420         fedora)  os_fedora  "$@";;
    421         debian)  os_debian  "$@";;
    422         gentoo)  os_gentoo  "$@";;
    423         msys2)   os_msys2   "$@";;
    424         nixos)   os_nixos   "$@";;
    425         *)       echo "Invalid --os argument: $OS"
    426                  exit 1
    427     esac || {
    428         echo "Unable to install on this system as $OS"
    429         exit 1
    430     }
    431 }
    432 
    433 ## +-----------------------------------------------------------+
    434 ## * Figure out were we are, install deps and build the program
    435 ## +-----------------------------------------------------------+
    436 
    437 handle_options "$@"
    438 
    439 os_argument "$@" || \
    440 os_macos    "$@" || \
    441 os_freebsd  "$@" || \
    442 os_arch     "$@" || \
    443 os_centos   "$@" || \
    444 os_openbsd  "$@" || \
    445 os_fedora   "$@" || \
    446 os_debian   "$@" || \
    447 os_gentoo   "$@" || \
    448 os_msys2    "$@" || \
    449 os_nixos    "$@" || \
    450 {
    451     OS_IS_HANDLED=
    452     if [ -z "$DRY_RUN" ]; then
    453         echo "Failed to recognize this system, trying to continue."
    454     fi
    455 }
    456 
    457 if [ -n "$DRY_RUN" ]; then
    458     [ -n "$OS_IS_HANDLED" ]
    459     exit $?
    460 fi
    461 
    462 if [ -n "$PKGCMD" ];then
    463     echo "---------------------------"
    464     echo "    Installing packages    "
    465     echo "---------------------------"
    466     if [ -n "$PKG_INSTALL_SKIP" ]; then
    467         echo "Skipping package installation (as requested)"
    468     elif [ -z "$PKG_INSTALL_FORCE" ] && have_packages_installed; then
    469         echo "Skipping package installation (already installed)"
    470     else
    471         assert_program "$PKGCMD"
    472         echo "$PKGCMD $PKGARGS $PACKAGES"
    473         if [ -n "$PKG_INSTALL_AS_ROOT" ]; then
    474             exec_privileged $PKGCMD $PKGARGS $PACKAGES
    475         else
    476             $PKGCMD $PKGARGS $PACKAGES
    477         fi
    478     fi
    479     echo
    480 fi
    481 
    482 # Try to be in the correct directory.
    483 if which dirname >/dev/null 2>&1; then
    484     cd "$(dirname "$0")" || {
    485         echo "Failed to change into the source directory"
    486         exit 1
    487     }
    488 fi
    489 
    490 echo "---------------------------"
    491 echo " Configuring and compiling "
    492 echo "---------------------------"
    493 
    494 # Create the configure script.
    495 if ! [ -f ./configure ]; then
    496     assert_program autoreconf
    497     echo "autoreconf -i"
    498     autoreconf -i
    499     [ -f ./configure ] || exit_fail
    500 fi
    501 
    502 # Build the program.
    503 if [ -n "$INSTALL_DIR" ]; then
    504     prefix=--bindir=$INSTALL_DIR
    505 fi
    506 
    507 echo "./configure -q $prefix && make clean && make -s"
    508 eval "./configure -q $(quote "$prefix") && make clean && make -s || exit_fail"
    509 echo
    510 if [ -n "$INSTALL_DIR" ]; then
    511     echo "---------------------------"
    512     echo "       Installing          "
    513     echo "---------------------------"
    514     echo make -s install
    515     if mkdir -p -- "$INSTALL_DIR" && [ -w "$INSTALL_DIR" ]; then
    516         make install || exit_fail
    517     else
    518         exec_privileged make install || exit_fail
    519     fi
    520     # Copy dynamic libraries on windows.
    521     if [ -f epdfinfo.exe ]; then
    522         assert_program awk
    523         assert_program ldd
    524         for dll in $(ldd epdfinfo.exe | awk '/\/mingw/ {print $3}'); do
    525             cp -u "$dll" "$INSTALL_DIR"
    526         done
    527     fi
    528     echo
    529 fi
    530 exit_success
    531 
    532 # Local Variables:
    533 # compile-command: "shellcheck autobuild"
    534 # End: