Вернуть каталоги include и runtime lib из Python

Допустим, я хочу использовать gcc из командной строки, чтобы скомпилировать расширение C для Python. Я бы структурировал вызов примерно так:

gcc -o applesauce.pyd -I C:/Python35/include -L C:/Python35/libs -l python35 applesauce.c

Я заметил, что параметры -I, -L и -l абсолютно необходимы, иначе вы получите ошибку, которая выглядит примерно так: это. Эти команды сообщают gcc, где искать заголовки (-I), где искать статические библиотеки (-L) и какую статическую библиотеку на самом деле использовать (python35, что на самом деле переводится как libpython35.a).

Теперь, очевидно, очень легко получить каталоги libs и include, если это ваша машина, поскольку они никогда не меняются, если вы этого не хотите. Однако я писал программу, которая вызывает gcc из командной строки, которую будут использовать другие люди. Строка, в которой происходит этот вызов, выглядит примерно так:

from subprocess import call
import sys
filename = applesauce.c
include_directory = os.path.join(sys.exec_prefix, 'include')
libs_directory = os.path.join(sys.exec_prefix, 'libs')

call(['gcc', ..., '-I', include_direcory, '-L', libs_directory, ...])

Однако у других будут другие платформы и другие структуры установки Python, поэтому простое объединение путей не всегда будет работать.

Вместо этого мне нужно решение внутри Python, которое будет надежно возвращать каталоги include и libs.

Редактировать:

Я просмотрел модуль distutils.ccompiler и нашел много полезных функций, которые частично используют distutils, но делают его настраиваемым для меня, чтобы сделать мой компилятор полностью кроссплатформенным. Единственное, мне нужно передать библиотеки include и runtime...

Редактировать 2:

Я посмотрел на distutils.sysconfig и могу надежно вернуть каталог «include», включая все файлы заголовков. Я до сих пор не знаю, как получить библиотеку времени выполнения.

Документы distutils.ccompiler находятся здесь

Программа, которой нужна эта функциональность, называется Cyther.


person Nick Pandolfi    schedule 31.03.2016    source источник


Ответы (2)


Если вы посмотрите на источник build_ext.py из distutils в методе finalize_options вы найдете код для разных платформ, используемый для поиска библиотек.

person totoro    schedule 09.04.2016
comment
Это то, что я искал. - person Nick Pandolfi; 09.04.2016

Самый простой способ скомпилировать расширения — использовать distutils, подобно этому;

from distutils.core import setup
from distutils.extension import Extension
setup(name='foobar',
      version='1.0',
      ext_modules=[Extension('foo', ['foo.c'])],
      )

Имейте в виду, что по сравнению с unix/linux, компиляция расширений для ms-windows не так просто, потому что разные версии компилятора ms тесно связаны с соответствующей библиотекой C. Таким образом, в ms-windows вы должны скомпилировать расширения для Python x.y с тем же компилятором, с помощью которого был скомпилирован Python x.y. Это означает использование старых и неподдерживаемых инструментов, например. Python 2.7, 3.3 и 3.4. Ситуация меняется (часть 1, part 2) с Python 3.5.

Редактировать: Изучив проблему подробнее, я сомневаюсь, что то, что вы хотите, достижимо на 100%. Учитывая, что инструменты, необходимые для компиляции и связывания, по определению находятся за пределами Python и что они даже не обязательно являются инструментами, с которыми был скомпилирован Python, информация в sys и sysconfig не гарантирует точного представления системы, которой на самом деле является Python. установлен на. Например. на большинстве машин с MS-Windows не будут установлены инструменты разработчика. И даже на платформах POSIX может быть разница между установленным компилятором C и компилятором, который построил Python, особенно когда он установлен как двоичный пакет.

person Roland Smith    schedule 02.04.2016
comment
Я делал это годами, и из-за багов и множества болезненных несовместимостей с distutils и vcvarsall.bat написал Cyther (pypi.python.org/). Мой вопрос - одна из текущих ошибок в Cyther. Я знаю, что это один из способов сделать это. Я просто не об этом спрашиваю, извините. - person Nick Pandolfi; 03.04.2016
comment
Какая платформа вызывает больше всего проблем? Windows, POSIX или OS-X? - person Roland Smith; 03.04.2016
comment
Используя distutils для компиляции, Windows доставляет мне самые трудные времена. Используя Cyther, Linux доставляет мне самые тяжелые времена - person Nick Pandolfi; 03.04.2016
comment
Как бы distutils вообще сделал это, если бы это было "невозможно" - person Nick Pandolfi; 06.04.2016
comment
Ну, если бы distutils было идеально, мы бы не говорили об этом... И я не говорю, что это невозможно, просто не на 100% надежно. - person Roland Smith; 07.04.2016