无法在OS X上链接Boost.Python

时间:2015-11-11 14:45:35

标签: cmake boost-python osx-elcapitan

我正在尝试用Boost.Python构建一个非常简单的例子。我用自制软件安装了boost和boost-python。我正在使用python 3.4.3并提升1.59。我的操作系统是El Capitan。

Boost.Python与python3一起安装,如下所示:

brew install boost-python --with-python3

我有3个文件:

/* greet.hpp */
#ifndef BOOSTPYTHONHELLOWORLD_GREET_HPP
#define BOOSTPYTHONHELLOWORLD_GREET_HPP

char const* greet();

#endif //BOOSTPYTHONHELLOWORLD_GREET_HPP



/* greet.cpp */    
#include "greet.hpp"

char const* greet()
{
    return "Hello world";
}



/* greet_ext.cpp */
#include "greet.hpp"
#include <boost/python.hpp>

BOOST_PYTHON_MODULE(greet_ext)
{
    using namespace boost::python;
    def("greet", greet);
}

我的CMakeLists.txt文件如下所示:

cmake_minimum_required(VERSION 3.3)
project(BoostPythonHelloWorld)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(PYTHON_LIBRARY "/usr/local/Cellar/python3/3.4.3/Frameworks/Python.framework/Versions/3.4/lib/libpython3.4m.dylib")
set(PYTHON_INCLUDE_DIR "/usr/local/Cellar/python3/3.4.3/Frameworks/Python.framework/Versions/3.4/include/python3.4m")
FIND_PACKAGE(PythonLibs 3.4 REQUIRED)
FIND_PACKAGE(Boost COMPONENTS python)
if(NOT WIN32)
    add_definitions(-DBOOST_ALL_DYN_LINK=1)
    add_definitions(-DBOOST_TEST_DYN_LINK)
endif()
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS} ${PYTHON_INCLUDE_DIRS})
add_library(greet SHARED greet.cpp)
add_library(greet_ext SHARED greet_ext.cpp)
target_link_libraries(greet_ext greet)
target_link_libraries(greet_ext ${PYTHON_LIBRARIES})
target_link_libraries(greet_ext ${Boost_LIBRARIES})
set_target_properties(greet_ext PROPERTIES PREFIX "")

当我运行CMake时,它会找到所有正确的python库(因为我手动指定了它们,如上面的文件中所示)。

在构建期间,我收到以下链接错误:

Scanning dependencies of target greet
[ 25%] Building CXX object CMakeFiles/greet.dir/greet.cpp.o
[ 50%] Linking CXX shared library libgreet.dylib
[ 50%] Built target greet
Scanning dependencies of target greet_ext
[ 75%] Building CXX object CMakeFiles/greet_ext.dir/greet_ext.cpp.o
[100%] Linking CXX shared library greet_ext.dylib
Undefined symbols for architecture x86_64:
  "boost::python::detail::init_module(PyModuleDef&, void (*)())", referenced from:
      _PyInit_greet_ext in greet_ext.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [greet_ext.dylib] Error 1
make[1]: *** [CMakeFiles/greet_ext.dir/all] Error 2
make: *** [all] Error 2

任何人都知道为什么会这样吗?

修改

如果我链接Python 2.7它可以工作,这意味着boost-python是针对python 2.7而不是3.4构建的,即使我指定了--with-python3选项..

所以,问题是,如何针对python 3.4构建boost-python?

3 个答案:

答案 0 :(得分:1)

我目前使用的解决方案是在没有python 2.7支持的情况下重新安装boost-python

我采取的步骤是:

  1. 卸载boost-python(如果已安装):brew uninstall boost-python
  2. 使用python3支持安装boost-python但不支持python 2.7:brew install boost-python --with-python3 --without-python

答案 1 :(得分:1)

为了在python 3中使用boost-python,你需要在你的CMakeLists.txt中改变它:

Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE, "Select ringtone:");
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, false);
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, true);
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_ALL);
startActivityForResult(intent, 123);

到此:

FIND_PACKAGE(Boost COMPONENTS python)

这样你可以使用python 2支持重新编译boost并仍然使用python 3。

答案 2 :(得分:1)

我建议通过boost-python3安装brew

您仍然需要提供次要版本号以及可能的库路径。以下对我有用:

BOOST_LIBRARYDIR=/usr/local/Cellar/boost-python3/1.67.0/lib cmake ..

包含CMakeLists.txt(位于..

FIND_PACKAGE(Boost COMPONENTS python36)

(显然是Boost 1.67.0和Python 3.6)。