Building static library of recipe routines


crab
01-29-2009, 10:28 PM
Hello,
I have purchase CD-ROM of NR v3.0.
It contains Fortran90 routines(older version) also.
These routines have lot of inter-dependencies.
so, i want to build a static/dynamic library of all of them.
I work in linux (openSuSE 10.2).
I tried following way,
=================================
#compile all (including utility progs. like nr.f90, nrtype.f90, etc.)
# it generates ".mod" file for many of them.
>gfortran *.f90 -c

#put them into one library archive
> ar crs libnrf90lib.a *.o *.mod
============================================

now when i use this lib file with my program to access some
NR routine, it asks for some ".mod" files.
When i put them into the dir. and then it compiles the program.
>gfortran myprog.f90 -l nrf90lib -L /path-to-libfile

pl. help me solve this prob.

thanks
regards,
crab

davekw7x
01-30-2009, 08:37 AM
>gfortran myprog.f90 -l nrf90lib -L /path-to-libfile



All of the mod files have to be on the Include path.

gfortran myprog.f90 -Ipath_to_directory_containing_mod_files -lnrf90lib -Lpath_to_directory_containing_libnrf90.a


For example: I copied the entire NR distribution to /home/dave/nr3. Fortran 90 NR source files are in /home/dave/nr3/legacy/nr2/f90_210/recipes. I create a static library named "libnr2f90.a" in that directory and I leave the .mod files there also.

I created a program file named z.f90 in /home/dave/nr3/legacy/nr2/f90_210/examples

I created a Makefile in /home/dave/nr3/legacy/nr2/f90_210/examples:

.SUFFIXES: .f90 .o
FORTRAN = gfortran
LIBDIR = ../recipes
INCLUDEDIR = ../recipes
LIB = nr2f90

TARGET = z

$(TARGET): $(TARGET).o
$(FORTRAN) $< -L$(LIBDIR) -l$(LIB) -o $@

.f90.o:
$(FORTRAN) -I$(INCLUDEDIR) -c $<


clean:
rm -f $(TARGET) $(TARGET).o



Then I just execute "make" from the command line. Here's what I see:


gfortran -I../recipes -c z.f90
gfortran z.o -L../recipes -lnr2f90 -o z


And the executable is created.

Now, suppose I want to compile xzroots.f90
I can modify the TARGET definition in the Makefile, or from the command line I can execute

make TARGET=xzroots


Here's what I see:

gfortran -I../recipes -c xzroots.f90
gfortran xzroots.o -L../recipes -lnr2f90 -o xzroots


And "./xzroots" runs the program.

Of course you can modify the LIB name definition and the LIBDIR and INCLUDEDIR path definitions to be whatever you need for your system. (Absolute paths or paths relative to your project file will work equally well.)


Regards,

Dave

crab
01-30-2009, 10:21 AM
Dear Dave
Thank you very much.
now i got it.
so, if i understand it properly, mod files are very similar
to header files of c/c++.
only diff. being that we dont include them in program file.

thanx again.
regards,
crab

davekw7x
01-30-2009, 12:05 PM
...mod files are very similar
to header files of c/c++....That is one way of looking at it. The "USE" statement tells the compiler to look for some stuff in some "mod" file somewhere. The command line "-I" switch tells the compiler where to look for the "mod" files.

Or some such thing.

Regards,

Dave

joe8232
09-02-2010, 10:08 AM
Hi,

Not sure if this is the best place to post this but I am having a problem creating a static library of the recipes on mac os x 10.6. I am using gfortran and have run the make file but when I execute make lib I get an error saying

/usr/bin/ranlib: file: libnr.a(nr.o) has no symbols
/usr/bin/ranlib: file: libnr.a(nrtype.o) has no symbols

and end up with a libnr.a file of 2.1mb. Does anyone have any idea what I'm doing wrong?

The start of my make file reads:
.SUFFIXES:
.SUFFIXES: .reslt .res .out .o .f90 .for .f
# Numerical Recipes makefile for Fortran 90
NRROOT=/sw/nr/recipes_f-90
# Edit this to be correct on your system
NRF90DIR=$(NRROOT)/recipes
NRXF90DIR=$(NRROOT)/demo/src
NRRESPDIR=$(NRROOT)/demo/responses
VPATH=$(NRF90DIR):$(NRXF90DIR):$(NRRESPDIR)
NRDAT=$(NRROOT)/demo/data
F90=gfortran
F90OPTS=-fno-range-check

