You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用distutils/setuptools简便编译链接Cython生成的C文件为可执行文件?

用distutils/setuptools编译链接Cython生成的C文件为可执行文件

你可以直接使用distutils内置的CCompiler类完成编译和链接操作,它会自动适配当前系统的编译器(Windows下的cl、Linux下的gcc等),无需手动指定路径或系统专属参数,和cythonize的适配逻辑完全一致。以下是最基础的编译链接原语用法:

1. 编译单个C文件为目标文件

通过CCompiler的compile方法可将单个C文件编译成目标文件(Windows为.obj,Linux为.o):

import distutils.ccompiler
import os

# 创建编译器实例,自动适配当前系统
compiler = distutils.ccompiler.new_compiler()

# 编译指定C文件,返回生成的目标文件路径
c_file = "cython_generated.c"
obj_file = compiler.compile([c_file])[0]
print(f"生成目标文件: {obj_file}")

2. 链接多个目标文件为可执行文件

用同一个编译器实例调用link_executable方法,将多个目标文件(包括Cython生成的和自定义C代码的目标文件)链接成可执行文件:

import sysconfig

# 获取Python头文件和库路径(Cython生成的C文件依赖Python运行时)
include_dirs = [sysconfig.get_path("include")]
library_dirs = [sysconfig.get_path("platstdlib")]
# 适配不同Python版本的库名称
py_version = sysconfig.get_config_var("VERSION")
libraries = [f"python{py_version}" + sysconfig.get_config_var("ABIFLAGS")]

# 待链接的目标文件列表
obj_files = [obj_file, "utils.o"]  # 假设还有一个自定义utils.c编译出的目标文件
# 根据系统设置可执行文件名称
executable_name = "my_program.exe" if os.name == "nt" else "my_program"

# 链接生成可执行文件
compiler.link_executable(
    obj_files,
    executable_name,
    include_dirs=include_dirs,
    library_dirs=library_dirs,
    libraries=libraries
)
print(f"生成可执行文件: {executable_name}")

完整示例脚本

把编译和链接逻辑整合到一个脚本,直接运行即可完成操作:

import distutils.ccompiler
import os
import sysconfig

def compile_c_to_obj(c_file):
    compiler = distutils.ccompiler.new_compiler()
    return compiler.compile([c_file])[0]

def link_objs_to_executable(obj_files, exec_name):
    compiler = distutils.ccompiler.new_compiler()
    include_dirs = [sysconfig.get_path("include")]
    library_dirs = [sysconfig.get_path("platstdlib")]
    py_version = sysconfig.get_config_var("VERSION")
    libraries = [f"python{py_version}" + sysconfig.get_config_var("ABIFLAGS")]
    
    compiler.link_executable(
        obj_files,
        exec_name,
        include_dirs=include_dirs,
        library_dirs=library_dirs,
        libraries=libraries
    )

if __name__ == "__main__":
    # 编译Cython生成的C文件
    cython_obj = compile_c_to_obj("my_cython_module.c")
    # 编译自定义辅助C文件(可选)
    utils_obj = compile_c_to_obj("utils.c")
    # 链接成可执行文件
    exec_name = "my_app.exe" if os.name == "nt" else "my_app"
    link_objs_to_executable([cython_obj, utils_obj], exec_name)

关键说明

  • new_compiler()会自动检测当前系统的编译器,无需手动指定cl或gcc的路径。
  • 通过sysconfig获取Python的头文件和库路径,避免手动配置Python依赖,跨平台通用。
  • 该方式完全基于distutils的基础API,没有setup.py的复杂配置逻辑,仅适用于当前开发机器的编译需求。

内容的提问来源于stack exchange,提问作者Ruediger Jungbeck

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 14:15:30