最近需要用到python的膠水功能,即python調用c++,將源文件編譯成.so,然後在python中import即可以用到此動態庫文件。同時,原始項目是使用cmake構建的,所以也希望用cmake構建boost python。找了好長時間沒有合適教程並且出現了一些問題,在這裏總結一下,歡迎補充和交流
參考地址:https://stackoverflow.com/questions/52929146/boostpython-and-cmake
hello_ext.cpp
#include <boost/python.hpp>
#include <iostream>
extern "C"
char const* greet()
{
return "hello, world";
}
BOOST_PYTHON_MODULE(libhello_ext)
{
using namespace boost::python;
def("greet", greet);
}
int main(){
std::cout<<greet()<<std::endl;
return 0;
}
此文件可以作爲一個簡單示例,#include <boost/python.hpp>是boostpython編程需要的頭文件。這裏要注意BOOST_PYTHON_MODULE(libhello_ext)括號中的內容要與生成動態文件庫同名(cmake生成的名稱前面加上了lib,這裏是爲了湊名稱相同,具體原因沒搞清楚)。有了源文件,在Ubuntu系統下可以直接使用Makefile,這裏也列舉出來。
# location of the Python header files
PYTHON_VERSION = 27
PYTHON_DOT_VERSION = 2.7
PYTHON_INCLUDE = /usr/include/python$(PYTHON_DOT_VERSION)
# location of the Boost Python include files and library
BOOST_INC = /usr/include
BOOST_LIB = /usr/lib/x86_64-linux-gnu/
# compile mesh classes
TARGET = hello_ext
$(TARGET).so: $(TARGET).o
g++ -shared -Wl,--export-dynamic $(TARGET).o -L$(BOOST_LIB) -lboost_python-py$(PYTHON_VERSION) -L/usr/lib/python$(PYTHON_DOT_VERSION)/config-x86_64-linux-gnu -lpython$(PYTHON_DOT_VERSION) -o $(TARGET).so
$(TARGET).o: $(TARGET).cpp
g++ -I$(PYTHON_INCLUDE) -I$(BOOST_INC) -fPIC -c $(TARGET).cpp
注意複製的時候g++前面是Tab。這裏主要說的是Cmake,給出Cmake的代碼,cmake每一行的含義可以找教程看一看,我看懂了也會更新的。
cmake_minimum_required(VERSION 3.6)
PROJECT(hello_ext)
# Find Boost
find_package(Boost REQUIRED COMPONENTS python-py27)
set(PYTHON_DOT_VERSION 2.7)
set(PYTHON_INCLUDE /usr/include/python2.7)
set(PYTHON_LIBRARY /usr/lib/python2.7/config-x86_64-linux-gnu)
include_directories(${PYTHON_INCLUDE} ${Boost_INCLUDE_DIRS})
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -lrt -O3")
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
SET(LIBNAME hello_ext)
add_library(${LIBNAME} SHARED hello_ext.cpp)
#add_executable(${PROJECT_NAME} hello_ext.cpp)
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${Boost_LIBRARIES} -lpython2.7 -fPIC)
TARGET_LINK_LIBRARIES(${LIBNAME} ${Boost_LIBRARIES} -lpython2.7 -fPIC -shared)
測試結果:
出現問題1:pyconfig.h no such file
可以的解決方法:在make之前
export CPLUS_INCLUDE_PATH=/usr/include/python2.7