1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

rattler-buildにおけるcondaパッケージ作成の注意点

Last updated at Posted at 2024-10-30

概要

ここではcondaビルド済みパッケージを作成する際に、躓いた点について備忘録的にまとめていく。

目次

  • rattler-buildとは
  • build環境とhost環境
  • run_exportsについて
  • stdlib("c")の設定
  • cmakeにおけるbuildスクリプトの書き方基本
  • テスト時におけるソースコードの利用
  • platform-specific noarch package

rattler-buidとは

prefix.dev社が開発しているRustを使って開発されている次世代のcondaパッケージ作成ツールである。conda-buildと同様なyaml形式のレシピ(meta.yaml ではなく recipe.yaml)を作成し、それに基づいてpypiにおけるwheel形式のような、conda用のビルド済み配布物(.condaファイル)の作成を行う。
詳しくはこちらのブログから: https://prefix.dev/blog/the_new_rattler_build

build環境とhost環境

condaビルドを行う際、build環境とhost環境がある。build環境はソースコードをビルドする環境、host環境はビルド済み配布物をインストールする環境である。そのため、host環境はtarget_platformとも呼ばれ、cross-compiling (例えば、linux-64からlinux-aarch64 (intelからARM)のコンパイルを行うこと)の際にも使用される。
また、それぞれの環境に必要なパッケージが異なり、build、host環境で必要となるパッケージはそれぞれ

  • buildtimeに必要なパッケージ (cmake, gcc, meson, pkg-configなどのコンパイラー・ビルドツール)
  • コンパイラ時にリンクするパッケージ (libboost, glib, hdf5, pythonなどのsharedライブラリやpythonライブラリ)
    である。

Python-C++ライブラリにおけるrecipe.yamlのrequirementセクションの例として以下のように設定する。

recipe.yamlの一部
requirements:
  build:
    - ${{ compiler("c") }}
    - ${{ compiler("cxx") }}
    - ${{ stdlib("c") }}
    - git
    - cmake
    - ninja
    - pkg-config
  host:
    - pip
    - python
    - numpy
    - cython
    - setuptools
    - setuptools-scm
    - scikit-build-core
    - scikit-build
    - libboost-devel
    - hdf5

このとき、libboost-develパッケージをbuildセクションに移動させると、build時に以下のようなエラーが表示される。

file Multiple conflicting paths found for libc++.1.dylib:
  $BUILD_PREFIX/lib//libc++.1.dylib
  $PREFIX/lib/libc++.1.dylib

これはコンパイル時のリンクで-Wl,-rpath,$BUILD_PREFIX/lib $BUILD_PREFIX/lib/libboost_filesystem.dylib-ldl $BUILD_PREFIX/lib/libboost_atomic.dylibが追加されるため、conflictionが起きていると思われる。

参考: https://prefix-dev.github.io/rattler-build/latest/compilers/#cross-compilation

run_exportsについて

ビルド時にリンクしたライブラリ(shared library等)はruntime環境でも必要になる。そのため、hostやbuildのrequirementで指定したパッケージをruntimeでのrequirementにも自動で追加させるためにrun_exportsが必要となる。

recipe.yaml
requirements:
    run_exports: my-package

例えば、numpyをhost環境のrequirementとして指定した場合、runtime環境でのrequirementに明示的に指定する必要はない。レシピ作成者がリンク時に利用したものと同じバージョンのnumpyを自動的にruntime環境で指定してくれる。

参考: https://prefix-dev.github.io/rattler-build/latest/reference/recipe_file/#run-exports

stdlib("c")の設定

build環境で${{ compiler("c") }}を指定する場合、conda-forgeにおいてC言語のstandard libraryをstdlib("c")として明示的に指定する必要がある。
参照: https://conda-forge.org/news/2024/03/24/stdlib-migration/

conda-forgeにおいてcompilerやstdlibは、conda_build_config.yamlにあるデフォル値によって決まるが、ローカルなPC環境でratller-buildを用いる場合、variants.yamlを手動で作成する必要がある。LinuxとmacOSにおけるC言語のstdlibのみを設定する場合、以下のようになる。

