5

我正在尝试发布一些软件,目前正在编写构建过程的脚本。我被困在我从未想过的事情上,在 x86_64 linux 上静态链接 LAPACK。在配置AC_SEARCH_LIB([main],[lapack])工作期间,但 lapack 单元的编译不起作用,例如undefiend reference to 'dsyev_'--no lapack/blas 例程未被注意到。

我已经确认我已经安装了这些库,甚至使用适当的选项自己编译了它们,以使它们具有相同的结果。

这是我几年前在 LAPACK 的第一次体验中使用的一个例子,它动态工作,但不是静态工作:http: //pastebin.com/cMm3wcwF

我用来编译的两种方法如下,

gcc -llapack -o eigen eigen.c
gcc -static -llapack -o eigen eigen.c
4

1 回答 1

6

您的链接顺序错误。在需要它们的代码之后链接库,而不是之前。像这样:

gcc -o eigen eigen.c -llapack 
gcc -static -o eigen eigen.c -llapack

这应该可以解决联动问题。


为了回答后面的问题为什么这样有效,GNUld文档这样说:

在命令中编写此选项的位置有所不同;链接器按照指定的顺序搜索和处理库和目标文件。因此,foo.o -lz bar.o' searches libraryz' 在文件 foo.o 之后但在 bar.o 之前。如果 bar.o 引用了 `z' 中的函数,这些函数可能不会被加载。

...........

通常以这种方式找到的文件是库文件——其成员是目标文件的归档文件。链接器通过扫描归档文件来处理归档文件,其中的成员定义了迄今为止已被引用但尚未定义的符号。但是如果找到的文件是一个普通的目标文件,它会以通常的方式链接。

IE。链接器将通过文件查找未解析的符号,并按照您提供的顺序(即“从左到右”)跟踪文件。如果在读取文件时尚未指定依赖项,则链接器将无法满足该依赖项。链接列表中的每个对象只被解析一次。

另请注意,在链接共享库或目标文件时检测到循环依赖关系的情况下,GNU ld 可以进行重新排序。但是静态库只解析一次未知符号。

于 2011-08-24T16:13:54.660 回答