【发布时间】:2019-05-13 15:48:46
【问题描述】:
我正在使用 Cython 作为由 CMake 驱动的大型项目的构建设置的一部分。
我似乎无法让 Cython 在合理的位置生成 .c 文件。
我的文件布局:
C:\mypath\src\demo.py # Cython source file
C:\mypath\build\bin # I want demo.pyd to end up here
C:\mypath\build\projects\cyt\setup.py # Generated by CMake
我的setup.py 是由 CMake 生成的(很多依赖于configure_file),位于上面指定的位置。
此位置符合总体项目的通常结构(构建了一百多个库和可执行文件),我不想(或可以轻松)更改。
生成的setup.py 如下所示:
from distutils.core import setup, Extension
from Cython.Build import cythonize
import os.path
extension_args = {
'extra_compile_args' : ['/DWIN32','/DWIN64'],
'extra_link_args' : ['/MACHINE:X64'],
}
source = '../../../src/demo.py'
modules = [Extension(
os.path.splitext(os.path.basename(source))[0],
sources = [source],
**extension_args
)]
modules = cythonize(
modules,
build_dir = 'BUILD_DIR',
compiler_directives = {'language_level' : 2}
)
setup(name = 'demo',
version = '0.1',
description = '',
ext_modules = modules)
(请注意,与实际情况相比,这大大简化了,它在extension_args 中传递了许多额外的参数,并包含许多source 文件,每个文件在modules 中都有自己的对象。
尽管如此,我已经验证了上面的最小化版本重现了我的问题)。
Cython 是这样运行的:
cd C:\mypath\build\projects\cyt
python setup.py build_ext --build-lib C:/mypath/build/bin --build-temp C:/mypath/build/projects/cyt
理想情况下,我希望所有来自 Cython 的中间构建工件(生成的 C 文件、目标文件、exp 文件等)驻留在 C:\mypath\build\projects\cyt 中或下方的某个位置。
但是,我似乎无法做到这一点。
以下是构建工件的最终结果:
-
demo.pyd以C:\mypath\build\bin结尾,我想要它。这里没问题。 - 目标文件
demo.obj以及链接文件demo.exp和demo.lib最终位于C:\mypath\build\projects\src。我希望他们在cyt内。 - C 文件
demo.c以C:\mypath\build\src结尾。同样,我想在projects\cyt中使用这个。
在setup.py 中,我正在按照this answer 中的建议为cythonize 设置build_dir 参数,但它似乎没有按我的意愿工作。
我还尝试按照another answer 在该问题上使用cython_c_in_temp,但这没有效果(从我对 Cython 源代码的检查来看,根本不适用于cythonize 调用)。
我尝试为source 使用绝对路径,但这让事情变得更糟,因为 C 文件最终生成在 demo.py 旁边,在源代码树内部(如 @987654351 @)。
我的问题:如何确保所有生成的中间文件(C、obj 和朋友)最终与生成的setup.py 位于同一目录中,或低于该目录?
我可以针对我的情况想出两种解决方法,但它们都像是我想避免的黑客攻击:
- 将所有 Python 源文件从它们在
C:\mypath\src中的位置复制到生成的setup.py旁边,这样我就可以在路径中没有..的情况下引用它们。 这可能会解决问题,但会给(已经很长的)构建过程带来数十种我宁愿避免的额外文件复制操作的负担。 - 由于文件最终的路径似乎是通过连接“
setup.py的目录+build_dir的值+source的值”组成的,我可以计算..的数量source路径并指定build_dir足够深,以便评估结果为我真正想要的路径。 这既非常hacky又非常脆弱。
我希望有更好的解决方案。
【问题讨论】:
-
我怀疑你的选项 #1 可能是最好的选择