You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用pyproject.toml+scikit-build-core+CMake构建Python库时,如何增量重新编译修改后的C++扩展?

pyproject.toml+scikit-build-core+CMake构建Python库时,如何增量重新编译修改后的C++扩展?

我太懂这种折腾了——之前用setup.py的时候,改个C++文件跑一句python setup.py build_ext --inplace就能快速增量编译,换了scikit-build-core+CMake这套新系统后,每次全量编译属实浪费时间。下面给你几个实用的方案,都是贴合这套工具链特性的增量编译方法:

方案1:直接调用CMake做增量编译(最接近make的原生方式)

scikit-build-core本质是帮你打理CMake的构建流程,所以跳过它直接操作CMake就能实现纯增量编译:

  • 先跑一次pip install --no-deps .或者scikit-build-core build,让scikit-build-core帮你生成完整的CMake构建环境(默认会在_skbuild目录下生成平台相关的子目录,比如Linux下是_skbuild/linux-x86_64-3.10,Windows下是_skbuild/win-amd64-3.10
  • 进入到该子目录下的cmake-build文件夹(这是CMake实际的构建工作目录)
  • 直接执行cmake --build .,CMake会自动扫描所有源文件的修改时间,只重新编译有变动的C++文件,速度和原生make一样快
  • 如果你想直接在项目根目录测试编译后的扩展,可以把cmake-build里生成的扩展文件(比如.so/.pyd/.dylib格式)复制到项目根目录,就和之前build_ext --inplace的效果完全一致

方案2:用scikit-build-core自带命令实现增量编译

scikit-build-core本身支持保留构建缓存,不用你手动找CMake目录:

  • 增量编译并生成构建产物:运行scikit-build-core build --no-clean,这个命令不会清空之前的构建缓存,CMake会自动处理增量编译
  • 增量编译后直接安装到当前环境:运行scikit-build-core install --no-deps --no-clean,相比pip install --no-deps .,它不会重新执行完整的配置流程,只编译变动的文件,安装速度快很多

方案3:优化CMake配置让增量编译更省心

在你的CMakeLists.txt里加几个配置,能让整个流程更贴近你之前用setup.py的习惯:

  • 不要用file(GLOB)自动收集源文件(虽然它能检测文件修改,但明确列出源文件能避免CMake漏检新增文件),直接把所有C++源文件写在add_library
  • 固定构建类型(比如DebugRelease),避免每次构建重新配置:在CMakeLists.txt开头加set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE)
  • 让扩展文件直接输出到项目根目录,省去手动复制的步骤:
    set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR})
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}) # Windows下需要这个
    
    之后不管是用cmake --build .还是scikit-build-core build --no-clean,编译好的扩展都会直接出现在项目根目录,你可以立刻用Python导入测试

一些注意事项

  • 如果你修改了CMakeLists.txt或者pyproject.toml,需要重新触发CMake配置(比如运行scikit-build-core configure),这时候会重新生成构建系统文件,可能会全量编译一次,但之后修改C++文件依然是增量的
  • 不同平台的_skbuild子目录命名略有差异,找不到的话可以直接看目录结构,找带Python版本和平台信息的文件夹就行
  • 确保在激活虚拟环境的状态下运行命令,避免路径或依赖版本混乱

内容来源于stack exchange

火山引擎 最新活动