From c02fbeff112e0172d0ad12bf7709099784305396 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Wed, 18 Mar 2015 20:41:52 -0400 Subject: Hey, I built Bash 1.14 on a modern box! --- public/build-bash-1.md | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 public/build-bash-1.md (limited to 'public/build-bash-1.md') diff --git a/public/build-bash-1.md b/public/build-bash-1.md new file mode 100644 index 0000000..e70a36b --- /dev/null +++ b/public/build-bash-1.md @@ -0,0 +1,87 @@ +Building Bash 1.14.7 on a modern system +======================================= +--- +date: "2015-03-18" +--- + +In a previous revision of my [Bash arrays post](./bash-arrays.html), 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 + +Converting to `stdarg` is pretty simple: For each variadic function +(functions that take a variable number of arguments), follow these steps: + +1. Replace `#include ` with `#include ` +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](./bash-1.14.7-gcc4-stdarg.patch) that does this. + +## Configuration + +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 use 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](./bash-1.14.7-machines-config.patch) +that does this. + +## Building + +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 -g` The default value for CFLAGS (defined in `cpp-Makefile`) +- `-Werror` Treat warnings as errors; force us to deal with any issues. +- `-Wno-int-to-pointer-cast -Wno-pointer-to-int-cast` Allow casting + between integers and pointers. Unfortunately, the way this version + of Bash was designed requires this. +- `-Wno-deprecated-declarations`. The `getwd` function in `unistd.h` + is considered deprecated (use `getcwd` instead). However, if + `getcwd` is available, Bash uses it's own `getwd` wrapper around + `getcwd` (implemented in `general.c`), and only uses the signature + from `unistd.h`, not the actually implementation from libc. +- `-include stdio.h -include stdlib.h -include string.h` Several files + are missing these header file includes. If not for `-Werror`, the + default function signature fallbacks would work. +- `-Dexp2=bash_exp2` Avoid a conflict between the parser's `exp2` + helper function and `math.h`'s base-2 exponential function. + +Have fun, software archaeologists! -- cgit v1.2.3