For a long time, I have been arranging the code for all my C++ projects in the same way:

joe@thirio> tree
.
├── bin
│   └── foobar
├── dep
│   ├── foo.d
│   └── bar.d
├── Makefile
├── obj
│   ├── foo.o
│   └── bar.o
└── src
    ├── foo.cc
    └── bar.cc

4 directories, 8 files

All the source code for the project lives under the src subdirectory. Each source file is compiled into the corresponding object file under obj, and any target executables are generated under bin. To allow for correct incremental builds, dependency information for each file is generated under dep. This layout keeps source files separate from generated files and works very well with git, requiring only a few lines in a .gitignore file to ignore all the generated files.

However, the Makefile used to achieve this is often unwieldy and writing one from scratch for each project is tiresome, especially for smaller projects. To solve this, I have created a script which I have somewhat narcissistically named jb.

jb, short for Joe’s Builder, is approximately 250 lines of zsh. When invoked, jb dynamically generates a Makefile by examining the contents of each file in the source directory. Since the makefile is procedurally generated, its unwieldiness is no longer an issue, and the dependency analysis that it does is crude but fast. It has what I consider to be “sensible defaults” which allow it to build most of my projects with no additional configuration. And, to top it all off, I even implemented autocompletion.

A snapshot of the script can be downloaded here.