簡體   English   中英

CMake 使用 Homebrew 公式安裝 pybind11 綁定

[英]CMake install pybind11 bindings using Homebrew formula

我想為 CMake 項目提供 Homebrew 公式,該項目構建和安裝 C++ 庫及其使用 pybind1 編寫的 Python 綁定理想情況下,該公式應該通過運行一個普通的

cmake --build . --target install

此安裝流程在本地運行良好,但使用 Homebrew 公式會在 Python 綁定的安裝目錄中引入問題:雖然頭文件和庫安裝在由 #{prefix} 標識的 Cellar 的正確目錄中,但綁定需要位於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 單獨安裝綁定。

編輯(output 的示例,涉及目錄):

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

/usr/local/Cellar/python@3.9/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/python@3.9/3.9.2_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/pyariadne.so":
  Operation not permitted.

目錄/usr/local/Cellar/python@3.9/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 上驗證它:最新的 GitHub Actions 機器,其中唯一需要的步驟是 brew 安裝 package。

這篇關於 Homebrew 討論的帖子中找到了解決方案,該解決方案依賴於 libexec 目錄和 pth 文件創建:

  1. 在 CMake 中使用 libexec 作為安裝目標,使其以使用 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["python@3.9"].bin/"python3"
    (lib/"python#{python_version}/site-packages/homebrew-ariadne.pth").write <<~EOS
      import site; site.addsitedir('#{libexec}')
    EOS
  end

這是 Luca 的好解決方案的一個更好的 CMake實現 應該通過緩存變量直接引入 package 自定義點,而不是通過特定於打包程序的標志。 這是標准GNUInstallDirs模塊采用的方法。 見下文:

find_package(Python)

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

Python_SITEARCH默認值為MyProj_INSTALL_PYTHONDIR ,但可以在 package 腳本中覆蓋它:

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["python@3.9"].bin/"python3"
  (lib/"python#{python_version}/site-packages/homebrew-ariadne.pth").write <<~EOS
    import site; site.addsitedir('#{libexec}')
  EOS
end

這種方式明顯更好,因為 CMake 構建不再需要了解有關 Homebrew 的任何信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM