CIS*2750 Lecture 2b - Makefiles PDF
Document Details
![ComfortableBowenite2676](https://quizgecko.com/images/avatars/avatar-16.webp)
Uploaded by ComfortableBowenite2676
University of Guelph
Tags
Summary
This document covers makefiles, a tool for automating the compilation of C programs. It explains the structure of makefiles, how to use them, and macro functions.
Full Transcript
CIS*2750 Lecture 2b: make les Based on CIS*2750 notes from previous generations of CIS*2750 instructors fi Makefiles The make utility executes a sequence of commands from a description le It is generally used to creat...
CIS*2750 Lecture 2b: make les Based on CIS*2750 notes from previous generations of CIS*2750 instructors fi Makefiles The make utility executes a sequence of commands from a description le It is generally used to create executables, but it can perform other tasks: remove les report the status of a project packaging multiple les into a distribution installing les in a directory building libraries The make utility is not unique the ant utility for Java is similar Cmake is supposed to be an improved make However, make is still a very common one, so we stick with it 2 fi fi fi Makefiles and the compiler toolchain The make utility and the compiler toolchain are completely separate, unrelated entities However, the make utility is usually used to automate code building, to you will regularly use it to pass ags to compilers, specify paths, specify library names, etc. Which is why it is essential to understand how the compiler toolchain works - otherwise, you can't use make les e ectives, and won't be able to understand sample make les (e.g. my examples) 3 fl fi ff Make - the vanilla approach There are many (crazy) ways to achieve the same e ects with make les Programmers tend to develop their preferential ways of coding them Good to get exposure to several people’s approaches to make les Learn/understand features you didn’t realize exist Avoid treating make le as “magical incantation” We will use a very straightforward and simple convention, for the sake of readability I recommend you stick with it - writing code you do not fully understand is always a bad idea 4 fi Makefiles It examines dependencies between les. The date and existence of a le is also examined. If les do not exist then make attempts to build them. If the compiled les do exist, but they depend on a le which has a newer date, then they are recompiled. 5 fi fi fi fi Makefile Structure Each entry in a make le consists of three parts: Target Prerequisites or dependencies Command line myprog: myprog.c myprog.h gcc myprog.c -o myprog 6 fi Makefile Structure Target Each entry in a make le consists of three parts: Target Prerequisites or dependencies Command line myprog: myprog.c myprog.h gcc myprog.c -o myprog Target 7 fi Makefile Structure Prerequisites or dependencies Each entry in a make le consists of three parts: Target Prerequisites or dependencies Command line Prerequisites or dependencies myprog: myprog.c myprog.h gcc myprog.c -o myprog 8 fi Makefile Structure Command line Each entry in a make le consists of three parts: Target Prerequisites or dependencies Command line myprog: myprog.c myprog.h gcc myprog.c -o myprog Command line 9 fi Makefile Structure Tab Each entry in a make le consists of three parts: Target Prerequisites or dependencies Command line myprog: myprog.c myprog.h gcc myprog.c -o myprog Tab 10 fi Part 1: target The target is what a particular make le entry aims to build Typically a target is a lename Can be an executable, e.g. myprog or a library, e.g. librecord.so Although not always, as we will see later 11 fi fi Part 2: prerequisites The prerequisites are les that must exist in order for a target to be "buildable" E.g. if we want to build myprog, the les myprog.c and myprog.h must exist If any of the prerequisites are newer than the target, then the command line is executed In other words, if any of the dependencies were modi ed after the target was created, we recompile the target Only the les which need to be recompiled will be recompiled - instead of all of them 12 fi fi fi Makefiles and efficiency Recompiling only the les which require it is important for large applications where recompiling everything is slow https://xkcd.com/303/ 13 fi Part 3: command line The command line is the command - typically, a Unix/Linux command line utility with arguments - that must be executed to build the target using the dependencies The command line must be prefaced by a single tab The tab must a single tab character and not spaces. This might cause you pain and anguish, so be careful. 14 Invoking Make Typing only: make at the command line will look for either a le named Makefile or makefile and build the rst target that appears in the le. Typing: make will build the speci ed target. 15 fi fi fi fi Invoking Make e.g. making a speci c target, with the following make le myprog: myprog.c gcc … fred: fred.c gcc … Typing make myprog will build myprog. make fred will build fred. Typing make will build myprog Because myprog is the rst target in the make le 16 fi fi fi Other common targets As mentioned earlier, targets do not have to be les, e.g. clean: rm *.o core These can be used to clean up les that you no longer need. In my examples, the clean target usually deletes all targets i.e. executables and library les all temporary.o les the core le Other people have other conventions 17 fi fi fi fi Checking the commands You can view the commands make would execute without actually executing them using -n ag For example: make -n will display the commands that would be executed for the rst target make someTarget -n will display the commands that would be executed for someTarget 18 fl Multiline command lines You can put multiple lines in the command line by separating them with a semi-colon. e.g. libawesome.a: awesome.c gcc awesome.c -o awesome.o -c ;\ ar cr libawesome.a awesome.o The backslash means continue to the next line. The backslash must be the last character on the line Note: not all versions of make require the backslash. 19 Makefile macros Macros are used to avoid repeatedly typing a lot of text in make les. Things like paths, compiler ags, and lists of libraries can appear in multiple locations in a make le and are annoying to retype. Macros replace long strings with shorter text. They are de ned using the equal sign: e.g. LIBS = -L/usr/local/lib -lm -llibname and they are referenced using a $ and brackets: e.g. $(LIBS) or ${LIBS} 20 fi fi fl Example: sample makefile Macro names are normally in upper case. CC = gcc LIBS = -lm -L/usr/local/lib -L. -lmyLib prog: prog.c $(CC) prog.c -o prog $(LIBS) This example: compiles using gcc, but we can easily specify a di erent compiler by changing the CC macro (e.g. clang) Links in libraries m (C math library) and myLib Speci es that the linker should look for libraries in /usr/local/lib and the current directory (.) in addition to the linker's standard search path 21 fi ff Undefined macros Unde ned macros are replaced with a null string (nothing). LIB = -lm -L/usr/local/lib -L. -lmyLib a1: a1.c a1.h gcc a1.c -o a1 $(LIBS) will run the command: gcc a1.c -o a1 22 fi Predefined macros Macro CC is prede ned as command cc. cc is a usually symbolic link to the default C compiler of your *nix distribution Typically either GNU C compiler or the LLVM C compiler other options exist depends on your *nix distribution Macro LD is prede ned as command ld. You can use these without de ning them. Or you can replace them with something else. e.g. CC = gcc 23 fi fi fi Macro string substitutions This allows you to use a macro and substitute a string in the macro. e.g. SRCS = a.c b.c c.c SRCS can be referenced with: $(SRCS:.c =.o) This will translate the list to: a.o b.o c.o 24 Macro string substitutions $(SRCS:.c = ) translates to: a b c The names of the executables can be created using the names of the source les a.c, b.c, and c.c. These allow you to do things like specify prerequisites without too much typing Can also reduce clutter in a make le for a large project, where a make le entry might have dozens of prerequisites 25 fi Suffix rules The following make le will compile the executables a, b, and c. SRCS = a.c b.c c.c all: $(SRCS:.c = ) Question: Why will this work? There are no instructions describing how to convert the C les into executables. 26 fi Suffix rules The answer is su x rules. These tell the system how to compile di erent types of les. By convention C les end with.c, Fortran les end with.f, C++ les end with.cc. Make has built-in rules which will use the correct compiler to turn a source code le into an executable. Type make -p to see all of the prede ned macros. 27 ffi fi fi fi Comments Comments begin with a # and continue to the end of the line. #build all assignments all: a1 a2 #a1 requires the math library a1: a1.c a1.h gcc a1.c -o a1 -lm -std=c11 -Wall a2: a2.c gcc a2.c -o a2 -std=c11 -Wall 28 Flags control options for the tools The components of the C toolchain mentioned in earlier can be controlled using make les Note: Some IDEs let you set ags indirectly by clicking options on property pages Others - primarily the multi-platform ones - use make (or cmake) under the hood and provide lists of ags that you can modify directly 29 fl fl Selecting the compiler in a Makefile We have already seen this: CC=gcc select gcc C compiler as front end Note: on a Mac, the command line utility "gcc" is an alias for the Clang compiler, unless you speci cally install GNU gcc We can also pass various options to the elements of the compiler toolchain 30 fi Preprocessor flags Preprocessor: CPPFLAGS= -Iinclude_file_dir Add include_ le_dir to the include paths of both and "" includes. We use this to avoid hardcoding relative or absolute paths into #include statements E.g. -I~/myproj/include Will add "~/myproj/include" to the include path, so all les in that directory can be included with a simple #include " lename.h" directive Other useful ags -Dsymbol[=value] Equivalent to #define symbol value -DNDEBUG disable assertions 31 fi fl Compiler flags Compiler: CFLAGS= -g save symbols for debugger -On optimization level (0,1,2,3) -Wall -std=c11 all warnings, C11 standard -fpic position-independent code (for shared object library) This ag goes in the command, not in CFLAGS: -c compile to.o le (don’t link) 32 fl fi Linker flags Linker: LDFLAGS= -Llibrary_dir Pass a library path to the linker Example: -L~/myproj/lib Add "~/myproj/lib" to the paths containing linked library les -llibrary link in library Example: -lfoo link in libfoo.so (or.a) -shared create shared object lib. These ags go in the command, not in LDFLAGS: -o lename create an output le with a speci c name, instead of the default Example: -o caltest 33 fi fl fi A note on code organization Large C codebases are often broken up into di erent directories, which often follow certain naming conventions: The headers do into the include directory This can be more complicated - e.g. public headers for the nal product go into include, other headers get placed into other directories The source code goes into the src directory Again, this can get a lot more complex The various binary les got into one or more directories - e.g. bin, lib, etc. 34 fi https://github.com/curl/curl Real-world example The curl library (used for command-line URL data transfer) 35 Standards for our course We will follow a similar convention in our course code in src headers in include Make le in the main directory A1 description will date the exact details The Make le and le structure for the List example have been updated accordingly, so you can use them as a template 36 fi fi fi Standards for our course Using the Make le macros This is where the macros shine We use macros to de ne locations of code and headers: INC = include/ SRC = src/ We then use them in our Make le - dependencies and the command line, e.g. StructListDemo.o: $(SRC)StructListDemo.c $(INC)LinkedListAPI.h $(CC) $(CFLAGS) -I$(INC) -c $(SRC)StructListDemo.c See the les in the updated ListExample.zip, posted in the Week 2 module on the course website 37 fi fi fi fi