This is the MOM5 component integrated in the IOW earth-system model.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

476 lines
15 KiB

<!--$Id: mkmf.html,v 2013/12/18 17:47:54 Niki.Zadeh Exp $ -->
<!-- using template.html
substitute AAA with the file
substitute BBB with exact path to RCS/CVS file -->
<!doctype html public "-//ietf//dtd html//en">
<meta name="description" content="">
<meta name="keywords" content="">
<link rel="stylesheet" href="balaji.css">
<title>mkmf user's guide</title>
<!-- title using title stylespec -->
<div class="title">
<h2>mkmf - a tool for making makefiles</h2>
<tt>mkmf</tt> is a tool written in perl5 that will construct a
makefile from distributed source. A single executable program is the
typical result, but I dare say it is extensible to a makefile for any
purpose at all.
<p><tt>Author: <a href="myaddr.html">Balaji</a>, SGI/GFDL.</tt>
<p>Features of <tt>mkmf</tt> include:
<li>It understands dependencies in f90 (<tt>module</tt>s and
<tt>use</tt>), the fortran <tt>include</tt> statement,
and the cpp <tt>#include</tt> statement in any type of source;
<li>There are no restrictions on filenames, module names, etc.;
<li>It supports the concept of overlays (where source is maintained in
layers of directories with a defined precedence);
<li>It can keep track of changes to <tt>cpp</tt> flags, and
knows when to recompile affected source (i.e, files
containing <tt>#ifdef</tt>s that have been changed since the
last invocation);
<li>It will run on any unix platform that has perl version 5 installed;
<li>It is free, and released under GPL. GFDL users can copy (or,
better still, directly invoke) the file
<tt>/net/vb/public/bin/mkmf</tt>. External users can download the
source <a
href="">here</a>. Current
public revision is 4.12.
<p><tt>mkmf</tt> is pronounced <i>make-make-file</i> or
<i>make-m-f</i> or even <i>McMuff</i> (Paul Kushner's suggestion).
<p>The calling syntax is:
<p><tt>mkmf [-a abspath] [-c cppdefs] [-d] [-f] [-m makefile] [-p program] [-t template] [-v] [-x] [args]</tt>
<li><tt>-a abspath</tt> attaches the <tt>abspath</tt> at
the <i>front</i> of all <i>relative</i> paths to sourcefiles;
<li><tt>cppdefs</tt> is a list of <tt>cpp</tt>
<tt>#define</tt>s to be passed to the source files: affected
object files will be selectively removed if there has been a change in
this state;
<li><tt>-d</tt> is a debug flag to <tt>mkmf</tt> (much
more verbose than <tt>-v</tt>, but probably of use only if you
are modifying <tt>mkmf</tt> itself);
<li><tt>-f</tt> is a formatting flag to restrict lines in the
makefile to 256 characters. This was introduced in response to a
customer who wanted to edit his makefiles using
<tt>vi</tt>). Lines longer than that will use continuation
lines as needed;
<li><tt>makefile</tt> is the name of the makefile written (default
<li><tt>template</tt> is a file containing a list of make
macros or commands written to the beginning of the makefile;
<li><tt>program</tt> is the name of the final target (default
<li><tt>-v</tt> is a verbosity flag to <tt>mkmf</tt>;
<li><tt>-x</tt> executes the makefile immediately;
<li><tt>args</tt> are a list of directories and files to be
searched for targets and dependencies.
<p><h4>Makefile structure:</h4>
<p>A <i>sourcefile</i> is any file with a source file suffix
(currently <tt>.F, .F90, .c, .f. .f90</tt>). An <i>includefile</i> is
any file with an include file suffix (currently <tt>.H, .fh, .h,
.inc</tt>). A valid sourcefile can also be an includefile.
<p>Each sourcefile in the list is presumed to produce an object file
with the same basename and a <tt>.o</tt> extension in the current
working directory. If more than one sourcefile in the list would produce
identically-named object files, only the first is used and the rest
are discarded. This permits the use of overlays: if <tt>dir3</tt>
contained the basic source code, <tt>dir2</tt> contained bugfixes, and
<tt>dir1</tt> contained mods for a particular run, <tt>mkmf dir1 dir2
dir3</tt> would create a makefile for correct compilation. Please note
that precedence <i>descends</i> from left to right. This is the
conventional order used by compilers when searching for libraries,
includes, etc: left to right along the command line, with the first
match invalidating all subsequent ones. See the <a
href="#examples">Examples</a> section for a closer look at precedence rules.
<p>The makefile currently runs <tt>$(FC)</tt> on fortran files
and <tt>$(CC)</tt> on C files. Flags to the compiler can be set
in <tt>$(FFLAGS)</tt> or <tt>$(CFLAGS)</tt>. The final
loader step executes <tt>$(LD)</tt>. Flags to the loader can be
set in <tt>$(LDFLAGS)</tt>. Preprocessor flags are used by
<tt>.F</tt>, <tt>.F90</tt> and <tt>.c</tt> files,
and can be set in <tt>$(CPPFLAGS)</tt>. These macros have a
default meaning on most systems, and can be modified in the template
file. The predefined macros can be discovered by running <tt>make
<p>In addition, the macro <tt>$(CPPDEFS)</tt> is applied to the
preprocessor. This can contain the <tt>cpp #define</tt>s which
may change from run to run. <tt>cpp</tt> options that do not
change between compilations should be placed in
<p>Includefiles are recursively searched for embedded includes.
<p>For <tt>emacs</tt> users, the make target
<tt>TAGS</tt> is always provided. This creates a TAGS file in
the current working directory with a cross-reference table linking all
the sourcefiles. If you don't know about emacs tags, please consult
the emacs help files! It is an incredibly useful feature.
<p>The default action for non-existent files is to <tt>touch</tt> them
(i.e create null files of that name) in the current working directory.
<p>All the object files are linked to a single executable. It is
therefore desirable that there be a single main program source among
the arguments to <tt>mkmf</tt>, otherwise, the loader is likely to
<p><h4>Treatment of [args]:</h4>
<p>The argument list <tt>args</tt> is treated sequentially from
left to right. Arguments can be of three kinds:
<li>If an argument is a sourcefile, it is added to the list of sourcefiles.
<li>If an argument is a directory, all the sourcefiles in
that directory are added to the list of sourcefiles.
<li>If an argument is a regular file, it is presumed to contain a list
of sourcefiles. Any line not containing a sourcefile is discarded. If
the line contains more than one word, the last word on the line should
be the sourcefile name, and the rest of the line is a file-specific
compilation command. This may be used, for instance, to provide
compiler flags specific to a single file in the sourcefile list:
f90 -Oaggress c.f90
<p>This will add <tt>a.f90, b.f90</tt> and <tt>c.f90</tt> to the
sourcefile list. The first two files will be compiled using the
generic command <tt>$(FC) $(FFLAGS)</tt>. But when the make requires
<tt>c.f90</tt> to be compiled, it will be compiled with <tt>f90
<p>The current working directory is always the first (and
top-precedence) argument, even if <tt>args</tt> is not supplied.
<p><h4>Treatment of [-c cppdefs]:</h4>
<p>The argument <tt>cppdefs</tt> is treated as
follows. <tt>cppdefs</tt> should contain a comprehensive list
of the <tt>cpp</tt> <tt>#define</tt>s to be
preprocessed. This list is compared against the current "state",
maintained in the file <tt>.cppdefs</tt> in the current
working directory. If there are any changes to this state,
<tt>mkmf</tt> will remove all object files
affected by this change, so that the subsequent <tt>make</tt>
will recompile those files. Previous versions of <tt>mkmf</tt>
attempted to <tt>touch</tt> the relevant source, an operation
that was only possible with the right permissions. The current version
works even with read-only source.
<p>The file <tt>.cppdefs</tt> is created if it does not exist. If you
wish to edit it by hand (don't!) it merely contains a list of the
<tt>cpp</tt> flags separated by blanks, in a single record, with no
newline at the end.
<p><tt>cppdefs</tt> also sets the <tt>make</tt> macro
<tt>CPPDEFS</tt>. If this was set in a template file and also
in the <tt>-c</tt> flag to <tt>mkmf</tt>, the value in
<tt>-c</tt> takes precedence. Typically, you should set only
<tt>CPPFLAGS</tt> in the template file, and
<tt>CPPDEFS</tt> via <tt>mkmf -c</tt>.
<p><h4>Treatment of includefiles:</h4>
<p>Include files are often specified without an explicit path, e.g
#include "config.h"
<p><tt>mkmf</tt> first attempts to locate the includefile in the same
directory as the source file. If it is not found there, it looks in
the directories listed as arguments, maintaining the same
left-to-right precedence as described above.
<p>This follows the behaviour of most f90 compilers: includefiles
inherit the path to the source, or else follow the order of include
directories specified from left to right on the <tt>f90</tt> command
line, with the <tt>-I</tt> flags <i>descending</i> in precedence from
left to right.
<p>If you have includefiles in a directory <tt>dir</tt> other than
those listed above, you can specify it yourself by including
<tt>-Idir</tt> in <tt>$(FFLAGS)</tt> in your template
file. Includepaths in the template file take precedence over those
generated by <tt>mkmf</tt>. (I suggest using
<tt>FFLAGS</tt> for this rather than <tt>CPPFLAGS</tt>
because fortran <tt>include</tt>s can occur even in source
requiring no preprocessing).
<p><a name="examples"><h4>Examples:</h4></a>
<p><li>The template file for the SGI MIPSpro compiler contains:
FC = f90
LD = f90
CPPFLAGS = -macro_expand
FFLAGS = -d8 -64 -i4 -r8 -mips4 -O3
LDFLAGS = -64 -mips4 $(LIBS)
LIST = -listing
The meaning of the various flags may be divined by reading the
manual. A line defining the <tt>make</tt> macro LIBS, e.g:
LIBS = -lmpi
may be added anywhere in the template to have it added to the link
command line.
Sample template files for different OSs and compilers are available in
the directory <tt>/net/vb/public/bin</tt>.
<p><li>This example illustrates the effective use of <tt>mkmf</tt>'s
precedence rules. Let the current working directory contain a file
named <tt>path_names</tt> containing the lines:
<p>The directory <tt>/home/src/base</tt> contains the files:
<p>Typing <pre>mkmf path_names /home/src/base</pre> produces the
following <tt>Makefile</tt>:
# Makefile created by mkmf $Id: mkmf.html,v 2013/12/18 17:47:54 Niki.Zadeh Exp $
-touch $@
all: a.out
c.o: /home/src/base/c.f90
$(FC) $(FFLAGS) -c /home/src/base/c.f90
a.o: updates/a.f90
$(FC) $(FFLAGS) -c updates/a.f90
b.o: updates/b.f90
$(FC) $(FFLAGS) -c updates/b.f90
./c.f90: /home/src/base/c.f90
cp /home/src/base/c.f90 .
./a.f90: updates/a.f90
cp updates/a.f90 .
./b.f90: updates/b.f90
cp updates/b.f90 .
SRC = /home/src/base/c.f90 updates/a.f90 updates/b.f90
OBJ = c.o a.o b.o
OFF = /home/src/base/c.f90 updates/a.f90 updates/b.f90
clean: neat
-rm -f .cppdefs $(OBJ) a.out
-rm -f $(TMPFILES)
localize: $(OFF)
cp $(OFF) .
etags $(SRC)
tags: $(SRC)
ctags $(SRC)
a.out: $(OBJ)
$(LD) $(OBJ) -o a.out $(LDFLAGS)
<p>Note that when files of the same name recur in the target list, the
files in the <tt>updates</tt> directory (specified in
<tt>path_names</tt>) are used rather than those in the base source
repository <tt>/home/src/base</tt>.
Assume that now you want to test some changes to <tt>c.f90</tt>. You
don't want to make changes to the base source repository itself prior
to testing; so you make yourself a local copy.
make ./c.f90
<p>You didn't even need to know where <tt>c.f90</tt> originally was.
Now you can make changes to your local copy <tt>./c.f90</tt>. To
compile using your changed copy, type:
mkmf path_names /home/src/base
The new Makefile looks like this:
# Makefile created by mkmf $Id: mkmf.html,v 2013/12/18 17:47:54 Niki.Zadeh Exp $
-touch $@
all: a.out
c.o: c.f90
$(FC) $(FFLAGS) -c c.f90
a.o: updates/a.f90
$(FC) $(FFLAGS) -c updates/a.f90
b.o: updates/b.f90
$(FC) $(FFLAGS) -c updates/b.f90
./a.f90: updates/a.f90
cp updates/a.f90 .
./b.f90: updates/b.f90
cp updates/b.f90 .
SRC = c.f90 updates/a.f90 updates/b.f90
OBJ = c.o a.o b.o
OFF = updates/a.f90 updates/b.f90
clean: neat
-rm -f .cppdefs $(OBJ) a.out
-rm -f $(TMPFILES)
localize: $(OFF)
cp $(OFF) .
etags $(SRC)
tags: $(SRC)
ctags $(SRC)
a.out: $(OBJ)
$(LD) $(OBJ) -o a.out $(LDFLAGS)
<p>Note that you are now using your local copy of <tt>c.f90</tt> for
the compile, since the files in the current working directory always
take precedence. To revert to using the base copy, just remove the
local copy and run <tt>mkmf</tt> again.
<p><li>This illustrates the use of <tt>mkmf -c</tt>:
mkmf -c "-Dcppflag -Dcppflag2=2 -Dflag3=string ..."
<p>will set <tt>CPPDEFS</tt> to this value, and also save this
state in the file <tt>.cppdefs</tt>. If the argument to
<tt>-c</tt> is changed in a subsequent call:
mkmf -c "-Dcppflag -Dcppflag2=3 -Dflag3=string ..."
<tt>mkmf</tt> will scan the source list for sourcefiles that make
references to <tt>cppflag2</tt>, and the corresponding object files
will be removed.
<p><li>In F90, the module name must occur on the same source line as
the <tt>module</tt> or <tt>use</tt> keyword. That is to
say, if your code contained:
<p><pre>use &
<br> this_module</pre>
<p>it would confuse <tt>mkmf</tt>. Similarly, a fortran
<tt>include</tt> statement must not be split across lines.
<p><li>Two <tt>use</tt> statements on the same line is not
currently recognized, that is:
<p><pre>use module1; use module2</pre>
<p>is to be avoided.
<p><li>I currently provide a default action for files listed as
dependencies but not found: in this case, I <tt>touch</tt> the
file, creating a null file of that name in the current directory. I am
willing to debate the wisdom of this, if you are disturbed. But it is
currently the least annoying way I've found to take care of a
situation when cpp <tt>#include</tt>s buried within obsolete
<tt>ifdef</tt>s ask for files that don't exist:
#ifdef obsolete
#include "nonexistent.h"
<p><li>If the formatting flag <tt>-f</tt> is used, long lines
will be broken up at intervals of 256 characters. This can lead to
problems if individual paths are longer than 256 characters.
<p><a name="Changes"><h4>Changes</h4></a>
The <a href="changes_mkmf.html">RCS log</a> for
<tt>mkmf</tt> contains a comprehensive list of changes. In the
unlikely event that you should wish to check out a retro version,
please get in touch with me, <a href="myaddr.html">Balaji</a>.
<li>An option to write a dependency graph, perhaps in HTML.
<p>Please address all inquires to <a href="myaddr.html">Balaji</a>,
<!-- footer using address stylespec -->
Author: <a href="myaddr.html">V. Balaji</a>
<br>Document last modified <!--#exec cmd="echo $LAST_MODIFIED" --></small>
<!-- store access stats -->
<!--#exec cmd="touch stats; chmod 666 stats" -->