Numerical Recipes Forum  

Go Back   Numerical Recipes Forum > Obsolete Editions Forum > General Problems in Using NR

Reply
 
Thread Tools Display Modes
  #1  
Old 01-07-2009, 02:21 AM
guy.tikochinsky guy.tikochinsky is offline
Registered User
 
Join Date: Jul 2008
Posts: 3
Question Compile *.c files

In general how do I compile my *.c files that uses the nr files?
Reply With Quote
  #2  
Old 01-07-2009, 09:49 AM
davekw7x davekw7x is offline
Registered User
 
Join Date: Jan 2008
Posts: 453
Quote:
Originally Posted by guy.tikochinsky View Post
In general how do I ...
There is no "general" set of instructions for compiling any C program, so the answer to, "How do I ... ?" is: "It depends."

How about giving us some details of your setup?

What compiler?
What Operating System?
What kind of directory structure? (Where are your NR distribution files? Where are your project source files?)


How do you compile your other (non-NR) *.c programs?

Command line?
Makefile?
Integrated Development Environment?
What?

Regards,

Dave

Last edited by davekw7x; 01-07-2009 at 11:31 AM.
Reply With Quote
  #3  
Old 01-08-2009, 04:01 AM
guy.tikochinsky guy.tikochinsky is offline
Registered User
 
Join Date: Jul 2008
Posts: 3
Compile *.c files

Hi,

Thanks for your respone.

I am using openSUSE 10.3 (i586) - Kenet 2.6

The compiler is gcc version 4.2.1

The directory structure is /usr/local/src/NR_C301/legacy/nr2/C_211

I am trying to compile one of the example.

I compile all the NR routine
.../recipes#gcc -v -I../other -I/usr/include *.c

=> rlftfrag.c:30: error: redefinition of 'main'
rlftfrag.c:9: error: previous definition of 'main' was here
rlftfrag.c:50: error: redefinition of 'main'
rlftfrag.c:9: error: previous definition of 'main' was here

.../recipes#ar cr libnr.a *.c

=> then I got file "libnr.a"

.../examples#gcc -g xjulday.c -I../other -I/usr/include -o xjulday -L ../recipes -lm

=>In file includes from xjulday.c:7:
../other/nr.h:423: error: conflivting type for 'select'
/usr/include/sys/select.h:112: error: previous declaration of 'select' was here

Thanks in Advance
Reply With Quote
  #4  
Old 01-08-2009, 09:09 AM
davekw7x davekw7x is offline
Registered User
 
Join Date: Jan 2008
Posts: 453
Quote:
Originally Posted by guy.tikochinsky View Post
=>In file includes from xjulday.c:7:
../other/nr.h:423: error: conflivting type for 'select'
/usr/include/sys/select.h:112: error: previous declaration of 'select' was here
For a start, I would suggest that you make sure that you don't change the original nr.h. Keep it just in case...

So, I suggest that you move the original nr.h to a "safe" directory. Make a copy in the recipes directory. Then comment out line 423 of nr.h in the recipes directory.
Code:
/*float select(unsigned long k, unsigned long n, float arr[]); */
Then try compiling the test program again.

I assume that you meant to tell it to use libnr.a, so: Maybe the compile command would be something like
Code:
gcc -g xjulday.c -I../other -o xjulday -L../recipes -lnr -lm
When you execute the test program, if it tells you that it can't find the data file, then you can copy dates1.dat from the ../data directory to the examples directory.

If this doesn't work, and you can't figure out why, then post again and tell us what happened. Don't try any of the following until you get a successful compilation and execution of xjulday.

If this does work, you will have to do something about the NR select() function in case you ever need it.

Here is what I did, way back when...

I made a copy of the select.c file in the recipes directory and called it nrselect.c, then I moved the original select.c to the "safe" directory.

I changed all references to the select() function in the files in NR recipes and examples and other directories to nrselect(). (I did this after moving the affected files to the "safe" directory and making copies back in their original directories.)

If you haven't done this already, don't forget to go back into your new nr.h and change line 423.

Code:
float nrselect(unsigned long k, unsigned long n, float arr[]);
At this point, I would delete libnr.a and recompile the entire library, since several recipes files have been changed.

Then try compiling various files in the examples directory. Let us know how it works out.


Regards,

Dave

Footnotes:
1. The above worked on my Centos 5 workstation (GNU gcc Version 4.1.2).

