5
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での設定方法と実行方法を紹介しました。

5
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
5
0