【发布时间】:2018-07-18 03:46:09
【问题描述】:
我有一个 C++ 项目,我为使用 SWIG 生成了 Python 绑定。我现在正在尝试通过添加安装操作来完成项目的 CMake 文件。但是每当我完成安装并尝试调用我的函数时,我都会收到一条错误消息,指出 foo has no attribute bar()。
这与 Python 不知道绑定所依赖的 .so 文件在哪里有关。如果foo.py 和_foo.so 都在同一个目录中,我可以完美地使用绑定。我正在努力弄清楚我应该如何以可移植的方式“安装” Python 绑定和它们所依赖的 .so。
显然,我可以将.so 的安装路径导出到LD_LIBRARY_PATH,但这对于必须有适当解决方案的问题来说似乎是一个棘手的工作。
我的CMakeLists.txt。我已经删除了与编译我的 C++ 库 RTK 相关的部分:
# Project
##
# TODO this actually needs 3.3+
cmake_minimum_required(VERSION 2.6)
project(RTKLIB)
FIND_PACKAGE(SWIG REQUIRED)
INCLUDE(${SWIG_USE_FILE})
FIND_PACKAGE(PythonLibs 3 REQUIRED)
INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_PATH})
find_program(PYTHON "python3" REQUIRED)
include(GNUInstallDirs)
# Variable declarations
##
# Define this directory
set(RTKLIB_ROOT ${CMAKE_CURRENT_SOURCE_DIR})
# Define the build dir
set(RTKLIB_BIN_DIR "${RTKLIB_ROOT}/build")
list(APPEND CMAKE_MODULE_PATH "${RTKLIB_ROOT}/cmake")
# Setup python vars
set(SETUP_PY_IN "${RTKLIB_ROOT}/setup.py.in") # initial version of setup.py
set(SETUP_PY "${RTKLIB_BIN_DIR}/setup.py") # cmake generated setup.py
set(OUTPUT "${RTKLIB_BIN_DIR}/python_timestamp") # Timestamp used as dep
set(RTKLIB_PY "rtk_lib") # name of the python lib
# Set the output dir for SWIG
set(CMAKE_SWIG_OUTDIR ${RTKLIB_BIN_DIR}/${RTKLIB_PY})
# Generate Python bindings
##
# SWIG Config
SET_PROPERTY(SOURCE include/rtk_lib.i PROPERTY CPLUSPLUS ON)
SWIG_ADD_MODULE(${RTKLIB_PY} python include/rtk_lib.i) # Generate C-Python bindings
SWIG_LINK_LIBRARIES(${RTKLIB_PY} RTK ${PYTHON_LIBRARIES}) # Link the bindings with python
# Generate the setup.py file
configure_file(${SETUP_PY_IN} ${SETUP_PY})
# Build command that depends on the SWIG output files and updates the timestamp
add_custom_command(OUTPUT ${OUTPUT}
COMMAND ${PYTHON} ${SETUP_PY} build
COMMAND ${CMAKE_COMMAND} -E touch ${OUTPUT}
DEPENDS ${RTKLIB_BIN_DIR}\${SWIG_MODULE_${RTKLIB_PY}_REAL_NAME})
# Custom target that depends on the timestamp file generated by the custom command
add_custom_target(ALL DEPENDS ${OUTPUT})
# Install the shared library
install(TARGETS ${SWIG_MODULE_${RTKLIB_PY}_REAL_NAME}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
# Install to user's packages
install(CODE "execute_process(COMMAND ${PYTHON} ${SETUP_PY} install --user)")
如果有帮助,这里是我的setup.py.in:
from distutils.core import setup
setup(name='rtk_lib',
version='${PACKAGE_VERSION}',
description="""Python bindings for rtk_lib, allowing for serial and
and file interfaces with RTK messages.""",
packages=['${RTKLIB_PY}'])
代码快速摘要:它为 C++ 生成与 Python 兼容的包装类,然后编译包装类并将其与 Python 库和原始 RTK C++ 库链接。之后,您有一个名为 rtk_lib 的目录,其中包含您的包装类和 rtk_lib.py 模块。在这个rtk_lib 目录之外是rtk_lib.py 所依赖的输出_rtk_lib.so 共享库。所以为了让绑定工作,我将_rtk_lib.so复制到rtk_lib目录并调用python3。然后我可以导入库,一切都很好。
我尝试安装共享库,但即便如此,我仍然得到相同的 rtk_lib has no attribute blablabla()。
【问题讨论】:
标签: python c++ cmake swig distutils