LoginSignup
0

More than 1 year has passed since last update.

nixとgit submodule

Last updated at Posted at 2021-12-20

目的

複数のレポジトリにあるプロジェクトを使って開発するときにgit submoduleを使うかと思います。
そのようなユースケースでnixとgit submoduleを組み合わせて使いたくなるかもしれません。
残念ながら、今の開発版のnix(2.6.0pre20211217_6e6e998)ではそのような使い方が難しいです。
なぜ難しいのか、今なら何ができるのか紹介します。

パッケージ作成:nix flakes

まず、nix & git submoduleでの使い方を紹介する前にnixでのパッケージの作り方としてのnix flakesについて簡単に説明します。

nixのパッケージはderivationですね。derivationはデフォルトのパッケージの集合であるnixpkgsから使用するパッケージや便利な関数、ビルドするソースとビルドするbashのスクリプトから構成されています。
nixpkgsはnixのスクリプトの中で<nixpkgs>となっています。これはパッケージをビルドする時の環境変数NIX_PATHが展開されます。
この環境変数はユーザーによって異なるため、そのまま使うと再現性のないパッケージが出来上がります。
それを防ぐためにnix flakesがあります。

nix flakesでは次のようなflake.nixファイルとそのロックファイルflake.lockを使います。
見てわかる通りnixpkgsのパスが埋め込まれています。ロックファイルには具体的なgitのハッシュ値が書かれます。

今回の話はこのnix flakesとgit submoduleを一緒に使うのが難しいという話です。

# Source: https://www.tweag.io/blog/2020-05-25-flakes/
{
  description = "A flake for building Hello World";

  inputs.nixpkgs.url = github:NixOS/nixpkgs/nixos-20.03;

  outputs = { self, nixpkgs }: {

    defaultPackage.x86_64-linux =
      # Notice the reference to nixpkgs here.
      with import nixpkgs { system = "x86_64-linux"; };
      stdenv.mkDerivation {
        name = "hello";
        src = self;
        buildPhase = "gcc -o hello ./hello.c";
        installPhase = "mkdir -p $out/bin; install -t $out/bin hello";
      };
  };
}

nixとgit submoduleの現状

nix flakesではbuiltins.fetchTree関数でソースを取り込むのですが、デフォルトでgit submoduleを使わない設定になっていました。
そこで#4922のPRでデフォルトonにするように変更が加えられました。
しかし、パフォーマンスの問題があり、再びデフォルトoffに戻されています。(discourseのソース

そのため、ユーザー定義によってgit submoduleを有効化する方法デフォルトonにする方法が模索されています。

そのうち実行可能ものがsubmodules=1というパラメータをあたえて有効化する方法です。#5434
これを使った方法を次に紹介します。

nixでgit submodulesを使う方法

nixでgit submodulesを使うためにflake.nixを編集します。
nix flakesのinputsにsubmoduleへのパスを設定します。(この機能は#5279で実装されています。)
例えばmy-subdirディレクトリのsubmoduleをinputsにいれるには下記のようにします。

# Source: https://www.tweag.io/blog/2020-05-25-flakes/
{
  description = "A flake for building Hello World";

  inputs.nixpkgs.url = github:NixOS/nixpkgs/nixos-20.03;
  inputs.my-submodule.url = path:./my-subdir; #ここに追加
  outputs = { self, nixpkgs, my-submodule }: {
#あと省略

そのあとnixでgit submodulesは有効にするために..?submodules=1に書き換えて各種コマンドを実行します。

パッケージのリストを出す場合は次のようになります。

# git submoduleがない通常の場合
nix flake show .
# git submoduleがある場合
nix flake show .?submodules=1

また、パッケージの作成する場合は下記のようになります。
この例ではhelloパッケージ(derivation)を作成します。

# git submoduleがない通常の場合
nix build .#hello
# git submoduleがある場合
nix build .?submodules=1#hello

まとめ

nix flakesの簡単な紹介のあと、nixとgit submodulesを一緒に使うために、nix flakesでの設定方法と実行方法を紹介しました。

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
What you can do with signing up
0