title: Creating a FORTRAN makefile
body: <p>I have a FORTRAN source code consisting of many different .F and .h files.  I need to build an executable from it, but I'm having some problems.  The makefile that I produced so far (which may have errors as I'm new to this) is:</p>
  
  <pre><code> # compiler
   FC = /usr/bin/gfortran-4.5
  
   # compile flags
   FCFLAGS = -g -c -fdefault-real-8 -fbacktrace -fno-align-commons
   # link flags
   FLFLAGS = -g -fbacktrace
  
   # source files and objects
   SRCS = $(patsubst %.F, %.o, $(wildcard *.F)) \
          $(patsubst %.h, %.mod, $(wildcard *.h))
  
   # program name
   PROGRAM = blah
  
   all: $(PROGRAM)
  
   $(PROGRAM): $(SRCS)
      $(FC) $(FCFLAGS) $@ $&lt;
  
   %.o: %.F
      $(FC) $(FLFLAGS) -o $@ $&lt;
  
   %.mod: %.h
      $(FC) $(FLFLAGS) -o $@ $&lt;
  
   clean:
      rm -f *.o *.mod
  </code></pre>
  
  <p>When I try to make the program, however, I'm getting a slew of undefined reference errors.  I mean, every function and subroutine call in the very first compiled .F file gives back an undefined reference error.  I thought this was because gfortran was trying to link the files instead of just compiling them and then linking at the end, but I thought the '-c' option was supposed to prevent that.</p>
  
  <p>UPDATE:</p>
  
  <p>As commenters have pointed out, I mixed up the compile and link flags.  Furthermore, you shouldn't compile *.h files.  Here is the latest, corrected makefile:</p>
  
  <pre><code># compiler
  FC = /usr/bin/gfortran-4.4
  
  # compile flags
  FCFLAGS = -g -c -fdefault-real-8 -fbacktrace -fno-align-commons -fbounds-check -std=legacy
  # link flags
  FLFLAGS =
  
  # source files and objects
  SRCS = $(patsubst %.F, %.o, $(wildcard *.F))
  
  # program name
  PROGRAM = blah
  
  all: $(PROGRAM)
  
  $(PROGRAM): $(SRCS)
      $(FC) $(FLFLAGS) -o $@ $&lt;
  
  %.o: %.F
      $(FC) $(FCFLAGS) -o $@ $&lt;
  
  clean:
      rm -f *.o *.mod
  </code></pre>
  
  <p>Now when I run make, it will compile each *.F file in the code, but it fails at the linking stage.  I get a bunch of undefined reference errors in the very first *.F file.  The compiler seems to be going over each *.F file individually in the linking stage, which I'm not sure is correct.  Then I get an error:</p>
  
  <pre><code>/usr/lib/gcc/x86_64-linux-gnu/4.4.5/libgfortranbegin.a(fmain.o): In function `main':
  (.text+0x26): undefined reference to `MAIN__'
  collect2: ld returned 1 exit status
  </code></pre>
  
  <p>However, if I type the command:</p>
  
  <pre><code>gfortran -o blah *.o
  </code></pre>
  
  <p>The executable will be built, so it seems like I did something wrong in the makefile for the linking stage.</p>
  
  <p>UPDATE: 5/9/2011</p>
  
  <p>Sverre pointed out the final problem with my makefile.  In my first target that builds the program, I use the shortcut command for only the first dependency ($&lt;), but I need to include all dependencies (i.e. all *.o files) using the ($^) shortcut.  The final, working makefile is as follows:</p>
  
  <pre><code># compiler
  FC      := /usr/bin/gfortran-4.5
  
  # compile flags
  FCFLAGS = -g -c -fdefault-real-8 -fbacktrace -fno-align-commons -fbounds-check
  # link flags
  FLFLAGS =
  
  # source files and objects
  SRCS = $(patsubst %.F, %.o, $(wildcard *.F))
  #       $(patsubst %.h, %.mod, $(wildcard *.h))
  
  # program name
  PROGRAM = vipre
  
  all: $(PROGRAM)
  
  $(PROGRAM): $(SRCS)
      $(FC) $(FLFLAGS) -o $@ $^
  
  %.o: %.F
      $(FC) $(FCFLAGS) -o $@ $&lt;
  
  # %.mod: %.h
  # $(FC) $(FCFLAGS) -o $@ $&lt;
  
  clean:
      rm -f *.o *.mod
  </code></pre>