Я использую 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
я устанавливаю параметр build_dir
для cythonize
, как предложено в этого ответа , ноКажется, это не работает так, как мне бы хотелось.Я также попытался использовать cython_c_in_temp
согласно другому ответу на этот вопрос, но это не имеет никакого эффекта (и, судя по моему осмотру исходного кода Cython, вообще не относится к cythonize
вызовам).
Я пытался использовать абсолютные пути для source
, но это еще больше ухудшило ситуацию, поскольку файл C в итоге сгенерировался прямо рядом с demo.py
, внутри дерева исходных текстов (как C:\src\demo.c
).
Мой вопрос: Как я могу убедиться, что все сгенерированные промежуточные файлы (C, obj и friends) окажутся в том же каталоге, что и сгенерированный setup.py
или ниже?
Я могу придумать два обходных пути для моей ситуации, но оба они чувствуют себя как хаки, которых я бы хотел избежать:
- Скопируйте весь Pythonисходные файлы из их местоположений в
C:\mypath\src
рядом с сгенерированными setup.py
, так что я могу ссылаться на них без ..
в пути.Это, скорее всего, решит проблему, но отягощает (уже долгий) процесс сборки десятками дополнительных операций копирования файлов, которых я бы предпочел избегать. - Поскольку путь, в котором заканчиваются файлы, создается путем объединения "каталог
setup.py
+ значение build_dir
+ значение source
", я мог бы посчитать число ..
в пути source
и указать build_dir
достаточно глубоко, чтобы результаты оценкипуть, который я на самом деле хочу.Это и очень хакерский, и очень хрупкий.
Надеюсь, что есть лучшее решение.