我将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
中。demo.c
以C:\mypath\build\src
结尾。同样,我要在projects\cyt
中使用。在setup.py
中,我按照this answer的建议为build_dir
设置了cythonize
参数,但是它似乎并没有达到我想要的效果。
我还尝试在此问题上按照another answer使用cython_c_in_temp
,但这没有任何效果(并且从我对Cython源代码的检查来看,根本不适用于cythonize
调用)。
我尝试为source
使用绝对路径,但这使情况变得更糟,因为C文件最终在源树的 内demo.py
旁边生成(为C:\src\demo.c
)。
我的问题:如何确保所有生成的中间文件(C,obj和好友)都与生成的setup.py
放在同一目录中,或在该目录下? ?
我可以针对我的情况考虑两种解决方法,但是它们都像黑客一样,我想避免:
C:\mypath\src
中的位置复制到生成的setup.py
旁边,以便我可以在路径中没有..
的情况下引用它们。
这可能会解决该问题,但是我宁愿避免数十次其他文件复制操作,从而使(已经很长的)构建过程负担沉重。setup.py
的目录+ build_dir
的值+ source
的值”组成的,因此我可以算出..
路径中source
的数量,并指定足够深的build_dir
,以便评估得出我实际想要的路径。
这既骇人又脆弱。我希望有更好的解决方案。
答案 0 :(得分:3)
所以看来您遇到了一个错误。这是相关的section of code in Cython。基本上,cythonize
会尝试这样构建.c
和.o
文件的路径:
C:/mypath/build/projects/cyt/BUILD_DIR/../../../src/demo.c
因此,您最终会陷入疯狂,而不是很好地包含临时文件。使用demo.py
的绝对路径也无济于事,因为相同的代码只会通过不变的方式传递绝对路径。
在没有广泛的猴子补丁的用户空间中,似乎没有办法解决此问题,因此我提交了pull-request to Cython with an actual fix。合并后,您应该可以运行:
cd C:\mypath\build\projects\cyt
python setup.py build_ext -b C:/mypath/build/bin -t .
获得所需的结果(-b
和-t
是--build-lib
和--build-temp
的缩写)。