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

如何从Setuptools向CMake传递Numpy头文件目录

解决CMake从setup.py传递Numpy头文件路径的问题

我完全懂你的痛点——硬编码路径实在太不灵活了,换个Python环境或者Numpy版本就容易出问题。你之前尝试的ext.include_dirs.append(numpy.get_include())没效果,核心原因是咱们用的是自定义CMakeExtension,setuptools的include_dirs是给它原生编译流程用的,而我们实际是通过调用独立的CMake进程构建,所以得把路径通过CMake参数主动传递过去,具体步骤如下:

1. 改造setup.py:获取Numpy路径并传递给CMake

首先,我们需要在构建流程里获取Numpy的include目录,然后把它作为CMake的定义参数加入到cmake_args列表中。另外,为了避免构建时找不到Numpy,最好在setup声明依赖,确保构建前先安装Numpy。

修改后的setup.py关键部分:

# 先导入numpy,同时处理可能未安装的情况
import numpy as np

# ... 保留原来的CMakeExtension和CMakeBuild类 ...

class CMakeBuild(build_ext):
    def run(self):
        # 确保构建前numpy已安装
        self.distribution.fetch_build_eggs(['numpy>=1.18'])
        super().run()

    def build_extension(self, ext):
        extdir = os.path.abspath(
            os.path.dirname(self.get_ext_fullpath(ext.name)))
        
        # 获取numpy的include路径
        numpy_include = np.get_include()
        
        cmake_args = [
            '-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=' + extdir,
            '-DPYTHON_EXECUTABLE=' + sys.executable,
            # 新增:把numpy路径作为参数传递给CMake
            '-DNUMPY_INCLUDE_DIR=' + numpy_include
        ]
        
        # ... 保留原来的cfg、build_args、env等逻辑 ...

setup(
    name='python_cpp_example',
    version='0.1',
    # ... 其他元信息 ...
    setup_requires=['numpy>=1.18'],  # 构建前自动安装numpy
    install_requires=['numpy>=1.18'], # 运行时依赖声明
    ext_modules=[CMakeExtension('python_cpp_example')],
    cmdclass=dict(build_ext=CMakeBuild),
    zip_safe=False,
)

2. 修改CMakeLists.txt:使用传递过来的路径

把原来硬编码的Numpy路径删掉,改用我们从setup.py传递过来的NUMPY_INCLUDE_DIR变量:

# 替换硬编码路径,改用传递的变量
if(NOT NUMPY_INCLUDE_DIR)
    message(FATAL_ERROR "NUMPY_INCLUDE_DIR not provided by setup.py!")
endif()
include_directories(${NUMPY_INCLUDE_DIR})

# 保留你的Pybind11配置,比如:
find_package(pybind11 REQUIRED)
pybind11_add_module(your_module_name your_source_files.cpp)

为什么之前的方法没用?

咱们用的CMakeExtension是自定义的,它的sources字段是空的,setuptools的include_dirs属性是给它原生的Extension编译流程(比如用distutils直接编译C/C++代码)设计的。但我们实际是通过调用外部CMake进程构建,setuptools不会自动把include_dirs传递给CMake,所以必须显式地通过-D参数把路径传给CMake,让CMake在构建时识别并使用这个路径。

这样修改后,不管你的Python环境里Numpy安装在哪个位置,setup.py都会自动找到正确的路径并传递给CMake,彻底摆脱硬编码的麻烦!

内容的提问来源于stack exchange,提问作者Santi Peñate-Vera

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 10:07:37