6

我已经静态编译 Python2.7 没有任何错误。为了测试我的构建,我使用以下代码段:

#include "Python.h"
int main()
{
   Py_Initialize();
}

我正在编译它:

$ gcc -static -I/path/to/python/header -L/path/to/my/staticpythonlib \ 
 -lpython2.7 -ldl -l_all_other_needed_lib /tmp/my_previous_snippet.c -o myouput

但是,发生了错误。gcc 声称著名的undefined reference.

test.c:(.text+0x1): 对“Py_Initialize”的未定义引用

奇怪的是,我使用了带有详细标志的 gcc(我不会在此处粘贴结果),编译器说,它正在使用我的 libpython,但找不到参考。所以我列出了我的静态 python2.7 库的符号:

$ nm /path/to/pythonlib |grep Py_Initialize
frozenmain.o           U Py_Initialize
pythonrun.o  0000009e9 T Py_Initialize
pythonrun.o  000000052 T Py_Initialize_Ex
main.o                 U Py_Initialize

我们可以看到,Py_Initialize在 pythonrun.o 中正确引用了它。但是我不知道编译器如何选择正确的目标文件。

我的问题是:

  1. 我如何确定 gcc 在我的 .a 库中使用了正确的目标文件?
  2. 我的编译选项有什么问题吗?

谢谢你的帮助。

4

2 回答 2

7

顺序很重要!更具体地说,gcc 参数中的顺序很重要。更具体地说,如果一个bar对象使用bluhlibrary中的函数bleh,那么该顺序-lbleh bar.o是有问题的,因为它没有理由让 gcc 在 中查找该bluh函数bleh。另一方面,当您使用时,bar.o -lblehgcc 知道您所指的是,bluh并且当它开始处理时,它会-lbleh尝试解决依赖关系。在http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html中很快提到了这一点。通常,始终在对象之后指定库。

要重现您的问题,请创建一个文件a1.c,如下所示:

#include "Python.h"

int main()
{
    Py_Initialize();
    return 0;
}

现在用gcc -static -I/usr/include/python2.7 -L/usr/lib/python2.7/config/ -lpython2.7 -ldl -lm -lutil -lz -pthread -o a1 a1.c. 这给出了对 的未定义引用Py_Initialize。当然,您必须更改路径以匹配您的安装。

现在,相反,编译它gcc -static -I/usr/include/python2.7 -L/usr/lib/python2.7/config/ -o a1 a1.c -lpython2.7 -ldl -lm -lutil -lz -pthread并且它可以工作(忽略可能的许多警告,这是另一回事)。

于 2012-12-10T12:30:09.823 回答
1

我正在使用python 2.7并在环境变量中设置python安装目录的路径。我也使用 boost 1.5.0

按照步骤编译以下代码

#include <python2.7/Python.h>
int main()
{
Py_Initialize();

PyRun_SimpleString("print \"Hello, world!\"");

Py_Finalize();
return 0;
}

运行命令:-

g++ hello.cc -lpython2.7
./a.out
于 2013-08-09T06:24:43.040 回答