gpt4 book ai didi

cmake - 同名的 Python 库和 CMake 目标

转载 作者:行者123 更新时间:2023-12-05 02:42:55 25 4
gpt4 key购买 nike

我正在构建一个仅包含 C++ header 的库“mylib”,并具有使用 pybind11 的 Python API。我想将“mylib”用作 CMake 目标(包含编译指令)和 Python API 的名称。但是,这会导致名称冲突

问题描述

考虑以下文件结构:

CMakeLists.txt
include/mylib.hpp
python_api.cpp

实际上还有测试和示例,每个都有自己的 CMakeLists.txt,但对于这个示例来说,唯一重要的是:

在(主)CMakeLists.txt 中,我定义了一个 CMake 目标“mylib”,它具有 header 的包含路径,但也“链接”了依赖项的目标。这样用户(或测试、示例或 Python API 的构建)只需“链接”目标即可。 (最后,当我安装 header 时,我还在 mylibTargets.cmake 中安装目标,以便为最终用户提供 CMake 支持)。

现在问题:我的 Python 包应该有相同的名称,“mylib”。但是,如果我用“mylib”调用 pybind11_add_module,CMake 会提示

CMake Error at .../share/cmake/pybind11/pybind11Tools.cmake:166 (add_library):
add_library cannot create target "mylib" because another target with the
same name already exists. The existing target is an interface library
created in source directory "..".
See documentation for policy CMP0002 for more details.

它有投诉的权利。同时,我不能为 CMake 目标(因为我想使用唯一的逻辑名称“mylib”安装和使用它)或 pybind11 目标(因为它必须编码“mylib”)使用不同的名称。

那么:我该如何解决这个问题?

(我发现的 only solution 是重命名其中一个目标,但如上所述我不想这样做)

详细示例

考虑简化的、单一的CMakeLists.txt:

cmake_minimum_required(VERSION 3.1..3.19)

# configure target

project(mylib)

find_package(xtensor REQUIRED)

add_library(${PROJECT_NAME} INTERFACE)

target_include_directories(${PROJECT_NAME} INTERFACE
$<INSTALL_INTERFACE:include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)

target_link_libraries(${PROJECT_NAME} INTERFACE xtensor)

# installation of headers and of CMake target

include(CMakePackageConfigHelpers)
include(GNUInstallDirs)

install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/" DESTINATION include)

install(TARGETS ${PROJECT_NAME} EXPORT ${PROJECT_NAME}-targets)

install(
EXPORT ${PROJECT_NAME}-targets
FILE "${PROJECT_NAME}Targets.cmake"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}")

# Build Python module

find_package(pybind11 CONFIG REQUIRED)
pybind11_add_module(${PROJECT_NAME} python_api.cpp) # <- target name conflict
target_link_libraries(example PUBLIC pybind11::module)

解决方法太有限

我可以将 Python API 的构建(以及稍后安装)完全拆分为一个独立的 CMakeLists.txt。但是,我想使用目标“mylib”,我已经配备了它需要的一切,来构建 Python API。因为我想在不强制安装库的情况下执行此操作,所以我不知道如何在“单个”CMakeLists.txt

中执行此操作

最佳答案

pybind11_add_module 只是 add_library 的包装器,它明确地写在 documentation 中对于那个功能。因此,大多数适用于公共(public)库的“技巧”也适用于 python 模块。

也就是说,如果您希望将结果文件命名为 mylib.so 但负担不起使用 mylib 作为目标名称,那么您可以使用任何其他名称目标 的名称,但调整 OUTPUT_NAME该目标的属性。例如:

# Python library target has suffix '_python'
pybind11_add_module(mylib_python ...)
# But name of the library file doesn't have this suffix
set_target_properties(mylib_python PROPERTIES OUTPUT_NAME mylib)

关于cmake - 同名的 Python 库和 CMake 目标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67212833/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com