我正在尝试通过Swig链接一个接口C ++和Python的程序。我也在使用CMake来简化C ++部分的开发。 CMakeLists.txt
上的Swig部分:
find_package(SWIG REQUIRED)
include(${SWIG_USE_FILE})
find_package(PythonLibs)
include_directories(${PYTHON_INCLUDE_PATH})
message(STATUS "PYTHON_INCLUDE_PATH: ${PYTHON_INCLUDE_PATH}")
message(STATUS "PYTHON_LIBRARIES: ${PYTHON_LIBRARIES}")
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/core)
set(CMAKE_SWIG_OUTDIR ${PROJECT_BINARY_DIR}/../lib/test)
SET_SOURCE_FILES_PROPERTIES(swig/core.i PROPERTIES CPLUSPLUS ON)
set_source_files_properties(swig/core.i SWIG_FLAGS "-includeall;-c++;-shadow")
swig_add_module(core python swig/core.i core/foo.cpp)
swig_link_libraries(core test_core ${PYTHON_LIBRARIES})
链接错误如下:
Scanning dependencies of target _core
[ 66%] Building CXX object CMakeFiles/_core.dir/__/lib/test/corePYTHON_wrap.cxx.o
[ 83%] Building CXX object CMakeFiles/_core.dir/core/foo.cpp.o
Linking CXX shared module _core.so
Undefined symbols for architecture x86_64:
"_PyClass_Type", referenced from:
SwigPyClientData_New(_object*) in corePYTHON_wrap.cxx.o
"_PyInstance_NewRaw", referenced from:
SWIG_Python_NewShadowInstance(SwigPyClientData*, _object*) in corePYTHON_wrap.cxx.o
"_PyInstance_Type", referenced from:
SWIG_Python_GetSwigThis(_object*) in corePYTHON_wrap.cxx.o
"_PyInt_AsLong", referenced from:
SWIG_AsVal_long(_object*, long*) in corePYTHON_wrap.cxx.o
SWIG_AsVal_unsigned_SS_long(_object*, unsigned long*) in corePYTHON_wrap.cxx.o
SWIG_AsVal_double(_object*, double*) in corePYTHON_wrap.cxx.o
"_PyInt_FromLong", referenced from:
SWIG_From_int(int) in corePYTHON_wrap.cxx.o
"_PyString_AsString", referenced from:
SWIG_Python_str_AsChar(_object*) in corePYTHON_wrap.cxx.o
"_PyString_AsStringAndSize", referenced from:
SWIG_AsCharPtrAndSize(_object*, char**, unsigned long*, int*) in corePYTHON_wrap.cxx.o
"_PyString_ConcatAndDel", referenced from:
SwigPyObject_repr(SwigPyObject*) in corePYTHON_wrap.cxx.o
swig_varlink_str(swig_varlinkobject*) in corePYTHON_wrap.cxx.o
"_PyString_Format", referenced from:
SwigPyObject_format(char const*, SwigPyObject*) in corePYTHON_wrap.cxx.o
"_PyString_FromFormat", referenced from:
SwigPyObject_repr(SwigPyObject*) in corePYTHON_wrap.cxx.o
SwigPyPacked_repr(SwigPyPacked*) in corePYTHON_wrap.cxx.o
SwigPyPacked_str(SwigPyPacked*) in corePYTHON_wrap.cxx.o
"_PyString_FromString", referenced from:
SWIG_Python_str_FromChar(char const*) in corePYTHON_wrap.cxx.o
swig_varlink_repr(swig_varlinkobject*) in corePYTHON_wrap.cxx.o
swig_varlink_str(swig_varlinkobject*) in corePYTHON_wrap.cxx.o
"_PyString_FromStringAndSize", referenced from:
SWIG_FromCharPtrAndSize(char const*, unsigned long) in corePYTHON_wrap.cxx.o
"_Py_InitModule4_64", referenced from:
_init_core in corePYTHON_wrap.cxx.o
SWIG_Python_SetModule(swig_module_info*) in corePYTHON_wrap.cxx.o
"__PyInstance_Lookup", referenced from:
SWIG_Python_GetSwigThis(_object*) in corePYTHON_wrap.cxx.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[3]: *** [_core.so] Error 1
make[2]: *** [CMakeFiles/_core.dir/all] Error 2
make[1]: *** [all] Error 2
make: *** [core] Error 2
我不知道从哪里开始搜索这个bug。这是Swig错误吗?或者它没有正确链接到Python库?我正在使用python 3。
修改
问题似乎来自CMake FindPythonLibs.cmake
代码在系统中找到的Python库之间的不匹配。这是配置部分的输出:
-- Found PythonLibs: /usr/lib/libpython3.4.dylib (found version "2.7.5")
-- PYTHON_INCLUDE_PATH: /System/Library/Frameworks/Python.framework/Headers
-- PYTHON_LIBRARIES: /usr/lib/libpython3.4.dylib
显然找到的版本与“2.7.5”不对应。因此,如果我手动将变量PYTHON_INCLUDE_DIR
更改为/Library/Frameworks/Python.framework/Versions/3.4/Headers
(这是相应的3.4版本Python的标题),问题就会消失。因此,CMake FindPythonLibs.cmake
代码中似乎存在错误。
/Library/Frameworks/Python.framework/Versions/3.4/Headers