Boilerplate for autotools-based C project

Vincent Bernat

When starting a new HTML project, a common base is HTML5 Boilerplate that helps by setting up the essential bits. Such a template is quite useful for both beginners and experienced developers as it is kept up-to-date with best practices and it avoids forgetting some of them.

Recently, I have started several small projects written in C for a customer. Each project was bootstrapped from the previous one. I thought it would be useful to start from a template instead. Hence, bootstrap.c,1 a template for simple projects written in C with the autotools, was born.

Usage#

A new project can be created from this template in three steps:

  1. Run Cookiecutter, a command-line tool to create projects from templates, and answer the questions.
  2. Setup Git.
  3. Complete the “todo list.”

Cookiecutter#

Cookiecutter is a new tool to create projects from templates. It uses Jinja2 as a template engine for file names and contents. It is language agnostic: you can use it for Python, HTML, JavaScript or… C!

Cookiecutter is simple. You can read an introduction from Daniel Greenfeld. Bootstrapping a new project is easy:

$ cookiecutter https://github.com/vincentbernat/bootstrap.c.git
Cloning into 'bootstrap.c'...
remote: Counting objects: 90, done.
remote: Compressing objects: 100% (68/68), done.
remote: Total 90 (delta 48), reused 64 (delta 22)
Unpacking objects: 100% (90/90), done.
Checking connectivity... done

full_name (default is "Vincent Bernat")? Alfred Thirsty
email (default is "bernat@luffy.cx")? alfred@thirsty.eu
repo_name (default is "bootstrap")? secretproject
project_name (default is "bootstrap")? secretproject
project_description (default is "boilerplate for small C programs with autotools")? Super secret project for humans

Cookiecutter asks a few questions to instantiate the templates correctly. The result has been stored in the supersecret directory:

.
├── autogen.sh
├── configure.ac
├── get-version
├── m4
│   ├── ax_cflags_gcc_option.m4
│   └── ax_ld_check_flag.m4
├── Makefile.am
├── README.md
└── src
    ├── log.c
    ├── log.h
    ├── Makefile.am
    ├── secretproject.8
    ├── secretproject.c
    └── secretproject.h

2 directories, 13 files

Remaining steps#

There are still a few steps to be executed manually. You first need to initialize Git, as some features of this template rely on it:

$ git init
Initialized empty Git repository in /home/bernat/tmp/secretproject/.git/
$ git add .
$ git commit -m "Initial import"
[…]

Then, you need to extract the todo list built from the comments contained in source files:

$ git ls-tree -r --name-only HEAD | \
>   xargs grep -nH "T[O]DO:" | \
>   sed 's/\([^:]*:[^:]*\):\(.*\)T[O]DO:\(.*\)/\3 (\1)/' | \
>   sort -ns | \
>   awk '(last != $1) {print ""} {last=$1 ; print}'

2003 Add the dependencies of your project here. (configure.ac:52)
2003 The use of "Jansson" here is an example, you don't have (configure.ac:53)
2003 to keep it. (configure.ac:54)

2004 Each time you have used `PKG_CHECK_MODULES` macro (src/Makefile.am:12)
2004 in `configure.ac`, you get two variables that (src/Makefile.am:13)
2004 you can substitute like above. (src/Makefile.am:14)

3000 It's time for you program to do something. Add anything (src/secretproject.c:76)
3000 you want here. */ (src/secretproject.c:77)
[…]

Only a few minutes are needed to complete these steps.

What do you get?#

Here are the main features:

  • Minimal configure.ac and Makefile.am.
  • Changelog based on Git logs and automatic version from Git tags.2
  • Manual page skeleton.
  • Logging infrastructure with variadic functions like log_warn(), log_info().
logging output of lldpd
Example of colored logging output

About the use of the autotools#

The autotools provide a build system for a project, including:

  • autoconf to generate a configure script; and
  • automake to generate makefiles using a similar but higher-level language.

Understanding the autotools can be difficult. There are a lot of bad documentations on the web and the manual does not help by describing corner-cases that would be useful if you wanted your project to compile for HP-UX. So, why do I use it?

  1. I have invested a lot of time to understand this build system. Once you grasp how it should be used, it works reasonably well and can cover most of your needs. Maybe CMake would be a better choice but I have yet to learn it. Moreover, the autotools are so widespread that you have to know how they work.
  2. There are a lot of macros available for autoconf. Many of them are included in the GNU Autoconf Archive and ready to use. The quality of such macros are usually quite good. If you need to correctly detect the appropriate way to compile a program with GNU Readline or something compatible, there is a macro for that.

If you want to learn more about the autotools, do not read the manual. Instead, have a look at Autotools Mythbuster. Start with a minimal configure.ac and do not add useless macros: a macro should be used only if it solves a real problem.

Happy hacking!


  1. Retrospectively, I think boilerplate.c would have been a better name. ↩︎

  2. For more information on these features, have a look at their presentation in a previous post about lldpd↩︎