【问题标题】:Undefined reference - despite lib being found by linker未定义的引用 - 尽管链接器找到了 lib
【发布时间】:2012-12-06 17:35:54
【问题描述】:

我有一个简单的程序来测试 python 开发文件的可用性:

#include<Python.h>
int main(){Py_Initialize(); Py_Finalize(); }

我将它(安装了 python 2.7)编译为gcc -I/usr/include/python2.7 -lpython2.7 p.c。它在其他机器上运行良好,除了在 Ubuntu 12.04(精确)的大部分干净的 chroot 上我不断得到

/tmp/ccj8Mgjb.o: In function `main':
p.c:(.text+0x5): undefined reference to `Py_Initialize'
p.c:(.text+0xa): undefined reference to `Py_Finalize'
collect2: ld returned 1 exit status

标头已安装,/usr/lib/libpython2.7.so 存在,但链接器仍然失败。该符号在.so文件中列出,gcc正在读取正确的libpython2.7.so:

$ nm -D libpython2.7.so.1.0  | grep Py_Initialize
00000000000c9c20 T Py_Initialize
00000000000c9260 T Py_InitializeEx

$ strace -f gcc -I/usr/include/python2.7 -lpython2.7 /tmp/p.c 2>&1 |grep   libpython2.7 |grep open
[pid 10618] open("/usr/lib/gcc/x86_64-linux-gnu/4.6/libpython2.7.so", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 10618] open("/usr/lib/gcc/x86_64-linux-gnu/4.6/libpython2.7.a", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 10618] open("/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/libpython2.7.so", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 10618] open("/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/libpython2.7.a", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 10618] open("/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../lib/libpython2.7.so", O_RDONLY) = 7

有什么想法吗?

【问题讨论】:

    标签: linker undefined-reference


    【解决方案1】:

    试试:

    gcc -I/usr/include/python2.7 p.c -lpython2.7 
    

    链接器在加载libpython2.7.a 时还不知道Py_Initialize 是必需的符号,所以它把它扔掉了。然后它到达 p.o 并抛出一个关于丢失符号的适合。以这种方式排序将让链接器在后续输入中查找丢失的符号。

    见:http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html

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

    【讨论】:

    • 顺便说一句,知道为什么它适用于其他机器吗?那是版本相关的行为吗?
    • 我认为这取决于正在使用的链接器。但如果你把它放在后面,它总是会起作用的。
    • 好的,我刚刚发现 gold 链接器可以工作,但是 binutils 中的旧 ldd 失败了。
    • 我在用 python 构建一个超级简单的测试程序时遇到了同样的问题。 Phil P 不久前在 Exim 邮件列表中提醒了我:“当涉及到符号解析以及命令上的文件和库的顺序时,一些最近的 gcc 版本没有恢复一些历史行为(Unix cc) -线?”基本上,将目标文件放在库之前,以便链接器知道要包含对哪些函数的引用。
    【解决方案2】:

    我也遇到了同样的链接问题。 但就我而言,提供-lpython 是不够的。还需要-L。即

    g++ -I/usr/include/python3.5 hw.cpp -L/usr/lib/python3.5/config-3.5m-x86_64-linux-gnu -lpython3.5
    

    是的。订单很重要。

    【讨论】:

      【解决方案3】:

      我遇到了同样的链接问题,我个人的问题是我的 32 位 mingw 编译器无法加载 64 位 python 库。我将我的 mingw 升级到 64 位并解决了我的问题。在这里留个便条,以防新手遇到同样的问题。

      【讨论】:

        【解决方案4】:

        如果安装了 python 3.x,也许这个命令可以工作:

        g++ hw.cpp `/usr/bin/python3-config --cflags` `/usr/python3-config --ldflags`
        

        顺便说一下,你应该检查你的 gcc 和 python 版本。

        据我所知,如果 gcc 版本是 5.4,python 版本是 3.7,它就不起作用。(python 3.5 是工作)

        运行/usr/bin/python3-config --cflags的时候,其实就是编译选项。

        【讨论】:

          猜你喜欢
          • 2016-06-01
          • 1970-01-01
          • 2022-09-27
          • 2017-02-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多