Skip to content

Instantly share code, notes, and snippets.

@m-ueno
Last active March 28, 2022 12:22
Show Gist options
  • Save m-ueno/f773f0e03a78eeedf7fcbd66db58ab24 to your computer and use it in GitHub Desktop.
Save m-ueno/f773f0e03a78eeedf7fcbd66db58ab24 to your computer and use it in GitHub Desktop.
14章補足資料

Cargo

リファレンス

The Cargo Book https://doc.rust-lang.org/cargo/

cargoとは (§2.1)

  • package manager
  • パッケージ管理にとどまらず、バイナリを作るための、あらゆる標準コマンドを提供する (-> §4)
  • crates.io : packageリポジトリ

dependencies (2.4, 3.1, 3.14)

依存パッケージの指定

# Cargo.toml
[dependencies]
rand = "0.8.3"
  • パッケージ名とsemantic versionで依存を指定する
  • <major>.<minor>.<patch>-<prerelease>+<build>
  • https://semver.org/
  • 注意
    • 言語によって微妙に表記が異なる
    • 0.xは開発バージョン. いつでも(破壊的)変更を加えてよい

overriding dependencies

crates.ioに未公開のバージョンのcrateに依存したいケースがある:

  • 手元でbugfixしたcrateを別のcrateから使う
  • 他人が作ったcrateの最新版masterを試したい
  • majorバージョンをpublish前にintegration testしたい
    • git branch指定してoverride
  • 書き方は[patch]の項を参照

依存パッケージの指定(詳細)

  • semver-compatible requirements
    • PythonやNodejsで~や^で範囲指定するやつ
  • 注意
    • 言語によって記号の意味が(結構)異なる
  • Caret requirements
    • 意味
      • 指定したバージョンから、最上位の非ゼロが変わらない限り最新のバージョンまで
    ^1.2.3  :=  >=1.2.3, <2.0.0
    ^1.2    :=  >=1.2.0, <2.0.0
    ^1      :=  >=1.0.0, <2.0.0
    ^0.2.3  :=  >=0.2.3, <0.3.0
    ^0.2    :=  >=0.2.0, <0.3.0
    ^0.0.3  :=  >=0.0.3, <0.0.4
    ^0.0    :=  >=0.0.0, <0.1.0
    ^0      :=  >=0.0.0, <1.0.0
    
  • ほかのrequirements記法は3.1節を参照
  • Rustでのお約束
    • 省略すると^ (caret) がつく. time = "1.2.3"time = "^1.2.3"は同じ
    • なるべくゆるく範囲指定する

バージョン解決

  • 依存ライブラリ群のバージョンを決定する方法

    • 制約充足問題 厳密解を得るのはNP困難 らしい
    • なのでパッケージマネージャごとに異なるヒューリスティクスが使われる
  • cargoでは、複数のパッケージが、共通のパッケージの別バージョンに依存する場合

    • semver compatibleなら、compatibility rangeを満たす最新のバージョン1つに決定
    • semver incompatibleなら、それぞれ別々のバージョンに依存する
    • 後者では version-incompatibility hazardsが起きる可能性がある
  • version-incompatibility hazards

    • https://doc.rust-lang.org/cargo/reference/resolver.html#version-incompatibility-hazards
    • 問題
      • 依存グラフにあるクレートの異なるバージョンが含まれると、それらの公開型を、それらの利用パッケージが(再)公開する場合に、衝突する
      A --> B --> C==2.0.0
       `--> D --> C==1.2.3
      
      • 例えばB,Dの公開APIが、C::Floatを使う場合が該当する?
    • 対策:semver trick
      • 簡単に言うと、非互換リリースをするとき(例 1.xが広く使われている状況で2.0.0をリリース)、新しいバージョンの型を旧バージョンでもre-exportしたポイントリリースを同時に発行する
  • dev-dependency, build-dependencyもある

その他もろもろ

  • manifest (3.2)

    • Cargo.toml
    • よくでてくるTOML記法: tableとarray of tables
      • tableはmapのこと
        • pythonのdict, JSONのobject
    # packageという名前のmap
    [package]
    name = "hello_world"
    version = "0.1.0"
    
    # 上と次の行は同じ
    package = { name = "hello_world", version = "0.1.0"}
    
    
    #
    # [[ ]] は mapのリスト
    # = array of tables
    [[bin]]
    name = "cool-tool"
    test = false
    bench = false
    
    [[bin]]
    name = "frobnicator"
    required-features = ["frobnicate"]
    
  • workspace (3.3)

    • Cargo.lockをシェアするパッケージ群
    • npm workspace, goのmoduleみたいな
  • features (3.4)

    • 条件付きコンパイル
    • cfg(features = "std")
    • featureごとにdependencyを分けられる
  • profiles (3.5)

    • ビルド(コンパイル)の設定を変える. 最適化、デバッグシンボル有無などなど
    • Cargo has 4 built-in profiles: dev, release, test, and bench
    • --release, --debugフラグ
  • configuration (3.6)

    • config.tomlにcargoの挙動を変える設定をかく
  • environment variables (3.7)

  • build script (3.8)

    • Makefile的な build.rs
    • rustc以外のコマンドを呼ぶときにつかう (例:Cのリンカを呼ぶ、code generatorを呼ぶ)
  • external tools (3.12)

    • cargoコマンドの出力をJSON形式にするオプションあり
    • cargo metadata
    • cargo-xxxという名のバイナリにパスを通せばサブコマンドxxxがつくれる (gitみたい)

crates.io

  • nodeのnpm, rubyのRubygemsのような中央リポジトリ
  • documentation
    • ドキュメンテーションコメント(3連スラッシュ)をレンダリングしてくれる
    • doctestもできる
    • 深い階層のモジュールは見づらい
      • -> トップレベルにre-export (pub use) すると見やすい
  • crates.ioにひとたび公開したら削除できない(取り下げはできる)
    • 秘密の情報publishしたらまずい
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment