Flake to produce shell script running in nix-shell-like environment

hello all, again!

I’m trying to make a flake’s output package that is a wrapper of some other thing.

so basically what I need is pkgs.writeShellApplication, but I need the environment of that shell script to be similar to what nix-shell -p produces, because whatever I’m wrapping may be calling to gcc and require some libraries, that I would provide like nix-shell -p xorg.libX11 for example…
writeShellApplication’s runtimeInput only affect PATH, so gcc running inside it cannot find libraries.

I have a feeling that I’m describing something really trivial, but I cannot quite figure out a good way to do this

Is this what you’re looking for?

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

  outputs = { self, nixpkgs, utils }:
    utils.lib.eachDefaultSystem (system:
      let
        pkgs = import nixpkgs { inherit system; };
      in
      {
        devShells.default = with pkgs; mkShell {
          
          packages = with pkgs; [
            # list packages you want to be in the path here ...
            gcc
            xorg.libX11
            zsh
            # additional custom scritps to be added to the path:
            (writeShellScriptBin "say-hello" ''
                echo "hello world!"
            '')
          ];
          shellHook = ''
            echo "Entering dev shell"
            exec zsh
          '';
        };
      }
    );
}
  • Add programs you want to install into the path in packages.
  • If you want stable, change ‘nixpkgs-unstable’ to ‘nixpkgs’.
  • Normally devshells run with bash, so I use ‘exec zsh’ in the shellHook so that it runs zsh. Replace zsh with your favorite shell, or remove the exec line and the zsh package if you want to use bash.

nix develop to build the flake and start the shell with your new environment.

1 Like

well, that’s the thing - i want the result of the build to be some executable script, so i can just run it and it sets the required environment, as if calling nix-shell -p ... itself, except i don’t want to wrap a call to nix-shell, as i want packages to be locked by flake’s lock

As a new nix user, I don’t know if this is considered “good practice”, but you can run nix develop with the script above, then echo export PATH="$PATH" > myscript, then exit the subshell. Then you can source myscript to change your path to include all the versions of stuff built by the flake. Is that what you’re trying to do?

The flake above sets other environment variables (such as, to help the linker find libX11), so you may need to add other necessary variables to the script from the devShell environment.
To me this seems a little more fragile than running the flake with ‘nix develop’ and entering the subshell. The flake would be reusable across machines, whereas the script may not be.
Hope that helps. If I didn’t understand your question, please LMK.

ah, interesting though of capturing environment.

I would try that, but I actually don’t know which env variables I need, it’s not just PATH.
That script will be running gcc, so it should gel all the other stuff that is set in nix package build environment for those dependent libraries.
I guess I could just capture it all, every env variable from the nix build process (instead of using nix develop that initializes the same env), but that does sound like an overkill, but on the other hand that does sound like A working solution…

thank you for that idea!