【问题标题】:undefined reference when compiling code with cfitsio library [duplicate]使用cfitsio库编译代码时未定义的引用[重复]
【发布时间】:2016-07-18 20:28:15
【问题描述】:

我在编译我的代码时收到 cfitsio 库中使用的每个函数的未定义引用错误。下面是 ma​​ke null 命令输出的相关部分(注意 -L/usr/lib/ -lcfitsio 在第一行):

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

以下是 Makefile 中 ma​​ke 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)"

dumpframe.c 中,我在文件顶部包含 cfitsio 标头 fitsio.h 以及其他包含:

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

该库是从源代码安装的。源代码位于 /usr/local/src/cfitsio/,然后通过以下命令安装:

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

这会导致库(libcfitsio.alibcfitsio.solibcfitsio.so.5libcfitsio.so .5.3.39) 安装在 /usr/lib/ 和辅助文件 (longnam.hfitsio.h , fitsio2.h, drvrsmem.h) 安装在 /usr/include/ 中。

我不确定是什么原因造成的,因为编译器不会抱怨缺少库或缺少 fitsio.h 头文件。

【问题讨论】:

    标签: c gcc makefile libraries undefined-reference


    【解决方案1】:

    将库放在目标文件之后,而不是之前。

    错误:

    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
    

    对:

    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
    

    请注意,-I/usr/include/cfitsio.h 选项没有用处,但考虑到标头位于 /usr/include 中,它也无害。 -I 选项采用目录名,而不是文件名。同样,-L/usr/lib 选项也没有好处,尽管它也没有坏处。自动搜索/usr/lib 库。

    【讨论】:

    • 我有点困惑为什么需要更改订单。我目前正在编辑给我的 Makefile,并且放入的顺序是“预定义的”,这意味着模板希望在目标文件之前有 -lcfitsio。我知道带有 .a 扩展名的库可能会导致问题,与 .so 扩展名相反。
    • 鉴于 makefile,问题可能是 LD_FLAGS 宏包含库信息,但在链接器命令行中的目标文件之前列出。如果您负责 makefile,解决此问题的一种方法是使用 LDFLAGS 设置库目录 (-L/opt/whatever/lib) 一个单独的 LDLIBSLDLIBES 宏来指定库 (-lwhatever)然后在链接器命令中的目标文件之后列出。这主要是传统的。如果不知道你的 makefile(s) 的相关位中有什么——你不负责——很难提供更多帮助。
    • 有些系统允许你在命令行的任何地方列出库;看起来这个 makefile 起源的系统就是这样一个系统。看起来您正在使用的系统无法让您在任何地方都可以使用图书馆——欢迎来到大多数“现实世界”。有关--as-needed 的信息,请参阅重复的问答,看看这是否对您有帮助。是的,这很麻烦。通过在对象之后列出库,精心设计(或以前移植)的包可以在两种类型的系统上正确编译。显然,这个包之前没有遇到过这个问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-22
    • 2022-01-21
    • 2011-02-19
    • 1970-01-01
    • 1970-01-01
    • 2013-01-21
    • 1970-01-01
    相关资源
    最近更新 更多