Skip to content

Latest commit

 

History

History
128 lines (96 loc) · 4.34 KB

makefiles.md

File metadata and controls

128 lines (96 loc) · 4.34 KB

Makefiles

Make is a UNIX utility that follows a blueprint you create for compiling programs. Calling make will automatically search your current directory for a file called "Makefile" and use it to call various compiler commands according to the rules outlined therein.

Jae's myadd Makefile

Take Jae's Makefile piece by piece. It can be found in this git repository as sample-makefile

CC  = gcc
CXX = g++

Make has a some pre-configured rules for how to compile programs. For example itknows how to specify files as arguments to a compiler. However, you should tell it what compiler to use for C files and C++ files. Here, we set the special make variables CC and CXX to gcc, the C-compiler, and g++, the c++ compiler.

INCLUDES =

CFLAGS   = -g -Wall $(INCLUDES)
CXXFLAGS = -g -Wall $(INCLUDES)

Here we define our own variable, INCLUDES, which we can use for directories thatwe wish to include at the compilation step. An example value for INCLUDES could be -I../myHeaders which would tell the compiler to look in the myHeaders directory, located one directory above the current directory, during the compilation step for missing header files and other sorts of relevant files. For this class, please do NOT use absolute paths in your Makefiles; we do not have the permissions to access your /home/your_uni directory (you'll learn about permissions later on).

After defining INCLUDES, we define the flags that we want each compiler to be run with. In this case we include the -g flag for debugging and -Wall flag to display all warnings. Lastly, we reference our variable INCLUDES to add those flags as well.

LDFLAGS = -g

LDFLAGS are the flags that are appended to the compiler when using it for linking. In this case we just want the debugging info to be included.

LDLIBS =

LDLIBS will automatically be appended to the linker commands. These are flags like -lm and function similarly to our INCLUDES variable but are added at a different step. m denotes the math library.

That's about it for our variable declarations. The next step is to define compile order and dependencies. The very first "target" or rule in your makefile gets built when you type make in this case the first target is:

main: main.o myadd.o

Note that we did not specify the linking rule, because make follows an implied linking rule:

$(CC) $(LDFLAGS) <all-dependent-.o-files> $(LDLIBS)

Also note that make assumes that main depends on main.o, so we could omit it:

main: myadd.o 

Basically what this rule says is make should produce an executable called "main" by linking myadd.o and main.o. This declares main.o and myadd.o as dependencies of main, meaning that if any of the dependencies (or their dependencies) change between the last time this target was run, it should re-run the outdated targets as well as this one.

The next target we declare is main.o:

main.o: main.c myadd.h

This says that main.o depends on main.c (assumed) as well as myadd.h. See last week's recitation notes to understand why main.o depends on myadd.h. We could omit main.c as follows:

main.o: myadd.h

Either way, we do not specify a rule here because make assumes the implicit rule:

$(CC) -c $(CFLAGS) <the-.c-file>

Lastly, we specify the target for myadd.o:

myadd.o: myadd.c myadd.h

We'll include two phony targets. We tell make that they're "phony" so that it doesn't attempt to use implicit rules or try to compile them. The first target we make is "clean" which should remove all intermediate files. Always include a clean so that make clean can be used to remove intermediate files like object files, compiled code, etc. This should return your directory to just its source code that can generate all the other files. Be careful: Using rm -f will not prompt you to remove files. This is customary for make clean but it also means if you make a mistake in designing your rule it could remove files that youdidn't want to. There is no "trash" in UNIX - they'll be gone forever.

Lastly, we define a phony "all" target that just depends on the main and clean targets. This will always remove all intermediate files and compiled files, forcing make to recompile everything when main is called.

.PHONY: clean
clean:
        rm -f *.o a.out core main

.PHONY: all
all: clean main