|René Nyffenegger's collection of things on the web|
René Nyffenegger on Oracle - Most wanted - Feedback
- Follow @renenyffenegger
The GNU build system
I'd say that more than 90% of the folks who have ever compiled an open source program, have followed this simple recipe steps:
I'd also say, that less than 10% of these people know how to assemble a package so that it can be compiled and installed with this recipe. Well, I certainly didn't, so I investigated what is known as the GNU build system.
I have tested the following on Windows with Cygwin. The necessary tools (like automake, autoconf, a shell and so on) need of course be installed.
First, I developped a very simple program that displays yesterday's date.
#ifndef PRINTDATE_H #define PRINTDATE_H #include <time.h> void printdate(); #endif
#ifndef YESTERDAY_H #define YESTERDAY_H #include <time.h> time_t yesterday(); #endif
Of course, this program is so simple that it could be compiled with a
But that's not what I am going to do.
For some reason (or maybe another?), autoscan requires the presence of a configure.ac file which can be empty. So I create one:
$ touch configure.ac
Now, I can run autoscan:
$ autoscan configure.ac: warning: missing AC_FUNC_STRFTIME wanted by: printdate.c:9 configure.ac: warning: missing AC_PREREQ wanted by: autoscan configure.ac: warning: missing AC_PROG_CC wanted by: main.c configure.ac: warning: missing AC_STRUCT_TM wanted by: printdate.c:4
autoscan also checks for portability issues. In my case, it found two: strftime and the tm struct are not 100% portable.
autoscan has created a
$ less configure.scan # -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_PREREQ(2.59) AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS) AC_CONFIG_SRCDIR([main.c]) AC_CONFIG_HEADER([config.h]) # Checks for programs. AC_PROG_CC # Checks for libraries. # Checks for header files. # Checks for typedefs, structures, and compiler characteristics. AC_STRUCT_TM # Checks for library functions. AC_FUNC_STRFTIME AC_OUTPUT
This file can now be used as a skeletton for the real configure.ac:
$ cp configure.scan configure.ac
I have changed this configure.ac:
# -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_PREREQ(2.59) AC_INIT(yesterday, 1.0) AM_INIT_AUTOMAKE AC_CONFIG_SRCDIR([main.c]) AC_CONFIG_HEADER([config.h]) # Checks for programs. AC_PROG_CC # Checks for libraries. # Checks for header files. # Checks for typedefs, structures, and compiler characteristics. AC_STRUCT_TM # Checks for library functions. AC_FUNC_STRFTIME AC_CONFIG_FILES([Makefile]) AC_OUTPUT
aclocal must be run in order to create
It was now time to create a Makefile.am.
bin_PROGRAMS = yesterday yesterday_SOURCES = main.c yesterday.c yesterday.h printdate.c printdate.h
autoheader is used to create a
Automake requires that the following files are present when it is invoked:
If automake is invoked with the -a option, it creates install-sh, missing, INSTALL, COPYING and depcomp. The rest must be created manually. For brevity's sake, I just touched them:
$ touch NEWS README AUTHORS ChangeLog
I was now ready to invoke automake, which created Makefile.in.
$ automake -a configure.ac: installing `./install-sh' configure.ac: installing `./missing' Makefile.am: installing `./INSTALL' Makefile.am: installing `./COPYING' Makefile.am: installing `./depcomp'
I am now creating the infamous
Testing the created
./configure checking for a BSD-compatible install... /usr/bin/install -c checking whether build environment is sane... yes checking for gawk... gawk checking whether make sets $(MAKE)... yes checking for gcc... gcc checking for C compiler default output file name... a.exe checking whether the C compiler works... yes checking whether we are cross compiling... no checking for suffix of executables... .exe checking for suffix of object files... o checking whether we are using the GNU C compiler... yes checking whether gcc accepts -g... yes checking for gcc option to accept ANSI C... none needed checking for style of include used by make... GNU checking dependency style of gcc... gcc3 checking whether struct tm is in sys/time.h or time.h... time.h checking for strftime... yes configure: creating ./config.status config.status: creating Makefile config.status: creating config.h config.status: executing depfiles commands
As can be seen from the output, it checks if
Creating a deliverable package:
Now, that I have a
$ make dist-gzip
This creates a
So, let's copy this file to a different (clean) directory and test it:
$ mkdir ../yesterday_test $ mv yesterday-1.0.tar.gz ../yesterday_test/ $ cd ../yesterday_test/ $ tar xfvz yesterday-1.0.tar.gz $ cd yesterday-1.0
So far, so good. It extracted some files and upon first inspection, all source files seem to be here as well as the configure script.
$ ./configure $ make $ make install
Ok, no errors. Let's go to yet another directory and see if yesterday can be called from there:
$ cd /tmp $ yesterday Yesterday was: 2004-11-30