{
  description = "PatOS is a minimal, immutable Linux distribution specialized for the Patagia Platform.";

  inputs = {
    flake-utils.url = "github:numtide/flake-utils";
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
  };

  outputs =
    {
      self,
      flake-utils,
      nixpkgs,
    }:
    flake-utils.lib.eachDefaultSystem (
      system:
      let
        pkgs = import nixpkgs { inherit system; };
      in
      {
        packages = {
          default = self.packages.${system}.image;
          image = pkgs.writeShellScriptBin "image" ''
            echo "make UKI..."
            echo ${self.packages.${system}.kernel.kernel}/bzImage
            ${self.packages.${system}.systemd.out}/usr/bin/ukify build \
            --linux ${self.packages.${system}.kernel.kernel}/bzImage \
            --initrd ./initrd.gz \
            --cmdline "console=ttyS0" \
            -o patos.efi
          '';

          kernel = pkgs.callPackage ./kernel { };
          glibc = pkgs.callPackage ./glibc { };
          mkinitrd = pkgs.writeShellScriptBin "mkinitrd" ''
            echo "make initrd..."
            mkdir -p out
            # copy systemd
            cp -r ${self.packages.${system}.systemd.out}/* out/
            pushd out

            chmod 755 etc usr/lib

            mkdir -p dev proc sys tmp root
            ln -sf usr/bin bin
            ln -sf usr/sbin sbin
            ln -sf usr/lib lib
            ln -sf usr/lib lib64

            ln -sf ../proc/self/mounts etc/mtab
            ln -sf usr/lib/systemd/systemd init

            ln -sf systemd/libsystemd-core-257.so usr/lib/
            ln -sf systemd/libsystemd-shared-257.so usr/lib/

            echo patos > ./etc/hostname
            cat <<EOF > ./etc/os-release
            NAME="Patos"
            PRETTY_NAME="Patos Platform"
            ID=patos
            EOF

            cat <<EOF > ./etc/passwd
            root::0:0:root:/root:/bin/sh
            bin:x:1:1:bin:/bin:/usr/bin/nologin
            daemon:x:2:2:daemon:/:/usr/bin/nologin
            mail:x:8:12:mail:/var/spool/mail:/usr/bin/nologin
            ftp:x:14:11:ftp:/srv/ftp:/usr/bin/nologin
            http:x:33:33:http:/srv/http:/usr/bin/nologin
            uuidd:x:68:68:uuidd:/:/usr/bin/nologin
            dbus:x:81:81:dbus:/:/usr/bin/nologin
            nobody:x:99:99:nobody:/:/usr/bin/nologin
            EOF
            chmod 644 ./etc/passwd

            cat <<EOF > ./etc/group
            root:x:0:root
            bin:x:1:root,bin,daemon
            daemon:x:2:root,bin,daemon
            sys:x:3:root,bin
            adm:x:4:root,daemon
            tty:x:5:
            disk:x:6:root
            lp:x:7:daemon
            mem:x:8:
            kmem:x:9:
            wheel:x:10:root
            ftp:x:11:
            mail:x:12:
            uucp:x:14:
            log:x:19:root
            utmp:x:20:
            locate:x:21:
            rfkill:x:24:
            smmsp:x:25:
            proc:x:26:
            http:x:33:
            games:x:50:
            lock:x:54:
            uuidd:x:68:
            dbus:x:81:
            network:x:90:
            video:x:91:
            audio:x:92:
            optical:x:93:
            floppy:x:94:
            storage:x:95:
            scanner:x:96:
            input:x:97:
            power:x:98:
            nobody:x:99:
            EOF
            chmod 644 ./etc/group

            # get shared libs
            find . -type f -executable | xargs ldd | awk '{print $3}' | grep -v systemd | sort -u | xargs cp -t usr/lib
            find . -type f -executable | xargs chmod 755

            # FIXME: hacky patch elf patching. Is there a better way????????
            find . -type f -executable -print | xargs -I {} ${pkgs.lib.getExe pkgs.patchelf} --set-rpath /lib {} 2> /dev/null
            find . -type f -executable -print | xargs -I {} ${pkgs.lib.getExe pkgs.patchelf} --set-interpreter /lib/ld-linux-x86-64.so.2 {} 2> /dev/null
            cp ${self.packages.${system}.glibc.out}/lib/ld-linux-x86-64.so.2 lib/
            ${pkgs.lib.getExe pkgs.patchelf} --remove-rpath lib/ld-linux-x86-64.so.2

            # gen initrd
            find . -print0 | ${pkgs.lib.getExe pkgs.cpio} --null --owner=root:root -o --format=newc | ${pkgs.lib.getExe pkgs.gzip} -9 > ../initrd.gz
          '';
          systemd = pkgs.callPackage ./systemd { };
        };

        checks = {
          simple-test = pkgs.runCommand "simple-test" { } ''
            ${self.packages.${system}.default}/bin/my-program
            touch $out
          '';
        };

        formatter = pkgs.nixpkgs-fmt;

        devShells.default = pkgs.mkShell {
          buildInputs = with pkgs; [
            erofs-utils
            just
            nixd
            nixfmt-rfc-style
            squashfs-tools-ng
          ];
        };

      }
    );
}