class: center, middle ### COMP26020 Programming Languages and Paradigms -- Part 1 *** # Automated Compilation ??? - Hello everyone - In this short video I will present you a tool named make - that allows to automate the compilation of programs composed of multiple and potentially many source files --- # Incremental Build ```bash # Initial build: gcc -c network.c -o network.o gcc -c parser.c -o parser.o gcc -c main.c -o main.o gcc main.o network.o parser.o -o prog # Assume we update parser.c, to rebuild we don't need to recompile everything: gcc -c parser.c -o parser.o gcc main.o network.o parser.o -o prog # Now we update parser.h, remember it's included in both parser.c and main.c, so: gcc -c parser.c -o parser.o gcc -c main.c -o main.o gcc main.o network.o parser.o -o prog ``` - **How to automate dependency management and the build process itself?** ??? - When we have a program composed of several modules - There is no need to rebuild the entire program when just one or a few source files are changed - Let's take the example from the following video in which we build our program from 3 source files, network.c, parser.c and main.c - We have an initial build in which we compile each file and link the object files into the program - Now assume we update parser.c, to rebuild the entire program we only need to recompile that source file and relink all object files - We don't need to recompile network.c and main.c - Same thin if we modified parser.h, we only need to recompile the files including that header, parser.c and main.c, then relink - How can we automate that so we don't have to type all this stuff on the command line each time we want to build? --- class: inverse, middle, center # Makefiles: Automated Build and Dependency Management ??? - So there is a tool called make, that is managed with files named Makefiles - They live alongside the sources and have a particular format describing the build and its dependencies --- # Makefiles - Let's consider the dependencies in our example program
--- # Makefiles - Let's consider the dependencies in our example program
??? - Let's consider the build dependencies for our example - The final executable is produce by the link stage that requires the 3 object files - network.o is the result of compiling network.c, which also include network.h - parser.o is the result of compiling parser.c that also includes network.h and parser.h - Finally, main.o is the result of compiling main.c, which includes both headers - Now that we have reasoned about the dependencies we know what needs to be done when a given file is modified - For example, if parser.h is modified, then both main.o and parser.o need to be rebuilt, and prog needs to be relinked --- # Makefiles - Text file named `Makefile` in the local source directory .leftcol[ ```bash # The first rule is executed when the # command make is typed in the local folder: all: prog # executable deps and command to buil1d it: prog: main.o network.o parser.o gcc main.o network.o parser.o -o prog # network.o deps and command to build it: network.o: network.c network.h gcc -c network.c -o network.o parser.o: parser.c parser.h network.h gcc -c parser.c -o parser.o main.o: main.c network.h parser.h gcc -c main.c -o main.o # Special rule to remove all build files clean: rm -rf *.o prog # ``` .codelink[
`17-automated-compilation/automated-compilation.zip`
] ] .rightcol[
Rule syntax: ```sh
:
[TAB]
``` ] ??? - We describe these dependencies in a file named `Makefile`: - It contains rules describing dependencies and actions with the following format - we have the target file on the left, followed with a colon, followed by the file the target depends on - For example main.o depends on main.c, network.h and parser.h - the final executable prog depends on main.o, network.o and parser.o - And so on - Below each target and list of dependencies, we have the command use to create the target - For example main.o is created by compiling main.c - and prog is created by linking the 3 object files - We also have a special rule all that will be executed when we type make in the local directory - And another special rule clean that removes all build file --- # Makefiles ```sh $ make gcc -c main.c -o main.o gcc -c network.c -o network.o gcc -c parser.c -o parser.o gcc main.o network.o parser.o -o prog $ make # try to rebuild without having modified anything make: Nothing to be done for 'all'. $ touch network.c # update network.c $ make gcc -c network.c -o network.o gcc main.o network.o parser.o -o prog $ touch parser.h # update parser.h $ make gcc -c main.c -o main.o gcc -c parser.c -o parser.o gcc main.o network.o parser.o -o prog make clean rm -rf *.o prog ``` ??? - In the local folder, use the `make` command to build the program: - Let's try it out --- # Summary - C/C++ application build automation and dependency management with `Makefiles` ---- .center[Feedback form: https://bit.ly/37uMy09]
??? - Note that with cs50 sandbox/IDE, `make` is configured to rebuild all targets by default. - So to get the regular behaviour use this command each time you load a terminal - And that's it - In this video we saw how to automate the build and manage the build dependencies for of C and C++ programs using make - In the next video we will talk about type conversion and casting