【问题标题】:cmake problem of target type when using swig with C++17在 C++17 中使用 swig 时目标类型的 cmake 问题
【发布时间】:2022-06-27 05:49:15
【问题描述】:

事情让我感到困惑,所以我希望清楚。

我制作了一个 c++17 库(这里称为 myLib),并使用 swig 将它与 python 绑定。当我手动编译时,一切正常。 现在,我想使用 cmake 自动化和清理我的工作:库没问题。

但是在使用 cmake 创建绑定时,事情对我来说变得越来越模糊。

我带来了以下 cmake 示例:

include(FindSWIG)

find_program(SWIG_PATH swig)
find_package(SWIG 4.0 COMPONENTS python)

include(UseSWIG)

find_package(PythonLibs 3 REQUIRED)
find_package(PythonInterp ${PYTHONLIBS_VERSION_STRING} REQUIRED)

set(CMAKE_SWIG_FLAGS -py3)

message("PYTHONLIBS_VERSION_STRING: ${PYTHONLIBS_VERSION_STRING}")
message("CMAKE_SWIG_FLAGS: ${CMAKE_SWIG_FLAGS}")

add_custom_target(
     binding_target
     )

include_directories("${PROJECT_SOURCE_DIR}/external/include" "${PROJECT_SOURCE_DIR}/include" ${PYTHON_LIBRARIES})
# If I use the following line instead to the previous, I get an error of target type non-compilable
# target_include_directories(binding_target "${PROJECT_SOURCE_DIR}/external/include" "${PROJECT_SOURCE_DIR}/include" ${PYTHON_LIBRARIES})


set_source_files_properties(py_myLib.i PROPERTIES CPLUSPLUS ON)

# If I use the following line, I get an error of target type non-compilable.
# target_compile_features(binding_target SHARED cxx_std_17)

swig_add_library(binding_target 
     TYPE SHARED 
     LANGUAGE python 
     SOURCES py_myLib.i
)
swig_link_libraries(binding_target ${PYTHON_LIBRARIES} USE_TARGET_INCLUDE_DIRECTORIES)

使用前面的代码,命令cmake .. 正在退出而没有错误,但是使用make 的编译返回错误,因为编译器没有使用选项-std=c++17 进行编译。 (顺便说一句,我想知道为什么 make 正在编译,而 make binding_target 什么都不做,我希望相反。)

我尝试使用 target_compile_features 行将 C++17 功能添加到编译中,但随后,我收到来自 cmake .. 的关于 target_compile_features called with non-compilable target type 的错误

所以我的问题是:如何正确构建(在目标内部)与 cmake 的 swig 绑定 (为此目标精确包含目录和编译选项)?

【问题讨论】:

  • swig_add_library(binding_target) 定义了目标 binding_target(除非 UseSWIG_TARGET_NAME_PREFERENCE 变量设置为 LEGACY)。在命令调用之前尝试使用该目标是没有用的。以及add_custom_target(binding_target)调用的原因是什么,它创建了同名的目标?
  • 感谢您的精确。使用add_custom_target(binding_target) 是一种误解。我虽然我必须在调用 swig_add_library 之前创建目标。

标签: python c++ cmake swig


【解决方案1】:

我想出了这个解决方案(毫不犹豫地改进它):

include(FindSWIG)

find_program(SWIG_PATH swig)
find_package(SWIG 4.0 COMPONENTS python)

include(UseSWIG)

find_package(PythonLibs 3 REQUIRED)
find_package(PythonInterp ${PYTHONLIBS_VERSION_STRING} REQUIRED)

set(CMAKE_SWIG_FLAGS -py3)

message("PYTHONLIBS_VERSION_STRING: ${PYTHONLIBS_VERSION_STRING}")
message("CMAKE_SWIG_FLAGS: ${CMAKE_SWIG_FLAGS}")


# 
set_source_files_properties(py_myLib.i PROPERTIES CPLUSPLUS ON)
set_property(SOURCE py_myLib.i PROPERTY SWIG_MODULE_NAME py_myLib)
set (UseSWIG_TARGET_NAME_PREFERENCE STANDARD)

swig_add_library(py_myLib 
   TYPE SHARED 
   LANGUAGE python 
   SOURCES py_myLib.i
)

# For Swig wrapping
set_property(TARGET py_myLib PROPERTY SWIG_INCLUDE_DIRECTORIES 
   "${PROJECT_SOURCE_DIR}/external/include" 
   "${PROJECT_SOURCE_DIR}/include"
)

# For Cxx compilation
set_property(TARGET py_myLib PROPERTY INCLUDE_DIRECTORIES 
   "${PROJECT_SOURCE_DIR}/external/include" 
   "${PROJECT_SOURCE_DIR}/include" 
   ${PYTHON_INCLUDE_PATH}
)
set_property(TARGET py_myLib PROPERTY COMPILE_OPTIONS -shared -std=c++17 ) #

# swig_link_libraries( 
target_link_libraries( py_myLib
   ${PYTHON_LIBRARIES} 
) 

# 
target_include_directories(py_myLib
   PRIVATE
      # where the library itself will look for its internal headers
      ${CMAKE_SOURCE_DIR}/include # 
      ${CMAKE_SOURCE_DIR}/external/include
   PUBLIC
      # where top-level project will look for the library's public headers
      $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include>
)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-04
    • 1970-01-01
    • 1970-01-01
    • 2018-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多