type = "app"; AFAICT, the value is always"app". I guess it’s something to do with scope for future expansion. Or maybe it’s related to the (AFAICT undocumented) restriction that all flake outputs must be attribute sets.
program = <nix store path>;
I’m struggling to provide my app with the environment it needs to run successfully. Hacking around this problem with solutions such like this
apps.my-app-with-environment = let
my-app-env-setting-script = pkgs.writeShellScriptBin "my-app-with-environment" ''
export PATH=${pkgs.lib.makeBinPath [ self.packages.my-package-without-env ]}:$PATH
export LD_LIBRARY_PATH=${pkgs.lib.makeLibraryPath [ pkgs.dep1 pkgs.dep2 ] }:$LD_LIBRARY_PATH
export EXTRA_REQUIRED_ENV_VAR=<some meaningful value>
exec something-in-my-package "$@"
'';
in { type = "app"; program = "${my-app-env-setting-script}/bin/my-app-with-environment"; };
seems to be working, but
Is there really no higher level way of endowing an app with an environment? To a first order approximation, my apps need the same environment as provided by the flake’s devShell. Is there some way to reuse it for this purpose?
In my devShell, setting of things like EXTRA_REQUIRED_ENV_VAR in my example above, is done automatically by the dependecies’ setupHooks. Is there a way to take advantage of these hooks in my-app-env-setting-script?
I think the idiomatic solution is to write a package that uses makeWrapper to begin with, at which point this complexity is abstracted in the package definition and not the flake.
This would also factor out the env setting so both the devShell and the app can share it.
Any particular reason you set these variables, on that note? Those seem like things mkDerivation should be sorting out.
No, but specifically PATH and LD_LIBRARY_PATH shouldn’t be necessary if you compiled the application in question with nix, due to the whole thing where nix digs for store paths in the binary once built.
Is this a non-nix binary you’re repacking? Is it doing some things where it tries to search for binaries in PATH that should really be patched to static paths at build time? It all depends a bit on the application, but usually if you have a nix-built binary these specific env modifications shouldn’t be necessary.
Sometimes they are necessary, of course, which is why makeWrapper exists, I’m just asking because this smells like a complex scenario where knowing context is important to judge what the best way actually is.
The project is all about helping users write applications in the Geant4 framework.
We are providing a user-project template which contains a flake, whose outputs include a package/app which is an application written by the user: the user provides the main function, which is linked against Geant4 (as well as our own) libraries. I think that PATH and LD_LIBRARY_PATH are all set by Nix, automatically. This part seems fine.
However, any Geant4 application needs to know where various datasets are located, and the Geant4 libraries rely on a bunch of G4*DATA environment variables to find these.
Iirc, those are explicitly not supported by nix shell, as that was considered too nixpkgs-specific to be supported. It is supported by nix-shell and nix develop via mkShell.
There’s probably a way to execute the shell from mkShell and pass the binary to it directly, but I don’t know how.
Personally I think there’s a need for a library of helpers around outputs.apps that solve little UX problems like this one.
Yes, we know that hook exists (I pointed it out in my previous message), and it seems to be working in nix develop/direnv (the envvars are set correctly, without us having to do anything explicitly). But we have miserably failed to figure out how to do anything better in the app, than setting them by hand in the wrapper script.