Making A Simple Program
Instructions to build a simple makefile for a single program.
A makefile consists of a set of rules, each with 3 parts:
- a target
- a list of prerequisites
- a list of commands
The general syntax for a rule is:
target: prerequisite-1 prerequisite-2 ...
command1
command2
...
The target and prerequisites are separated by a colon (:). The commands must be preceded by a tab (NOT spaces).
makefile:4: *** missing separator. Stop.
If you see this message it usually means you have spaces instead of tabs.
From the terminal, navigate to the folder that has the code you wish to make a Makefile for. The sample shown below uses the MakeBasics project from the CS260 code (should be cs260Code/Week01/MakeBasics/).
Using your text editor, make a file called
Makefile
in that directory. Make sure it does not have an extension (no .txt at the end).To edit the Makefile, you must use a text editor editor that will NOT put spaces in when you type a tab. By default, many programming tools will convert a press of the tab key into spaces. VSCode should correctly handle tabs (unless you have changed the settings). To see if you have tabs or spaces in VSCode, use View > Command Pallette and then View: Toggle Render Whitespace. Spaces will show as individual
.
s while tabs show as→
followed by blank space.Alternatively, you can use a simple text editor:
- Windows: Notepad
- Mac: Textedit (see these instructions for switching to plain text mode)
In the Makefile put the following:
.PHONY: program.exe program.exe: main.cpp Answer.cpp Answer.h g++ -g -Wall -o program.exe main.cpp Answer.cpp
.PHONY: program.exe
is a way to tell make that we always want make to run the commands when this target is invoked. Normally, make would try to figure out ifprogram.exe
actually needs to be rebuilt by comparing its date to that of its prerequisites. Normally, you might not declareprogram.exe
as PHONY to prevent unnecessary rebuilds - especially if working on a large project where builds could take many minutes. However, always rebuilding is a nice way to make sure that your code ALWAYS gets rebuilt when you run make (which is essential if you are doing something like switching back and forth from Windows to Linux while developing.)The next line - the first required one - defines the target
program.exe
. A target that builds a file is typically given a name that matches the file it builds.After the
:
on that line, it lists three prerequisite files. These files must exist to run the rule. (If they are missing, make will try to build them using rules that match their names or, if those are not available, fail the build). If the rule is not declared.PHONY
, the prerequisites also will be used to determine if the target is up to date and thus the build can be skipped.The next line is the command to run. This command builds the file
program.exe
using g++-g
says to include debugging info. This helps if you use Valgrind on this project-Wall
says to mention ‘all’ warnings-o program.exe
gives the output file the correct namemain.cpp Answer.cpp
are the list of files that need to be compiled
Note that you should not list the
.h
files in the list of files to be compiled. They are not compiled, they are included into the.cpp
files as appropriate. Any.h
files you might edit should be listed in the prerequisites, but only there.Save the Makefile.
Continuing in the terminal, type:
make
The default behavior for make is to run the first target in the file. In this, case that is the target
program.exe
. You can also run a particular rule by calling it explicitly.make program.exe
Now type:
./program.exe
To run the program
program.exe
which is in the current directory (.
). In general, this is how you will want to run your programs.Usually, people add some additional rules to every makefile with some common behavior. These are called ‘phony’ rules, because they are not named after a file they produce but just given convenient names. You always should use
.PHONY
for these rules.Add a rule to clean up, leaving the Makefile
.PHONY: program.exe program.exe: main.cpp Answer.cpp Answer.h g++ -g -Wall -o program.exe main.cpp Answer.cpp .PHONY: clean clean: rm -f program.exe
The
all
target should come first, so that running make with no arguments builds everything by default. The all target simply depends on all of the files you want to make sure are always up-to-date, and does not need a recipe. Theclean
target doesn't have any prerequisites, so it always runs, and it deletes files created by the build process. It usesrm
to remove files, and the-f
option means that it won't ask for confirmation or complain if the file(s) already don't exist.Note that
rm
is a Linux/MacOS command. The clean rule will not work if run in Windows. (To work in Windows it would have to execute the commanddel program.exe
)Now if you run
make clean
, you should end up with only your source files and not the compiled program.You can rebuild the program with
make
ormake all
. If you try to rebuild it after the program has already been built and there are no changes to the source files, make will detect that nothing needs to be done.