1#!/bin/sh
2VERSION='2017-09-19 07:31' # UTC
3
4# Building coreutils from a git-cloned directory may require versions of
5# tools like autoconf, automake, gettext, etc. that are newer than the ones
6# provided by the distribution on which you want to build.  In that case,
7# you can use this script to bootstrap the "autotools" tool chain, starting
8# with m4 (prereq of autoconf), then autoconf (prereq of automake), etc.
9# It also builds a few others, including gettext and pkg-config.
10# The results are installed in a directory whose --prefix you specify, and
11# it tells you how to update envvars like PATH and (if you use pkg-config)
12# PKG_CONFIG_PATH.
13
14# On principle, I find it best to ensure that packages I care about work
15# with the latest versions of all of these tools.  While these tools are
16# paragons of portability, you should ensure that recent distribution
17# versions work, too.
18
19# Written by Jim Meyering
20
21# For systems with limited/botched make (the case of most vendor makes!),
22# allow the user to override it.
23MAKE=${MAKE-make}
24
25prog_name=`basename $0`
26die () { echo "$prog_name: $*" >&2; exit 1; }
27
28tarballs='
29  https://pkgconfig.freedesktop.org/releases/pkg-config-0.28.tar.gz
30  https://ftp.gnu.org/gnu/m4/m4-1.4.17.tar.gz
31  https://ftp.gnu.org/gnu/autoconf/autoconf-2.69.tar.gz
32  https://ftp.gnu.org/gnu/automake/automake-1.15.tar.gz
33  https://ftp.gnu.org/gnu/libtool/libtool-2.4.6.tar.gz
34  https://ftp.gnu.org/gnu/gettext/gettext-0.19.6.tar.gz
35'
36
37usage() {
38  echo >&2 "\
39Usage: $0 [OPTION]...
40Download, build, and install some tools.
41
42Options:
43 --prefix=PREFIX    install tools under specified directory
44 --skip-check       do not run \"make check\" (this can save 50+ min)
45 --help             display this help and exit
46
47For example, to install programs into \$HOME/autotools/bin, run this command:
48
49  $prog_name --prefix=\$HOME/autotools
50
51If you've already verified that your system/environment can build working
52versions of these tools, you can make this script complete in just a
53minute or two (rather than about an hour if you let all \"make check\"
54tests run) by invoking it like this:
55
56  $prog_name --prefix=\$HOME/autotools --skip-check
57
58"
59}
60
61# Get the public keys associated with each .sig file.
62# for i in *.sig; do k=$(gpgv $i 2>&1 | sed -n 's/.*key ID //p'); \
63# gpg --keyserver pgp.mit.edu --recv-key $k; done
64
65# Get the listed tarballs into the current directory.
66get_sources()
67{
68  case `wget --help` in
69    *'--no-cache'*)
70      WGET_COMMAND='wget -nv --no-cache';;
71    *'--cache=on/off'*)
72      WGET_COMMAND='wget -nv --cache=off';;
73    *'--non-verbose'*)
74      WGET_COMMAND='wget -nv';;
75    *)
76      die 'no wget program found; please install it and try again';;
77  esac
78
79  # Download the each tar-ball along with its signature, if there is one.
80  pkgs=
81  for t in $tarballs; do
82    base=`basename $t`
83    pkgs="$pkgs $base"
84    test -f $base || $WGET_COMMAND $t
85
86    # No signatures for some :-(
87    case $base in pkg-config*) continue;; esac
88
89    test -f $base.sig || $WGET_COMMAND $t.sig
90    # Verify each signature.
91    gpg --quiet --verify --trust-model=always   \
92        --trusted-key=32419B785D0CDCFC          \
93        --trusted-key=3859C03B2E236E47          \
94        --trusted-key=B93F60C6B5C4CE13          \
95        --trusted-key=F382AE19F4850180          \
96        --trusted-key=FC818E17429F96EA          \
97        --trusted-key=60F906016E407573          \
98        --trusted-key=D605848ED7E69871          \
99        $base.sig > /dev/null 2>&1              \
100      || echo "info: not verifying GPG signature for $base" 1>&2
101  done
102  printf 'ok\n' 1>&2
103  echo $pkgs
104}
105
106#################################################################
107set -e
108
109# Parse options.
110
111make_check=yes
112prefix=
113
114for option
115do
116  case $option in
117    --help) usage; exit;;
118    --skip-check) make_check=no;;
119    --prefix=*) prefix=`expr "$option" : '--prefix=\(.*\)'`;;
120    *) die "$option: unknown option";;
121  esac
122done
123
124test -n "$prefix" \
125  || die "you must specify a --prefix"
126
127case $prefix in
128  /*) ;;
129  *) die 'invalid prefix: '"$prefix"': it must be an absolute name';;
130esac
131
132# Don't run as root.
133# Make sure id -u succeeds.
134my_uid=`id -u` && test -n "$my_uid" || die "'id -u' failed"
135test $my_uid -ne 0 || die "please don't run this program as root"
136
137# Ensure that prefix is not /usr/bin or /bin, /sbin, etc.
138case $prefix in
139  /bin|/sbin|/usr/bin|/usr/sbin)
140    die "don't set PREFIX to a system directory";;
141  *) ;;
142esac
143
144# Create a build directory, then cd into it for the rest....
145tmpdir=.build-auto-tools
146mkdir -p $tmpdir
147cd $tmpdir
148
149pkgs=`get_sources`
150
151export PATH=$prefix/bin:$PATH
152for pkg in $pkgs; do
153  echo building/installing $pkg...
154  dir=`basename $pkg .tar.gz`
155  rm -rf $dir
156  gzip -dc $pkg | tar xf -
157  cd $dir
158  ./configure CFLAGS=-O2 LDFLAGS=-s --prefix=$prefix >makerr-config 2>&1
159  $MAKE >makerr-build 2>&1
160  if test $make_check = yes; then
161    case $pkg in
162      # FIXME: these are out of date and very system-sensitive
163      automake*) expected_duration_minutes=40;;
164      autoconf*) expected_duration_minutes=15;;
165      libtool*) expected_duration_minutes=3;;
166      *);;
167    esac
168    if test -n "$expected_duration_minutes"; then
169      echo "running 'make check' for $pkg; NB: this can take over" \
170           "$expected_duration_minutes minutes"
171    fi
172    $MAKE check >makerr-check 2>&1
173  fi
174  $MAKE install >makerr-install 2>&1
175  echo "done at `date +%Y-%m-%d.%T`"
176  cd ..
177done
178
179# Without checks (and with existing tarballs), it takes just one minute.
180# Including all checks, it takes nearly an hour on an AMD64/3400+
181
182case $PKG_CONFIG_PATH in
183  $prefix/lib/pkgconfig:/usr/lib/pkgconfig)
184    echo 'Good! your PKG_CONFIG_PATH envvar is already set';;
185  *) cat <<EOF;;
186**************************************************************************
187Be sure that PKG_CONFIG_PATH is set in your environment, e.g.,
188PKG_CONFIG_PATH=$prefix/lib/pkgconfig:/usr/lib/pkgconfig
189**************************************************************************
190EOF
191esac
192
193case $PATH in
194  "$prefix/bin:"*) echo 'Good! your PATH is fine';;
195  *) cat <<EOF;;
196**************************************************************************
197Be sure that "$prefix/bin" is earlier in your PATH than /bin, /usr/bin, etc.
198**************************************************************************
199EOF
200esac
201
202cat <<EOF
203**************************************************************************
204You may want to remove the tool build directory:
205rm -rf $tmpdir
206**************************************************************************
207EOF
208
209## Local Variables:
210## eval: (add-hook 'write-file-hooks 'time-stamp)
211## time-stamp-start: "VERSION='"
212## time-stamp-format: "%:y-%02m-%02d %02H:%02M"
213## time-stamp-time-zone: "UTC"
214## time-stamp-end: "' # UTC"
215## End:
216