Rustのtargetディレクトリをあるディレクトリ以下で共有する
Rustのビルドによるアーティファクトはビルドのキャッシュを含め、すべてtarget
ディレクトリに出力される。
デフォルトでは、target
ディレクトリはプロジェクトのルートディレクトリ、すなわち(ワークスペースであればワークスペースの)Cargo.toml
があるディレクトリに作成されるが、複数のプロジェクトで多くの同じパッケージを依存関係として持つ場合、同じものをプロジェクトごとにビルドすることになるため、ビルド時間的にもディスク容量的にもかなりの重複が生じることになる。
project-a/target/...
project-b/target/...
project-c/target/...
より高度な方法として、sccacheのようなツールを使うこともできるが、単純な方法として、Cargoの設定でtarget
ディレクトリに同じディレクトリを使うように指定することができる。
環境変数CARGO_TARGET_DIR
を設定したり、
export CARGO_TARGET_DIR="/path/to/shared/target"
$CARGO_HOME/config.toml
にbuild.target-dir
を設定したり、
[build]
target-dir = "/path/to/shared/target"
といった方法があるが、実はこれらより先に、現在のディレクトリ以上にある.cargo/config.toml
を下から上へと再帰的に読んでくれるという仕組みがあるので、これを使うと、プロジェクトごとだったり、親ディレクトリごとだったりに、target
ディレクトリを指定することもできる。
.cargo/config.toml
の相対パスは、.cargo
のあるディレクトリを基準として解釈される。
なので、例えば次のような.cargo/config.toml
を作成することで、そのディレクトリ以下のすべてのプロジェクトで同じtarget
ディレクトリ(.cargo/target
)を使うようにできる。
[build]
target-dir = ".cargo/target"
.cargo/config.toml
.cargo/target/...
project-a/
project-b/
project-c/
その際、あるプロジェクトだけ例外として扱いたい場合は、現在のディレクトリを含めてより近いディレクトリにある.cargo/config.toml
が優先されるので、そのプロジェクトのディレクトリに次のような.cargo/config.toml
を作成して、target
ディレクトリを指定すれば良い。
[build]
target-dir = "target"
例えば、project-c
にこのファイルを追加した場合、project-c
のビルド結果はproject-c/target
に出力されるようになる。
.cargo/config.toml
.cargo/target/...
project-a/
project-b/
project-c/.cargo/config.toml
project-c/target/...
このような使い方をする場合、.gitignore_global
などに.cargo/config.toml
を追加しておくと良いかもしれない。
.cargo/config.toml
ただし、その場合は逆にtarget
ディレクトリを.gitignore
に追加することを忘れないようにしなければならないだろう。
/target