GNU Make is "the Make of Makes" - the near-ultimate build tool (or at least the ultimate implementation of "make"). It is one of those tools which is an absolute must-have in my toolbox, and any machine without GNU Make installed is hardly a machine at all. Here you can find a small collection of stuff i have cobbled together for use with GNU Make. If you are unfamiliar with Make, Wikipedia has an interesting article about it.
Managing Projects with GNU Make, 3.xth Edition
If you want to get a good grasp of Make's features, O'Reilly's Managing Projects with GNU Make, Third Edition is an excellent resource, especially when used alongside the official GNU Make manual. It is available for purchase as a book (of typical O'Reilly quality) or electronically under the terms of the GNU Free Documentation License. Unfortunately, the publishers "cheat" a bit and make the content available only in PDF and they distribute the document as 22 separate PDFs (one per chapter), which makes the data not only difficult to use, but also difficult to adapt under its "open" license. Frustrated by O'Reilly's cheeky distribution, i have forked a copy of the book and reformatted it in OpenDocument format. The fork contains the entire contents of the 3rd Edition book (except for the index and one now-irrelevant section), all published errata for the book, plus has better intra-document cross-referencing.
The *.gz files below contain not only the docs but also some ready-to-use sample Makefile code.
ShakeNMake is a helper makefile which supplies several useful features for single-directory project trees. It is intended to replace the whole configure/make process in source trees for very small, one-shot, or experimental projects. It is intended for use on platforms hosting GNU tools such as gcc, the GNU linker, bash, and GNU sed. It has undergone only limited testing under Cygwin. For the curious: its name is a reference to an old American cooking product.
Using ShakeNMake is trivial. Simply copy
shake-n-make.make to your project directory
and create a Makefile like this:
#!/usr/bin/make default: all #PACKAGE.NAME = MyPackage #PACKAGE.VERSION = 1.2.3 # ^^^^ the PACKAGE vars are not needed since the removal # of the long-unused 'dist' and doxygen-related rules. # In practice they were simply never used. include shake-n-make.make # ... the rest of your code goes here ...
That will provide support for the following features:
- Compiling C/C++ sources, including per-file compilation flags.
- Building binaries from C/C++ sources and/or objects, including per-binary compile/link flags.
- Building shared and static libraries.
- Transparent and automatic (and fast) dependencies generation for C/C++.
- Cleaning up the source tree.
The following features were in older (pre-2019) versions but were removed because they were never used (but might be re-added, if a need arises):
- Building a tarred or zipped distribution file ("make dist").
- Installation and deinstallation of files ("make install" and "make uninstall").
- Generating API documentation using Doxygen, including generation of a distribution tarball for the doxygen docs.
Here's a quick example of setting up the compilation of a DLL and a static library:
# Dynamic library: myLibrary.DLL.OBJECTS = foo.o bar.o $(myLibrary.DLL.OBJECTS): CFLAGS+=-fPIC myLibrary.LDFLAGS = -L/some/path -lmyOtherLib $(call ShakeNMake.CALL.RULES.DLLS,myLibrary) # Static library: myLibrary.LIB.OBJECTS = $(myLibrary.DLL.OBJECTS) $(call ShakeNMake.CALL.RULES.LIBS,myLibrary) # Add the libs to the 'all' target: all: myLibrary.LIB myLibrary.DLL # Note that myLibrary.LIB and myLibrary.DLL are names of TARGETS, not FILES. # If you want the FILE names, use $(myLibrary.LIB) and $(myLibrary.DLL).
That creates targets called myLibrary.DLL and myLibrary.LIB and sets the variables myLibrary.DLL and myLibrary.LIB to myLibrary.so and myLibrary.a, respectively.
For a description of how to use all of the provided features, please read the docs in shake-n-make.make.
This tarball includes a complete demonstration mini-project for ShakeNMake:
- (updated for more modern compiler requirements but removes the long-unused (un)install, dist, and doxygen rules)
(example code might fail to compile
on newer compilers, which tend to require the