It is perfectly fine to just inline the package definition into environment.systemPackages
in your configuration.nix
:
# configuration.nix
{ pkgs }:
{
environment.systemPackages = [
(with pkgs; stdenv.mkDerivations {
# …
})
];
}
or if you prefer slightly cleaner
# configuration.nix
{ pkgs }:
{
environment.systemPackages =
let
mypkg = (with pkgs; stdenv.mkDerivations {
# …
});
in [
mypkg
];
}
Or if you want to pass it to multiple options, you can define it in wider scope.
# configuration.nix
{ pkgs }:
let
mypkg = (with pkgs; stdenv.mkDerivations {
# …
});
in {
environment.systemPackages = [
mypkg
];
systemd.packages = [
mypkg
];
}
If you like to keep your configuration.nix
clean, you can move the package definition to a separate file:
# configuration.nix
{ pkgs }:
{
environment.systemPackages = [
(import ./pkgs/mypkg { inherit pkgs; })
];
}
# pkgs/mypkgs/default.nix
{ pkgs }:
stdenv.mkDerivations {
# …
}
And if you expect you will want to move the package to nixpkgs
later, you might as well use the convention of accepting dependencies as separate arguments:
# configuration.nix
{ pkgs }:
{
environment.systemPackages = [
(pkgs.callPackage ./pkgs/mypkg { })
];
}
# pkgs/mypkgs/default.nix
{ stdenv, foo, bar }:
stdenv.mkDerivations {
# …
}
It is even nicer to use overlays, which will add the package to pkgs
passed to your configuration modules. They allow, among other things, easier re-use across repositories since they can be applied over different versions of Nixpkgs.
# configuration.nix
{ pkgs }:
{
environment.systemPackages = [
pkgs.mypkg
];
nixpkgs.overlays = [
(import ./overlays/pkgs)
];
}
# overlays/pkgs.nix
final: prev:
{
mypkgs = prev.callPackage ../pkgs/mypkgs {};
}
# pkgs/mypkgs/default.nix
{ stdenv, foo, bar }:
stdenv.mkDerivations {
# …
}
And of course, there are many more combinations in between. Nix is an expression based language so you can easily move expressions wherever fits your style.