Chapter 02 - Makefiles ---------------------- "Make it so." [Jean Luc Picard] = 02.01 === Makefiles ====================================== A makefile is a script which contains all necessary commands to build a project. Instead of typing all the commands again and again they are store in this one script file. Read about makefile here: http://www.gnu.org/software/make/manual/make.html Important topics: - Targets have to be written at the begin of a line (column 0); word ends with a colon : commands have to be indented myprog: cc -o myprog main.cpp - Dependencies have to be placed right behind the target myprog: main.o - Variables use only capitals and underscores values have to be in the same line; use backslashes to wrap lines CFILES = main.cpp \ add.cpp - .Rulez Makefiles are not only used to build programs from source files but are used in a wide variaty of applications: e.g. to be TeX-documents. = 02.02 === My 1st Makefile ================================ Create a file with the name 'Makefile' in Example_01/ Edit the file: Create a default target called 'myprog' Create for this target a dependency to the object files: main.o function_add.o The commands which are executed by this target should link the object files. Create a target for the object files with a dependency to the source code files: main.cpp function_add.cpp function_add.hpp The commands which are executed by this target should compile the source files. Try to build the program by executing: #> make = 02.03 === Using Variables ================================ Use variables for the - binary - object files - source files If more than 1 filename is assigned to a variable for reasons for "visibility" only 1 filename is written per line. To connect the lines to "logically 1 line" use a backslash \ at the end of all lines, but the last. Create a target 'clean' which executes commands to remove binary, object files, and a core. Command lines don't need to be connected by backslashes but there are no blank lines allowed in between! Test the makefile. = 02.04 === The -I Option ================================== Create a subdir include/ . Move the file function_add.hpp to this subdir. Change in main.cpp the line: #include "function_add.hpp" to #include ‹function_add.hpp› #> make clean #> make Results in an error, because the header could not be found anymore. Use the compiler-option -I to pass more search pathes for include files to the compiler: -Imysearchpath Add -Iinclude to the compile command. #> make = 02.05 === Even More Variables ============================ Use variables for the - compiler command - linker command - common compiler flags - include flags for the compiler - linker flags = 02.06 === Linking Libraries ============================== Change the makefile so that the binary depends on only 1 object file: main.o and a dynamic lib: libMyLib.so Create a target for libMyLib.so which depends on function_add.o Use the commands from chapter 1 to build the lib. = 02.07 === More Directories and Makefiles ================= Create a subdir in Example_01/ called FunctionAdd/ Move funtion_add.cpp & function_add.hpp to it. Create a link in include/ which points to the header function_add.hpp now in FunctionAdd/ Create a new makefile in FunctionAdd/ which builds only the lib (but doesn't create/link a binary). Build the lib. Create a subdir in Example_01/ called lib/ Create in lib a link which points to the currently build lib in FunctionAdd/ Create a subdir in Example_01/ called Application/ Move main.cpp and the 1st makefile to it. Modify the makefile so that the include flag points to ../include Add a linker flag to find the lib: -L../lib Create a new makefile in Example_01/ with a target 'myprog' which executes the commands: cd FunctionAdd ; make cd Application ; make Create a target 'clean' which executes the commands: cd FunctionAdd ; make clean cd Application ; make clean This way, this makefile calls other makefiles in subdirectories. Try to build the program. Before executing the program use ldd to check whether the dynamic lib is found. This should not be the case. Add the absolute path to the lib/-dir to the environment variable LD_LIBRARY_PATH Check with ldd again. = 02.08 === The -l Option ================================== Instead of using the comlete library name libMyLib.so the option -l can be used. To use this option, the lib name has to begin with 'lib' and end with .so or .a e.g. libMyLib.so Then the lib can be linked with -lMyLib simply skipping the beginning 'lib' and the filename extension .so The -l option belongs to the linker. = 02.09 === Linker Options ================================= Instead of/additionally to using LD_LIBRARY_PATH to define the search pathes some linker options can be used. To pass a search path to the linker which should be used during run time to find shared objects use the options: -Wl,-rpath -Wl,/search/path/to/lib Remove the search path from the environment variable LD_LIBRARY_PATH and try to use just these linker options. = 02.10 === Using the include-Directive ==================== Some parts of makefiles remain the same for all projects. Other parts are different for each projects. These can be handle by variables, which are then used in the common parts, which can be held in their own file. Then they are included from the project specific makefile. BIN = myprog OFILES = main.o ... include path/CommonMakfile.mk Files which are included from a Makefile can have different filenames - they don't have to be named 'Makefile'. As the filename extension .mk is used. = 02.11 === Default Targets ================================ The default target is usually the first target in the makefile.
(C) by n-o-d