构建工具开发工具CLI【免费下载链接】CMakeMirror of CMake upstream repository项目地址https://gitcode.com/gh_mirrors/cm/CMake点击查看免费下载UseSWIG是 CMake 官方模块用于在构建系统中集成 SWIG 中的底层实现原理自定义命令生成、支持文件管理、依赖跟踪与各语言目标命名规则能够直接在真实项目中编写可复制的 SWIG 绑定构建配置。前置条件先 FindSWIG 再 include(UseSWIG)UseSWIG模块本身不负责查找 SWIG 可执行文件官方文档明确说明“假设 FindSWIG 模块已被加载”。因此标准用法是find_package(SWIG COMPONENTS python) # 先定位 SWIG 与目标语言支持 if(SWIG_FOUND) include(UseSWIG) swig_add_library(mymod LANGUAGE python SOURCES mymod.i) endif()find_package(SWIG ...)由 FindSWIG 提供它会解析swig -version与swig -swiglib输出产出以下结果变量SWIG_FOUND是否找到指定版本的SWIG 及所请求的语言组件SWIG_VERSIONSWIG 版本号SWIG_lang_FOUND使用COMPONENTS/OPTIONAL_COMPONENTS时每个小写目标语言是否可用SWIG_DIRSWIG 安装的Lib目录路径swig -swiglib的结果实现中会以SWIG_LIB${SWIG_DIR}环境变量传给 swig 调用SWIG_EXECUTABLE缓存变量SWIG 可执行文件路径可手工指定。COMPONENTS中的语言名必须是小写且与swig_add_library的LANGUAGE参数一致如python、perl5。也支持版本范围与可选组件find_package(SWIG 4.0 COMPONENTS python OPTIONAL_COMPONENTS fortran)swig_add_library模块的核心命令该命令自 CMake 3.8 引入用于“以给定名称和指定语言定义 swig 模块”完整语法为swig_add_library(name [TYPE SHARED|MODULE|STATIC|USE_BUILD_SHARED_LIBS] LANGUAGE language [NO_PROXY] [DEBUG_POSTFIX postfix] [OUTPUT_DIR directory] [OUTFILE_DIR directory] SOURCES file... )由swig_add_library创建的目标拥有与 add_library 目标相同的能力可直接用于任何接受目标的命令例如target_link_libraries。TYPE库类型SHARED、MODULE、STATIC语义与add_library完全一致指定USE_BUILD_SHARED_LIBS时根据当前 BUILD_SHARED_LIBS 变量值为ON或OFF决定生成SHARED或STATIC库未指定时默认MODULE动态加载模块。实现中Modules/UseSWIG.cmake当类型为MODULE时还会自动设置NO_SONAME ON避免模块携带 soname。LANGUAGE目标语言指定 SWIG 的封装目标语言版本演进如下CMake 3.1 起支持 Go 和 LuaCMake 3.2 起支持 RCMake 3.18 起支持 Fortran。模块内部会通过SWIG_MODULE_INITIALIZE宏将语言名转大写与小写分别用于生成文件和 swig 的-lang命令行旗标。语言名无法识别时会直接FATAL_ERRORSWIG Error: Language ... not found。NO_PROXY跳过代理层CMake 3.12 引入对应 swig 的-noproxy选项阻止生成目标语言的代理proxy包装层。例如 Python 模式下正常会生成一个mymod.py代理文件内含import _mymod而NO_PROXY会跳过该层。实现中Modules/UseSWIG.cmake会将该标记并入SWIG_MODULE_name_EXTRA_FLAGS且若CMAKE_SWIG_FLAGS已含-noproxy则不重复追加。DEBUG_POSTFIX调试配置后缀CMake 4.2 引入用于管理目标的 DEBUG_POSTFIX 属性目前仅对python语言有意义。若全局属性 DEBUG_CONFIGURATIONS 已定义则为每个调试配置定义CONFIG_POSTFIX目标属性未定义时默认使用DEBUG实现见 Modules/UseSWIG.cmake 与 L1005-L1009。OUTPUT_DIR 与 OUTFILE_DIR输出目录控制两者均为 CMake 3.12 引入分别对应 swig 的-outdir语言特定文件输出目录与-o生成的 C/C 源文件输出目录。OUTPUT_DIR的取值优先级为命令的OUTPUT_DIR选项CMAKE_SWIG_OUTDIR变量未指定时取决于UseSWIG_MODULE_VERSION值为 1 或未定义时输出到 CMAKE_CURRENT_BINARY_DIR值为 2 时使用专有目录其路径可通过只读目标属性SWIG_SUPPORT_FILES_DIRECTORY获取。OUTFILE_DIR的取值优先级为命令选项OUTFILE_DIR→ 变量SWIG_OUTFILE_DIR→ 否则回退到OUTPUT_DIR或CMAKE_SWIG_OUTDIR。重要提示当UseSWIG_MODULE_VERSION为 2 时强烈建议为每个目标使用独立的专有输出目录。因为目标构建时输出目录内容会被整体清空见下文支持文件管理共用一个目录会在不同目标间互相干扰、甚至误删文件。SOURCES接口文件识别SOURCES中扩展名为.i的文件会被识别为 SWIG 工具输入其余文件按常规方式编译链接。该默认行为可通过变量SWIG_SOURCE_FILE_EXTENSIONSCMake 3.14 起覆盖。实现中Modules/UseSWIG.cmake会把扩展名列表拼成正则过滤出 SWIG 输入若一个都没有则报错SWIG_ADD_LIBRARY: no SWIG interface files specified。版本行为变化与注意事项CMake 3.13当策略 CMP0078 为NEW时命令创建名为name的标准目标旧行为则使用不同目标名并存入SWIG_MODULE_name_REAL_NAME变量。CMake 3.15替代库名例如通过 OUTPUT_NAME 属性设置会传递给 Python 和 CSharp 包装库。CMake 3.21当策略 CMP0122 为NEW时CSharp 生成的库使用标准命名约定否则沿用旧行为。多配置生成器模块不支持 SWIG 生成的“随配置变化”的文件所有构建配置必须产生相同的生成源文件。Makefile 生成器若某些源文件的USE_SWIG_DEPENDENCIES属性为FALSE模块不追踪文件依赖需要依赖name_swig_compilation自定义目标来确保 SWIG 生成文件已存在其他生成器可直接依赖 SWIG 生成的源文件。源文件属性在调用 swig_add_library 之前设置SWIG 输入文件.i上的源文件属性必须在调用swig_add_library之前设置以便生成文件正确继承所需设置属性引入版本说明CPLUSPLUS—以 C 模式调用 SWIG-c生成.cxx而非.cSWIG_FLAGS3.12 弃用向 SWIG 可执行文件传递自定义旗标已被下列细粒度属性取代INCLUDE_DIRECTORIES/COMPILE_DEFINITIONS/COMPILE_OPTIONS3.12追加 SWIG 编译旗标语义同 INCLUDE_DIRECTORIES 等属性USE_TARGET_INCLUDE_DIRECTORIES3.13为TRUE时把目标 INCLUDE_DIRECTORIES 转发给 SWIGFALSE时忽略未设置时参考目标属性SWIG_USE_TARGET_INCLUDE_DIRECTORIESGENERATED_INCLUDE_DIRECTORIES/GENERATED_COMPILE_DEFINITIONS/GENERATED_COMPILE_OPTIONS3.12作用于生成的 C/C 文件填充生成文件的INCLUDE_DIRECTORIES、COMPILE_DEFINITIONS、COMPILE_OPTIONS属性DEPENDS3.12为源文件指定额外依赖USE_SWIG_DEPENDENCIES3.20为TRUE时由 swig 工具自身生成隐式依赖仅对 Makefile、Ninja、Xcode3.21 起和 Visual Studio3.22 起生成器有意义默认FALSESWIG_MODULE_NAME—指定目标语言中的实际模块导入名当无法从源码自动扫描或与文件基名不同时必须设置OUTPUT_DIR3.19为该源文件指定语言特定文件的输出目录-outdirOUTFILE_DIR3.19为该源文件指定生成源文件的输出目录-o典型示例set_property(SOURCE mymod.i PROPERTY CPLUSPLUS ON) set_property(SOURCE mymod.i PROPERTY SWIG_MODULE_NAME mymod_realname) swig_add_library(mymod LANGUAGE python SOURCES mymod.i)关于SWIG_MODULE_NAME从 CMake 3.14 起若策略 CMP0086 为NEW会向 SWIG 编译器传递-module module_name否则模块名依赖 SWIG 自行从%module指令扫描。模块名自动扫描逻辑见 Modules/UseSWIG.cmake先读取源属性SWIG_MODULE_NAME其次用正则匹配.i文件中的%module foo语法再次匹配%module (options...) foo语法最后回退到文件基名。目标属性对整个 SWIG 模块统一配置目标级属性可对模块内所有 SWIG 输入文件统一生效属性引入版本说明SWIG_INCLUDE_DIRECTORIES/SWIG_COMPILE_DEFINITIONS/SWIG_COMPILE_OPTIONS3.12作用于所有 SWIG 输入文件语义同目标属性 INCLUDE_DIRECTORIES、COMPILE_DEFINITIONS、COMPILE_OPTIONSSWIG_USE_TARGET_INCLUDE_DIRECTORIES3.13为TRUE时转发目标INCLUDE_DIRECTORIES给 SWIGFALSE或未定义时忽略可被源属性USE_TARGET_INCLUDE_DIRECTORIES覆盖SWIG_GENERATED_INCLUDE_DIRECTORIES/SWIG_GENERATED_COMPILE_DEFINITIONS/SWIG_GENERATED_COMPILE_OPTIONS3.12填充所有生成的 C/C 文件的INCLUDE_DIRECTORIES、COMPILE_DEFINITIONS、COMPILE_FLAGS属性SWIG_DEPENDS3.12为所有 SWIG 输入文件增加依赖官方示例set(UseSWIG_TARGET_NAME_PREFERENCE STANDARD) swig_add_library(mymod LANGUAGE python SOURCES mymod.i) set_property(TARGET mymod PROPERTY SWIG_COMPILE_DEFINITIONS MY_DEF1 MY_DEF2) set_property(TARGET mymod PROPERTY SWIG_COMPILE_OPTIONS -bla -blb)只读目标属性获取支持文件信息以下两个是输出型只读属性用于查询 SWIG 接口编译产生的支持文件信息SWIG_SUPPORT_FILES3.12 起SWIG 编译期间生成的包装文件列表。例如set(UseSWIG_TARGET_NAME_PREFERENCE STANDARD) swig_add_library(mymod LANGUAGE python SOURCES mymod.i) get_property(support_files TARGET mymod PROPERTY SWIG_SUPPORT_FILES)注意只列出最主要的支持文件若使用%template等 SWIG 高级特性关联支持文件可能未列出此时优先使用SWIG_SUPPORT_FILES_DIRECTORY属性处理支持文件。SWIG_SUPPORT_FILES_DIRECTORY3.12 起支持文件生成目录。当源属性OUTPUT_DIR被定义时该属性可能包含多个目录实现见 Modules/UseSWIG.cmake所有去重后的输出目录都会追加进该属性。支持文件清单的组装逻辑Modules/UseSWIG.cmake依据模块头部的语言扩展名表按后缀过滤生成源例如 Python 为.py、Java 为.java与JNI.java、CSharp 为.cs与PINVOKE.cs、Perl/Perl5 为.pm见 L424-L428。CMake 变量全局定制 swig_add_library 与 SWIG变量引入版本说明UseSWIG_MODULE_VERSION3.12取 1 或未定义应用旧行为取 2采用关于支持文件的新策略——SWIG 接口编译前会清空支持文件输出目录。取值非法时报错CMAKE_SWIG_FLAGS—为所有 swig 调用追加旗标CMAKE_SWIG_OUTDIR—指定语言特定文件输出目录-outdir优先级低于命令OUTPUT_DIR选项SWIG_OUTFILE_DIR3.8指定生成源文件输出目录未指定时使用CMAKE_SWIG_OUTDIRSWIG_MODULE_name_EXTRA_DEPS—为name生成的模块指定额外依赖SWIG_SOURCE_FILE_EXTENSIONS3.14覆盖默认仅将.i视为 SWIG 源的行为例如set(SWIG_SOURCE_FILE_EXTENSIONS .i .swg)SWIG_USE_SWIG_DEPENDENCIES3.20为TRUE时由 swig 自身生成隐式依赖仅对 Makefile、Ninja、Xcode3.21 起、Visual Studio3.22 起生成器有意义默认FALSE未定义的源文件属性USE_SWIG_DEPENDENCIES会以该变量值初始化另外模块还维护UseSWIG_TARGET_NAME_PREFERENCE变量LEGACY或STANDARD控制目标命名STANDARD使用name原名LEGACY下 Python 非NO_PROXY模块的目标名带_前缀_name因为生成的module.py含import _modulename语句需要对应的_modulename.soUnix/_modulename.pydWindows二进制见 Modules/UseSWIG.cmake。策略CMP0078为NEW时强制为STANDARD。已废弃命令swig_link_librariesswig_link_libraries(name item...)自 CMake 3.13 起弃用应改用带标准目标名的 target_link_libraries或在旧目标命名下使用${SWIG_MODULE_name_REAL_NAME}。新命令与target_link_libraries能力相同策略CMP0078为NEW时swig_add_library创建标准目标name应直接使用target_link_libraries旧行为CMP0078为OLD且UseSWIG_TARGET_NAME_PREFERENCE为LEGACY或 CMake 3.12 之前下推荐使用target_link_libraries(${SWIG_MODULE_name_REAL_NAME} ...)而非该命令。实现中Modules/UseSWIG.cmake还兼容了SWIG_ADD_MODULE宏——调用它会打印弃用警告并转调swig_add_library。源码级原理SWIG 编译是如何接入构建系统的自定义命令与生成文件命名核心函数SWIG_ADD_SOURCE_TO_MODULEModules/UseSWIG.cmake为每个.i文件生成一个add_custom_command先创建输出目录再以SWIG_LIB${SWIG_DIR}环境变量调用${SWIG_EXECUTABLE}依次拼接-lang、源文件旗标含-I、-D前缀转换的生成器表达式、-outdir、-cCPLUSPLUS 时、-moduleCMP0086 NEW 时、额外旗标、-o 生成文件最后是输入文件本身。生成的主源文件名规则为outfiledir/源文件基名语言大写_wrap.c # C 模式 outfiledir/源文件基名语言大写_wrap.cxx # C 模式SWIG_CXX_EXTENSION把语言名拼入文件名是为了让同一个.i文件可被封装为多种语言而互不冲突。生成文件与额外支持文件均被标记GENERATED 1并写入ADDITIONAL_CLEAN_FILES。输出目录与支持文件管理UseSWIG_MODULE_VERSION 2当UseSWIG_MODULE_VERSION大于 1 时每个源文件使用专有工作目录workingdir/源文件基名.files并在自定义命令中插入两步脚本调用Modules/UseSWIG.cmakeACTIONCLEAN先清空输出目录中的旧生成文件再删除工作目录防止过时文件残留ACTIONCOPY编译完成后把工作目录中的新文件复制回输出目录。这两步由 Modules/UseSWIG/ManageSupportFiles.cmake 实现GLOB_RECURSE收集文件 →file(REMOVE)/file(COPY)。这正是文档强调“每个目标使用独立输出目录”的原因。依赖跟踪的两种策略默认关闭USE_SWIG_DEPENDENCIES为FALSE时Makefile 生成器额外引入时间戳机制__SWIG_COMPUTE_TIMESTAMP见 Modules/UseSWIG.cmake自定义命令输出为nameLANGUAGE.stamp时间戳文件生成源作为BYPRODUCTS并利用IMPLICIT_DEPENDS CXX做隐式依赖同时创建name_swig_compilation自定义目标依赖这些时间戳L954-L958解决依赖文件被移除时的重建问题对应上游 issue #16830。开启时USE_SWIG_DEPENDENCIES为TRUE仅 Makefile/Ninja/Xcode/Visual Studio时swig 以-MD -MF name.d生成 depfile通过自定义命令的DEPFILE机制接入 Ninja 等的依赖扫描。各语言目标命名规则SWIG_ADD_LIBRARY函数后半段Modules/UseSWIG.cmake针对不同语言调整目标 PREFIX/SUFFIX 属性使产物名符合各语言运行时约定OctavePREFIX 、SUFFIX .octGoPREFIX JavamacOS 上SUFFIX .jnilibMINGW/CYGWIN/MSYS 上PREFIX 对应System.loadLibrary(LIBRARY)的查找规则LuaMODULE 类型PREFIX Python非 NO_PROXY 时PREFIX _Windows 上SUFFIX .pyd自 Python 2.5 起扩展模块后缀并应用DEBUG_POSTFIXR / Ruby / Perl / Perl5PREFIX Ruby 与 Perl 在 macOS 上分别使用.bundle、.dylib后缀CSharp策略 CMP0122 为NEW时保持默认前缀否则PREFIX macOS 上SUFFIX .dylibFortran不覆盖库前缀。CSharp 与 Python 的特殊旗标CSharp 模式下自动补-dllimport $TARGET_FILE_BASE_NAME:...确保生成代码里的DllImport名称与 CMake 创建的库名一致Modules/UseSWIG.cmakePython 单输入文件且非 NO_PROXY 时自动补-interface旗标使代理代码中的名称与库名匹配L662-L669。测试与验证RunCMake/UseSWIG仓库在 Tests/RunCMake/UseSWIG 提供针对策略行为的回归测试是理解模块行为边界的直接参考CMP0078-NEW/OLD/WARN.cmake与CMP0078-common.cmake验证新旧目标命名行为。公共测试文件设置CMP0086 NEW、指定SWIG_EXECUTABLE与SWIG_DIR后include(UseSWIG)并调用swig_add_library(example LANGUAGE python TYPE MODULE SOURCES example.i)随后打印PREFIX与SWIG_MODULE_example_REAL_NAME对照-stdout.txt/-stderr.txt期望输出CMP0086-NEW/OLD/WARN.cmake验证SWIG_MODULE_NAME是否传递-module旗标CMP0122-NEW/OLD/WARN.cmake与-check.cmake验证 CSharp 目标命名约定example.i%module example与runme.py最小 Python 绑定示例SetPOSTFIX.cmake验证调试后缀设置。这些测试同时展示了最小可用配置形态cmake_minimum_requiredproject(... C)include(测试.cmake)再配合SWIG_EXECUTABLE变量即可在 CI 中模拟 SWIG 存在的情形。最小实战模板综合以上内容一个完整的 Python 绑定项目只需cmake_minimum_required(VERSION 3.20) project(mypybind CXX) find_package(SWIG 4.0 COMPONENTS python REQUIRED) include(UseSWIG) set(UseSWIG_MODULE_VERSION 2) # 启用支持文件目录管理 # 源文件属性必须在 swig_add_library 之前设置 set_property(SOURCE mymod.i PROPERTY CPLUSPLUS ON) set_property(SOURCE mymod.i PROPERTY SWIG_MODULE_NAME mymod) swig_add_library(mymod TYPE MODULE LANGUAGE python SOURCES mymod.i ) target_link_libraries(mymod PRIVATE MyCppLib) target_include_directories(mymod PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) # 查询生成的支持文件只读属性 get_property(_swig_support TARGET mymod PROPERTY SWIG_SUPPORT_FILES) message(STATUS SWIG support files: ${_swig_support})构建后即可在输出目录获得mymod.py代理层与_mymod.so/_mymod.pyd二进制扩展完成一次完整的“C/C → Python”自动封装流程。适用前提与限制以上行为以当前仓库Modules/UseSWIG.cmake为准多配置生成器不支持随配置变化的生成文件Makefile 生成器默认不跟踪 SWIG 隐式依赖需依赖name_swig_compilation目标或显式开启USE_SWIG_DEPENDENCIES使用UseSWIG_MODULE_VERSION 2时务必为每个目标配置独立输出目录。赞分享构建工具开发工具CLI【免费下载链接】CMakeMirror of CMake upstream repository项目地址https://gitcode.com/gh_mirrors/cm/CMake点击查看免费下载相关推荐Apache OpenDAL™ 多语言绑定详解C、C、Java、Python 等20语言支持Apache OpenDAL™ 多语言绑定详解C、C、Java、Python 等20语言支持 Apache OpenDAL™ 是一个强大的数据访问层项目数据存储后端NumPy 与 SWIG 完全指南用 numpy.i 为 C/C 数组自动生成 Python 封装NumPy 与 SWIG 完全指南用 numpy.i 为 C/C 数组自动生成 Python 封装 SWIGSimplified Wrapper and科学计算数据分析动漫下载加速终极指南如何用专业Tracker列表实现500%速度提升动漫下载加速终极指南如何用专业Tracker列表实现500%速度提升 还在为动漫资源下载速度慢如蜗牛而烦恼吗 动漫Tracker加速 项目为您提供了一套完整上一篇RedwoodRecord 实战指南基于 Prisma 的 Redwood 原生 ORM 全解析下一篇Airbyte source-youtube-data 连接器工程剖析增量策略、错误处理与配额治理实战创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考