Могу ли я добиться точного контроля над расположением .c файлов, сгенерированных Cythonize? - PullRequest
0 голосов
/ 12 декабря 2018

Я использую 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или ниже?


Я могу придумать два обходных пути для моей ситуации, но оба они чувствуют себя как хаки, которых я бы хотел избежать:

  1. Скопируйте весь Pythonисходные файлы из их местоположений в C:\mypath\src рядом с сгенерированными setup.py, так что я могу ссылаться на них без .. в пути.Это, скорее всего, решит проблему, но отягощает (уже долгий) процесс сборки десятками дополнительных операций копирования файлов, которых я бы предпочел избегать.
  2. Поскольку путь, в котором заканчиваются файлы, создается путем объединения "каталог setup.py + значение build_dir + значение source ", я мог бы посчитать число .. в пути source и указать build_dir достаточно глубоко, чтобы результаты оценкипуть, который я на самом деле хочу.Это и очень хакерский, и очень хрупкий.

Надеюсь, что есть лучшее решение.

1 Ответ

0 голосов
/ 18 декабря 2018

Похоже, вы столкнулись с ошибкой.Вот соответствующий раздел кода на Cython .По сути, cythonize будет пытаться построить пути к вашим .c и .o файлам следующим образом:

C:/mypath/build/projects/cyt/BUILD_DIR/../../../src/demo.c

, и поэтому вместо красиво содержащихся временных файлов вы получите безумие.Использование абсолютного пути к demo.py также не поможет, поскольку тот же код будет просто пропускать абсолютные пути через неизмененные.

Похоже, нет способа исправить это в пользовательском пространстве, за исключениемОбширные исправления, поэтому я отправил запрос на извлечение в Cython с фактическим исправлением .После слияния вы сможете запустить:

cd C:\mypath\build\projects\cyt
python setup.py build_ext -b C:/mypath/build/bin -t .

, чтобы получить желаемый результат (-b и -t - это краткие формы --build-lib и --build-temp).

...