I was recently re-organizing a non-NixOS home-manager config. I already have it pretty modularized, and a few of the specific module files make use of options. I’m running into some unexpected issues with options being referenced before they’re defined though, that lead me to believe that modules may be getting imported breadth-first rather than depth-first like they clearly should be.
For example:
A top.nix contains the equivalent of
import = [
./general.nix
./specific.nix
];
general.nix contains the equivalent of
import = [
./theprogram.nix
];
theprogram.nix defines some options in addition to some config
specific.nix then makes use of the custom option from theprogram.nix, presuming it was already included due to depth-first module importing along the path top.nix → general.nix → theprogram.nix.
custom.theprogram.enablething = true;
However I get an error saying the custom.theprogram.enablething doesn’t exist and pointing me to the specific.nix file if I do this. But if I simply move the import of theprogram.nix to be from top.nix instead of from general.nix, so the import path is top.nix → theprogram.nix, instead of top.nix → general.nix → theprogram.nix, the problem no longer occurs.
Is this known behavior? Is there a good way around it?
In the real world this is a flake.nix with a long list of host configurations that all import a modules/shared.nix and a host-specific hosts/this_host.nix file. The modules/shared.nix is importing a list of application-specific nix files that should be used on all hosts, some of which include options. The host-specific (hosts/this_host.nix) file expects to be able to make use of options from some of those shared application nix files…
Order of module imports really shouldn’t matter; you have either discovered a bug or found some way to abuse the module system that it isn’t expecting. Can you share a working example?
If I move the ./modules/nixgl.nix from any of these per-host configs into the imports list inside the ./modules/all.nix (as just ./nixgl.nix), rebuilding (with --impure because nixGL) says the custom.nixGL.gpu option (defined in the modules/nixgl.nix file) isn’t defined within the hosts/${specific_host}.nix file.
Specifically, if I do the rebuild and switch for home-manager on aaravchen@helios300 or aaravchen2@laptopFedora, after moving the ./modules/nixgl.nix on lines 156 and 225 to be a line ./nixgl.nix in all.nix before line 24, doing a regbuild fails with the error that custom.nixGL.gpu (see nixgl.nix:25) isn’t defined when referenced in hosts/laptopFedora_aaravchen2.nix:31 or hosts/helios300_aaravchen.nix:33.
But how it’s currently written, where the nixgl.nix file is directly imported by the flake.nix is working file
An aside: --impure shouldn’t be necessary as long as you explicitly select the nixGL output that’s applicable to your gpu.
Anyway, I cloned the repo and applied the following diff to your config:
diff --git a/flake.nix b/flake.nix
index 5e55b16..9211326 100644
--- a/flake.nix
+++ b/flake.nix
@@ -222,7 +222,6 @@
./user.nix
./modules/all.nix
# must be included before use, which is everywhere
- ./modules/nixgl.nix
./hosts/helios300_aaravchen.nix
# self-manage fleek
{
diff --git a/hosts/helios300_aaravchen.nix b/hosts/helios300_aaravchen.nix
index dc3ef18..a4c0d08 100644
--- a/hosts/helios300_aaravchen.nix
+++ b/hosts/helios300_aaravchen.nix
@@ -1,7 +1,6 @@
{ pkgs, misc, lib, config, options, ... }: {
imports = [
- ../identities/personal.nix # set the default git identity
#../modules/fedora_shells.nix
../programs/terminator.nix
../programs/kitty.nix
diff --git a/modules/all.nix b/modules/all.nix
index 8d98af2..203369f 100644
--- a/modules/all.nix
+++ b/modules/all.nix
@@ -21,6 +21,7 @@
# "includes". By convention programs/ are for individual programs, while modules/ are less specific.
# WARNING: If any of these have options defined the import
imports = [
+ ./nixgl.nix
../programs/bash.nix
../programs/zsh.nix
And at least aaravchen@helios300 evals fine.
$ nix eval .\#homeConfigurations.aaravchen@helios300.activationPackage
warning: Git tree '/tmp/tmp.EE6GQQ6sWL/fleek-config' is dirty
«derivation /nix/store/lxqcqdgkyicw6m57ps9b9pgwbjghp46z-home-manager-generation.drv»
Yes, as long as nixgl.nix is in any import list in any module in the transitive closure of flake.nix, it should work (and does, based on the few tests I’ve run).
Huh, I must have made some other mistake I didn’t identify then. I assumed it would work like you described, and tried redoing it a few times with the same effect before I brought it here. But if I make the same changes now, it works just like you found as well.
What do you mean by “select the nixGL output that’s applicable to your gpu”? I’d love to do this if I knew how.
The documentation is really sparse and non-specific for how to apply the home-manager nixGL wrapper, and I have some systems that have iGPUs, some that have dGPUs, and some that are hybrids (Prime systems). I haven’t been able to find anything very clear anywhere in the forum that didn’t look to be very out of date, or unclear on how it would apply to a home-manager flake on a non-NixOS host (most info I’ve found seems to be non-flake based, or NixOS system only).
Use nixGLIntel or nixGLNvidia instead of letting it auto-select.
That makes no sense to me, nixgl would not be used on NixOS, the whole point is to fix issues outside of NixOS as the readme mentions.
Though in my experience, it’s a complete 50/50 if the project works or not.
Clarification: I was mixing up the home-manager nixGL and the vanilla nixGL.
Home-manager has nixGL support for automatically wrapping program binaries and desktop file calls to program binaries with nixGL commands. But because they tried to make it extra fancy, it has some options to select the specific GPU card based on PCIe bus for one of the wrappers, and unfortunately those options get evaluated even if you never use that wrapper, making it mandatory to build with --impure (right now) if you use the home-manager nixGL feature.
The home-manager nixGL feature includes support for using it on NixOS as well (the wrapping is sitll useful if you wanted to run a command using a specific GPU for example).