首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >cmake + swig +依赖策略

cmake + swig +依赖策略
EN

Stack Overflow用户
提问于 2016-09-07 05:54:13
回答 3查看 2.1K关注 0票数 6

今天我尝试使用"cmake + swig“的组合来为我的代码生成绑定。基本上它是有效的:

代码语言:javascript
复制
set(SWIG_EXECUTABLE "/usr/bin/swig")
find_package(SWIG REQUIRED)
include(${CMAKE_CURRENT_SOURCE_DIR}/UseSWIG.cmake)

set(CMAKE_SWIG_FLAGS -package example)
set(CMAKE_SWIG_OUTDIR "${CMAKE_CURRENT_SOURCE_DIR}/example")
set_source_files_properties(native.i PROPERTIES CPLUSPLUS ON)
SWIG_ADD_MODULE(core Java native.i lib.cpp)
include_directories(${CMAKE_CURRENT_SOURCE_DIR})

具有这样的原生特性。i:

代码语言:javascript
复制
%module native
%include "lib.hpp"
%{
#include "lib.hpp"
  %}

但是,如果我更改了swig构建系统,cmake build不会调用swig来重新生成代码。所以我必须使用touch native.i才能让它工作,这是非常烦人的。

我找到了swig-M选项来生成依赖项,你知道如何使用它来修复UseSWIG.cmake

UseSWIG.cmake只是使用add_custom_command生成,所以我需要add_custom_command依赖于动态的文件集,而不是静态的?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-04-02 06:37:47

我相信我已经找到了您的请求的解决方案。

我目前使用的是一种解决方案,其中添加了所有相关的依赖项,以便无论何时修改任何已解析的标头,SWIG都会重新生成接口。

其想法是创建一个自定义目标,它除了删除生成的接口文件外,还会接触到一个虚拟文件。我已经为一个名为fnm的项目提供了下面的解决方案,该项目具有一个包装器swig_fnm

代码语言:javascript
复制
# Method to make swig_fnm.i depend on input headers
execute_process(COMMAND swig -M -python -c++  -I${CMAKE_CURRENT_BINARY_DIR}/.. -I${CMAKE_CURRENT_SOURCE_DIR}/.. swig_fnm.i
  WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
  OUTPUT_VARIABLE swig_deps
  INPUT_FILE swig_fnm.i)
# Match all lines except the first one until " \"
string(REGEX MATCHALL "\n  [^ ]+" temp ${swig_deps})

# Valid dependency extensions
set(valid_ext .h .hpp)

# Dependency list
set(swig_deps_actual)
foreach(t ${temp})
  string(STRIP "${t}" t)

  # Add to dependency list
  if (EXISTS "${t}")
    set(filter)
    get_filename_component(filter "${t}" EXT)
    if (";${valid_ext};" MATCHES ";${filter};")
      set(swig_deps_actual ${swig_deps_actual} "${t}")
    endif()
  endif()
endforeach()

# This makes configure run again, but does not regenerate the SWIG interface.
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${swig_deps_actual})

# All headers except for the single .i file are ignored
swig_add_module(swig_fnm python swig_fnm.i ${swig_fnm_HEADERS} ${swig_deps_actual})

# Removes generated file (if any of the dependent files are changed)
add_custom_command(
  OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/swig.stamp
  COMMAND ${CMAKE_COMMAND} -E remove ${swig_generated_file_fullname}
  COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/swig.stamp
  DEPENDS ${swig_deps_actual} # The dependent files
  COMMENT "Removing old SWIG generated file" VERBATIM)

# Custom target for establishing dependency
add_custom_target(
  swigtrick
  DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/swig.stamp)

# Dependency
add_dependencies(_swig_fnm swigtrick)
票数 3
EN

Stack Overflow用户

发布于 2016-09-12 18:14:47

在配置过程中,您可以使用-M标志运行swig来生成依赖项。然后可以解析它的输出,并将其作为DEPDENDS传递给add_custom_command。

输出如下所示:

代码语言:javascript
复制
test_wrap.c: \
  .../swig.swg \
  ... \
  test.i \
  test.h

这可以用execute_command生成,需要进一步处理:

代码语言:javascript
复制
execute_process(COMMAND swig -M <SWIG_ARGUMENTs> OUTPUT_VARIABLES swig_deps)

# Match all lines except the first one until " \"
string(REGEX MATCHALL "\n  [^ ]+" temp ${swig_deps})
set(swig_deps)
foreach(t ${temp})
    string(STRIP "${t}" t)
    set(swig_deps ${swig_deps} "${t}")
endforeach()

...

add_custom_command(... DEPENDS ${swig_deps})

这使得swig依赖于包含在.i文件中的所有标头。如果以添加新依赖项的方式编辑某个.i或头文件,则需要重新配置,以便cmake知道这一点。如果添加CMAKE_CONFIGURE_DEPENDS,这会自动发生。

代码语言:javascript
复制
set_property(DIRECTORY ${CMAKE_SOURCE_DIR} APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${swig_deps} test.i)
票数 2
EN

Stack Overflow用户

发布于 2016-09-07 15:51:19

事实上,查看UseSWIG.cmake的源代码,custom commands是基于.i文件构建的,并且缺少对other sources的依赖。您可以做的是将extra dependencies添加到自定义命令中:

代码语言:javascript
复制
set(SWIG_MODULE_core_EXTRA_DEPS lib.hpp)
SWIG_ADD_MODULE(core Java native.i lib.cpp)

或者,您可以修改UseSWIG.cmake以自动添加依赖项:

代码语言:javascript
复制
macro(SWIG_ADD_SOURCE_TO_MODULE name outfiles infile other_sources)
    # ...
    add_custom_command(
        # ...
        DEPENDS ${SWIG_MODULE_${name}_EXTRA_DEPS} ${other_sources}
        # ...
    )
endmacro()

# ...

foreach(it ${swig_dot_i_sources})
    SWIG_ADD_SOURCE_TO_MODULE(${name} swig_generated_source ${it} ${swig_other_sources})
    set(swig_generated_sources ${swig_generated_sources} "${swig_generated_source}")
endforeach()

这就引出了我最初的评论:

代码语言:javascript
复制
SWIG_ADD_MODULE(core Java native.i lib.cpp lib.hpp)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39358420

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档