Home > C++ Classes, Programming > Smart Makefile for C/C++/ObjC

Smart Makefile for C/C++/ObjC

August 1st, 2009 Leave a comment Go to comments

To download:

1
bzr branch http://bazaar.enseed.com/demo/c-makefile/

This is a smart Makefile that I have written and used over the years. It will look in your current directory and compile any .c or .cpp that it finds. It also builds dependencies from your c and cpp files (headers used) and will recompile your source file if one of the dependency has been modified. It uses a Makefile.spec file to modify the default behaviour (for example, compile a subdirectory, link as a library, etc…).

It also comes built-in with colorgcc.

Here’s how you use it:

What’s Done Automatically

You will automatically get the following:

  • Your OS name as a global macro definition (-DYOUR_OS_NAME)
  • Dependency tracking for every source file maintained in a .dep directory, meaning that a source file will only be recompiled if a dependency or the source file itself has changed.
  • Errors and warnings in color: simply type make colorgcc to install and use colorgcc.
  • A debug (default) and release mode: type make MODE=release to compile in release mode (debugging symbols off and optimizations on)
  • At any time, type make explain to get a description of what’s going in in the Makefile’s head (how it interprets your Makefile.spec and what it sees in your current directory).

Getting StartedDownload the file somewhere, and just type make. You should see:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
$shell>make

You should to write a Makefile.spec file containing your target
as well as any special configuration.  For instance:

INCLUDE +=
CFLAGS +=
LDFLAGS +=
LINKWITH +=  EXECUTABLE =
ARCHIVE =
DYNLIB =
SUBDIR +=

Object files are created in a "obj" directory and dependency
files are hidden in a ".dep" directory.  If you have problems
after adding or removing a source file, you should try deleting
the dependency file (or the whole dependency directory if you're
lazy).

If you want to know what's going to happen, try:
make explain

If you'd like a default "Makefile.spec" to be conveniently
created for you, type
make Makefile.spec

Finally, if you don't care about all this and just want to compile
your files into .o files, type:
make objects

It’s telling you that you need a Makefile.spec, and it’s offering you to dump a template for you – which is what we’ll do: make Makefile.spec.

1
2
3
$shell>make Makefile.spec

Makefile.spec file created

Open the Makefile.spec in your favorite text editor, you’ll find this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# Default Makefile.spec

#Additional include paths
INCLUDE +=

#Additional C flags
CFLAGS +=

#Additional C++ flags
CPPFLAGS +=

#List of libraries to link with
LINKWITH +=

#Additional Linker flags
LDFLAGS +=

#Name of the executable to create
EXECUTABLE =

#Name of the static library to create
ARCHIVE =

#Name of the dynamic library to create
DYNLIB =

#Other directories to update before compiling
SUBDIR =

For now, we’ll just build an executable.

Building an Executable

To build an executable, simply set a value to “EXECUTABLE” in your Makefile.spec. For example:

1
2
#Name of the executable to create
EXECUTABLE = test

Whatever cpp and c files found in your directory will be compiled and linked together into an executable named (in this case)test. For example, we have a test.cpp file:

1
2
3
4
5
6
7
8
9
10
11
12
13
$shell>make

--------------------[test.d]-----------------
g++ -M -Wall -DDarwin -O3  -Weffc++   test.cpp | sed "s|test.o:|.dep/test.d:|" > .dep/test.d

=====================[test.o]=====================
g++ -Wall -DDarwin -O3  -Weffc++   -c -o obj/test.o ./test.cpp

##################[test]################
g++ -o test    obj/test.o

$shell>./test
hello world!!!

Building a Static Library

Building a static library is just as simple as building an executable. In your Makefile.spec:

1
2
3
4
5
#Name of the executable to create
EXECUTABLE =

#Name of the static library to create
ARCHIVE = mylib

When typing make, you’ll get:

1
2
3
4
5
6
7
8
9
10
11
$shell>make

--------------------[test.d]-----------------
g++ -M -Wall -DDarwin -O3  -Weffc++   test.cpp | sed "s|test.o:|.dep/test.d:|" > .dep/test.d

=====================[test.o]=====================
g++ -Wall -DDarwin -O3  -Weffc++   -c -o obj/test.o ./test.cpp

##################[mylib.a]################
ar rc "mylib.a"    obj/test.o
ranlib "mylib.a"

Getting Colors

By default, errors in your code will look like this when you compile:

$shell>make

=====================[test.o]=====================
colorgcc g++ -Wall -DDarwin -O3  -Weffc++   -c -o obj/test.o ./test.cpp
./test.cpp: In function 'int main(int, const char**)':
./test.cpp:5: error: 'printf' was not declared in this scope
make: *** [obj/test.o] Error 1

If you have colorgcc installed in your paths, this makefile will detect it and use it. Otherwise, simply type make colorgcc and colorgcc will be installed in your current directory. Thereafter, your errors will look like this:

$shell>make

=====================[test.o]=====================
colorgcc g++ -Wall -DDarwin -O3  -Weffc++   -c -o obj/test.o ./test.cpp
./test.cpp: In function 'int main(int, const char**)':
./test.cpp:5: error: 'printf' was not declared in this scope
make: *** [obj/test.o] Error 1

There’s More

There’s more but this is just meant to get you started using this Makefile. For the rest, look at the file itself and see what’s going on. The file has been keep as simple as possible and shouldn’t be to difficult to modify…

Categories: C++ Classes, Programming Tags:
  1. No comments yet.
  1. No trackbacks yet.
*

Please leave these two fields as-is:

Protected by Invisible Defender. Showed 403 to 159,832 bad guys.