autogen.sh 9.92 KB
Newer Older
1
#!/bin/sh
2
### autogen.sh - tool to help build Emacs from a repository checkout
3

Paul Eggert's avatar
Paul Eggert committed
4
## Copyright (C) 2011-2018 Free Software Foundation, Inc.
5

6
## Author: Glenn Morris <rgm@gnu.org>
7
## Maintainer: emacs-devel@gnu.org
8 9 10 11 12 13 14 15 16 17 18 19 20 21

## This file is part of GNU Emacs.

## GNU Emacs is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.

## GNU Emacs is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.

## You should have received a copy of the GNU General Public License
22
## along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
23 24 25

### Commentary:

26 27
## The Emacs repository does not include the configure script (and
## associated helpers).  The first time you fetch Emacs from the repo,
28
## run this script to generate the necessary files.
29
## For more details, see the file INSTALL.REPO.
30 31 32 33

### Code:

## Tools we need:
34
## Note that we respect the values of AUTOCONF etc, like autoreconf does.
Paul Eggert's avatar
Paul Eggert committed
35
progs="autoconf"
36 37

## Minimum versions we need:
38
autoconf_min=`sed -n 's/^ *AC_PREREQ(\([0-9\.]*\)).*/\1/p' configure.ac`
39 40 41 42 43 44 45 46 47


## $1 = program, eg "autoconf".
## Echo the version string, eg "2.59".
## FIXME does not handle things like "1.4a", but AFAIK those are
## all old versions, so it is OK to fail there.
## Also note that we do not handle micro versions.
get_version ()
{
48 49
    vers=`($1 --version) 2> /dev/null` && expr "$vers" : '[^
]* \([0-9][0-9.]*\).*'
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
}

## $1 = version string, eg "2.59"
## Echo the major version, eg "2".
major_version ()
{
    echo $1 | sed -e 's/\([0-9][0-9]*\)\..*/\1/'
}

## $1 = version string, eg "2.59"
## Echo the minor version, eg "59".
minor_version ()
{
    echo $1 | sed -e 's/[0-9][0-9]*\.\([0-9][0-9]*\).*/\1/'
}

