`pkgs.linuxManualConfig` no longer exists?

https://nixos.org/manual/nixpkgs/stable/#sec-linux-kernel says that there’s a function named pkgs.linuxManualConfig that can be used when “most of the common configuration has to be altered or disabled to achieve a kernel as expected by the target use case”, which is the situation I am in right now. It goes on to say that if you think you need this you should read the source code of the function very carefully, with a link into the nixpkgs Github repo – and that link is broken. It points at https://github.com/NixOS/nixpkgs/blob/d77bda728d5041c1294a68fb25c79e2d161f62b9/pkgs/os-specific/linux/kernel/build.nix, which brings up a 404 page for me.

If I look at the nixos-25.11 branch instead, pkgs/os-specific/linux/kernel/build.nix does exist, but it doesn’t appear to define a function named linuxManualConfig. Code search doesn’t find anything else that defines that function either. There is a file named pkgs/os-specific/linux/kernel/manual-config.nix on the 25.11 branch, but it doesn’t seem to be used by anything whatsoever.

So this is like 75% documentation bug report – the nixpkgs manual section on building custom kernels is out of date – and 25% plea for help: in 25.11 and going forward, how am I supposed to build a custom kernel if I want to start from scratch with the kernel configuration? (Ideally, also, without having to adjust configuration.nix every time the 25.11 channel pushes some kernel bugfixes.)

It’s defined at pkgs/top-level/all-packages.nix but that’s just a reference to linuxKernel.manualConfig which that’s referencing pkgs/os-specific/linux/kernel/build.nix.

The thing I didn’t understand when I originally posted this question is that, unlike how it is in more conventional programming languages, in Nix a file that defines a library routine often doesn’t give that routine a name.

all-packages.nix defines pkgs.linuxManualConfig to be an alias for pkgs.linuxKernel.manualConfig. linux-kernels.nix defines linuxKernel.manualConfig as

 manualConfig = callPackage ../os-specific/linux/kernel/build.nix { }; 

and callPackage is a thin wrapper around the import primitive … so, the file ../os-specific/linux/kernel/build.nix is expected to define a function, and the name pkgs.linuxManualConfig eventually comes to refer to that function, but kernel/build.nix doesn’t have to (and indeed can’t) give that function any name.

I thought linuxManualConfig had been removed because that name wasn’t present in kernel/build.nix, but that’s not how Nix works.

No, callPackage is a full blown dependency injection framework. Its first argument doesn’t even need to be a path.

2 Likes

Do you mean all the autoArgs stuff? None of that appears to be relevant to the question of where to look for the body of the definition of a function declared as <name> = callPackage <path> {}, which is the only thing I was talking about.

I am saying that framing “callPackage as a thin wrapper around import” is missleading. The use of callPackage completely changes how the function is made available and how you have to interprete the contents of the imported file.

The only thing I do agree with, sometimes you have to resolve one or two levels of import, even after git grep, though that is the easier part in understanding how a function actually works, once having found its actual definition in the code base.

Could you expand on this, please? Right now, for the cases I am currently staring at, it seems like callPackage is “just” a way to fake default values for function parameters, and when its second argument is {} it doesn’t even do that.

Please understand the dependency injection part of callPackage.

I have to admit, I am absolutely not a fan of using it for functions, but framing it as “thin wrapper” around anything but callPackageWith is plain wrong and misleading.

1 Like

Noogle gives you a link to both the attribute and function definition for this reason, by the way.

It’s worth noting that nix simply doesn’t have a way to declare function names, we’re just packing functions into attrsets which are arbitrary key/value mappings. But this also means it mostly comes down to style, we could deliberately always place functions in attrsets, and forbid this indirection that confused you, at the cost of some extra indentation.

I don’t think routine is the correct word in this context, as an aside, since “execution” in the procedural sense doesn’t really happen, but that’s really splitting hairs.

1 Like