Automake and Autoconf - richardjwild/arctracker GitHub Wiki
I was really hoping not to have to get into this so soon, but since my Makefile seemed to be b0rked it looked like I had no choice. GNU Autoconf is part of a suite of programs that aim to take the pain out of writing portable programs to run on various Unix systems. Essentially, you write input for Autoconf in the form of M4 macro programs, that define the various dependencies of your program. Autoconf expands the macros to produce a shell script called configure which, when run, checks the host system to see whether the dependencies are available. If any of the required dependencies are unavailable then it stops and complains. If all the required dependencies are available then it creates a header file called config.h which defines a bunch of C macros that you can use to enable and disable the parts of your codebase that depend on your optional dependencies. For example, Arctracker has optional dependencies on ALSA and aRts: these sections of the code are switched in or out by the generated config.h file depending on whether or not they are available.
Writing portable makefiles is also a non-trivial task, due to the various subtle differences in the make programs on various Unixes, and so GNU Automake is a similar tool that generates these so that they will work on the host system.
These issues that Autoconf/Automake/Libtool/whatever set out to solve are probably less difficult than they once were, now that Linux has all but taken over the Unix world. Believe me, it used to be a jungle out there. Nevertheless, Arctracker uses Auto{conf,make} and so I'm probably stuck with them. I may as well make them work properly.
According to the documentation, files used in preparing a software package for distribution, when using just Autoconf:
your source files --> [autoscan*] --> [configure.scan] --> configure.ac
configure.ac --.
| .------> autoconf* -----> configure
[aclocal.m4] --+---+
| `-----> [autoheader*] --> [config.h.in]
[acsite.m4] ---'
Makefile.in
Additionally, if you use Automake, the following additional productions come into play:
[acinclude.m4] --.
|
[local macros] --+--> aclocal* --> aclocal.m4
|
configure.ac ----'
configure.ac --.
+--> automake* --> Makefile.in
Makefile.am ---'
Files used in configuring a software package:
.-------------> [config.cache]
configure* ------------+-------------> config.log
|
[config.h.in] -. v .-> [config.h] -.
+--> config.status* -+ +--> make*
Makefile.in ---' `-> Makefile ---'
Which is...a little complicated. I really wanted to document all the steps I went through figuring all this stuff out, but I was soon eyeballs deep in GNU documentation, man pages and Stackoverflow threads...
To cut a long story short, eventually I figured out that the correct source files I needed were configure.ac:
AC_PREREQ([2.69])
AC_INIT([Arctracker], [0.2.0], [[email protected]])
AM_INIT_AUTOMAKE([foreign])
AC_CONFIG_SRCDIR([play_mod.c])
AC_CONFIG_HEADERS([config.h])
# Checks for programs.
AC_PROG_CC
# Checks for libraries.
AC_CHECK_LIB(asound, snd_pcm_writei)
AC_CHECK_LIB(artsc, arts_write)
# Checks for header files.
AC_CHECK_HEADERS([stdlib.h string.h sys/ioctl.h sys/soundcard.h sys/unistd.h sys/fcntl.h])
# Checks for typedefs, structures, and compiler characteristics.
AC_C_BIGENDIAN
# Checks for library functions.
AC_FUNC_MALLOC
AC_FUNC_REALLOC
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
and Makefile.am:
CC=@CC@
INSTALL=@INSTALL@
CFLAGS=@CFLAGS@
LDFLAGS=@LDFLAGS@
CLIBS=@LIBS@
INSTALLDIR=@prefix@
arctracker: arctracker.o initialise.o read_mod.o play_mod.o
$(CC) $(CFLAGS) $(LDFLAGS) -o arctracker arctracker.o initialise.o read_mod.o play_mod.o $(CLIBS)
arctracker.o: arctracker.h arctracker.c
$(CC) $(CFLAGS) -c arctracker.c
initialise.o: arctracker.h initialise.c
$(CC) $(CFLAGS) -c initialise.c
read_mod.o: arctracker.h read_mod.c
$(CC) $(CFLAGS) -c read_mod.c
play_mod.o: arctracker.h log_lin_tab.h play_mod.c
$(CC) $(CFLAGS) -c play_mod.c
clean:
rm -f ./arctracker ./*.o 2>/dev/null
install: arctracker
$(INSTALL) ./arctracker $(INSTALLDIR)/bin/arctracker
uninstall:
rm -f $(INSTALLDIR)/bin/arctracker 2>/dev/null
Everything else is automatically generated. To build and install the program from a fresh clone, you need to have GNU Autoconf and GNU Automake installed, and you should execute the following commands:
autoreconf -vfi
./configure
make arctracker
sudo make install
When I was done, this was the complete list of things in my .gitignore file:
arctracker
*.o
config.log
arctracker.cbp
arctracker.layout
autom4te.cache/
autoscan.log
compile
missing
stamp-h1
Makefile
Makefile.in
aclocal.m4
config.h
config.h.in
config.status
configure
install-sh
Oh, and the actual problem? I needed to move $(CLIBS) to the end of the command to build the arctracker target. On the plus side, at least I trimmed all the unneeded fat from the build system and now Git only tracks the actual sources, nothing that gets generated automatically. As an aside, I promise never to complain about Maven again!