Makefile Maker

Home --> Useful Scripts --> Makefile Maker

Problem

For a small C++ project it would be nice to have a python script that creates a makefile. In this way, shell scripts can be avoided entirely. The python script MakefileMaker.py.txt does just that. The script is intended for projects where all the .cpp and .h files are within the same directory, although this is not necessary.

How To Use It

First, make sure your current working directory is the one that contains all your .cpp and .h files. Call this the "Source" directory.

Next, put the script MakefileMaker.py.txt in the directory ../BuildTools/ and remove the .txt extension. (you can put it wherever, I just keep it here for simplicity).

Within the ../BuildTools/ directory, you should create the following files:
source_file_names.txt
header_only_file_names.txt
lib_names.txt
lib_paths.txt
Within the file source_file_names.txt, list all the names of your .cpp files (without the .cpp extension). Write one name per line. Each of these .cpp files should have an accompanying .h file, the only exception being main.cpp which should not have an accompanying .h file. For example, if your project consists of the files main.cpp, foo.h, and foo.cpp, the file source_file_names.txt should be exactly as follows:
main
foo
Within the file header_only_file_names.txt, you should list the names of all .h files that do not have an accompanying .cpp file. Again, write only one name per line.

If you do not want to create the files source_file_names.txt and header_only_file_names.txt by hand, see the section Listing .cpp and .h Files below.

Within the file lib_names.txt, write all the library names as they would appear as input to g++. For example, if your program only uses the library OpenAL32, then the file lib_names.txt should be exactly as follows:
-lOpenAL32
Within the file lib_paths.txt, write all the (additional) paths that you want g++ to search for libraries. For example, in a project that I wrote that uses OpenAL libraries contained within the directory c:/MinGw/lib/AL, my file lib_paths.txt is exactly as follows:
 c:/MinGw/lib/AL 
The names and locations of the files source_file_names.txt, header_only_file_names.txt, lib_names.txt, and lib_paths.txt can be changed. If you wish to do this, simply modify the appropriate variables of the "Parameters" section of MakefileMaker.py:
# ##############################################################
#              Parameters (Feel free To change)
# ##############################################################

verbose                 = False
exe_name                = '../Release/Program.exe'
source_list_file        = '../BuildTools/source_file_names.txt'
header_only_list_file   = '../BuildTools/header_only_file_names.txt'
lib_list_file           = '../BuildTools/lib_names.txt'
lib_paths_file          = '../BuildTools/lib_paths.txt'
resource_str            = '../Resources/resource.o'
You are now ready to run the script. To do so, run the following command:
python ../BuildTools/MakefileMaker.py
The script will search all the appropriate .cpp and .h files that were listen in source_file_names.txt and header_only_file_names.txt for include directives. For example, if the file foo.cpp has line
#include bar.h
within it, then the dependency of foo.cpp and bar.h will be recorded. Include directives with angle brackets will be ignored. If you want to see which .h and .cpp files depend on each other, set the "verbose" parameter to "True" in the script. Once all .h and .cpp files have been searched, the file Makefile will be created in the current working directory. This makefile has various targets, which will be discussed later.

Before calling make, you need to make sure that you have a directory named Obj in the Source directory. This is where all the object files will be outputed. Also make sure that you have the directory ../Release/. This is where the program will be outputed. If you want the program outputed to a different location, simply change the "exe_name" parameter in MakefileMaker.py. If you want to link in a resource, for example ../Resources/resource.o, then create the directory ../Resources/ and create the resource file resource.o. If you do not want to link in a resource, then set the parameter resource_str in the script to the empty string.

You are now ready to compile and link your project. This can be done using the various targets in Makefile. Here are all the targets that you may wish to execute in Makefile:
proj
comp_all
comp
link
The target proj is the main target, which will cause the project to be compiled and linked. The target comp_all will forcibly recompile all source files. The target comp will compile all source files that need to be updated based on their dependencies. The target link will link the project, creating the executable.

That is, run the command
make
and your executible should be created!

Listing .cpp and .h Files

Instead of manually entering entries into the files ../BuildTools/source_file_names.txt and ../BuildTools/header_only_file_names.txt, these files can be created automatically using the script MakefileMakerHelper.py

Put the script MakefileMakerHelper.py into the directory ../BuildTools/. Next, run the command
python ../BuildTools/MakefileMakerHelper.py 
This will find all .h and .cpp files in the current working directory and will create the files ../BuildTools/source_file_names.txt and ../BuildTools/header_only_file_names.txt appropriately.

Example Project

Here is a simple example project demonstrating the script. The files lib_names.txt and lib_paths.txt are just examples and could be replaced with empty files. To try out the script, go to the "Source" directory and follow the above directions.