使用静态链接 LAPACK。

6
我正在尝试发布一些软件,目前正在处理构建过程中的脚本。我被卡住了,这是我从未想过的事情,在x86_64 linux上静态链接LAPACK。在配置期间,AC_SEARCH_LIB([main],[lapack])可以工作,但编译lapack组件不起作用,例如undefiend reference to 'dsyev_',没有lapack/blas例程被忽略。我确认我已经安装了库,并使用适当的选项将它们编译为静态库,但结果相同。这是我几年前第一次使用LAPACK时使用的动态示例:http://pastebin.com/cMm3wcwF。我使用的两种编译方法如下:
gcc -llapack -o eigen eigen.c
gcc -static -llapack -o eigen eigen.c
1个回答

8

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

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

这应该解决了链接问题。


回答下一个问题,为什么这样做是有效的,GNU ld文档给出了如下说明:

命令中写入此选项位置很重要;连接器按照指定顺序搜索和处理库文件和目标文件。因此,foo.o -lz bar.o在文件foo.o之后但bar.o之前搜索库文件z。如果bar.o引用了z中的函数,则这些函数可能无法加载。

........

通常这种方法找到的文件是库文件——归档文件,其成员是目标文件。连接器通过扫描归档文件查找已经被引用但未定义的符号来处理归档文件。但是如果找到的文件是普通的目标文件,则会像通常一样进行链接。

也就是说,连接器在读取文件时会进行一次遍历以查找未解决的符号,并且它们按照您提供的顺序(即“从左到右”)跟随文件。如果还没有指定依赖关系,则当读取文件时,连接器将无法满足依赖关系。链接列表中的每个对象只被解析一次。

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


1
其他库需要完全运行,包括 -llapack -lblas -lgfortran -lm - nlucaroni
链接器将尝试调整链接顺序以满足活动依赖关系图。但是链接语句仍然按“从左到右”的顺序读取,如果您指定了一个当前集合中没有依赖关系的库,则它将被跳过。这就是这里发生的事情。 - talonmies
1
但是当库被指定时,您的程序尚未编译为对象(请记住,从左到右阅读),因此它会被跳过。 - talonmies
请查看我的编辑。Lapack 需要 Blas,它们都需要 Fortran 运行时库,而这又需要 C 数学库。如果您在 Fortran 库之前提供数学库,则链接器尚不知道它需要使用该库。 - talonmies
我的困惑基于这个句子,“连接器将尝试调整链接顺序以满足活动依赖图”。 我没有看到它,您给出的描述也没有提到它。 - nlucaroni
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接