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.
stdarg is pretty simple: For each variadic function (functions that take a variable number of arguments), follow these steps:
function_name (va_alist) va_dclwith
function_name (char *format, ...).
- Removing the declaration and assignment for
formatfrom the function body.
va_start (args, format);in the function bodies.
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
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:
#if defined (i386)with
#if defined (i386) || defined (__x86_64__). The purpose of this is obvious.
#define USE_TERMCAP_EMULATIONto 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:
-O -gThe default value for CFLAGS (defined in
-WerrorTreat warnings as errors; force us to deal with any issues.
-Wno-int-to-pointer-cast -Wno-pointer-to-int-castAllow casting between integers and pointers. Unfortunately, the way this version of Bash was designed requires this.
unistd.his considered deprecated (use
getcwdinstead). However, if
getcwdis available, Bash uses it’s own
general.c), and only uses the signature from
unistd.h, not the actuall implementation from libc.
-include stdio.h -include stdlib.h -include string.hSeveral files are missing these header file includes. If not for
-Werror, the default function signature fallbacks would work.
-Dexp2=bash_exp2Avoid a conflict between the parser’s
exp2helper function and
math.h’s base-2 exponential function.
Have fun, software archaeologists!