【问题标题】:Packaging and installing python bindings with CMake使用 CMake 打包和安装 python 绑定
【发布时间】: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


    【解决方案1】:

    看起来像一个老问题,但无论如何。

    请参阅此示例 swig_examples_cpp 显示由 SWIG 包装的简单 C++ 函数,使用 CMake 和 CLion 构建它。 C版是here

    这是完整的 Python Cmake 文件:

    project(python_example)
    
    find_package(SWIG REQUIRED)
    include(${SWIG_USE_FILE})
    
    find_package(PythonLibs)
    include_directories(${PYTHON_INCLUDE_PATH})
    include_directories(${CMAKE_CURRENT_SOURCE_DIR})
    set(CMAKE_SWIG_FLAGS "")
    
    set_source_files_properties(../src/example.i PROPERTIES CPLUSPLUS ON)
    
    swig_add_library(python_example
            TYPE MODULE
            LANGUAGE python
            OUTPUT_DIR ../../py_out   # move the .so to py_out
            OUTFILE_DIR .             # leave the .cpp in cmake-build-debug
            SOURCES ../src/example.i
            ../src/example.cpp ../src/example.h
            )
    
    set_target_properties(python_example PROPERTIES
            LIBRARY_OUTPUT_DIRECTORY ../../py_out  # must match dir in OUTPUT_DIR
            )
    

    构建完成后,运行 python test.py 来查看它。请注意,这都是在 bash/Ubuntu 中的,所以 MacO 应该没问题,但 windows 可能会导致您流失。

    请参阅自述文件了解完整详情。

    【讨论】:

      猜你喜欢
      • 2021-06-04
      • 2013-09-17
      • 2017-04-22
      • 1970-01-01
      • 1970-01-01
      • 2016-11-24
      • 1970-01-01
      • 1970-01-01
      • 2016-09-30
      相关资源
      最近更新 更多