Я использую 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 и др.) оказываются в том же каталоге, что и сгенерированный setup.py
, или ниже?
Я могу придумать два обходных пути для моей ситуации, но они оба кажутся хаками, которых я хотел бы избежать:
- Скопируйте все исходные файлы Python из их расположений в
C:\mypath\src
рядом с сгенерированнымsetup.py
, чтобы я мог ссылаться на них без..
в пути. Это, вероятно, решило бы проблему, но обременяет (и без того длинный) процесс сборки десятками дополнительных операций копирования файлов, которых я бы предпочел избежать. - Поскольку путь, по которому заканчиваются файлы, кажется, состоит из конкатенации «каталог
setup.py
+ значениеbuild_dir
+ значениеsource
», я мог бы подсчитать количество..
в путиsource
и указатьbuild_dir
достаточно глубоко, чтобы результаты оценки по пути, который я действительно хочу. Это очень хакерский и очень хрупкий.
Я надеюсь, что существует лучшее решение.