[英]Can I achieve precise control over location of .c files generated by cythonize?
I am using Cython as part of my build setup for a large project, driven by CMake. 我使用Cython作为我的构建设置的一部分,由CMake驱动的大型项目。 I can't seem to get Cython to generate the
.c
files in a sensible location. 我似乎无法让Cython在合理的位置生成
.c
文件。
My file layout: 我的文件布局:
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
My setup.py
is generated by CMake (a lot of it depends on configure_file
), in the location specified above. 我的
setup.py
是由CMake生成的(很多都取决于configure_file
),位于上面指定的位置。 This location conforms to the usual structure of the overarching project (which builds over a hundred libraries and executables) and is not something I want to (or can easily) change. 这个位置符合总体项目的常规结构(它构建了超过一百个库和可执行文件),并不是我想要(或可以轻易)改变的东西。
The generated setup.py
looks like this: 生成的
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)
(Note that this is heavily simplified compared to the real case, which passes many additional arguments in extension_args
, and includes many source
files, each with its own object in modules
. Nevertheless, I have verified that the minimised version above reproduces my issue). (请注意,与实际情况相比,这大大简化了,它在
extension_args
传递了许多其他参数,并且包含许多source
文件,每个文件在modules
都有自己的对象。但是,我已经验证上面的最小化版本再现了我的问题)。
Cython is run like this: 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
Ideally, I would want all intermediary build artefacts from Cython (the generated C files, object files, exp files, etc.) to reside somewhere in or below C:\\mypath\\build\\projects\\cyt
. 理想情况下,我希望Cython中的所有中间构建工件(生成的C文件,目标文件,exp文件等)都驻留在
C:\\mypath\\build\\projects\\cyt
或之下。 However, I can't seem to achieve that. 但是,我似乎无法实现这一目标。 Here is where build artefacts actually end up:
以下是构建文物最终的结果:
demo.pyd
ends up in C:\\mypath\\build\\bin
, where I want it. demo.pyd
最终在C:\\mypath\\build\\bin
,我想要它。 No problem here. demo.obj
, along with the linked files demo.exp
and demo.lib
, end up in C:\\mypath\\build\\projects\\src
. demo.obj
以及链接文件demo.exp
和demo.lib
最终位于C:\\mypath\\build\\projects\\src
。 I want them inside cyt
. cyt
。 demo.c
ends up in C:\\mypath\\build\\src
. demo.c
最终在C:\\mypath\\build\\src
。 Again, I want this in projects\\cyt
. projects\\cyt
这个。 In the setup.py
, I am setting the build_dir
parameter for cythonize
as suggested in this answer , but it doesn't seem to work as I would like. 在
setup.py
,我按照本答案中的建议设置了build_dir
参数,但它似乎没有按照我的cythonize
工作。 I also tried using cython_c_in_temp
as per another answer on that question, but that has no effect (and judging from my inspection of Cython source code, does not apply to cythonize
calls at all). 我也尝试使用
cython_c_in_temp
作为该问题的另一个答案 ,但这没有效果(从我对Cython源代码的检查判断,根本不适用于cythonize
调用)。
I tried using an absolute paths for source
, but that made things even worse, as the C file ended up generated right next to demo.py
, inside the source tree (as C:\\src\\demo.c
). 我尝试使用绝对路径作为
source
,但这使事情变得更糟,因为C文件最终生成在源代码树内的demo.py
旁边(如C:\\src\\demo.c
)。
My question: How can I make sure that all the generated intermediary files (C, obj, and friends) end up in the same directory as the generated setup.py
, or below that? 我的问题:如何确保所有生成的中间文件(C,obj和朋友)最终与生成的
setup.py
位于同一目录中,或者在下面?
I can think of two workarounds for my situation, but they both feel like hacks which I would like to avoid: 我可以为我的情况考虑两种解决方法,但它们都像我想要避免的黑客:
C:\\mypath\\src
to alongside the generated setup.py
, so that I can refer to them without ..
in the path. C:\\mypath\\src
的位置复制到生成的setup.py
旁边,这样我就可以在路径中引用它们而不用..
That would likely solve the issue, but burdens the (already long) build process with tens of additional file copy operations I'd rather avoid. setup.py
+ the value of build_dir
+ the value of source
", I could count the number of ..
in the source
path and specify build_dir
deep enough so that the evaluation results in the path I actually want. setup.py
的目录+ build_dir
的值+ source
的值”来组成的,所以我可以计算source
路径中的..
的数量并指定build_dir
足够深以便评估结果在我真正想要的路径上。 This is both extremely hacky and very fragile. I hope a better solution exists. 我希望有更好的解决方案。
So it seems like you've run into a bug. 所以你好像遇到了一个bug。 Here's the relevant section of code in Cython .
这是Cython中相关的代码部分 。 Basically,
cythonize
will try to build the paths to your .c
and .o
files as so: 基本上,
cythonize
将尝试构建.c
和.o
文件的路径,如下所示:
C:/mypath/build/projects/cyt/BUILD_DIR/../../../src/demo.c
and so instead of nicely contained temporary files, you end up with insanity. 因此,你最终会有精神错乱,而不是很好地包含临时文件。 Using an absolute path to
demo.py
won't help either, since that same code will just pass absolute paths through unchanged. 使用
demo.py
的绝对路径也demo.py
,因为相同的代码只会传递绝对路径。
There doesn't seem to be a way to fix this in user-space short of extensive monkey-patching, so I submitted a pull-request to Cython with an actual fix . 似乎没有办法在用户空间中解决这个问题,而不是广泛的猴子修补,所以我向Cython提交了一个实际修复的拉取请求 。 Once that's been merged in, you should then be able to run:
一旦合并,您应该能够运行:
cd C:\mypath\build\projects\cyt
python setup.py build_ext -b C:/mypath/build/bin -t .
to get the result you want ( -b
and -t
are the short forms of --build-lib
and --build-temp
). 获得你想要的结果(
-b
和-t
是--build-lib
和--build-temp
的简短形式)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.