【问题标题】:Why do I get undefined reference with the same link line?为什么我会使用相同的链接线获得未定义的引用?
【发布时间】:2014-08-31 18:06:17
【问题描述】:

我目前正在编译两个程序。

同一链接行在其中一个上不会产生错误,而在另一个上会产生大量未定义的引用。

链接线是:

/usr/bin/c++   -Wall -pedantic -std=c++11   -fopenmp -O3 -DNDEBUG  
CMakeFiles/program.dir/src/main.cpp.o  -o program -rdynamic 
/home/felix/Development/local/lib/volop/libvolop.so 
/home/felix/Development/local/lib/ghost/libghost.so 
/home/felix/Development/local/lib/libhwloc.so 
/usr/local/lib/libmpicxx.so 
/usr/local/lib/libmpi.so -lrt -lpthread -L/usr/lib -lgsl -lgslcblas -lm 
/home/felix/Development/PRIMME/libprimme.a 
-L/usr/lib -lgsl -lgslcblas -lm -llapack 
-L/usr/lib -lgsl -lgslcblas -lm /home/felix/libblas/lib/libopenblas.so 
/home/felix/Development/PRIMME/libprimme.a 
-llapack 
/home/felix/libblas/lib/libopenblas.so 
-Wl,-rpath,/home/felix/Development/local/lib/volop:/home/felix/Development/local/lib/ghost:/home/felix/Development/local/lib:/usr/local/lib:/home/felix/libblas/lib 

以及相关的错误:

/home/felix/Development/local/lib/ghost/libghost.so: undefined reference to `MPI_Allgather'
/home/felix/Development/local/lib/ghost/libghost.so: undefined reference to `MPI_Init_thread'

等等,所有 MPI 链接器错误。但是,正如您从链接中看到的那样,mpi 已链接到其中。在另一个程序中它工作得很好。

这是在具有相同编译器的同一台计算机上。链接线由 cmake 生成。两个程序的 CMakeLists.txt 相同。

一旦我开始在产生错误的程序中显式地使用 MPI 方法,我就会停止出现链接器错误。为什么?

编辑:根据 cmets 的要求

ldd /home/felix/Development/local/lib/ghost/libghost.so
linux-vdso.so.1 =>  (0x00007fff6dff8000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f8d70837000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f8d70531000)
libgomp.so.1 => /usr/lib/x86_64-linux-gnu/libgomp.so.1 (0x00007f8d70321000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f8d7010b000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f8d6feed000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f8d6fb26000)
/lib64/ld-linux-x86-64.so.2 (0x00007f8d70f81000)

【问题讨论】:

  • 我不认为这是重复的,因为它不是找不到符号的一般链接器错误。如果我在我正在编译的程序中使用 MPI 方法,则链接了正确的文件并且它工作正常。如果我不这样做,我会得到未定义的引用错误
  • 可能值得在 /usr/local/lib/libmpicxx.so 中列出符号以确保符号与 libghost.so 中的符号匹配
  • ldd /home/felix/Development/local/lib/ghost/libghost.so 的输出是什么?
  • 我尝试了许多不同的测试用例,其中包含一个导入 MPI 符号的中间共享对象,但没有一个能够重现您的问题。尝试按照 Wesley Bland 的指示将可执行文件与 mpic++ 链接。此外,libghost.so 没有在其DT_NEEDED 部分中指定libmpi.so(从ldd 的输出中可以明显看出)这可能意味着它也没有使用适当的编译器包装器链接。

标签: c++ linker cmake mpi undefined-reference


【解决方案1】:

通常当有人在使用 MPI 时遇到奇怪的链接器错误时,这是​​因为他们没有使用为他们完成工作的编译器包装器。

当您(或代表您的其他人)在您的机器上安装 MPI 时,会创建一些包装器以将所有必要的标志添加到编译器行,就像还安装了启动器 mpiexec 一样。这些包装器称为mpiccmpic++mpicxxmpifc 等。您可以像使用任何其他编译器一样使用它们。如果您需要添加自己的库等,欢迎您提供自己的编译器标志。

【讨论】:

    【解决方案2】:

    我不能 100% 确定,但这在我身上发生过很多次。原因是链接顺序:这很重要。

    您需要将库从层次结构的“顶部”链接到“底部”;例如,首先放置最复杂的库,然后放置其他库所依赖的库。

    尝试将libmpi.so 放在最后,看看它是否有效(或者如果您认为重要,则将其他东西随机排列)。

    【讨论】:

    • 仅当涉及来自静态存档 (libblabla.a) 的符号时,顺序才重要。当链接到不适用的共享对象时。即使该顺序对于共享对象也很重要,libghost.so 在链接命令中仍然出现在 libmpi.so 之前。
    猜你喜欢
    • 1970-01-01
    • 2011-02-08
    • 1970-01-01
    • 1970-01-01
    • 2014-04-06
    • 1970-01-01
    • 2015-03-23
    • 2012-02-05
    • 1970-01-01
    相关资源
    最近更新 更多