I have a utility program written in Haskell. I have successfully built it using nix-build jot.nix
. But now I would like to install it in NixOS and have it be available on $PATH.
I have read what the NixOS manual says about custom packages, but I think that example is for an autotools build, and I can’t figure out how to adapt that example to my situation. I think some changes need to be made to jot.nix.
I anticipate that my /etc/nixos/configuration.nix would look like this:
{ config, pkgs, ... }:
{
imports =
[ # Include the results of the hardware scan.
/etc/nixos/hardware-configuration.nix
/etc/nixos/R.nix
/home/amy/jot/jot.nix
];
. . .
environment.systemPackages = with pkgs; [
. . .
jot
. . .
];
. . .
jot.nix:
let
pkgs = import <nixpkgs> { };
in
{ jot = pkgs.haskellPackages.callPackage ./default.nix { };
}
And here’s default.nix, which was created using cabal2nix
, time
}:
mkDerivation {
pname = "Jot";
version = "1.1";
src = ./.;
isLibrary = false;
isExecutable = true;
executableHaskellDepends = [
base cmdargs directory filepath process time
];
license = stdenv.lib.licenses.publicDomain;
}
You’re pretty close.
the short way is to add this to the top of you configuration.nix:
let
jot = pkgs.haskellPackages.callpackage /home/amy/jot/jot.nix {};
in {
environment.systemPackages = [ jot ] ++ (with pkgs; [ ... ]);
#or alternatively (depending on stylistic preference
environment.systemPackages = with pkgs; [ jot ... ];
...
}
the advantage of the former is that it won’t create any conflicts with pkgs.jot
in the event that such a package exists. I’m not certain which it would choose in the event of a conflict so I always to the the first way for safety.
Down the line you might consider adding several custom packages, and you might want those packages to be visible to nix-env. To accomplish that you can do:
configuration.nix
let
mypkgs = import ./mypkgs.nix {};
in {
nix.nixPath = [
"nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixos/nixpkgs"
"nixos-config=/etc/nixos/configuration.nix"
"mypkgs=/etc/nixos/mypkgs.nix"
"/nix/var/nix/profiles/per-user/root/channels"
];
environment.systemPackages = (with mypkgs; [ jot foo ]) ++ (with pkgs; [ bar baz ]);
}
mypkgs.nix
{ system ? builtins.currentSystem }:
let
pkgs = import <nixpkgs> { inherit system; };
callPackage = pkgs.lib.callPackagesWith (pkgs // self);
self = {
# if this is used a dependency for another haskellPackage you will need to redefine "pkgs.haskellPackages.callPackage", but for simple cases this is sufficient.
jot = pkgs.haskellPackages.callPackage /home/amy/jot/jot.nix { };
foo = callPackage /path/to/foo { }; # where directory foo contains a default.nix
harold = callPackage /path/to/harold/harold.nix { };
};
in self
and VOILA nix-env -f '<mypkgs>' -iA mypkgs.jot
should install for any users.
2 Likes
I added your first suggestion to the top of my config file, but I’m not sure I did it correctly. I’m getting the following error message. (Note: /etc/nixos/configuration.nix is a symlink to /home/amy/dotWombat/etc/nixos/configuration.nix)
# nixos-rebuild switch
error: syntax error, unexpected ',', expecting '.' or '=', at /home/amy/dotWombat/etc/nixos/configuration.nix:10:9
(use '--show-trace' to show detailed location information)
building Nix...
error: syntax error, unexpected ',', expecting '.' or '=', at /home/amy/dotWombat/etc/nixos/configuration.nix:10:9
(use '--show-trace' to show detailed location information)
building the system configuration...
error: syntax error, unexpected ',', expecting '.' or '=', at /home/amy/dotWombat/etc/nixos/configuration.nix:10:9
(use '--show-trace' to show detailed location information)
/etc/nixos/configuration.nix (aka /home/amy/dotWombat/etc/nixos/configuration.nix)
# Edit this configuration file to define what should be installed on
# your system. Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running ‘nixos-help’).
let
jot = pkgs.haskellPackages.callpackage /home/amy/jot/jot.nix {};
in {
environment.systemPackages = [ jot ] ++ (with pkgs; [ ]);
}
{ config, pkgs, ... }:
{
imports =
[ # Include the results of the hardware scan.
/etc/nixos/hardware-configuration.nix
/etc/nixos/R.nix
];
# Use the GRUB 2 boot loader.
boot.loader.grub.enable = true;
boot.loader.grub.version = 2;
# boot.loader.grub.efiSupport = true;
# boot.loader.grub.efiInstallAsRemovable = true;
# boot.loader.efi.efiSysMountPoint = "/boot/efi";
# Define on which hard drive you want to install Grub.
boot.loader.grub.device = "/dev/sda"; # or "nodev" for efi only
boot.initrd.checkJournalingFS = false;
# networking.hostName = "nixos"; # Define your hostname.
# networking.wireless.enable = true; # Enables wireless support via wpa_supplicant.
# Configure network proxy if necessary
# networking.proxy.default = "http://user:password@proxy:port/";
# networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain";
# Select internationalisation properties.
i18n = {
consoleFont = "Lat2-Terminus16";
consoleKeyMap = "uk";
defaultLocale = "en_IE.UTF-8";
};
# Set your time zone.
time.timeZone = "Europe/Dublin";
# List packages installed in system profile. To search, run:
# $ nix search wget
environment.systemPackages = with pkgs; [
auctex
bash
binutils-unwrapped
cabal2nix
curl
dmenu2
docker
dzen2
emacs
firefox
gcc
ghc
ghostscript # for pdf2dsc
gitAndTools.gitFull
gnome3.meld
gnumake
haskellPackages.cabal-install
haskellPackages.stylish-haskell
haskellPackages.X11-xft
kdeApplications.okular
libreoffice
lxqt.qterminal
gnome3.gnome-disk-utility
pandoc
pdfmod
pkgconfig
python
python3
python36Packages.csvkit
rEnv
rsync
stack
sxiv
tectonic
texstudio
texlive.combined.scheme-basic
tree
unison
vlc
x11
xmonad-with-packages
xorg.libX11
xsel
wget
];
# Some programs need SUID wrappers, can be configured further or are
# started in user sessions.
# programs.mtr.enable = true;
# programs.gnupg.agent = { enable = true; enableSSHSupport = true; };
# List services that you want to enable:
# Enable the OpenSSH daemon.
# services.openssh.enable = true;
# Open ports in the firewall.
# networking.firewall.allowedTCPPorts = [ ... ];
# networking.firewall.allowedUDPPorts = [ ... ];
# Or disable the firewall altogether.
# networking.firewall.enable = false;
# Enable CUPS to print documents.
# services.printing.enable = true;
# Enable sound.
sound.enable = true;
hardware.pulseaudio.enable = true;
# Enable the X11 windowing system.
# services.xserver.enable = true;
# services.xserver.layout = "uk";
# services.xserver.xkbOptions = "eurosign:e";
services.xserver = {
enable = true;
layout = "ie";
windowManager.xmonad = {
enable = true;
enableContribAndExtras = true;
extraPackages = haskellPackages: [
haskellPackages.xmonad
haskellPackages.xmonad-contrib
haskellPackages.xmonad-extras
];
};
};
# Enable touchpad support.
# services.xserver.libinput.enable = true;
# Enable the KDE Desktop Environment.
services.xserver.displayManager.sddm.enable = true;
services.xserver.desktopManager.plasma5.enable = true;
# Define a user account. Don't forget to set a password with ‘passwd’.
users.users.amy = {
isNormalUser = true;
home = "/home/amy";
description = "Amy de Buitleir";
extraGroups = [ "wheel" "networkmanager" "vboxsf" ];
uid = 1000;
};
# This value determines the NixOS release with which your system is to be
# compatible, in order to avoid breaking some software such as database
# servers. You should change this only after NixOS release notes say you
# should.
system.stateVersion = "18.09"; # Did you read the comment?
}
You just concatenated two valid nix expressions. But, like in this case, the result is usually not another valid nix expression. 
You could format it like this:
https://pastebin.com/raw/v2QfFZip
2 Likes
I think I’m almost there. I have my configuration.nix exactly as given in your pastebin, but I’m getting
# nixos-rebuild switch
building Nix...
building the system configuration...
error: attribute 'callpackage' missing, at /home/amy/dotWombat/etc/nixos/configuration.nix:38:11
(use '--show-trace' to show detailed location information)
I changed “callpackage” to “callPackage”, and now it works. Thank you Growpotkin and earvstedt for the help.