automaker - Automatically create Makefiles for C projects
automaker is designed to automatically generate Makefile
s for C projects. The idea is that you declare dependencies explicitly in your source files, then run automaker
, and your Makefile
will be created.
For example, given a source file greeter.c
, to produce a Makefile
that will produce the greeter
executable along with any dependencies, run:
$ automaker greeter.c > Makefile
Here’s how it works: automaker
opens greeter.c
and looks for a comment section of the following format:
/*
%use io_getline;
%use io_put;
%use io_putline;
*/
The above would mean greeter
needs to be linked with io_getline.o
, io_put.o
, io_putline
and any dependencies that come along with them (as defined in io_getline.c
, io_put.c
, and io_putline.c
). (A completely flat file structure is expected: automaker
is meant for small(ish) C projects.) Each file (with a .o
suffix) would be added to greeter
’s Makefile
entry, along with any more dependencies generated after checking the file (with a .c
suffix) for any of its dependencies, recursively. It then outputs a fully functioning Makefile
capable of building greeter
.
You may supply more than one main source file. For example:
$ automaker myprog1.c myprog2.c myprog3.c > Makefile
The above constructs a Makefile that creates executables myprog1
, myprog2
, and myprog3
, linking them with all necessary dependencies.
To give a more complete example, the source code for greeter.c
might look like:
/*
%use io_getline;
%use io_put;
%use io_putline;
*/
#include "io.h"
#include "str.h"
static str name = {0};
int main()
{
io_putline(io_stdout, "Type your name: ");
io_getline(io_stdin, &name);
io_put(io_stdout, "Hello, "); io_putline(io_stdout, &name);
return 0;
}
Then, to produce the Makefile
necessary to build test, run:
$ automaker greeter.c > Makefile
This will produce the following Makefile
:
default: it
load:
echo '#!/bin/sh' > load
echo 'main="$$1"; shift' >> load
echo 'exec cc -o "$$main" "$$main".o $${1+"$$@"}' >> load
chmod +x load
compile:
echo '#!/bin/sh' > compile
echo 'exec cc -c $${1+"$$@"}' >> compile
chmod +x compile
greeter: load greeter.o io_getline.o io_put.o io_putline.o
./load myprog io_getline.o io_put.o io_putline.o
io_getline.o: compile io_getline.c
./compile io_getline.c
io_put.o: compile io_put.c
./compile io_put.c
io_putline.o: compile io_putline.c
./compile io_putline.c
it: greeter
clean:
rm -f *.o greeting
The code is on GitHub and, like most of my work, is public domain.