make - krishnaramb/cplusplus GitHub Wiki
- to compile all the cpp or c++ files: g++ *.cpp or g++ *.c++
- This will generate
a.exe
. This process might take long time since it compilers all the files irrespective of whether it is changed or not.
If you have MINGW installed in your machine, locate to the location ~MinGW\bin
. This location contains make.exe
along with the g++.exe
and gcc.exe
. Make sure you put this location in the environment path.
- with this process, we can ask compiler to compile only those files that are changed. This implementation will reduce the comilation time.
- create a file and name it as Makefile without any extension. The general syntax for the command is as below. The second line
action
should be at the sapce one tab.
target:dependencies
action
- output is the executable. I am going to recreate my executable file output whenever my object files user.o and Vector.o changes
-
g++ user.o Vector.o -o output
means whenever either of these obj filesVector.o
anduser.o
changes, recompileuser.o
,Vector.o
into executableoutput
.-o
means create an executable. - Now lets instruct our make file how to create the obj files
- We are creating
user.o
file wheneveruser.c++
file changes. The lineg++ -c user.c++
means go ahead and compile fileuser.c++
and-c
flag here means create the object file with the same name .i.euser.o
file - Once you create a
Makefile
, just typemake
in the command prompt and it does work for you and create the executable. -
make clean
command will clear all the obj files. In linux yourm *.o
instead. - you should remember that we can run any of the command below starting with
make
. This will invoke the command below it. example,make run
command will executeoutput.exe
. - In atom editor, you can directly right click the file Makefile and click
make run
output:user.o Vector.o
g++ user.o Vector.o -o output
user.o: user.c++
g++ -c user.c++
Vector.o: Vector.c++ Vector.h
g++ -c Vector.c++
clean:
del /f *.o output.exe
run:
output
target β¦ : prerequisites β¦
recipe
β¦
β¦
edit : main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
cc -o edit main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
main.o : main.c defs.h
cc -c main.c
kbd.o : kbd.c defs.h command.h
cc -c kbd.c
command.o : command.c defs.h command.h
cc -c command.c
display.o : display.c defs.h buffer.h
cc -c display.c
insert.o : insert.c defs.h buffer.h
cc -c insert.c
search.o : search.c defs.h buffer.h
cc -c search.c
files.o : files.c defs.h buffer.h command.h
cc -c files.c
utils.o : utils.c defs.h
cc -c utils.c
clean :
rm edit main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
- this makefile describes the way an executable file called edit depends on eight object files which, in turn, depend on eight C source and three header files.
- We split each long line into two lines using backslash \
- By default, make starts with the first target (not targets whose names start with β.β). This is called the default goal.
- Goals are the targets that make strives ultimately to update
- In the simple example of the previous section, the default goal is to update the executable program edit; therefore, we put that rule first.
- In the simple example of the previous section, the default goal is to update the executable program edit; therefore, we put that rule first.:cupid:
- make reads the makefile in the current directory and begins by processing the first rule
- In the example, this rule is for relinking edit; but before make can fully process this rule, it must process the rules for the files that edit depends on, which in this case are the object files. Each of these files is processed according to its own rule. These rules say to update each β.oβ file by compiling its source file. The recompilation must be done if the source file, or any of the header files named as prerequisites, is more recent than the object file, or if the object file does not exist.
- If some other rule is not depended on by the goal (or anything it depends on, etc.), that rule is not processed, unless you tell make to do so (with a command such as make clean).
edit : main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
cc -o edit main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
- Such duplication is error-prone; if a new object file is added to the system, we might add it to one list and forget the other.
- We can eliminate the risk and simplify the makefile by using a variable
- Variables allow a text string to be defined once and substituted in multiple places later
objects = main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
- Each place we want to put a list of the object file names, we can substitute the variableβs value by writing
$(objects)
- After using variable, the makefile will look like
objects = main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
edit : $(objects)
cc -o edit $(objects)
main.o : main.c defs.h
cc -c main.c
kbd.o : kbd.c defs.h command.h
cc -c kbd.c
command.o : command.c defs.h command.h
cc -c command.c
display.o : display.c defs.h buffer.h
cc -c display.c
insert.o : insert.c defs.h buffer.h
cc -c insert.c
search.o : search.c defs.h buffer.h
cc -c search.c
files.o : files.c defs.h buffer.h command.h
cc -c files.c
utils.o : utils.c defs.h
cc -c utils.c
clean :
rm edit $(objects)
- There are two ways that a variable in GNU make can have a value; we call them the two flavors of variables.
- The first flavor of variable is a recursively expanded variable
- Variables of this sort are defined by lines using β=β
- The value you specify is installed verbatim; if it contains references to other variables, these references are expanded whenever this variable is substituted (in the course of expanding some other string). When this happens, it is called recursive expansion
foo = $(bar)
bar = $(ugh)
ugh = Huh?
all:;echo $(foo
- echo βHuh?β: β$(foo)β expands to β$(bar)β which expands to β$(ugh)β which finally expands to βHuh?β.
CFLAGS = $(CFLAGS) -O
- it will cause an infinite loop in the variable expansion. (Actually make detects the infinite loop and reports an error.)
- Simply expanded variables are defined by lines using β:=β or β::=β
Automatic Variables gnu.org
- Suppose you are writing a pattern rule to compile a β.cβ file into a β.oβ file: how do you write the βccβ command so that it operates on the right source file name?
- You cannot write the name in the recipe, because the name is different each time the implicit rule is applied.
- What you do is use a special feature of make, the automatic variables.
- These variables have values computed afresh for each rule that is executed, based on the target and prerequisites of the rule. In this example, you would use β$@β for the object file name and β$<β for the source file name.
- Itβs very important that you recognize the limited scope in which automatic variable values are available: they only have values within the recipe.
- In particular, you cannot use them anywhere within the target list of a rule; they have no value there and will expand to the empty string.
- Also, they cannot be accessed directly within the prerequisite list of a rule. A common mistake is attempting to use $@ within the prerequisites list; this will not work
-
$@
--> The file name of the target of the rule -
$<
--> The name of the first prerequisite. If the target got its recipe from an implicit rule, this will be the first prerequisite added by the implicit rule -
$?
--> The names of all the prerequisites that are newer than the target, with spaces between them -
$^
--> The names of all the prerequisites, with spaces between them.
-
It is not necessary to spell out the recipes for compiling the individual C source files, because make can figure them out: it has an implicit rule for updating a
.o
file from a correspondingly named.c
file using acc -c
command. -
it will use the recipe βcc -c main.c -o main.oβ to compile main.c into main.o. e can therefore omit the recipes from the rules for the object files
-
When a β.cβ file is used automatically in this way, it is also automatically added to the list of prerequisites. We can therefore omit the β.cβ files from the prerequisites, provided we omit the recipe.
objects = main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
edit : $(objects)
cc -o edit $(objects)
main.o : defs.h
kbd.o : defs.h command.h
command.o : defs.h command.h
display.o : defs.h buffer.h
insert.o : defs.h buffer.h
search.o : defs.h buffer.h
files.o : defs.h buffer.h command.h
utils.o : defs.h
.PHONY : clean
clean :
rm edit $(objects)
- How to delete all the object files and executables so that the directory is βcleanβ.?
clean:
rm edit $(objects)
- In practice, we might want to write the rule in a somewhat more complicated manner to handle unanticipated situations
.PHONY : clean
clean :
-rm edit $(objects)
-
This prevents make from getting confused by an actual file called clean and causes it to continue in spite of errors from rm.
-
A rule such as this should not be placed at the beginning of the makefile, because we do not want it to run by default! πΊππ
-
Thus, in the example makefile, we want the rule for edit, which recompiles the editor, to remain the default goal
-
Since clean is not a prerequisite of edit, this rule will not run at all if we give the command βmakeβ with no arguments.
-
In order to make the rule run, we have to type βmake cleanβ.
-
β#β in a line of a makefile starts a comment.
- By default, when make looks for the makefile, it tries the following names, in order: GNUmakefile, makefile and Makefile
- If you want to use a nonstandard name for your makefile, you can specify the makefile name with the β-fβ or β--fileβ option.
CC=gcc
CFLAGS=-I.
hellomake: hellomake.o hellofunc.o
$(CC) -o hellomake hellomake.o hellofunc.o
- we've defined some constants CC and CFLAGS. It turns out these are special constants that communicate to make how we want to compile the files hellomake.c and hellofunc.c.
- In particular, the macro CC is the C compiler to use, and CFLAGS is the list of flags to pass to the compilation command.
- By putting the object files--hellomake.o and hellofunc.o--in the dependency list and in the rule, make knows it must first compile the .c versions individually, and then build the executable hellomake.
CC=gcc
CFLAGS=-I.
DEPS = hellomake.h
%.o: %.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
hellomake: hellomake.o hellofunc.o
$(CC) -o hellomake hellomake.o hellofunc.o
-
This addition first creates the macro DEPS, which is the set of .h files on which the .c files depend.
-
Then we define a rule that applies to all files ending in the .o suffix.
-
The rule says that the .o file depends upon the .c version of the file and the .h files included in the DEPS macro.
-
The rule then says that to generate the .o file, make needs to compile the .c file using the compiler defined in the CC macro.
-
The
-c
flag says to generate the object file, the-o $@
says to put the output of the compilation in the file named on the left side of the:
, the$<
is the first item in the dependencies list, and theCFLAGS
macro is defined as above -
As a final simplification, let's use the special macros
$@
and$^
, which are the left and right sides of the :, respectively, to make the overall compilation rule more general. -
In the example below, all of the include files should be listed as part of the macro DEPS, and all of the object files should be listed as part of the macro OBJ.
CC=gcc
CFLAGS=-I.
DEPS = hellomake.h
OBJ = hellomake.o hellofunc.o
%.o: %.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
hellomake: $(OBJ)
$(CC) -o $@ $^ $(CFLAGS)