2. I also moved all files in the recipes directory with a main() function to another directory before compiling the library so that there wouldn't be any files in the library with a main() function. A minor point, maybe, but I like things to be as clean as possible (within reason).

Last edited by davekw7x; 01-08-2009 at 04:41 PM.
Reply With Quote
  #5  
Old 01-11-2009, 12:39 AM
guy.tikochinsky guy.tikochinsky is offline
Registered User
 
Join Date: Jul 2008
Posts: 3
Hi Dave,

thanks a lot. It's working.

Guy
Reply With Quote
  #6  
Old 04-22-2009, 11:30 AM
squidx squidx is offline
Registered User
 
Join Date: Apr 2009
Posts: 2
I'm also having a problem compiling my *.c files

I'm new at c, which is why I'm trying to work with the NR in the first place.

When I downloaded the files, they did not come with any clear instructions or any Makefiles that I could see.

I'm using Linux (ubuntu) and CLI gcc. My initial goal is to get lu decomposition working, with the old c code version. And I'm kind of in a panic -- I was expecting this part of my work to be a piece of cake, yet I'm wasting all kinds of time on it.

I've tried all kinds of things, some of which gave me *.a library files, with no good results. What I'm hoping for, (against hope?) is a way to just collect all the necessary files in a directory (copied, not original) and *either* some commands to make the libraries I need, *or* the proper gcc "incantations" to just attach the NR .c and .h files and compile my code.

If I can even get the calendar demo going, I'll be better off.

It seems like others here have done it - please help!
Thanks,
Alex
Reply With Quote
  #7  
Old 04-22-2009, 01:04 PM
davekw7x davekw7x is offline
Registered User
 
Join Date: Jan 2008
Posts: 453
Quote:
Originally Posted by squidx View Post
...
I'm using Linux (ubuntu) and CLI gcc....
In my opinion, creating a library of the NR routines is "the way to go." Different compilers on different operating systems have different ways of doing such things, and the authors couldn't cover all possibilities, could they?