## $1 = program
## $2 = minimum version.
Paul Eggert's avatar
Paul Eggert committed
68
## Return 0 if program is present with version >= minimum version.
69 70 71 72 73
## Return 1 if program is missing.
## Return 2 if program is present but too old.
## Return 3 for unexpected error (eg failed to parse version).
check_version ()
{
Paul Eggert's avatar
Paul Eggert committed
74
    ## Respect, e.g., $AUTOCONF if it is set, like autoreconf does.
75
    uprog0=`echo $1 | sed -e 's/-/_/g' -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
76

77
    eval uprog=\$${uprog0}
78

79 80 81 82 83
    if [ x"$uprog" = x ]; then
        uprog=$1
    else
        printf '%s' "(using $uprog0=$uprog) "
    fi
84

85 86
    command -v $uprog > /dev/null || return 1
    have_version=`get_version $uprog` || return 4
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104

    have_maj=`major_version $have_version`
    need_maj=`major_version $2`

    [ x"$have_maj" != x ] && [ x"$need_maj" != x ] || return 3

    [ $have_maj -gt $need_maj ] && return 0
    [ $have_maj -lt $need_maj ] && return 2

    have_min=`minor_version $have_version`
    need_min=`minor_version $2`

    [ x"$have_min" != x ] && [ x"$need_min" != x ] || return 3

    [ $have_min -ge $need_min ] && return 0
    return 2
}

105
do_check=true
106
do_autoconf=false
107 108
do_git=false

109
for arg; do
110 111
    case $arg in
      --help)
112 113
	exec echo "$0: usage: $0 [--no-check] [target...]
  Targets are: all autoconf git";;
114
      --no-check)
115
        do_check=false;;
116
      all)
117
	do_autoconf=true
118
	test -r .git && do_git=true;;
119
      autoconf)
120
	do_autoconf=true;;
121 122 123 124 125 126 127
      git)
	do_git=true;;
      *)
	echo >&2 "$0: $arg: unknown argument"; exit 1;;
    esac
done

128 129
case $do_autoconf,$do_git in
  false,false)
Paul Eggert's avatar
Paul Eggert committed
130
    do_autoconf=true
131
    test -r .git && do_git=true;;
132
esac
133

Paul Eggert's avatar
Paul Eggert committed
134
# Generate Autoconf-related files, if requested.
135

136
if $do_autoconf; then
137

138 139 140
  if $do_check; then

    echo 'Checking whether you have the necessary tools...
141
(Read INSTALL.REPO for more details on building Emacs)'
142

143
    missing=
144

145
    for prog in $progs; do
146

147
      sprog=`echo "$prog" | sed 's/-/_/g'`
Glenn Morris's avatar
Glenn Morris committed
148

149
      eval min=\$${sprog}_min
150

151
      printf '%s' "Checking for $prog (need at least version $min) ... "
152

153
      check_version $prog $min
154

155
      retval=$?
156

157 158 159 160
      case $retval in
          0) stat="ok" ;;
          1) stat="missing" ;;
          2) stat="too old" ;;
161
          4) stat="broken?" ;;
162 163
          *) stat="unable to check" ;;
      esac
164

165
      echo $stat
166

167 168 169 170
      if [ $retval -ne 0 ]; then
          missing="$missing $prog"
          eval ${sprog}_why=\""$stat"\"
      fi
171

172
    done
173 174


175
    if [ x"$missing" != x ]; then
176

177
      echo '
178
Building Emacs from the repository requires the following specialized programs:'
179

180 181
      for prog in $progs; do
          sprog=`echo "$prog" | sed 's/-/_/g'`
Glenn Morris's avatar
Glenn Morris committed
182

183
          eval min=\$${sprog}_min
184

185 186
          echo "$prog (minimum version $min)"
      done
187 188


189
      echo '
190
Your system seems to be missing the following tool(s):'
191

192 193
      for prog in $missing; do
          sprog=`echo "$prog" | sed 's/-/_/g'`
Glenn Morris's avatar
Glenn Morris committed
194

195
          eval why=\$${sprog}_why
196

197 198
          echo "$prog ($why)"
      done
199

200
      echo '
201 202 203 204 205 206 207 208 209 210 211 212
If you think you have the required tools, please add them to your PATH
and re-run this script.

Otherwise, please try installing them.
On systems using rpm and yum, try: "yum install PACKAGE"
On systems using dpkg and apt, try: "apt-get install PACKAGE"
Then re-run this script.

If you do not have permission to do this, or if the version provided
by your system is too old, it is normally straightforward to build
these packages from source.  You can find the sources at:

213
https://ftp.gnu.org/gnu/PACKAGE/
214 215 216 217 218 219 220

Download the package (make sure you get at least the minimum version
listed above), extract it using tar, then run configure, make,
make install.  Add the installation directory to your PATH and re-run
this script.

If you know that the required versions are in your PATH, but this
221 222
script has made an error, then you can simply re-run this script with
the --no-check option.
223

224
Please report any problems with this script to bug-gnu-emacs@gnu.org .'
225

226 227 228 229
      exit 1
    fi

    echo 'Your system has the required tools.'
230

231
  fi                            # do_check
232

Paul Eggert's avatar
Paul Eggert committed
233 234 235 236 237 238 239 240 241 242 243
  # Build aclocal.m4 here so that autoreconf need not use aclocal.
  # aclocal is part of Automake and might not be installed, and
  # autoreconf skips aclocal if aclocal.m4 is already supplied.
  ls m4/*.m4 | LC_ALL=C sort | sed 's,.*\.m4$,m4_include([&]),' \
    > aclocal.m4.tmp || exit
  if cmp -s aclocal.m4.tmp aclocal.m4; then
    rm -f aclocal.m4.tmp
  else
    echo "Building aclocal.m4 ..."
    mv aclocal.m4.tmp aclocal.m4
  fi || exit
244 245

  echo "Running 'autoreconf -fi -I m4' ..."
246 247 248

  ## Let autoreconf figure out what, if anything, needs doing.
  ## Use autoreconf's -f option in case autoreconf itself has changed.
Paul Eggert's avatar
Paul Eggert committed
249
  autoreconf -fi -I m4 || exit
250 251 252
fi


253
# True if the Git setup was OK before autogen.sh was run.
254

255
git_was_ok=true
256

257 258 259 260 261 262 263 264
if $do_git; then
    case `cp --help 2>/dev/null` in
      *--backup*--verbose*)
	cp_options='--backup=numbered --verbose';;
      *)
	cp_options='-f';;
    esac
fi
265

266

267 268
# Like 'git config NAME VALUE' but verbose on change and exiting on failure.
# Also, do not configure unless requested.
269

270 271
git_config ()
{
272 273
    $do_git || return

274 275 276 277
    name=$1
    value=$2

    ovalue=`git config --get "$name"` && test "$ovalue" = "$value" || {
278 279 280 281 282 283 284 285 286 287 288
       if $git_was_ok; then
	   echo 'Configuring local git repository...'
	   case $cp_options in
	       --backup=*)
		   config=$git_common_dir/config
		   cp $cp_options --force -- "$config" "$config" || exit;;
	   esac
       fi
       echo "git config $name '$value'"
       git config "$name" "$value" || exit
       git_was_ok=false
289 290 291 292 293
    }
}

## Configure Git, if requested.

294 295 296
# Get location of Git's common configuration directory.  For older Git
# versions this is just '.git'.  Newer Git versions support worktrees.

297
{ test -r .git &&
Paul Eggert's avatar
Paul Eggert committed
298 299 300
  git_common_dir=`git rev-parse --no-flags --git-common-dir 2>/dev/null` &&
  test -n "$git_common_dir"
} || git_common_dir=.git
301 302
hooks=$git_common_dir/hooks

303 304 305 306 307 308
# Check hashes when transferring objects among repositories.

git_config transfer.fsckObjects true


# Configure 'git diff' hunk header format.
309

310 311
git_config diff.elisp.xfuncname \
	   '^\(def[^[:space:]]+[[:space:]]+([^()[:space:]]+)'
312 313 314 315 316
git_config 'diff.m4.xfuncname' '^((m4_)?define|A._DEFUN(_ONCE)?)\([^),]*'
git_config 'diff.make.xfuncname' \
	   '^([$.[:alnum:]_].*:|[[:alnum:]_]+[[:space:]]*([*:+]?[:?]?|!?)=|define .*)'
git_config 'diff.shell.xfuncname' \
	   '^([[:space:]]*[[:alpha:]_][[:alnum:]_]*[[:space:]]*\(\)|[[:alpha:]_][[:alnum:]_]*=)'
317 318
git_config diff.texinfo.xfuncname \
	   '^@node[[:space:]]+([^,[:space:]][^,]+)'
319 320


321
# Install Git hooks.
322

323 324
tailored_hooks=
sample_hooks=
325

326
for hook in commit-msg pre-commit; do
327
    cmp -- build-aux/git-hooks/$hook "$hooks/$hook" >/dev/null 2>&1 ||
328
	tailored_hooks="$tailored_hooks $hook"
329
done
330 331 332 333 334 335 336 337 338 339 340 341

git_sample_hook_src ()
{
    hook=$1
    src=$hooks/$hook.sample
    if test ! -r "$src"; then
	case $hook in
	    applypatch-msg) src=build-aux/git-hooks/commit-msg;;
	    pre-applypatch) src=build-aux/git-hooks/pre-commit;;
	esac
    fi
}
342
for hook in applypatch-msg pre-applypatch; do
343 344
    git_sample_hook_src $hook
    cmp -- "$src" "$hooks/$hook" >/dev/null 2>&1 ||
345
	sample_hooks="$sample_hooks $hook"
346
done
347

348 349
if test -n "$tailored_hooks$sample_hooks"; then
    if $do_git; then
350 351
	echo "Installing git hooks..."

352 353 354 355 356
	if test ! -d "$hooks"; then
	    printf "mkdir -p -- '%s'\\n" "$hooks"
	    mkdir -p -- "$hooks" || exit
	fi

357 358
	if test -n "$tailored_hooks"; then
	    for hook in $tailored_hooks; do
359 360 361
		dst=$hooks/$hook
		cp $cp_options -- build-aux/git-hooks/$hook "$dst" || exit
		chmod -- a-w "$dst" || exit
362 363 364 365 366
	    done
	fi

	if test -n "$sample_hooks"; then
	    for hook in $sample_hooks; do
367
		git_sample_hook_src $hook
368
		dst=$hooks/$hook
369
		cp $cp_options -- "$src" "$dst" || exit
370
		chmod -- a-w "$dst" || exit
371 372
	    done
	fi
373 374
    else
	git_was_ok=false
375 376 377
    fi
fi

378 379
if test ! -f configure; then
    echo "You can now run '$0 autoconf'."
380
elif test -r .git && test $git_was_ok = false && test $do_git = false; then
381 382
    echo "You can now run '$0 git'."
elif test ! -f config.status ||
Paul Eggert's avatar
Paul Eggert committed
383
	test -n "`find configure src/config.in -newer config.status`"; then
384 385
    echo "You can now run './configure'."
fi
386 387 388 389

exit 0

### autogen.sh ends here