混合C++和Python的项目目录结构
假设你想创建一个同时使用 C++ 和 Python 的编程项目。这个 Foo 的 C++ 项目结构使用 CMake,而 Python 模块是通过 Swig 创建的。它的文件结构大概是这样的:
├── CMakeLists.txt
├── FooConfig.cmake.in
├── FooConfigVersion.cmake.in
├── Makefile
├── README
├── foo
│ ├── CMakeLists.txt
│ ├── config.hpp.in
│ ├── foo.cpp
│ └── foo.hpp
└── swig
└── foo.i
现在你想在一个 Python 项目中使用 Foo 项目,比如叫做 Bar:
├── AUTHORS.rst
├── CONTRIBUTING.rst
├── HISTORY.rst
├── LICENSE
├── MANIFEST.in
├── Makefile
├── README.rst
├── docs
│ ├── Makefile
│ ├── authors.rst
│ ├── conf.py
│ ├── contributing.rst
│ ├── history.rst
│ ├── index.rst
│ ├── installation.rst
│ ├── make.bat
│ ├── readme.rst
│ └── usage.rst
├── bar
│ ├── __init__.py
│ └── bar.py
├── requirements.txt
├── setup.cfg
├── setup.py
├── tests
│ ├── __init__.py
│ └── test_bar.py
└── tox.ini
这个结构是通过 cookiecutter 的 pypackage 模板 创建的。还有一个 BoilerplatePP 模板可以用来生成一个 CMake 的 C++ 项目(没有 Swig 部分)。所以现在我有了两个项目的结构,并且考虑到开发主要会在 Python 中进行,项目会在不同的系统上运行,我需要考虑以下几个问题:
- 混合这两个项目的最佳方式是什么?我应该把两个根目录合并吗?应该把 Foo 的 C++ 项目放在 Bar 项目的目录里,还是反过来?我可能倾向于把上面显示的整个 C++ 结构放在 Python 项目根目录的一个文件夹里,但我想提前了解可能的坑,因为 CMake 系统非常强大,可能反过来做会更方便。
- 如果我决定把 Foo 项目放在 Bar 的一个目录里,Python 的 setuptools 包是否和 CMake 的构建系统一样强大?我问这个是因为当我查看 Bar 项目时,顶层似乎只有一堆脚本,但我不知道这是否相当于 CMake,因为我对 Python 还不太熟悉。
- 上面提到的 Bar 项目只有一个 bar 目录,但我假设当这个项目扩展时,不会在根目录下有很多其他目录,而是会在 bar 里放置其他包含 Python 代码的目录。这是正确的吗(从 Pythonic 的角度来看)?
- 我假设整个项目会生成一个单一的 egg,这样可以在许多不同的 Python 系统中安装和运行。由 Foo 项目创建的模块集成起来容易吗?我假设这个模块会在一个不同于 bar 的目录中创建。
- 为了让 bar 目录中的 Python 代码能够使用,由 Swig 创建的模块必须可用,所以我想最简单的方法是通过 CMake 系统修改环境变量
PYTHONPATH
。这样做可以吗,还是有更好的方法?
1 个回答
8
如果这个C++程序只会在包含它的Python包中使用:
你可以把C++代码放在属于它的Python包里,这样做比较安全。比如在你的例子中,可以在“bar”目录下再放一个“foo”目录。这样打包最终的Python模块会简单一些。
如果这个C++程序是可以重复使用的:
我建议你考虑把东西分成“包”,也就是把独立的部分放在一起,每个部分都是自成一体的。所有独立的部分都放在同一层级。如果某个部分需要依赖另一个部分,你就从同一层级的对应“包”中导入。这就是依赖关系通常是怎么运作的。
我不会把一个包放在另一个包里面,因为它们并不严格属于同一个包。假设你开始了第三个项目,需要“foo”,但不需要“bar”,那就麻烦了。
我会把“foo”和“bar”这两个包放在同一个“项目”目录下(而且我可能会给每个包单独建立一个代码仓库,这样每个包就能更方便地维护和安装)。