mirror of
https://github.com/nwchemgit/nwchem.git
synced 2026-07-27 05:35:37 -04:00
283 lines
13 KiB
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.
|
|
|