我正在尝试编译一些fortran代码,而且我遇到了一些令人困惑的链接错误。我有一些代码可以编译并放入静态库中:
>gfortran -c -I../../inc -o bdout.o bdout.F
>ar rv libgeo.a bdout.o
然后我尝试使用一些简单的测试代码针对该库进行编译,并获得以下内容:
>gfortran -o mytest -L -lgeo mytest.F
/tmp/cc4uvcsj.o: In function `MAIN__':
mytest.F:(.text+0xb0): undefined reference to `ncwrite1_'
collect2: ld returned 1 exit status
它不在对象命名中,因为一切看起来都很好:
>nm -u libgeo.a
bdout.o:
U _gfortran_exit_i4
U _gfortran_st_write
U _gfortran_st_write_done
U _gfortran_transfer_character
U _gfortran_transfer_integer
U ncobjcl_
U ncobjwrp_
U ncopencr_
U ncopenshcr_
U ncopenwr_
U ncwrite1_
U ncwrite2_
U ncwrite3_
U ncwrite4_
U ncwritev_
我也可以查看原始目标文件:
>nm -u bdout.o
U _gfortran_exit_i4
U _gfortran_st_write
U _gfortran_st_write_done
U _gfortran_transfer_character
U _gfortran_transfer_integer
U ncobjcl_
U ncobjwrp_
U ncopencr_
U ncopenshcr_
U ncopenwr_
U ncwrite1_
U ncwrite2_
U ncwrite3_
U ncwrite4_
U ncwritev_
测试代码只包含对bdout.o中定义的函数的单个调用:
program hello
print *,"Hello World!"
call ncwrite1( istat, f, ix2, ix3, ix4, ix5, ih )
end program hello
我无法弄清问题是什么。有没有人有什么建议?也许只是一种追踪问题的方法?
干杯。
答案 0 :(得分:1)
不知道这是否有助于解决这一特定问题,但一般情况下,始终将链接器命令放在目标文件之后。其次,如果libgeo.a在当前目录中,则需要显式添加,空-L AFAIK不执行任何操作。即。
gfortran -o mytest mytest.F -L. -lgeo
编辑:另请注意,nm输出中的“U”表示符号未定义。即.o文件引用了所述符号,但该符号实际上是在其他文件中。即您可能需要在定义ncwrite1_符号的库中显式链接。
答案 1 :(得分:1)
问题是您没有链接到包含该功能的库。这有两个可能的原因:
ncwrite1
函数。使用nm
验证是否(或不是)情况。如果我们假设geo库具有您正在使用的功能(检查!),那么您应该像这样构建和链接:
gfortran -o mytest -L. mytest.F -lgeo
答案 2 :(得分:0)
问题可能是对ncwrite1的调用与子例程的库定义的签名不匹配,而错误消息实际上告诉你的是它无法找到带有签名的ncwrite1版本匹配电话。您的程序似乎没有使用ncwrite1的显式接口,因此在编译时不会捕获这样的类型错误。
答案 3 :(得分:0)
首先,感谢所有回答的人。我发帖是为了正式结束这个帖子。事实证明,编写库(libgeo.a)的人在使用编译器标志宏-D(宏)打开的代码中放置了几个#ifdef语句。然后,这些#ifdef将用于扩展具有特定参数的函数名称。如果没有向编译器提供适当的宏,则函数名称保持未展开状态,因此符号未定义。 GRRRR ...