0

I am receiving an undefined reference error for every function used from the cfitsio library when compiling my code. Below is the relevant chunk of the make null command's output (Note that -L/usr/lib/ -lcfitsio is in the first line):

gcc -g -I../mdl/null   -DCHABRIER -DCHANGESOFT -DDENSITYU -DDENSITYUNOTP -DDIFFUSION -DDODVDS -DDTADJUST -DEPSACCH -DPARTICLESPLIT -DPROMOTE -DGASOLINE -DJEANSSOFT -DNSMOOTHINNER -DRTFORCE -DSETTRAPFPE -DSTARFORM -DTHERMALCOND -DTOPHATFEEDBACK -DTWOPHASE -DVSIGVISC -DWENDLAND -DRADIATION -DRADIATIONLUM -DDDSIMPLE -DR2PPBMAX -DCOOLING_METAL  -L/usr/lib/ -lcfitsio  -I/usr/include/fitsio.h -o gasoline.dfTest main.o master.o param.o outtype.o pkd.o pst.o grav.o ewald.o walk.o eccanom.o hypanom.o fdl.o htable.o smooth.o smoothfcn.o collision.o qqsmooth.o cooling_metal.o cosmo.o romberg.o starform.o feedback.o millerscalo.o supernova.o supernovaia.o startime.o stiff.o runge.o dumpframe.o dffuncs.o dumpvoxel.o rotbar.o special.o ssio.o   treezip.o log.o radiation.o erf.o v_sqrt1.o ../mdl/null/mdl.o -lm
dumpframe.o: In function `fitsError':
/.../dumpframe.c:2156: undefined reference to `ffrprt'
dumpframe.o: In function `dfFinishFrame':
/.../dumpframe.c:2175: undefined reference to `ffinit'
/.../dumpframe.c:2176: undefined reference to `ffcrim'
/.../dumpframe.c:2197: undefined reference to `ffppr'
/.../dumpframe.c:2198: undefined reference to `ffclos'
collect2: error: ld returned 1 exit status
Makefile:539: recipe for target 'gasoline.dfTest' failed
make[1]: *** [gasoline.dfTest] Error 1
make[1]: Leaving directory '/home/grondjj/Code/gasoline'
Makefile:457: recipe for target 'null' failed
make: *** [null] Error 2gcc -g -I../mdl/null   -DCHABRIER -DCHANGESOFT -DDENSITYU -DDENSITYUNOTP -DDIFFUSION -DDODVDS -DDTADJUST -DEPSACCH -DPARTICLESPLIT -DPROMOTE -DGASOLINE -DJEANSSOFT -DNSMOOTHINNER -DRTFORCE -DSETTRAPFPE -DSTARFORM -DTHERMALCOND -DTOPHATFEEDBACK -DTWOPHASE -DVSIGVISC -DWENDLAND -DRADIATION -DRADIATIONLUM -DDDSIMPLE -DR2PPBMAX -DCOOLING_METAL  -L/usr/lib/ -lcfitsio  -I/usr/include/fitsio.h -o gasoline.dfTest main.o master.o param.o outtype.o pkd.o pst.o grav.o ewald.o walk.o eccanom.o hypanom.o fdl.o htable.o smooth.o smoothfcn.o collision.o qqsmooth.o cooling_metal.o cosmo.o romberg.o starform.o feedback.o millerscalo.o supernova.o supernovaia.o startime.o stiff.o runge.o dumpframe.o dffuncs.o dumpvoxel.o rotbar.o special.o ssio.o   treezip.o log.o radiation.o erf.o v_sqrt1.o ../mdl/null/mdl.o -lm
dumpframe.o: In function `fitsError':
/.../dumpframe.c:2156: undefined reference to `ffrprt'
dumpframe.o: In function `dfFinishFrame':
/.../dumpframe.c:2175: undefined reference to `ffinit'
/.../dumpframe.c:2176: undefined reference to `ffcrim'
/.../dumpframe.c:2197: undefined reference to `ffppr'
/.../dumpframe.c:2198: undefined reference to `ffclos'
collect2: error: ld returned 1 exit status
Makefile:539: recipe for target 'gasoline.dfTest' failed
make[1]: *** [gasoline.dfTest] Error 1
make[1]: Leaving directory '/home/grondjj/Code/gasoline'
Makefile:457: recipe for target 'null' failed
make: *** [null] Error 2

Here are the relevant lines from the Makefile for make null

 FITS_LIB = -L/usr/lib/ -lcfitsio

 BASE_LD_FLAGS = $(PNG_LIB) $(GSL_LIB) $(FITS_LIB)

 NULL_LD_FLAGS   = $(BASE_LD_FLAGS) 

 null:
      cd $(NULL_MDL); make "CC=$(CC)" "CFLAGS=$(NULL_CFLAGS)"
      make $(EXE) "CFLAGS=$(NULL_CFLAGS)" "LD_FLAGS=$(NULL_LD_FLAGS)"\
           "MDL=$(NULL_MDL)" "XOBJ=$(NULL_XOBJ)" "LIBMDL=$(NULL_LIBMDL)"

In dumpframe.c I include the cfitsio header fitsio.h along with the other inlcudes at the top of the file:

 #ifndef GSS_DUMPFRAME
 #include <stdio.h>
 #include <stdlib.h>
 #include <math.h>
 #include <assert.h>
 #include <string.h>
 #include "fitsio.h"

