代码之家  ›  专栏  ›  技术社区  ›  Brian Dolan

在OS X上使用带CMake的Boost Python

  •  2
  • Brian Dolan  · 技术社区  · 8 年前

    我正在尝试这样做 boost python with cmake OSX上的示例。这篇文章有点旧,但我找不到任何更新的。我的目标是使用CMake(因为我使用的是CLion)来构建C++和Python库的集成项目。我正在OS X上使用Python 2.7

    我的.cpp文件是

    #include <boost/python.hpp>
    
    char const* yay()
    {
      return "Yay!";
    }
    
    BOOST_PYTHON_MODULE(libyay)
    {
      using namespace boost::python;
      def("yay", yay);
    }
    

    我的cmakelists.txt

    CMAKE_MINIMUM_REQUIRED(VERSION 3.3)
    IF(NOT CMAKE_BUILD_TYPE)
      SET(CMAKE_BUILD_TYPE "DEBUG")
      #SET(CMAKE_BUILD_TYPE "RELEASE")
      #SET(CMAKE_BUILD_TYPE "RELWITHDEBINFO")
      #SET(CMAKE_BUILD_TYPE "MINSIZEREL")
    ENDIF()
    
    FIND_PACKAGE(PythonLibs 2.7 REQUIRED)
    
    FIND_PACKAGE(Boost)
    IF(Boost_FOUND)
      INCLUDE_DIRECTORIES("${Boost_INCLUDE_DIRS}" "/usr/include/python2.7")
      SET(Boost_USE_STATIC_LIBS OFF)
      SET(Boost_USE_MULTITHREADED ON)
      SET(Boost_USE_STATIC_RUNTIME OFF)
      FIND_PACKAGE(Boost COMPONENTS python)
    
      ADD_LIBRARY(yay SHARED yay.cpp)
      TARGET_LINK_LIBRARIES(yay ${Boost_LIBRARIES} ${PYTHON_LIBRARIES})
    ELSEIF(NOT Boost_FOUND)
      MESSAGE(FATAL_ERROR "Unable to find correct Boost version. Did you set BOOST_ROOT?")
    ENDIF()
    
    
    IF(CMAKE_COMPILER_IS_GNUCXX)
      ADD_DEFINITIONS("-Wall")
    ELSE()
      SET(CMAKE_CXX_FLAGS "-Wall")
      MESSAGE("You have compiler " ${CMAKE_CXX_COMPILER_ID})
      #MESSAGE(FATAL_ERROR "CMakeLists.txt has not been tested/written for your compiler.")
      MESSAGE("CMakeLists.txt has not been tested/written for your compiler.")
    ENDIF()
    

    最后,我打开一个Python控制台并尝试

    from ctypes import *
    ly = cdll.LoadLibrary("libyay.dylib")
    print ly.yay()
    

    产生此错误:

    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/usr/local/Cellar/python/2.7.12_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ctypes/__init__.py", line 375, in __getattr__
        func = self.__getitem__(name)
      File "/usr/local/Cellar/python/2.7.12_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ctypes/__init__.py", line 380, in __getitem__
        func = self._FuncPtr((name_or_ordinal, self))
    AttributeError: dlsym(0x7fdb5344aec0, yay): symbol not found
    

    我希望能得到以下方面的指导:(a)集成C++和Python的整个方法是否过时,(b)这个错误应该告诉我什么,以及(C)使用CMake的其他方法。

    1 回复  |  直到 8 年前
        1
  •  2
  •   Brian Dolan    8 年前

    关键似乎是我的Python版本在加载 .dylib 由make生成的文件。我不知道为什么,所以我在CMakeLists中使用了这个技巧。txt文件,并包括 if(APPLE)

    cmake_minimum_required( VERSION 3.3 )
    project( BoostPythonHelloWorld )
    
    # Make a .so output!
    if(APPLE)
    set(CMAKE_SHARED_LIBRARY_SUFFIX ".so")
    endif(APPLE)
    
    # Find necessary packages
    find_package( PythonLibs 2.7 REQUIRED )
    include_directories( ${PYTHON_INCLUDE_DIRS} )
    
    find_package( Boost COMPONENTS python REQUIRED )
    include_directories( ${Boost_INCLUDE_DIR} )
    
    # Build our library
    add_library( greet SHARED greet.cpp )
    
    # Define the wrapper library that wraps our library
    add_library( greet_ext SHARED greet_ext.cpp )
    target_link_libraries( greet_ext ${Boost_LIBRARIES} ${PYTHON_LIBRARIES} greet )
    # don't prepend wrapper library name with lib
    set_target_properties( greet_ext PROPERTIES PREFIX "" )
    

    cmake make 我能够打开Python shell并运行

    import greet_ext
    greet_ext.greet()
    

    我已经发布了一个完整的例子 github 还有,我要感谢野鸡 a useful post