Here's what worked for me on Centos Linux with gcc 4.1.2. I'm thinking it "should work" with any gcc-based system. (But I can't test all of them, can I?) Try the following, and let us know how it works out.

1. Copy distribution files to a directory of your choice. For example, I created a directory named /home/dave/nr2c. See the earlier posts in this thread about the select() function. For now comment out the "select()" prototype definition in nr2c/other/nr.h. You can fix it up later.

2. Then In home/dave/nr2c/recipes I created the following Makefile:
Code:
#
# Makefile for Numerical Recipes Version 2 C library
#
#

CC       = gcc
INCLUDES = -I../other

#
#  I obtained the list of source files by capturing "ls *.c" and
#  with a text editor, I added the "\" at the end of each line
#  except the last one.
#
#  Note that you don't want to compile anything with main() into
#  your library: Here are all of the C files except
#      badluk.c fredex.c sfroid.c sphfpt.c sphoot.c
#
#

SOURCES = \
addint.c  chixy.c    f1dim.c   iindexx.c  mrqmin.c    ratlsq.c   sort2.c \
airy.c    choldc.c   factln.c  indexx.c   newt.c      ratval.c   sort3.c \
amebsa.c  cholsl.c   factrl.c  interp.c   fmin.c      rc.c       spctrm.c \
amoeba.c  chsone.c   fasper.c  irbit1.c   select.c    rd.c       spear.c \
amotry.c  chstwo.c   fdjac.c   irbit2.c   nrutil.c    realft.c   sphbes.c \
amotsa.c  cisi.c     fgauss.c  jacobi.c   odeint.c    rebin.c     \
anneal.c  cntab1.c   fill0.c   jacobn.c   orthog.c    red.c       \
anorm2.c  cntab2.c   fit.c     julday.c   pade.c      relax.c    splie2.c \
arcmak.c  complex.c  fitexy.c  kendl1.c   pccheb.c    relax2.c   splin2.c \
arcode.c  convlv.c   fixrts.c  kendl2.c   pcshft.c    resid.c    spline.c \
arcsum.c  copy.c     fleg.c    kermom.c   pearsn.c    revcst.c   splint.c \
asolve.c  correl.c   flmoon.c  ks2d1s.c   period.c    reverse.c  spread.c \
atimes.c  cosft1.c   four1.c   ks2d2s.c   piksr2.c    rf.c       sprsax.c \
avevar.c  cosft2.c   fourew.c  ksone.c    piksrt.c    rj.c       sprsin.c \
covsrt.c   fourfs.c  kstwo.c    pinvs.c     rk4.c      sprspm.c \
balanc.c  crank.c    fourn.c   laguer.c   plgndr.c    rkck.c     sprstm.c \
banbks.c  cyclic.c   fpoly.c   lfit.c     poidev.c    rkdumb.c   sprstp.c \
bandec.c  daub4.c    fred2.c   linbcg.c   polcoe.c    rkqs.c     sprstx.c \
banmul.c  dawson.c   linmin.c   polcof.c    rlft3.c    stifbs.c \
bcucof.c  dbrent.c   fredin.c  lnsrch.c   poldiv.c    rofunc.c   stiff.c \
bcuint.c  ddpoly.c   frenel.c  locate.c   polin2.c    rotate.c   stoerm.c \
beschb.c  decchk.c   frprmn.c  lop.c      polint.c    rsolv.c    svbksb.c \
bessi.c   df1dim.c   ftest.c   lubksb.c   powell.c    rstrct.c   svdcmp.c \
bessi0.c  dfour1.c   gamdev.c  ludcmp.c   predic.c    rtbis.c    svdfit.c \
bessi1.c  dfpmin.c   gammln.c  machar.c   probks.c    rtflsp.c   svdvar.c \
bessik.c  dfridr.c   gammp.c   matadd.c   psdes.c     rtnewt.c   toeplz.c \
bessj.c   dftcor.c   gammq.c   matsub.c   pwt.c       rtsafe.c   tptest.c \
bessj0.c  dftint.c   gasdev.c  medfit.c   pwtset.c    rtsec.c    tqli.c \
bessj1.c  difeq.c    gaucof.c  memcof.c   pythag.c    rzextr.c   trapzd.c \
bessjy.c  dlinmin.c  gauher.c  metrop.c   pzextr.c    savgol.c   tred2.c \
bessk.c   dpythag.c  gaujac.c  mgfas.c    qgaus.c     scrsho.c   tridag.c \
bessk0.c  drealft.c  gaulag.c  mglin.c    qrdcmp.c    trncst.c \
bessk1.c  dsprsax.c  gauleg.c  midexp.c   qromb.c     selip.c    trnspt.c \
bessy.c   dsprstx.c  gaussj.c  midinf.c   qromo.c     ttest.c \
bessy0.c  dsvbksb.c  gcf.c     midpnt.c   qroot.c     shell.c    tutest.c \
bessy1.c  dsvdcmp.c  golden.c  midsql.c   qrsolv.c    shoot.c    twofft.c \
beta.c    eclass.c   gser.c    midsqu.c   qrupdt.c    shootf.c   vander.c \
betacf.c  eclazz.c   hpsel.c   miser.c    qsimp.c     simp1.c    vegas.c \
betai.c   ei.c       hpsort.c  mmid.c     qtrap.c     simp2.c    voltra.c \
bico.c    eigsrt.c   hqr.c     mnbrak.c   quad3d.c    simp3.c    wt1.c \
bksub.c   elle.c     hufapp.c  mnewt.c    quadct.c    simplx.c   wtn.c \
bnldev.c  ellf.c     hufdec.c  moment.c   quadmx.c    simpr.c    wwghts.c \
brent.c   ellpi.c    hufenc.c  mp2dfr.c   quadvl.c    sinft.c    zbrac.c \
broydn.c  elmhes.c   hufmak.c  mpdiv.c    ran0.c      slvsm2.c   zbrak.c \
bsstep.c  erfcc.c    hunt.c    mpinv.c    ran1.c      slvsml.c   zbrent.c \
caldat.c  erff.c     hypdrv.c  mpmul.c    ran2.c      sncndn.c   zrhqr.c \
chder.c   erffc.c    hypgeo.c  mpops.c    ran3.c      snrm.c     zriddr.c \
chebev.c  eulsum.c   hypser.c  mppi.c     ran4.c      sobseq.c   zroots.c \
chebft.c  evlmem.c   icrc.c    mprove.c   rank.c      solvde.c \
chebpc.c  expdev.c   icrc1.c   mpsqrt.c   ranpt.c     sor.c \
chint.c   expint.c   igray.c   mrqcof.c   ratint.c    sort.c

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

TARGET  = libnr2c.a

$(TARGET): $(OBJECTS)
	ar cr $@ $^
	@echo -e "\n***   Created $(TARGET) library in `pwd` \n"
	@echo -e "Now execute \"sudo make install\"\n"

INSTALLLIBDIR = /usr/lib/nr
INSTALLINCDIR = /usr/include/nr
install: $(TARGET)
	mkdir -p $(INSTALLLIBDIR)
	cp $(TARGET) $(INSTALLLIBDIR)
	mkdir -p $(INSTALLINCDIR)
	cp ../other/*.h $(INSTALLINCDIR)
	

.c.o:
	$(CC) $(INCLUDES) -c $< -o $@

clean:
	rm -f *.o $(TARGET)
3. Now you can enter "make" on the command line in that directory.

Actually I entered the following so that I could see the output as the compiler tries to build the library, and I will also have a record of the proceedings in a file named make.log
Code:
   make 2>& 1 | tee make.log
On the screen (and at the end of make.log), after the compile and ar commands, I saw:
Code:
***   Created libnr2c.a library in /home/dave/nr2c/recipes 

Now execute "sudo make install"

Now, in the "make.log" file, there were some warnings about "fmin". Unfortunately, the NR code has an "fmin" function (implemented in "fmin.c") that conficts with the standard math library function fmin. At some later time you can make some changes in newt.c and broydn.c and fmin.c to make the warnings go away, but for now just leave them alone. If there are any errors or other warnings that you can't resolve, then ask.


4. Now I entered "sudo make install" See Footnote.

Now I saw:
Code:
mkdir -p /usr/lib/nr
cp libnr2c.a /usr/lib/nr
mkdir -p /usr/include/nr
cp ../other/*.h /usr/include/nr
5. For my use, I always create directories for NR application programs at the same level as the recipes directory.

For example If I wanted to make a program to test ludcmp, I would make a directory /home/dave/nr2c/ludcmp

I use a Makefile that lets me put the code anywhere, but I think I have a better chance of finding this stuff later if I organize things along these lines. In other words: YMMV (Your Mileage May Vary).

6. In that directory, I would create a test program in C. Maybe I would name it "test.c"

7. Then I put the following Makefile in that directory:

Code:
#use nr2 header and library to compile examples
#
# invoke this makefile with something like
#     make TARGET=xludcmp
#
# or use a script like makeit:
### 
### #!/bin/sh
### # invoke makefile with target
### if [ $# == 0 ]
### then
###     echo "You must supply a target name for the Makefile"
###     exit
### else
### target=$1
### shift 1
### echo "make TARGET=$target $*"
### make TARGET=$target $*
### fi
#
# then just
#     makeit xludcmp
#
CC                 = gcc
CFLAGS             = -Wall -W
INSTALL_INCLUDEDIR = /usr/include/nr
INSTALL_LIBDIR     = /usr/lib/nr
INSTALL_LIB        = nr2c

INCLUDEDIR = $(INSTALL_INCLUDEDIR)
INCLUDES   = -I$(INSTALL_INCLUDEDIR)
LIBDIR     = -L$(INSTALL_LIBDIR)

LIBS       = -l$(INSTALL_LIB) -lm

TARGET = test
OBJS   = $(TARGET).o

$(TARGET): $(OBJS)
	$(CC) $(OBJS) $(LIBDIR) $(LIBS) -o $(TARGET)

.c.o:
	$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@

clean:
	rm -f $(OBJS) $(TARGET)
8. Now, I simply enter "make" in the ludcmp directory.

Regards,

Dave

Footnotes:

If you don't use "sudo", then just do "su" to become root, and then execute "make install"

If you don't want to copy files to /usr/include and /usr/lib, then just leave the library file and headers where they are, and modify the Makefile that I showed to define the directories used for including and library loading.

To compile examples supplied with the distribution, you can put the Makefile in the nr2c/examples directory and then if you want to compile xludcmp.c you can enter the following at the command line:

Code:
make TARGET=xludcmp
If you want to compile xludksb.c, then just enter
Code:
make TARGET=xludksb
Etc.


In my opinion, that beats the heck of editing the Makefile for each different file that you want to compile.

Of course if you have only one file in your test directory and it isn't named "test.c", then just edit the "TARGET=" line in the Makefile and enter "make" on the command line.
Reply With Quote
  #8  
Old 04-22-2009, 11:35 PM
squidx squidx is offline
Registered User
 
Join Date: Apr 2009
Posts: 2
Wow! That's a really good method!

Dave,

That is certainly a streamlined version of the setup, even better than the one you posted before.

This works really well on my machine. Now here's a thought: if I want to run it on a shared system (say a 8-processor system, or whatever), how can I do this if I don't have sudo privileges or access to the important directories.

Do you know if the libraries have been specially compiled for my platform, or could I copy them over once they are done, and build some kind of folder structrure that makes sense?

Thanks again,
Alex
Reply With Quote
  #9  
Old 04-23-2009, 09:34 AM
davekw7x davekw7x is offline
Registered User
 
Join Date: Jan 2008
Posts: 453
Quote:
Originally Posted by squidx View Post
...how can I do this if I don't have sudo,,,
Well, I said
Quote:
Originally Posted by davekw7x
If you don't want to copy files to /usr/include and /usr/lib, then just leave the library file and headers where they are, and modify the Makefile that I showed to define the directories used for including and library loading.
You don't have to "install" anything with the Makefile. You can just copy library and header files to some convenient places and use their location in each project's Makefile.

Here are some details, along the lines of the setup that I described previously:


1. I had previously copied the NR2 stuff to /home/dave/nr2c so that source files are in /home/dave/nr2c/recipes and include files are in /home/dave/nr2c/other.

2. If I have already built the library, there is a file named libnr2c.a in the /home/dave/nr2c/recipes. If I have not already built the library, I execute "make" in the /home/dave/nr2c/recipes directory using the first Makefile that I showed in the previous post. If I don't have write privileges to /usr directories and/or I don't want to write to "special" places, then I do not (can not) execute "make install" as defined in the library Makefile of my previous post. I could leave the library and include files where they are.

So...

3. For each project I would create a directory that will hold the C files for that project. I would probably create /home/dave/nr2c/project_name (same as I previously suggested), but it can be "anywhere" that I choose.


4. In each project directory I use the following Makefile. It is like the project Makefile that I showed previously, but a couple of changes make it work "anywhere."

In my example, I left the libnr2c.a file in /home/dave/nr2c/recipes and the include files are in /home/dave/nr2c/other

Code:
#
CC                 = gcc
CFLAGS             = -Wall -W
#
# This assumes that the library name is libnr2c.a
#
INSTALL_LIB        = nr2c

#
# put your installation directory path here
#
# So, this assumes the library is /home/dave/nr2c/recipes/libnr2c.a
#
NR2CDIR    = /home/dave/nr2c

INCLUDEDIR = $(NR2CDIR)/other
INCLUDES   = -I$(INCLUDEDIR)
LIBDIR     = -L$(NR2CDIR)/recipes

LIBS       = -l$(INSTALL_LIB) -lm

TARGET = test
OBJS   = $(TARGET).o

$(TARGET): $(OBJS)
	$(CC) $(OBJS) $(LIBDIR) $(LIBS) -o $(TARGET)

.c.o:
	$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@

clean:
	rm -f $(OBJS) $(TARGET)
Quote:
Originally Posted by squidx
Do you know if the libraries have been specially compiled for my platform
No, I don't know. Furthermore I personally don't care about pre-built NR libraries for my applications. Why do I not care? Because in my projects I need to know where each and every thing comes from. What if someone made some "minor" change in the source before they compiled the stuff? (Maybe they applied some "errata" information, and maybe not.) What if I want to make some "minor" (or maybe some "major") change? Since the source is available, I use it. I'm funny that way.
Quote:
Originally Posted by squidx
...could I copy them over once they are done, and build some kind of folder structrure that makes sense?
Yes. I think that is a reasonable approach.


You need libnr2c.a to be somewhere that the compiler can access. It doesn't have to be in your $HOME/nr2c/recipes directory. So, you can build libnr2c.a as I showed, then copy it somewhere else and change the LIBDIR definition in the project Makefile in this post.

You need the include files to be somewhere that the compiler can access. They do not have to be in your $HOME/nr2c/other directory. So you can copy them to some other directory and change the INCLUDEDIR definition in the project Makefile in this post.

Bottom line:
You don't actually need to define NR2CDIR in the project Makefile; you can just hard-code that path to the library and include files.

Regards,

Dave

Last edited by davekw7x; 04-23-2009 at 11:15 AM.
Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is On

Forum Jump


All times are GMT -5. The time now is 01:54 PM.


Powered by vBulletin® Version 3.8.6
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.