g++ 与 python.h,如何编译

Posted

技术标签:

【中文标题】g++ 与 python.h,如何编译【英文标题】:g++ with python.h, how to compile 【发布时间】:2012-04-20 20:00:12 【问题描述】:

我用 g++ 编译了一个测试代码,没有任何问题。

#include "Python.h"  

int main(int argc, char** argv)  
  
    Py_Initialize();  
    PyRun_SimpleString("import pylab");  
    PyRun_SimpleString("pylab.plot(range(5))");  
    PyRun_SimpleString("pylab.show()");  
    Py_Exit(0);  
 

g++ -o test test.cpp -I/usr/include/python2.7/ -lpython2.7 工作正常并运行。

但是当我尝试将此代码嵌入到另一个项目中时,它失败了。这真的让我很困惑。

Makefile 如下所示。

CXX=g++  
CXXFLAGS=-DIB_USE_STD_STRING -Wall -Wno-switch -g  
ROOT_DIR=..  
BASE_SRC_DIR=$ROOT_DIR/PosixSocketClient  
INCLUDES=-I$ROOT_DIR/Shared/ -I$BASE_SRC_DIR -I/usr/include/python2.7  
LIBRARY=-L/usr/lib/python2.7/config  
TARGET=eu  

$(TARGET):  
    $(CXX) $(CXXFLAGS) $(INCLUDES) -o EClientSocketBase.o -c   $(BASE_SRC_DIR)/EClientSocketBase.cpp  
    $(CXX) $(CXXFLAGS) $(INCLUDES) -o EPosixClientSocket.o -c   $(BASE_SRC_DIR)/EPosixClientSocket.cpp  
    $(CXX) $(CXXFLAGS) $(INCLUDES) -o PosixTestClient.o -c PosixTestClient.cpp  
    $(CXX) $(CXXFLAGS) $(INCLUDES) -o Main.o -c Main.cpp
    $(CXX) $(LIBRARY) -lpython2.7 -o $@ EClientSocketBase.o EPosixClientSocket.o PosixTestClient.o Main.o 

clean:  
    rm -f $(TARGET) *.o  

这个项目可以正常编译并运行,我所做的唯一更改是在 Main.cpp 文件中添加测试代码。警告/错误信息显示:

在 /usr/include/python2.7/Python.h:8:0 包含的文件中, 来自 Main.cpp:15: /usr/include/python2.7/pyconfig.h:1158:0:警告:“_POSIX_C_SOURCE”重新定义[默认启用] /usr/include/features.h:163:0: 注意:这是之前定义的位置 /usr/include/python2.7/pyconfig.h:1180:0:警告:“_XOPEN_SOURCE”重新定义[默认启用] /usr/include/features.h:165:0: 注意:这是之前定义的位置 g++ -L/usr/lib/ -lpython2.7 -ldl -lutil -o eu EClientSocketBase.o EPosixClientSocket.o PosixTestClient.o Main.o Main.o:在函数main': /home/bbc/TWS/IBJts/cpp/eu-ats/Main.cpp:81: undefined reference toPy_Initialize' /home/bbc/TWS/IBJts/cpp/eu-ats/Main.cpp:82:未定义对PyRun_SimpleStringFlags' /home/bbc/TWS/IBJts/cpp/eu-ats/Main.cpp:83: undefined reference toPyRun_SimpleStringFlags'的引用 /home/bbc/TWS/IBJts/cpp/eu-ats/Main.cpp:84:未定义引用PyRun_SimpleStringFlags' /home/bbc/TWS/IBJts/cpp/eu-ats/Main.cpp:85: undefined reference toPy_Exit' collect2: ld 返回 1 个退出状态 make: * [eu] 错误 1 ​​

有什么帮助吗?谢谢!

【问题讨论】:

也许 lib python 是一个“普通”C 库,因此您可能必须使用 external "C" .. 包含它以确保 C“链接”(确实,.h 确实会检查它是否正在运行在 C 或 C++ 编译器下...) 试试 nm libpython2.7.so | grep Py_Initialize 看看这个符号是否在库中。 您在main.cpp 中添加了几行代码并出现了几个错误。尝试恢复到旧版本,验证它是否有效,然后只添加 #include "Python.h" 行,看看会发生什么。我敢打赌你会得到“重新定义”的错误,而不是“未定义”的错误,这意味着你可能只是忘记在某个头文件中放置一个头保护。一旦成功,我们就可以解决“未定义”错误,这可能来自未能链接目标文件(如Python.o)。 解决了,makefile中真正的问题是参数的顺序,我不知道顺序很重要(一行的顺序)。 要消除_POSIX_C_SOURCE 警告,请确保首先包含Python.h 【参考方案1】:

请看卢卡斯的评论以获得答案:

“要消除 _POSIX_C_SOURCE 警告,请确保在所有其他头文件之前包含 Python.h。”

我遇到了同样的问题。我使用 Boost Python,所以对我来说,我将 boost/python.hpp 的包含移到了我的 .cpp 文件的第一行。

(Lukas,将您的评论发布为答案,以便提问的人可以将其标记为正确答案,并且该问题不会在 *** 中保持“未回答”状态。)

【讨论】:

【参考方案2】:

这是 Python 中的一个错误:https://bugs.python.org/issue1045893

如果您首先包含 Python.h,编译器不会抱怨,但 GNU libc 的 /usr/include/features.h 会在定义 _GNU_SOURCE 时覆盖它:

# undef _POSIX_C_SOURCE # 定义 _POSIX_C_SOURCE 200809L #undef _XOPEN_SOURCE # 定义_XOPEN_SOURCE 700

【讨论】:

以上是关于g++ 与 python.h,如何编译的主要内容,如果未能解决你的问题,请参考以下文章

使用 Python.h 未定义符号进行 C++ 编译

尝试编译C扩展模块时缺少Python.h

libxml2静态编译缺少python.h的问题解决

python能够执行,但编译第三包遇到 python.h no such file or directory

Python.h 编译错误:collect2.exe Id 返回 1 退出状态

指定g++ 头文件路径的方法