Поиск каталога сайтов-пакетов python с помощью CMake

Я использую CMake для создания своего приложения. Как я могу найти, где находится каталог сайтов-пакетов python? Мне нужен путь, чтобы скомпилировать расширение для python.

CMake должен быть в состоянии найти путь во всех трех основных ОС, поскольку я планирую развернуть свое приложение на Linux, Mac и Windows.

я пытался использовать

include(FindPythonLibs)
find_path( PYTHON_SITE_PACKAGES site-packages ${PYTHON_INCLUDE_PATH}/.. )

однако это не работает.

Я также могу получить путь, запустив

python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"

в оболочке, но как мне вызвать это из CMake?

РЕШЕНИЕ:

Спасибо, Алекс. Итак, команда, которая дает мне каталог сайта-пакета:

execute_process ( COMMAND python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()" OUTPUT_VARIABLE PYTHON_SITE_PACKAGES OUTPUT_STRIP_TRAILING_WHITESPACE)

Команда OUTPUT_STRIP_TRAILING_WHITESPACE необходима для удаления завершающей новой строки.


person D R    schedule 07.08.2009    source источник
comment
Просто для дальнейшего использования; Я нашел этот отличный пакет: github.com/lyricat/Hotot/tree/master/ cmake/модули   -  person dashesy    schedule 28.02.2013
comment
Для тех, кто использует python 3.x, оператор print должен читать: print(get_python_lib())   -  person wesanyer    schedule 19.04.2018


Ответы (4)


Вы можете выполнять внешние процессы в cmake с помощью execute_process (и получить вывод в переменную, если это необходимо, как здесь).

person Alex Martelli    schedule 07.08.2009
comment
Это похоже на взлом. Это все еще (после шести лет) путь? - person Torsten Bronger; 20.05.2015
comment
@TorstenBronger Почему это взлом? CMake нужно откуда-то получить информацию, так почему бы не спросить, кто знает лучше, то есть непосредственно Python? - person kynan; 17.02.2017
comment
FWIW, мое намерение использовать CMake состоит в том, чтобы использовать его для абстрагирования от таких вещей. - person Torsten Bronger; 08.03.2017
comment
Вероятно, это взлом, но теперь он взломан Официально CMake: Python_SITELIB / Независимый каталог установки сторонней платформы. / Информация возвращена distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=False). - person FeRD; 17.09.2019

Слегка обновленная версия, которую я использовал для lcm:

execute_process(
  COMMAND "${PYTHON_EXECUTABLE}" -c "if True:
    from distutils import sysconfig as sc
    print(sc.get_python_lib(prefix='', plat_specific=True))"
  OUTPUT_VARIABLE PYTHON_SITE
  OUTPUT_STRIP_TRAILING_WHITESPACE)

Это устанавливает PYTHON_SITE в соответствующий путь относительно префикса, подходящий для использования, например:

install(
  FILES ${mypackage_python_files}
  DESTINATION ${PYTHON_SITE}/mypackage)

(Пожалуйста, не устанавливайте абсолютный путь! Это обходит CMAKE_INSTALL_PREFIX.)

person Matthew    schedule 12.10.2016
comment
Какой смысл в if True:? Только для того, чтобы вы могли сделать отступ в оставшихся двух строках? - person kynan; 16.02.2017
comment
Именно так: чтобы встроенный скрипт не разбивался в отступы окружающего кода CMake. - person Matthew; 17.02.2017

Начиная с CMake 3.12 вы можете использовать модуль FindPython, который заполняет переменные Python_SITELIB и Python_SITEARCH для архитектурно-независимые и специфичные библиотеки соответственно.

Пример:

find_package(Python ${PYTHON_VERSION} REQUIRED COMPONENTS Development)
Python_add_library(foo MODULE
    src/foo.cc src/python_interface.cc
)
install(TARGETS foo DESTINATION ${Python_SITEARCH}/foo)
person Erbureth says Reinstate Monica    schedule 18.09.2018
comment
Проблема в том, что Python_SITEARCH / Python_SITELIB / и т. д. являются абсолютными путями, что (как отмечает @Matthew выше) делает их непригодными для install(), поскольку это нарушит обработку CMAKE_INSTALL_PATH. - person FeRD; 17.09.2019
comment
@FeRD Это будет только половина перерыва, CMAKE_INSTALL_PATH по-прежнему соблюдается, но к нему будет добавлен весь абсолютный путь, например. г. /builds/python-foo/debian/python3-foo/usr/lib/python3/dist-packages/foo/foo.so Идеальным решением было бы вообще не использовать CMake для установки, однако это решение отлично работает для пакетов Debian. - person Erbureth says Reinstate Monica; 29.09.2019
comment
Вы действительно проверяли это? По моему опыту, это неправильно. И я цитирую из документацию CMake для install: если указывается полный путь (с косой чертой или буквой диска), он используется напрямую. Если задан относительный путь, он интерпретируется относительно значения переменной CMAKE_INSTALL_PREFIX. Указанный вами путь является примером пути к каталогу сборки, который отличается от пути install. (Трюк с вызовом get_python_lib(prefix=''), как это делает Мэтью выше, работает... но CMake этого не делает.) - person FeRD; 30.09.2019
comment
@FeRD У меня есть, хотя только как часть процесса создания пакета Debian. Путь из моего предыдущего комментария взят из вывода команды make install, которая запускается механизмом debhelper. - person Erbureth says Reinstate Monica; 30.09.2019
comment
Интересный. Возможно ли, что debhelper использует DESTDIR вместо CMAKE_INSTALL_PREFIX? DESTDIR (в качестве аргумента make, например, make install DESTDIR=/some/install/path) добавляет префикс даже к абсолютным путям. - person FeRD; 30.09.2019
comment
@FeRD Я не уверен, похоже, он использует cmake напрямую. Вот анонимный журнал сборки, если вы можете найти в нем что-то: pastebin.com/TazFVxMZ - person Erbureth says Reinstate Monica; 30.09.2019
comment
Да, вот она, строка 168: dh_auto_install --buildsystem=cmake --builddirectory="/builds/python_foo/.pybuild/pythonX.Y_2.7/build" --destdir="/builds/python_foo/debian/python-foo" На самом деле установка CMake вообще никогда не использует CMAKE_INSTALL_PREFIX. - person FeRD; 30.09.2019

Я предлагаю использовать get_python_lib(True), если вы делаете это расширение как динамическую библиотеку. Этот первый параметр должен быть истинным, если вам нужно местоположение для конкретной платформы (в 64-битных машинах Linux это может быть /usr/lib64 вместо /usr/lib)

person Ruben    schedule 29.03.2010