The library was installed from source code. The source resides in /usr/local/src/cfitsio/, it was then installed via the following commands:

 $ ./configure --prefix=/usr
 $ make shared
 $ make install
 $ make clean

Which results in the libraries (libcfitsio.a, libcfitsio.so, libcfitsio.so.5, libcfitsio.so.5.3.39) being installed in /usr/lib/ and the auxiliary files (longnam.h, fitsio.h, fitsio2.h, drvrsmem.h) being installed in /usr/include/.

I am not sure what causes this, as the compiler does not complain about missing libraries or a missing fitsio.h header file.

jasper
  • 193
  • 3
  • 17

1 Answers1

0

Put the library after the object files, not before.

Wrong:

gcc -g -I../mdl/null -DCHABRIER -DCHANGESOFT -DDENSITYU -DDENSITYUNOTP \
    -DDIFFUSION -DDODVDS -DDTADJUST -DEPSACCH -DPARTICLESPLIT -DPROMOTE \
   -DGASOLINE -DJEANSSOFT -DNSMOOTHINNER -DRTFORCE -DSETTRAPFPE -DSTARFORM \
   -DTHERMALCOND -DTOPHATFEEDBACK -DTWOPHASE -DVSIGVISC -DWENDLAND -DRADIATION \
   -DRADIATIONLUM -DDDSIMPLE -DR2PPBMAX -DCOOLING_METAL \
   -L/usr/lib/ -lcfitsio  -I/usr/include/fitsio.h \
   -o gasoline.dfTest main.o master.o param.o outtype.o pkd.o pst.o grav.o ewald.o \
   walk.o eccanom.o hypanom.o fdl.o htable.o smooth.o smoothfcn.o collision.o \
   qqsmooth.o cooling_metal.o cosmo.o romberg.o starform.o feedback.o millerscalo.o \
   supernova.o supernovaia.o startime.o stiff.o runge.o dumpframe.o dffuncs.o \
   dumpvoxel.o rotbar.o special.o ssio.o treezip.o log.o radiation.o erf.o v_sqrt1.o \
   ../mdl/null/mdl.o -lm

Right:

gcc -g -I../mdl/null -DCHABRIER -DCHANGESOFT -DDENSITYU -DDENSITYUNOTP \
    -DDIFFUSION -DDODVDS -DDTADJUST -DEPSACCH -DPARTICLESPLIT -DPROMOTE \
   -DGASOLINE -DJEANSSOFT -DNSMOOTHINNER -DRTFORCE -DSETTRAPFPE -DSTARFORM \
   -DTHERMALCOND -DTOPHATFEEDBACK -DTWOPHASE -DVSIGVISC -DWENDLAND -DRADIATION \
   -DRADIATIONLUM -DDDSIMPLE -DR2PPBMAX -DCOOLING_METAL \
   -o gasoline.dfTest main.o master.o param.o outtype.o pkd.o pst.o grav.o ewald.o \
   walk.o eccanom.o hypanom.o fdl.o htable.o smooth.o smoothfcn.o collision.o \
   qqsmooth.o cooling_metal.o cosmo.o romberg.o starform.o feedback.o millerscalo.o \
   supernova.o supernovaia.o startime.o stiff.o runge.o dumpframe.o dffuncs.o \
   dumpvoxel.o rotbar.o special.o ssio.o treezip.o log.o radiation.o erf.o v_sqrt1.o \
   ../mdl/null/mdl.o -lcfitsio -lm

Note that the -I/usr/include/cfitsio.h option does no good, though it also does no harm given that the header is in /usr/include. The -I option takes a directory name, not a file name. Similarly, the -L/usr/lib option does no good, though it too does no harm either. The /usr/lib library is searched automatically.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • I am a little confused as to why the order needs to be changed. I am currently editing a Makefile given to me, and the order things get put in are "predefined", meaning the template wants to have -lcfitsio before the object files. I am aware that the library with the .a extension might cause problems, as apposed to the .so extensions. – jasper Jul 18 '16 at 20:51
  • Given the makefile, the problem is probably that the `LD_FLAGS` macro contains library information but is listed before the object files in the linker command line. If you're in charge of the `makefile`, one way around this is to use `LDFLAGS` to set library directories (`-L/opt/whatever/lib`) a separate `LDLIBS` or `LDLIBES` macro to specify the libraries (`-lwhatever`) which is then listed _after_ the object files in the linker command. This is mostly traditional. Without knowing what is in the relevant bits of your makefile(s) — which you aren't in charge of — it's hard to help much more. – Jonathan Leffler Jul 18 '16 at 20:52
  • Some systems allow you to list libraries anywhere on the command line; it appears that the system this makefile originated on is one such system. It also appears you're using a system that doesn't afford you the luxury of allowing libraries anywhere — welcome to the majority of the 'real world'. See the duplicate Q&A for information about `--as-needed` and see whether that helps you. Yes, it's a nuisance. Well designed (or previously ported) packages compile correctly on both types of system, by listing libraries after objects. Apparently, this package hasn't encountered this problem before. – Jonathan Leffler Jul 18 '16 at 20:55