variants.yaml
c_stdlib:
  - if: linux
    then: sysroot
  - if: osx
    then: macosx_deployment_target

c_stdlib_version:
  - if: linux
    then: 2.17
  - if: osx and x86_64
    then: 10.13
  - if: osx and arm64
    then: 11.0

また、このファイルにpythonのバージョンを複数設定することで、github actionにおけるmatrixのような、複数ビルドも可能となる。(conda-forgeのconda_build_config.yamlのpythonセクションを参照)

cmakeにおけるbuildスクリプトの書き方基本

cmakeをbuild requirementに指定した場合、CMAKE_ARGSなど自動的に設定される。
また、cmakeにおけるPython_EXECUTABLEを、Host環境上のpythonに指定する必要がある。
以下にcmakeninjaを用いたビルド・コンパイルスクリプト(build.sh)の例を示す。

build.sh
#!/bin/bash

# CMake extra configuration:
extra_cmake_args=(
    -G Ninja
    -DCMAKE_INSTALL_LIBDIR=lib
    -DBUILD_SHARED_LIBS=ON
    # Python bindings
    -DPython_EXECUTABLE="$PYTHON"
    -DPython3_EXECUTABLE="$PYTHON"
)

cmake ${CMAKE_ARGS} "${extra_cmake_args[@]}" \
    -DCMAKE_PREFIX_PATH=$PREFIX \
    -DCMAKE_INSTALL_PREFIX=$PREFIX \
    -B build -S $SRC_DIR

# Build and install
ninja
ninja install

ビルド時のデフォルト環境変数についてはこちらを参照

参考: https://conda-forge.org/docs/maintainer/knowledge_base/#using-cmake

テスト時におけるソースコードの利用

ビルド配布物を作成後、rattler-buildではテストが行われる。その際、ビルド環境は削除され、ソースコードへのパスである$SRC_DIRも利用できない。
テスト環境へ、ソースコードにあるテストスクリプトや設定ファイルをコピーするためにはrecipe.yamlのtestセクションを以下のように設定する。

recipe.yamlの一部
tests:
  - script:
      - pytest
    files:
      source:
        - python/tests/
        - pyproject.toml
    requirements:
      run:
        - pytest

ここではpytestを用いたテストスクリプトを想定している。script:におけるfile: sources:にテスト時必要となるファイルをソースフォルダからコピーできる。

参考: https://prefix-dev.github.io/rattler-build/latest/reference/recipe_file/#extra-test-files

Platform-specific noarch package

noarchパッケージとはpure-PythonパッケージのようなCPU architectureやOSに依存しない(コンパイラされたバイナリーファイルを含まない)パッケージである。しかし、例えば、activationスクリプトを含める場合や、runtime依存にOS依存がある場合、プラットフォーム(OS)依存のnoarchパッケージが必要となる。
このとき、conda-forgeでのビルドであればこれを達成できる。

方法

recipe.yamlのrun requirementにてターゲットOSを示すvirtual packages: __linux, __osx, __win, __unixを加える。(__unixはLinuxとMacOS両方を示す。)

recipe.yaml
build:
  number: 0
  noarch: python
requirements:
  # ...
  run:
    - python >=${{ python_min }}
    - numpy
    - if: linux
      then:
        - __linux
        - linux-only-dependency 
    - if: osx
      then:
        - __osx
        - osx-only-dependency
    - if: win
      then:
        - __win
        - windows-only-dependency

conda-forgeにおいて、noarchだとlinux_64のCIランナーしかデフォルトで走らないが、複数のビルドplatformを走らせたい場合はconda-forge.yamlnoarch_platformsに追加する。

conda-forge.yaml
noarch_platforms:
  - linux_64
  - osx_64
  - win_64

参照: https://conda-forge.org/docs/maintainer/knowledge_base/#noarch-packages-with-os-specific-dependencies

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?