NWChem/doc/prog/makefile_libs.tex

283 lines
13 KiB
TeX

\section{Makefiles and Libraries}
\label{sec:makelib}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% NOTE: the first part of this section (up to the discussion of the
% environmental variables NWCHEM_TOP and NWCHEM_TARGET)
% is adapted from the current (as of 9/29/98) version of
% the file Build.notes, from ~/doc/ in the CVS repository. If Build.notes
% has been updated since, this section should be updated, too.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
The working assumption in documenting the NWChem code is that the
developers will be relatively sophisticated hackers, used to deciphering
C and Fortran source code and makefile scripts. The steps for building
an executable version of the code are as automated as is practical, with
upward of a hundred individual makefiles in the source code directory
tree. The developer is advised to look carefully at the top-level
makefile
{\tt ...src/config/makefile.h} to get a feel for what this package can
be built for and for some instructions about variables that must be set
before invoking {\tt make}.
The makefiles will work only with GNU {\tt make}, and it must be the one
that appears first in your path, otherwise dependent "makes" will not
invoke the right one.
The code in the CVS repository is set up to run on machines for
which working floating point precision is DOUBLE PRECISION. If your
platform wants REAL, you need to do a {\tt make dbl\_to\_sngl} before
anything else. (Remember to do {\tt make sngl\_to\_dbl} {\em before} checking
anything back into the repository. Doing this before updating from
the repository helps avoid problems too. Since code comes out of the
repository set up for DOUBLE PRECISION, you will probably have
to convert after your update anyway.)
Which routines are subject to precision conversion is governed by a
{\tt USES\_BLAS} macro in each makefile. Only files listed in this macro
will be processed for precision changes. If you write new routines
that use {\tt BLAS} or {\tt LAPACK}, be sure to add them to the {\tt USES\_BLAS} macro
too.
The current philosophy is that by default objects are built without
optimization (and normally with debugging on, to facilitate
development). Only those routines which are performance hot spots are
optimized. This helps avoid stupid compiler bugs which, by empirical
observation, are more likely to show up on things other than
hard-working number crunching. Each makefile contains an {\tt OBJ\_OPTIMIZE}
macro which should name those routines that {\em should} be built with
optimization. All the rest should be listed in the OBJ macro. The
extra arguments used when compiling optimized code are the
platform-dependent [FC]OPTIMIZE macros in \verb+config/makefile.h+. If you
want to turn off all optimization, change these and rebuild.
At present, the package is almost entirely self-contained. The only
thing left out is George Fann's PEIGS (Parallel EIGenSolver,
pronounced "pigs") library. For most platforms, the makefiles already
include pointers to the canonical locations for the PEIGS library for
that platform. If your link complains about this library, contact one
of the NWChem developers for help, or send e-mail to
{\tt nwchem-developers@emsl.pnl.gov}.
To build the package, go to the source directory ({\tt .../src}) in your
local copy of the NWChem source directory tree and type 'make'. (NOTE:
If you are messing
around only in specific subdirectories, you can do 'make' inside them, and
then 'make nwchem\_link' in directory {\tt src}. This will save you from traversing
{\em every} directory in the package -- but your version of these directories
had better be up to date!)
Object libraries are constructed in the {\tt lib} directory. The executable
ends up in {\tt src} (strange but true).
Before you actually do the build, however, you must set up your own
environment properly.
In your environment, or on the {\tt make} command line, you must specify two
variables
\begin{itemize}
\item {\tt NWCHEM\_TARGET} --- the name of the machine to build for.
\item {\tt NWCHEM\_TOP} --- the full path to the top level NWChem
directory.
\end{itemize}
Look in the {\tt README} file in the top-level NWChem directory for
information about supported target platforms. For instance, you might
insert the following in your \verb+.cshrc+ file on a SUN with SunOS
4.1.3
\begin{verbatim}
setenv NWCHEM_TARGET SUN
if (! $?NWCHEM_TOP) setenv NWCHEM_TOP $HOME/nwchem
\end{verbatim}
(The test to see if \verb+NWCHEM_TOP+ is already defined permits you
to build in an alternative directory without having to edit your
\verb+.cshrc+ file). Given just this information the structure of
NWChem makes it easy to write a makefile to build a library for a
module (.e.g, {\tt libddscf.a} for the SCF module) or to add routines
into a library shared between multiple modules ({\tt libutil.a}
which includes at least the util, geometry, basis, global, and ma
trees).
A minimal makefile looks like this
\begin{verbatim}
LIBRARY = libminimal.a
OBJ = a.o b.o c.o
include ../config/makefile.h
include ../config/makelib.h
\end{verbatim}
The above specifies that the object files are to be generated by
compiling available source (C or Fortran, without optimization) and
put into the library {\tt libminimal.a} (in the NWChem library
directory). Nothing else is necessary. If the library source is not
located in a subdirectory of the NWChem {\tt src} directory then the
path to the included files must be modified accordingly.
A slightly more complex makefile looks like this
\begin{verbatim}
LIBRARY = libsimple.a
OBJ = a.o b.o c.o
OBJ_OPTIMIZE = d.o
USES_BLAS = c.o
HEADERS = simple.fh
LIB_TARGETS = test
include ../config/makefile.h
include ../config/makelib.h
test: test.o $(LIBRARY_PATH)
$(LINK.f) -o $@ $^
a.o b.o c.o test.o: simple.fh private.fh
\end{verbatim}
This makefile builds the library {\tt libsimple.a} from four object
files of which only one ({\tt d.o}) is optimized. The source
associated with {\tt c.o} uses FORTRAN BLAS and will be automatically
converted on machines where 64 bit reals are single precision (e.g.,
requiring {\tt sgemm()} rather than {\tt dgemm()}). The header file
{\tt simple.fh} is exported automatically into the NWChem include
directory ({\tt src/include}) where it may be included by other
modules which reference these routines. Associated with the module is
the executable {\tt test} (not made by default) which will be cleaned
up automatically with \verb+make clean+. The final line
specifies a dependency of certain object files on various header
files.
At an absolute minimum, a makefile for a module must do the following:
\begin{enumerate}
\item include \verb+../config/makefile.h+ --- this will
define {\tt TARGET} (among other things)
from which any machine dependent actions are driven.
Because the first rule in this file
builds the library, there should be {\em no} targets before this.
(NOTE: if you do not need to use {\tt TARGET} then it is best to include this
file at the same point that {\tt makelib.h} is included.)
\item define {\tt LIBRARY} as the name of the library to be made.
\end{enumerate}
The makefile can also do the following, at the developer's option:
\begin{enumerate}
\item define {\tt OBJ} as the list of object files to be made
without optimization
\item define {\tt OBJ\_OPTIMIZE} as the list of object files to
be made with optimization. (HINT: It is good practice to keep this list
short, to minimize exposure to possible compiler errors.)
\item define {\tt HEADERS} as the list of header/include files to be
copied into the common include directory. (WARNING: Do NOT copy {\tt include}
files into the {\tt include} directory by hand. This is done
automatically, and any separately copied files will be lost.)
\item define {\tt LIB\_TARGETS} as any additional files made in
this subdirectory that may need cleaning up
\item define {\tt LIB\_DEFINES} as any additional defines for
the C preprocessor (for both Fortran and C)
\item define {\tt LIB\_INCLUDES} as any additional include
directories
\item define {\tt SUBDIRS} as any subdirectories to build (NOTE: If you do this,
makefiles in subdirectories will need to modify the paths to
the include files.)
\item define {\tt USES\_BLAS} to be the list of FORTRAN files that
need BLAS names converting between single and double (e.g., {\tt
ddot} to {\tt sdot})
\item define any additional targets (e.g., test programs)
\end{enumerate}
Addtional things you will need to know how to do:
\begin{enumerate}
\item To modify the optimization being used, specify on the command
line {\tt C/FDEBUG} or {\tt C/FOPTIMIZE} to override the flags for the
{\tt OBJ} and {\tt OBJ\_OPTIMIZE} files respectively. E.g.,
\begin{verbatim}
make FDEBUG="-g -O1"
make FOPTIMIZE="-O3 -Superfast -bugs" FDEBUG="-O1"
\end{verbatim}
\item The library is put directly into the NWChem library
directory and the full path to the library (if needed by your
makefile) is automatically put into the variable {\tt
LIBRARY\_PATH}.
\item The object files are put directly into the libraries and are
not kept elsewhere. This has several implications
\begin{itemize}
\item You can (apart from TCGMSG and GA which are being fixed) build
executables and libraries for multiple platforms in the same
source tree.
\item To force recompilation of all source in a given directory
\verb+make clean+ works by deleting the object files from
the library, and deletes the library itself only if it is empty.
You have to
actually either delete the corresponding library or touch the
source files.
\item To override the compilation options for a specifc file (e.g.,
because of compiler errors on a specific platform) you must
specify the dependency on the object file in the library. Here
are two examples. The first one (\verb+dosymops.f+) does not need
preprocessing, whereas the second one (\verb+sym_mo_ap_op.F+) does
and this must be done explicity within the rule for this file.
This preprocessing is normally done automatically.
\begin{verbatim}
ifeq ($(TARGET),CRAY-T3D)
FNOOPT = -dp -Ccray-t3d -Wf"-o noscalar,jump,noieeedivide"
$(LIBRARY_PATH)(dosymops.o): dosymops.f
$(FC) -c $(FNOOPT) $^
$(LIBRARY_PATH)(sym_mo_ap_op.o): sym_mo_ap_op.F
$(FCONVERT)
$(FC) -c $(FNOOPT) sym_mo_ap_op.f
@/bin/rm -f sym_mo_ap_op.f
endif
\end{verbatim}
%$ ... to unscrew emacs latex hiliting
\end{itemize}
\item The target {\tt clean} will recursively descend subdirectories and
delete object files from both the directory and associated library,
core files and files defined in {\tt LIB\_TARGETS}.
\item The target {\tt realclean} will, in addition to the actions of
clean, also delete the library and any emacs backup files.
\item The target {\tt cleanF} will recursively descend subdirectories
and search for and delete \verb+.f+ files for which a corresponding
\verb+.F+ file exists. This is useful on machines for which the
conversion from \verb+.F+ to \verb+.f+ is done explicitly rather
than by the compiler.
\item The target {\tt depend} will recursively descend subdirectories
and append onto the end of makefiles dependencies of \verb+.F+ and
\verb+.c+ files on header files that have been included using the
notation \verb+#include "filename"+. File includes using angle
brackets are assumed to be system files and dependencies are not
generated. If the include file is in the local directory, the
dependency is generated upon that. Otherwise, a dependency is
generated upon a file in the NWChem include directory.
Do not insert anything below the line
\begin{verbatim}
# DO NOT EDIT BENEATH THIS LINE ... GENERATED AUTOMATICALLY
\end{verbatim}
since it will be lost the next time that \verb+make depend+
is run.
\end{enumerate}
Typing {\tt make} in the top-level NWChem directory will traverse the
entire directory tree twice. Once to ensure the include files are
up-to-date and then again for the libraries. This can take a while.
Therefore,
when working on development of a particular a module alone,
it is usually much faster to
\begin{enumerate}
\item execute {\tt make} in the subdirectory, and
\item execute {\tt make link} in the top NWChem directory.
\end{enumerate}
Note that this approach cannot be used if recompilation of another
module is also required, since the
special target link just relinks the code and does not traverse
the directory tree. {\em After doing a \verb+cvs update+ you should:}
\begin{enumerate}
\item do a {\tt make depend}
if you have not recently, in any directory you
have been working in, and
\item do a full {\tt make} from the top level to ensure that all libraries
incorporate any changed common blocks or declarations.
\end{enumerate}
In addition, the top-level makefile has the target {\tt test} which
builds the executable \verb+nwchem_test+ in the \verb+src/+ directory
(rather than the usual \verb+$(BINDIR)/nwchem+), % $
and the target {\tt prof}
which builds \verb+nwchem_prof+ (in \verb+src/+)
for performance profiling by linking with the -p option.