Here's a list of typical mistakes people make with makefiles.
Issue #1 - using spaces instead of tabs
The command make
is notoriously picky about the formatting in a Makefile
. You'll want to make sure that the action associated with a given target is prefixed by a tab and not spaces.
That is a single Tab followed by the command you want to run for a given target.
Example
This being your target.
main.out: GradeBook.o main.o
The command that follows should have a single Tab in front of it.
g++ -Wall -g -o main.out GradeBook.o main.o
^^^^--Tab
Here is your Makefile cleaned up
//Here is my makefile:
main.out: GradeBook.o main.o
g++ -Wall -g -o main.out GradeBook.o main.o
main.o: main.cpp GradeBook.h
g++ -Wall -g -c main.cpp
GradeBook.o: GradeBook.cpp GradeBook.h
g++ -Wall -g -c GradeBook.cpp
clean:
rm -f main.out main.o GradeBook.o
Issue #2 - naming it wrong
The tool make
is expecting the file to be called Makefile
. Anything else, you need to tell make
what file you want it to use.
$ make -f mafile
-or-
$ make --file=makefile
-or-
$ make -f smurfy_makefile
NOTE: If you name your file Makefile
, then you can get away with just running the command:
$ make
Issue #3 - Running Makefiles
Makefile
's are data files to the command make
. They aren't executables.
Example
make it executable
$ chmod +x makefile
run it
$ ./makefile
./makefile: line 1: main.out:: command not found
g++: error: GradeBook.o: No such file or directory
g++: error: main.o: No such file or directory
g++: fatal error: no input files
compilation terminated.
./makefile: line 4: main.o:: command not found
g++: error: main.cpp: No such file or directory
g++: fatal error: no input files
compilation terminated.
./makefile: line 7: GradeBook.o:: command not found
g++: error: GradeBook.cpp: No such file or directory
g++: fatal error: no input files
compilation terminated.
./makefile: line 10: clean:: command not found
Other isues
Beyond the above tips I'd also advice you to make heavy use of make
's ability to do "dry-runs" or "test mode". The switches:
-n, --just-print, --dry-run, --recon
Print the commands that would be executed, but do not execute them
(except in certain circumstances).
Example
Running the file makefile
.
$ make -n -f makefile
g++ -Wall -g -c GradeBook.cpp
g++ -Wall -g -c main.cpp
g++ -Wall -g -o main.out GradeBook.o main.o
But notice that none of the resulting files were actually created when we ran this:
$ ls -l
total 4
-rw-rw-r--. 1 saml saml 0 Dec 22 08:39 GradeBook.cpp
-rw-rw-r--. 1 saml saml 0 Dec 22 08:45 GradeBook.h
-rw-rw-r--. 1 saml saml 0 Dec 22 08:45 main.cpp
-rwxrwxr-x. 1 saml saml 262 Dec 22 08:25 makefile