/ usr / bin / ld:在Ubuntu上找不到-lpython-dev。使用PyObject编译C程序

时间:2016-01-29 14:03:13

标签: python c ubuntu gcc

我有以下需要与Python集成的C程序:

#include <Python.h>

PyObject* get_details(){
    PyObject *details = PyDict_New();
    PyObject *key, *value;
    key = PyUnicode_FromString("full name");
    value = PyUnicode_FromString("Pete Graham");
    PyDict_SetItem(details, key, value);
    return details;
}

我可以使用:

在OS X上编译程序
gcc -I /Library/Frameworks/Python.framework/Versions/3.4/Headers \
-L /Library/Frameworks/Python.framework/Versions/3.4/lib \
-lpython3.4 get_person_dict.c

当我尝试在Ubuntu /usr/bin/ld: cannot find -lpython3.4.

上编译程序时出错

这是我在Ubuntu上使用的命令我已经为python lib路径尝试了各种值。

gcc -I /usr/include/python3.4 \
-L /usr/local/lib \
-lpython3.4 get_person_dict.c

我安装了带有sudo apt-get install python3.4-dev版本的Ubuntu trusty64的python,并且正在Vagrant上使用。

2 个答案:

答案 0 :(得分:5)

有几件事是错误的。

正如@JJHakala告诉你的那样,

python3.4-config --libs

将告诉您将可执行文件与Python 3.4链接所需的库 运行时,即:

-lpython3.4m -lpthread -ldl  -lutil -lm

python3.4-config --ldflags

会告诉你所有你必须传递给链接器以实现的选项 同样的结果,即:

-L/usr/lib/python3.4/config-3.4m-x86_64-linux-gnu \
-L/usr/lib -lpython3.4m -lpthread -ldl  -lutil -lm \
 -Xlinker -export-dynamic -Wl,-O1 -Wl,-Bsymbolic-functions

因此,让我们尝试将这些链接器选项放入您的gcc命令行而不是 您使用过的链接器选项。你的命令行是:

$ gcc -I /usr/include/python3.4 -L/usr/local/lib -lpython3.4 get_person_dict.c

带链接器选项:

-L/usr/local/lib -lpython3.4

所以我们会尝试:

$ gcc -I /usr/include/python3.4 `python3.4-config --ldflags` get_person_dict.c

这不起作用。输出是:

/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o: In function `_start':
/build/buildd/glibc-2.21/csu/../sysdeps/x86_64/start.S:114: undefined reference to `main'
/tmp/ccrczTMI.o: In function `get_details':
get_person_dict.c:(.text+0x9): undefined reference to `PyDict_New'
get_person_dict.c:(.text+0x17): undefined reference to `PyUnicode_FromString'
get_person_dict.c:(.text+0x25): undefined reference to `PyUnicode_FromString'
get_person_dict.c:(.text+0x40): undefined reference to `PyDict_SetItem'
collect2: error: ld returned 1 exit status

我们对所有调用的Python 3.4函数都有未定义的引用 get_person_dict.c,以及对main

的未定义引用

未定义的Python 3.4引用的原因是, 仍然是,在任何调用其中定义的函数的文件之前将库传递给链接器。所以 链接器依次进入命令行上的每个库并对自己说: 我是否注意到对此库中具有定义的未定义函数的任何调用? 不。然后我不需要链接此库中的任何内容。并传递。 在忽略所有库之后,它会到达您的get_person_dict.c(或者在...中) 现实,编译器具有的临时目标文件/tmp/ccrczTMI.o 以前从get_person_dict.c汇编而来。发现未定义 引用PyDict_NewPyUnicode_FromString PyUnicode_FromStringPyDict_SetItem。但是现在没有剩下可以定义它们的库。 他们 定义的库是桥下的水,所以 未定义的引用仍然是链接错误。

在链接序列中,需要定义的文件必须在之前出现 提供定义的文件。

那很容易纠正:

$ gcc -I /usr/include/python3.4  get_person_dict.c `python3.4-config --ldflags`

现在输出是:

/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o: In function `_start':
/build/buildd/glibc-2.21/csu/../sysdeps/x86_64/start.S:114: undefined reference to `main'
collect2: error: ld returned 1 exit status

链接器现在已经找到了所有Python 3.4函数的定义。但它 仍然说它无法找到main的定义。

原因是你发布的C“程序”不是程序,它是 只是函数PyObject* get_details()的定义。每个C程序, 根据定义,它有一个main函数,这是第一个被调用的函数。对于 这个原因,当您尝试将一些文件和库链接到C程序时, 正如您尝试的那样,链接器会自动链接调用的启动代码 main。但你没有main

所以你不能将你的get_person_dict.c链接为一个程序,即使你得到了 联系顺序权。您可以编译它,而无需链接它:

$ gcc -I /usr/include/python3.4  -c -o get_person_dict.o get_person_dict.c

它为您提供了一个包含已编译的对象文件get_person_dict.o,但是 没有关联,PyObject* get_details()的定义。它将与之相同 gcc为你编译的临时目标文件/tmp/ccrczTMI.o而不是 告诉我上面的编译和链接尝试失败。

但是在编译了get_person_dict.o之后,您可以将 链接到其中 一个程序,只要你还链接 - 之后 - 其他库那个 定义它调用的函数:

<强> get_person_prog.c

#include <Python.h>
#include <stdio.h>

extern PyObject * get_details(); // Ought to be put in a header

int main(void)
{
    PyObject * pyobj = get_details();
    if (pyobj) {
        puts("Got the details");
    }
    return  0;
}

编译:

$ gcc -I /usr/include/python3.4  -c -o get_person_prog.o get_person_prog.c

按正确的顺序链接目标文件和库,以制作程序prog

$ gcc -o prog get_person_prog.o get_person_dict.o `python3.4-config --ldflags`

执行命令

$ ./prog
Got the details

答案 1 :(得分:1)

在debian / jessie中

python3.4-config --ldflags

告诉我应该使用哪些链接参数,这些参数也适用于Ubuntu。该命令位于python3.4-dev包中。

python3.4-config --libs

告诉链接时所需库的名称。

输出

-L/usr/lib/python3.4/config-3.4m-x86_64-linux-gnu -L/usr/lib -lpython3.4m 
-lpthread -ldl -lutil -lm -Xlinker -export-dynamic 
-Wl,-O1 -Wl,-Bsymbolic-functions`

包含-lpython3.4m,但问题中不包含-lpython3.4。使用它应该有助于解决这个特定的问题。