🗂

Juliaのプロジェクト環境とパッケージ (2)

2023/05/27に公開

前回の記事を拡張して、複数の開発中のパッケージ間の連携を取る方法を解説します。

入門用の記事のため、

  • 依存性においてバージョンを指定しない

などの簡略化を行っています。これらの内容は、パッケージのバージョン管理、GitHubとの連携を学んだ後、導入します。

AnotherMyPackageの作成

前回と同様に、~/workspace/以下に、AnotherMyPackageを作成しましょう。

using Pkg
Pkg.generate("AnotherMyPackage")

~/workspace/AnotherMyPackage以下の構成はこのようになっているはずです。

AnotherMyPackage
├── Project.toml
└── src
    └── AnotherMyPackage.jl

Project.tomlは以下の様になっています (UUIDはもちろん一致しません)。

name = "AnotherMyPackage"
uuid = "adf45001-a329-49be-8890-7478aa02962a"
authors = ["Hiroshi Shinaoka <h.shinaoka@gmail.com>"]
version = "0.1.0"

AnotherMyPackageへの依存性の追加

では、前回作ったMyPackageをAnotherMyPackage環境に開発モードでインストールすると同時に、依存性を追加してみましょう。

> cd ~/workspace/AnotherMyPackage
> julia
(@v1.9) pkg> # ]キーを押してパッケージモードへ
(@v1.9) pkg> activate .
  Activating project at `~/workspace/AnotherMyPackage`

(AnotherMyPackage) pkg> dev ~/workspace/MyPackage
   Resolving package versions...
    Updating `~/workspace/AnotherMyPackage/Project.toml`
  [eb66ca03] + MyPackage v0.1.0 `~/workspace/MyPackage`
    Updating `~/workspace/AnotherMyPackage/Manifest.toml`
  [eb66ca03] + MyPackage v0.1.0 `~/workspace/MyPackage`
(以下略)

Project.tomlに、依存性が無事追加されました。

name = "AnotherMyPackage"
uuid = "adf45001-a329-49be-8890-7478aa02962a"
authors = ["Hiroshi Shinaoka <h.shinaoka@gmail.com>"]
version = "0.1.0"

[deps]
MyPackage = "eb66ca03-d5f6-4852-a7de-5dc300cf5d77"

Manifest.tomlには、他のパッケージと同様に、MyPackageの情報 (pathなど)が追加されています。

[[deps.MyPackage]]
deps = ["LinearAlgebra"]
path = "/path/to/your/homedirectory/workspace/MyPackage"
uuid = "eb66ca03-d5f6-4852-a7de-5dc300cf5d77"
version = "0.1.0"

AnotherMyPackage環境から、MyPackageパッケージをimportするには、以下の様に行います。

julia> using Pkg; Pkg.activate("~/workspace/AnotherMyPackage")
  Activating new project at `~/workspace/AnotherMyPackage/~/workspace/AnotherMyPackage`
julia> import MyPackage
julia> MyPackage.greet()
Hello World!

ここで、MyPackageをパッケージ (=ライブラリ)として呼び出しただけで、MyPackage環境は有効にしていないことに注意しましょう。

依存パッケージのProject.tomlを更新した場合

julia> using Pkg; Pkg.activate("~/workspace/MyPackage")
  Activating new project at `~/workspace/MyPackage/~/workspace/MyPackage`

julia> Pkg.add("Random")
   Resolving package versions...
    Updating `~/workspace/MyPackage/~/workspace/MyPackage/Project.toml`
  [9a3f8284] + Random
    Updating `~/workspace/MyPackage/~/workspace/MyPackage/Manifest.toml`
  [9a3f8284] + Random
  [ea8e919c] + SHA v0.7.0
  [9e88b42a] + Serialization

次に、MyPackage/src/MyPackage.jlに、Randomパッケージのimportを追記します。

module MyPackage

import LinearAlgebra
import Random # 新しく追記

greet() = print("Hello World!")

# Compute dot
function mydot(x, y)
    return LinearAlgebra.dot(x, y)
end

end # module MyPackage

次に新しいREPLを起動して、AnotherMyPackage環境から、MyPackageをimportすると、以下の様なエラーが出ると思います。

julia> using Pkg; Pkg.activate("~/workspace/AnotherMyPackage")
  Activating new project at `~/workspace/MyPackage/~/workspace/AnotherMyPackage`

julia> using MyPackage
[ Info: Precompiling MyPackage [eb66ca03-d5f6-4852-a7de-5dc300cf5d77]
ERROR: LoadError: ArgumentError: Package MyPackage does not have Random in its dependencies:
- You may have a partially installed environment. Try `Pkg.instantiate()`
  to ensure all packages in the environment are installed.
- Or, if you have MyPackage checked out for development and have
  added Random as a dependency but haven't updated your primary
  environment's manifest file, try `Pkg.resolve()`.
- Otherwise you may need to report an issue with MyPackage

これは、前回の記事で見たもに非常によく似ています。MyPackageパッケージの依存性の変化が正しく、AnotherMyPackage側に反映されていません。エラーメッセージに従い、AnotherMyPackage環境のパッケージモードでresolveを実行すれば直ります。

(AnotherMyPackage) pkg> resolve
  No Changes to `~/workspace/AnotherMyPackage/Project.toml`
    Updating `~/workspace/AnotherMyPackage/Manifest.toml`
  [9a3f8284] + Random
  [ea8e919c] + SHA v0.7.0
  [9e88b42a] + Serialization
julia> import MyPackage # import成功!

[注意] もし、MyPackageがグローバル環境に開発モードで追加されていた場合、グローバル環境側でもPkg.resolve()関数を呼び出して依存関係を解決する必要があります。

Discussion