===Compiling Code=== To compile code we use a compiler. Popular choices for Fortran and C are either gcc or intel compilers. In this example we will look at compiling Fortran with gfortran. gfortran is an open source GNU compiler. It is actually more than just a compiler. When we call gfortran we are calling a compiler driver which decides what tasks to send to a fortran compiler, assembler and linker. Often we have a source code that consists of many different files. Subroutines in each file are called by code in the other files. These files need to be linked together. There are two steps in building programs: - Compiling the individual source files into object files - Linking the files with each other and numerical libraries In the first step, compiling, gfortran goes through the source code files and converts them to assembler, which are instructions to run on a CPU. This step usually produces object files ending in ''.o'' and files with the extension ''.mod''. ''.mod'' files are used when compiling other source files that depend on the first. To compile a source file we use the following command: $ gfortran -c file1.f90 The second step, linking, gfortran links together the compiled object files and, optionally, external numerical libraries into an executable file. **Blas** and **Lapack** are popular numerical libraries. They contain many fast subroutines for manipulating matrices. To link files together we can use the following command: $ gfortran -o file1.o file2.o file3.o -L/usr/lib/ -llpack -lblas Here the option ''-L/usr/lib'' indicates the directory where the libraries can be found and ''-l'' is used to link each of the libraries. But we have to compile the files in right order, as they depend on each other. This is where make can help us. I made an example code for you called inverse. It inverts a simple 3x3 matrix using lapack. It is a simple code and it is not really important that we understand it. It is more important to note that I divided the code up into four different ''.f90'' files. inverse.f90 is the main file which calls subroutines from input.f90 and invert.f90. invert.f90 calls a subroutine from lu_decompose.f90. I also created a simple makefile to build the program let's take a look and see if we can understand it. #This is a makefile for inverse. F90 = gfortran LIBDIR = -L/usr/lib LIBS = \ $(LIBDIR) \ -llapack \ -lblas OBJS = \ lu_decompose.o \ invert.o \ input.o \ inverse.o \ %.o:%.f90 $(F90) -c $*.f90 inverse: $(OBJS) $(F90) -o inverse $(OBJS) $(LIBS) #dependencies invert.o: invert.f90 lu_decompose inverse.o: inverse.f90 input.o invert.o input.o: input.f90 lu_decompose.o: lu_decompose.f90 clean: rm -f *.o *.mod Let's unpack this makefile. First we define some macros. The compiler as ''$F90'', our library path as ''$LIBDIR'', our external libraries as ''$LIBS'' and the object file names as ''$OBJS''. Then we use a pattern rule to compile all ''.f90'' files in object files. The executable inverse depends on all objects and links the object files with each other and the external libraries. Next we define all the dependencies. Notice that we can define them here and make will automatically figure out in which order to run the pattern rule ''%.o:%.f90''. That's quite convenient. Finally we define a clean target. It is not an actual file. Sometimes we call these targets **phoney** targets. It has a command to delete all the ''.o'' and ''.mod'' files created in the compile process. It won't normally run since make only runs the first command in a makefile and any rules which create dependencies for the first target. But, we can force it to run by typing: $ make clean in the shell. ===Suffix rules & Implicit rules=== You will likely encounter one more type of rule, suffix rules. These rules consist of file suffixes listed together. e.g. ''.f.o'' It is confusing that in suffix rules the prerequisite is listed first and then the target. These rules also only work with built-in suffixes. You can add to the make built-in suffixes with the line: .SUFFIXES: .f90 Suffix rules are obsolete and pattern rules should be used instead. But for compatibility with a old make files they are kept. I much prefer to use pattern rules since they are more general and clearer. Another thing you should be aware of is that make includes several built-in rules also called **implicit rules**. We can see all of the variables and rules of make if we type ''make -p'' into the shell. Make will search through these implicit rules if you list a target with no rule or a dependency that has no rule.