首页 > 解决方案 > 使用 pip 构建 CMake 扩展

问题描述

我正在开发具有以下结构的 C++/Python 项目:

foo
├── CMakeLists.txt
├── include
├── source
└── python
    ├── foo
    │   ├── _foo_py.py
    │   └── __init__.py
    ├── setup.py
    └── source
        ├── CMakeLists.txt
        └── _foo_cpp.cpp

foo/sourcefoo/include包含 C++ 源文件并foo/python/source/_foo_cpp.cpp包含此 C++ 代码的 pybind11 包装器代码。Runningsetup.py应该构建 C++ 代码(通过运行 CMake),_foo_cpp以共享对象的形式创建一个 Python 模块,并将其与_foo_py.py. 即我希望能够简单地调用python setup.py installfoo/pythonfoo模块安装到我的系统。我目前正在使用 CMake 扩展类setup.py来完成这项工作:

class CMakeExtension(Extension):
    def __init__(self, name, sourcedir):
        Extension.__init__(self, name, sources=[])
        self.sourcedir = os.path.abspath(sourcedir)


class CMakeBuild(build_ext):
    def run(self):
        try:
            subprocess.check_output(['cmake', '--version'])
        except OSError:
            raise RuntimeError("cmake command must be available")

        for ext in self.extensions:
            self.build_extension(ext)

    def build_extension(self, ext):
        if not os.path.exists(self.build_temp):
            os.makedirs(self.build_temp)

        self._setup(ext)
        self._build(ext)

    def _setup(self, ext):
        cmake_cmd = [
            'cmake',
            ext.sourcedir,
        ]

        subprocess.check_call(cmake_cmd, cwd=self.build_temp)

    def _build(self, ext):
        cmake_build_cmd = [
            'cmake',
            '--build', '.',
        ]

        subprocess.check_call(cmake_build_cmd, cwd=self.build_temp)

当我尝试直接调用时出现问题pipfoo/python例如:

pip wheel -w wheelhouse --no-deps .

似乎在运行代码之前setup.pypip将工作目录的内容复制到一个临时目录中。这显然不包括 C++ 代码和顶级CMakeLists.txt. 这反过来又会导致CMakeBuild._setup失败,因为在将根目录复制到另一个位置之后,似乎无法foo从内部获取到根目录的路径。setup.pypip

我可以做些什么来使此设置同时python与 和一起使用pip吗?我已经看到一些方法首先运行cmakesetup.pysetup.py.in注入包版本、根目录路径等生成一个,但我想避免这种情况并setup.py调用cmake而不是相反。

标签: pythonc++cmakepipsetup.py

解决方案


推荐阅读