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
476 lines
15 KiB
<!--$Id: mkmf.html,v 1.1.2.1 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"> |
|
<html> |
|
|
|
<head> |
|
<meta name="description" content=""> |
|
<meta name="keywords" content=""> |
|
<link rel="stylesheet" href="balaji.css"> |
|
|
|
<title>mkmf user's guide</title> |
|
</head> |
|
|
|
<body> |
|
|
|
<!-- title using title stylespec --> |
|
<div class="title"> |
|
<h2>mkmf - a tool for making makefiles</h2> |
|
<hr> |
|
<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> |
|
<hr> |
|
</div> |
|
|
|
<p>Features of <tt>mkmf</tt> include: |
|
|
|
<p><ul> |
|
|
|
<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="ftp://ftp.gfdl.gov/pub/vb/mkmf/mkmf">here</a>. Current |
|
public revision is 4.12. |
|
|
|
</ul> |
|
|
|
<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> |
|
|
|
<p><ol> |
|
|
|
<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 |
|
<tt>Makefile</tt>); |
|
|
|
<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 |
|
<tt>a.out</tt>); |
|
|
|
<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. |
|
|
|
</ol> |
|
|
|
<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</tt>. |
|
|
|
<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 |
|
<tt>$(CPPFLAGS)</tt>. |
|
|
|
<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 |
|
complain. |
|
|
|
<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: |
|
|
|
<p><ul> |
|
<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: |
|
|
|
<p><pre> |
|
a.f90 |
|
b.f90 |
|
f90 -Oaggress c.f90 |
|
</pre> |
|
|
|
<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 |
|
-Oaggress</tt>. |
|
</ul> |
|
|
|
<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 |
|
<p><pre> |
|
#include "config.h" |
|
</pre> |
|
|
|
<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> |
|
<ol> |
|
<p><li>The template file for the SGI MIPSpro compiler contains: |
|
|
|
<p> |
|
<pre> |
|
FC = f90 |
|
LD = f90 |
|
CPPFLAGS = -macro_expand |
|
FFLAGS = -d8 -64 -i4 -r8 -mips4 -O3 |
|
LDFLAGS = -64 -mips4 $(LIBS) |
|
LIST = -listing |
|
</pre> |
|
|
|
The meaning of the various flags may be divined by reading the |
|
manual. A line defining the <tt>make</tt> macro LIBS, e.g: |
|
|
|
<p><pre> |
|
LIBS = -lmpi |
|
</pre> |
|
|
|
may be added anywhere in the template to have it added to the link |
|
command line. |
|
|
|
<p> |
|
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><pre> |
|
updates/a.f90 |
|
updates/b.f90 |
|
</pre> |
|
|
|
<p>The directory <tt>/home/src/base</tt> contains the files: |
|
|
|
<p><pre> |
|
a.f90 |
|
b.f90 |
|
c.f90 |
|
</pre> |
|
|
|
<p>Typing <pre>mkmf path_names /home/src/base</pre> produces the |
|
following <tt>Makefile</tt>: |
|
|
|
<p><pre> |
|
# Makefile created by mkmf $Id: mkmf.html,v 1.1.2.1 2013/12/18 17:47:54 Niki.Zadeh Exp $ |
|
|
|
|
|
.DEFAULT: |
|
-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 |
|
neat: |
|
-rm -f $(TMPFILES) |
|
localize: $(OFF) |
|
cp $(OFF) . |
|
TAGS: $(SRC) |
|
etags $(SRC) |
|
tags: $(SRC) |
|
ctags $(SRC) |
|
a.out: $(OBJ) |
|
$(LD) $(OBJ) -o a.out $(LDFLAGS) |
|
|
|
</pre> |
|
|
|
<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. |
|
|
|
<p><pre> |
|
make ./c.f90 |
|
</pre> |
|
|
|
<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: |
|
|
|
<p><pre> |
|
mkmf path_names /home/src/base |
|
make |
|
</pre> |
|
|
|
The new Makefile looks like this: |
|
|
|
<p><pre> |
|
# Makefile created by mkmf $Id: mkmf.html,v 1.1.2.1 2013/12/18 17:47:54 Niki.Zadeh Exp $ |
|
|
|
|
|
.DEFAULT: |
|
-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 |
|
neat: |
|
-rm -f $(TMPFILES) |
|
localize: $(OFF) |
|
cp $(OFF) . |
|
TAGS: $(SRC) |
|
etags $(SRC) |
|
tags: $(SRC) |
|
ctags $(SRC) |
|
a.out: $(OBJ) |
|
$(LD) $(OBJ) -o a.out $(LDFLAGS) |
|
|
|
</pre> |
|
|
|
<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>: |
|
|
|
<p><pre> |
|
mkmf -c "-Dcppflag -Dcppflag2=2 -Dflag3=string ..." |
|
</pre> |
|
|
|
<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: |
|
|
|
<p><pre> |
|
mkmf -c "-Dcppflag -Dcppflag2=3 -Dflag3=string ..." |
|
</pre> |
|
|
|
<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. |
|
|
|
</ol> |
|
|
|
<p><h4>Caveats:</h4> |
|
<ol> |
|
<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: |
|
|
|
<p><pre> |
|
#ifdef obsolete |
|
#include "nonexistent.h" |
|
#endif |
|
</pre> |
|
|
|
<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. |
|
|
|
</ol> |
|
|
|
<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>. |
|
|
|
<p><h4>TODO:</h4> |
|
|
|
<ol> |
|
<li>An option to write a dependency graph, perhaps in HTML. |
|
</ol> |
|
|
|
<p>Please address all inquires to <a href="myaddr.html">Balaji</a>, |
|
SGI/GFDL. |
|
|
|
<!-- footer using address stylespec --> |
|
<br><hr> |
|
<address> |
|
Author: <a href="myaddr.html">V. Balaji</a> |
|
<br>Document last modified <!--#exec cmd="echo $LAST_MODIFIED" --></small> |
|
</address> |
|
</body> |
|
|
|
<!-- store access stats --> |
|
<!--#exec cmd="touch stats; chmod 666 stats" --> |
|
<!--#exec cmd="echo $DOCUMENT_NAME $REMOTE_IDENT@$REMOTE_HOST $HTTP_REFERER $HTTP_REFERER $DATE_LOCAL >> stats" --> |
|
</html>
|
|
|