davekw7x
09-02-2010, 06:46 PM
HiHi.



Not sure if this is the best place to postIt seems to be as good a place as any.

problem creating a static libraryThe Original Poster of this thread said that he already had created a static library, so I didn't bother telling how I created one.

on mac os x 10.6.

Well, I can show the Makefile that I used to create a static library on my Centos 5.5 Linux workstations (GNU gfortran version 4.1.2 and GNU make version 3.81). Maybe it will help, but YMMV (Your Mileage May Vary).

Anyhow, this is one approach for NR Fortran 90 version 2.1. Put this in the recipes directory and run "make" from there. (See Footnote.)

.SUFFIXES: .f90 .o

FORTRAN = gfortran
# Put nrtype, nrutil, nr first
#
# Then put the files that have modules defined
#
# Then put all of the other source files
#
# Note that xlinbcg.f90 was supplied in the examples
# directory, but module xlinbcg_data from that file
# is needed for asolve.f90 and atimes.f90, so it copies
# xlinbcg.f90 here and uses it as part of the source file
# list.
#
SOURCES = nrtype.f90 nrutil.f90 nr.f90 arcmak.f90 chixy.f90 \
dlinmin.f90 fmin.f90 hufmak.f90 hypgeo.f90 kermom.f90 \
linmin.f90 mpops.f90 odeint.f90 pwtset.f90 ran_state.f90 \
rkdumb.f90 sfroid.f90 sphfpt.f90 sphoot.f90 xlinbcg.f90 \
airy.f90 amebsa.f90 amoeba.f90 anneal.f90 arcode.f90 \
asolve.f90 atimes.f90 avevar.f90 badluk.f90 balanc.f90 \
banbks.f90 bandec.f90 banmul.f90 bcucof.f90 bcuint.f90 \
beschb.f90 bessi.f90 bessi0.f90 bessi1.f90 bessik.f90 \
bessj.f90 bessj0.f90 bessj1.f90 bessjy.f90 bessk.f90 \
bessk0.f90 bessk1.f90 bessy.f90 bessy0.f90 bessy1.f90 \
beta.f90 betacf.f90 betai.f90 bico.f90 bnldev.f90 \
brent.f90 broydn.f90 bsstep.f90 caldat.f90 chder.f90 \
chebev.f90 chebft.f90 chebpc.f90 chint.f90 choldc.f90 \
cholsl.f90 chsone.f90 chstwo.f90 cisi.f90 cntab1.f90 \
cntab2.f90 convlv.f90 correl.f90 cosft1.f90 cosft2.f90 \
covsrt.f90 cyclic.f90 daub4.f90 dawson.f90 dbrent.f90 \
ddpoly.f90 decchk.f90 dfpmin.f90 dfridr.f90 dftcor.f90 \
dftint.f90 difeq.f90 eclass.f90 eclazz.f90 ei.f90 \
eigsrt.f90 elle.f90 ellf.f90 ellpi.f90 elmhes.f90 \
erf.f90 erfc.f90 erfcc.f90 eulsum.f90 evlmem.f90 \
expdev.f90 expint.f90 factln.f90 factrl.f90 fasper.f90 \
fdjac.f90 fgauss.f90 fit.f90 fitexy.f90 fixrts.f90 \
fleg.f90 flmoon.f90 four1.f90 four1_alt.f90 four1_gather.f90 \
four2.f90 four2_alt.f90 four3.f90 four3_alt.f90 fourcol.f90 \
fourcol_3d.f90 fourn_gather.f90 fourrow.f90 fourrow_3d.f90 fpoly.f90 \
fred2.f90 fredex.f90 fredin.f90 frenel.f90 frprmn.f90 \
ftest.f90 gamdev.f90 gammln.f90 gammp.f90 gammq.f90 \
gasdev.f90 gaucof.f90 gauher.f90 gaujac.f90 gaulag.f90 \
gauleg.f90 gaussj.f90 gcf.f90 golden.f90 gser.f90 \
hqr.f90 hufdec.f90 hufenc.f90 hunt.f90 hypdrv.f90 \
hypser.f90 icrc.f90 igray.f90 index_bypack.f90 indexx.f90 \
interp.f90 irbit1.f90 irbit2.f90 jacobi.f90 jacobn.f90 \
julday.f90 kendl1.f90 kendl2.f90 ks2d1s.f90 ks2d2s.f90 \
ksone.f90 kstwo.f90 laguer.f90 lfit.f90 linbcg.f90 \
lnsrch.f90 locate.f90 lop.f90 lubksb.f90 ludcmp.f90 \
machar.f90 medfit.f90 memcof.f90 mgfas.f90 mglin.f90 \
midexp.f90 midinf.f90 midpnt.f90 midsql.f90 midsqu.f90 \
miser.f90 mmid.f90 mnbrak.f90 mnewt.f90 moment.f90 \
mp2dfr.f90 mpdiv.f90 mpinv.f90 mpmul.f90 mppi.f90 \
mprove.f90 mpsqrt.f90 mrqmin.f90 newt.f90 orthog.f90 \
pade.f90 pccheb.f90 pcshft.f90 pearsn.f90 period.f90 \
plgndr.f90 poidev.f90 polcoe.f90 polcof.f90 poldiv.f90 \
polin2.f90 polint.f90 powell.f90 predic.f90 probks.f90 \
psdes.f90 pwt.f90 pythag.f90 pzextr.f90 qrdcmp.f90 \
qromb.f90 qromo.f90 qroot.f90 qrsolv.f90 qrupdt.f90 \
qsimp.f90 qtrap.f90 quad3d.f90 quadct.f90 quadmx.f90 \
quadvl.f90 ran.f90 ran0.f90 ran1.f90 ran2.f90 \
ran3.f90 rank.f90 ratint.f90 ratlsq.f90 ratval.f90 \
rc.f90 rd.f90 realft.f90 recur1.f90 recur2.f90 \
relax.f90 relax2.f90 resid.f90 rf.f90 rj.f90 \
rk4.f90 rkck.f90 rkqs.f90 rlft2.f90 rlft3.f90 \
rotate.f90 rsolv.f90 rstrct.f90 rtbis.f90 rtflsp.f90 \
rtnewt.f90 rtsafe.f90 rtsec.f90 rzextr.f90\
savgol.f90 scrsho.f90 select.f90 select_bypack.f90 \
select_heap.f90 select_inplace.f90 shoot.f90 shootf.f90 simplx.f90 \
simpr.f90 sinft.f90 slvsm2.f90 slvsml.f90 sncndn.f90 \
snrm.f90 sobseq.f90 solvde.f90 sor.f90 sort.f90 \
sort2.f90 sort3.f90 sort_bypack.f90 sort_byreshape.f90 sort_heap.f90 \
sort_pick.f90 sort_radix.f90 sort_shell.f90 spctrm.f90 spear.f90 \
sphbes.f90 sphoot.f90 splie2.f90 splin2.f90 spline.f90 \
splint.f90 sprsax.f90 sprsdiag.f90 sprsin.f90 sprstp.f90 \
sprstx.f90 stifbs.f90 stiff.f90 stoerm.f90 svbksb.f90 \
svdcmp.f90 svdfit.f90 svdvar.f90 toeplz.f90 tptest.f90 \
tqli.f90 trapzd.f90 tred2.f90 tridag.f90 ttest.f90 \
tutest.f90 twofft.f90 vander.f90 vegas.f90 voltra.f90 \
wt1.f90 wtn.f90 wwghts.f90 zbrac.f90 \
zbrak.f90 zbrent.f90 zrhqr.f90 zriddr.f90 zroots.f90

OBJECTS = $(SOURCES:.f90=.o)

TARGET = libnr2f90.a

$(TARGET): $(OBJECTS)
rm -f $@
ar cr $@ $^
@echo -e "\n***Created $(TARGET) library***\n"

%.o: %.f90
$(FORTRAN) -c $< -o $@

xlinbcg.f90: ../examples/xlinbcg.f90
cp ../examples/xlinbcg.f90 .

clean:
rm -f *.mod *.o xlinbcg.f90 $(TARGET)


My response to the Original Post showed a Makefile that I use to link with the library. These days I use the slightly more modern form

%.o: %.f90
$(FORTRAN) -I$(INCLUDEDIR) -c $<


instead of the old-fashioned

.f90.o:
$(FORTRAN) -I$(INCLUDEDIR) -c $<


(But the results are the same.)



Regards,

Dave

Footnote:
Maybe it seems like I'm doing it the "hard way," but I like to know exactly what goes into my library file and how it gets there. In my case, the size of libnr2f90.a was something like 1.6 MBytes. You can run nm -s or objdump -f to verify the contents of the library file.