CMake устанавливает привязки pybind11 с использованием формулы Homebrew

Я хотел бы предоставить формулу Homebrew для проекта CMake, который создает и устанавливает библиотеку C ++ вместе с ее привязками Python, написанными с использованием pybind11. Формула в идеале должна работать при запуске простого

cmake --build . --target install

Этот процесс установки отлично работает локально, но использование формулы Homebrew создает проблему в каталоге установки для привязок Python: в то время как заголовки и библиотеки устанавливаются в соответствующий каталог в Cellar, обозначенном # {prefix}, привязки должны быть в каталог сайтов-пакетов, видимый Python. Я получаю такой каталог в CMake, используя

install(TARGETS pyariadne DESTINATION ${Python_SITEARCH})

но похоже, что каталог не доступен для записи Homebrew, возвращая Operation not permitted. Определение каталога установки по следующим

execute_process(COMMAND python3 -m site --user-site OUTPUT_VARIABLE INSTALL_DIR)

также не работает, поскольку Homebrew определяет временный пользовательский сайт в / tmp, и, следовательно, любая установленная там библиотека впоследствии удаляется.

Как мне установить все из Homebrew, не прибегая к изменению прав доступа к каталогам? Я бы хотел избежать упаковки для pypi и использования pip для отдельной установки привязок.

РЕДАКТИРОВАТЬ (пример вывода, задействованные каталоги):

[109/110] Install the project...
-- Install configuration: "Release"
-- Installing: 

/usr/local/Cellar/[email protected]/3.9.2_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/pyariadne.so
CMake Error at cmake_install.cmake:49 (file):
  file INSTALL cannot copy file
  "/tmp/ariadne-20210305-1763-ggejxl/ariadne-2.1-rc2/build/pyariadne.so" to
  
"/usr/local/Cellar/[email protected]/3.9.2_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/pyariadne.so":
  Operation not permitted.

Каталог /usr/local/Cellar/[email protected]/3.9.2_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages ссылается на /usr/local/lib/python3.9/site-packages. У первого есть пользователь lgeretti: staff, у второго - пользователь lgeretti: admin.

Эта проблема возникает не только на моем компьютере, но я также проверяю ее на компьютере macos: latest GitHub Actions, где единственный необходимый шаг - это заварить установку пакета.


person Luca Geretti    schedule 05.03.2021    source источник
comment
Вы уверены, что используете Python, установленный Homebrew, а не системный по умолчанию? Каталоги Homebrew должны быть доступны для записи пользователем.   -  person Alex Reinking    schedule 05.03.2021
comment
Я позитивен. Я добавил пример вывода в исходный пост.   -  person Luca Geretti    schedule 06.03.2021
comment
Вы запустили brew doctor и убедились, что проблем с установкой нет?   -  person Alex Reinking    schedule 06.03.2021
comment
заварить доктор в порядке. Внизу OP я добавил задействованные каталоги и группу user: для каждого, хотя я не ожидал, что возникнут какие-то проблемы с привилегиями пользователей.   -  person Luca Geretti    schedule 06.03.2021


Ответы (2)


Это лучшая реализация хорошего решения Луки в CMake. Точки настройки пакета следует вводить непосредственно через переменную кеша, а не специфичный для упаковщика флаг. Это подход, используемый стандартным модулем GNUInstallDirs. См. ниже:

find_package(Python)

set(MyProj_INSTALL_PYTHONDIR "${Python_SITEARCH}"
    CACHE STRING "Install destination for Python targets")
install(TARGETS pyariadne DESTINATION "${MyProj_INSTALL_PYTHONDIR}")

Значение по умолчанию для MyProj_INSTALL_PYTHONDIR - Python_SITEARCH, но его можно переопределить в сценарии пакета:

def install
  mkdir "build" do
    system "cmake -G \"Ninja\" .. -DCMAKE_BUILD_TYPE=Release " \
           "-DMyProj_INSTALL_PYTHONDIR=libexec -DCMAKE_INSTALL_PREFIX=#{prefix}"
    system "cmake", "--build", ".", "--target", "install", "--parallel"
  end

  python_version = Language::Python.major_minor_version Formula["[email protected]"].bin/"python3"
  (lib/"python#{python_version}/site-packages/homebrew-ariadne.pth").write <<~EOS
    import site; site.addsitedir('#{libexec}')
  EOS
end

Этот способ значительно лучше, потому что сборке CMake больше не нужно ничего знать о Homebrew.

person Alex Reinking    schedule 06.03.2021
comment
Спасибо, это действительно чище, чем использованный мной флаг состояния. - person Luca Geretti; 07.03.2021

Нашел решение в этом посте в обсуждениях Homebrew, которые опираются на каталог libexec и pth создание файла:

  1. Используйте libexec в качестве цели установки в CMake, сделав это условием использования Homebrew, а не локальной установки:
  if (HOMEBREW)
      install(TARGETS pyariadne DESTINATION libexec)
  else()
      find_package(Python)
      install(TARGETS pyariadne DESTINATION ${Python_SITEARCH})
  endif()
  1. Задайте в формуле следующее, чтобы создать файл .pth:
  def install
    mkdir "build" do
      system "cmake -G \"Ninja\" .. -DCMAKE_BUILD_TYPE=Release -DHOMEBREW=1 -DCMAKE_INSTALL_PREFIX=#{prefix}"
      system "cmake", "--build", ".", "--target", "install", "--parallel"
    end

    python_version = Language::Python.major_minor_version Formula["[email protected]"].bin/"python3"
    (lib/"python#{python_version}/site-packages/homebrew-ariadne.pth").write <<~EOS
      import site; site.addsitedir('#{libexec}')
    EOS
  end
person Luca Geretti    schedule 06.03.2021
comment
Здорово, что вы нашли решение! Но это не лучший способ делать что-то в CMake. См. Мой ответ для чего-то более надежного. - person Alex Reinking; 06.03.2021