我可以精确控制cythonize生成的.c文件的位置吗?
Can I achieve precise control over location of .c files generated by cythonize?
我将 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
文件,每个文件在 [=19= 中都有自己的对象].
尽管如此,我已经确认上面的最小化版本重现了我的问题。
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
中,我按照 中的建议为 cythonize
设置了 build_dir
参数,但它似乎并没有像我希望的那样工作.
我还尝试根据 对该问题使用 cython_c_in_temp
,但这没有任何效果(并且从我对 Cython 源代码的检查来看,根本不适用于 cythonize
调用)。
我尝试为 source
使用绝对路径,但这让事情变得更糟,因为 C 文件最终生成在 demo.py
、 内部 [=89] =] 源代码树(如 C:\src\demo.c
)。
我的问题:如何确保所有生成的中间文件(C、obj 和朋友)最终与生成的目录位于同一目录中setup.py
,还是低于这个?
对于我的情况,我可以想到两种解决方法,但它们都像是我想避免的黑客攻击:
- 将所有 Python 源文件从它们在
C:\mypath\src
中的位置复制到生成的 setup.py
旁边,这样我就可以在路径中没有 ..
的情况下引用它们.
这可能会解决问题,但会增加(已经很长的)构建过程的负担,因为我宁愿避免数十个额外的文件复制操作。
- 由于文件结束的路径似乎是由 "the directory of
setup.py
+ the value of build_dir
+ the value of source
" 串联而成,我可以计算 source
路径中 ..
的数量并指定 build_dir
足够深,以便评估结果符合我真正想要的路径。
这既非常骇人听闻又非常脆弱。
我希望有更好的解决方案。
看来您 运行 遇到了错误。这是相关的 section of code in Cython。基本上,cythonize
将尝试构建 .c
和 .o
文件的路径,如下所示:
C:/mypath/build/projects/cyt/BUILD_DIR/../../../src/demo.c
所以你最终会变得精神错乱,而不是很好地包含临时文件。使用 demo.py
的绝对路径也无济于事,因为相同的代码只会通过绝对路径而不改变。
除了广泛的猴子修补之外,似乎没有办法在用户 space 中解决这个问题,所以我提交了一个 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
的缩写形式)。
我将 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
文件,每个文件在 [=19= 中都有自己的对象].
尽管如此,我已经确认上面的最小化版本重现了我的问题。
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
中,我按照 cythonize
设置了 build_dir
参数,但它似乎并没有像我希望的那样工作.
我还尝试根据 cython_c_in_temp
,但这没有任何效果(并且从我对 Cython 源代码的检查来看,根本不适用于 cythonize
调用)。
我尝试为 source
使用绝对路径,但这让事情变得更糟,因为 C 文件最终生成在 demo.py
、 内部 [=89] =] 源代码树(如 C:\src\demo.c
)。
我的问题:如何确保所有生成的中间文件(C、obj 和朋友)最终与生成的目录位于同一目录中setup.py
,还是低于这个?
对于我的情况,我可以想到两种解决方法,但它们都像是我想避免的黑客攻击:
- 将所有 Python 源文件从它们在
C:\mypath\src
中的位置复制到生成的setup.py
旁边,这样我就可以在路径中没有..
的情况下引用它们. 这可能会解决问题,但会增加(已经很长的)构建过程的负担,因为我宁愿避免数十个额外的文件复制操作。 - 由于文件结束的路径似乎是由 "the directory of
setup.py
+ the value ofbuild_dir
+ the value ofsource
" 串联而成,我可以计算source
路径中..
的数量并指定build_dir
足够深,以便评估结果符合我真正想要的路径。 这既非常骇人听闻又非常脆弱。
我希望有更好的解决方案。
看来您 运行 遇到了错误。这是相关的 section of code in Cython。基本上,cythonize
将尝试构建 .c
和 .o
文件的路径,如下所示:
C:/mypath/build/projects/cyt/BUILD_DIR/../../../src/demo.c
所以你最终会变得精神错乱,而不是很好地包含临时文件。使用 demo.py
的绝对路径也无济于事,因为相同的代码只会通过绝对路径而不改变。
除了广泛的猴子修补之外,似乎没有办法在用户 space 中解决这个问题,所以我提交了一个 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
的缩写形式)。