Luke Shumaker » blog » build-bash-1

Building Bash 1.14.7 on a modern system

In a previous revision of my Bash arrays post, I wrote:

Bash 1.x won’t compile with modern GCC, so I couldn’t verify how it behaves.

I recall spending a little time fighting with it, but apparently I didn’t try very hard: getting Bash 1.14.7 to build on a modern box is mostly just adjusting it to use stdarg instead of the no-longer-implemented varargs. There’s also a little fiddling with the pre-autoconf automatic configuration.


Converting to stdarg is pretty simple: For each variadic function (functions that take a variable number of arguments), follow these steps:

  1. Replace #include <varargs.h> with #include <stdarg.h>
  2. Replace function_name (va_alist) va_dcl with function_name (char *format, ...).
  3. Removing the declaration and assignment for format from the function body.
  4. Replace va_start (args); with va_start (args, format); in the function bodies.
  5. Replace function_name (); with function_name (char *, ...) in header files and/or at the top of C files.

There’s one function that uses the variable name control instead of format.

I’ve prepared a patch that does this.


Instead of using autoconf-style tests to test for compiler and platform features, Bash 1 used the file machines.h that had #ifdefs and a huge database of of different operating systems for different platforms. It’s gross. And quite likely won’t handle your modern operating system.

I made these two small changes to machines.h to get it to work correctly on my box:

  1. Replace #if defined (i386) with #if defined (i386) || defined (__x86_64__). The purpose of this is obvious.
  2. Add #define USE_TERMCAP_EMULATION to the section for Linux [sic] on i386 (# if !defined (done386) && (defined (__linux__) || defined (linux))). What this does is tell it to link against libcurses to use curses termcap emulation, instead of linking against libtermcap (which doesn’t exist on modern GNU/Linux systems).

Again, I’ve prepared a patch that does this.


With those adjustments, it should build, but with quite a few warnings. Making a couple of changes to CFLAGS should fix that:

make CFLAGS='-O -g -Werror -Wno-int-to-pointer-cast -Wno-pointer-to-int-cast -Wno-deprecated-declarations -include stdio.h -include stdlib.h -include string.h -Dexp2=bash_exp2'

That’s a doozy! Let’s break it down:

Have fun, software archaeologists!