Table of Contents
The currently recommended, cross-platform solution to compiling KMonad is to use the stack Haskell project manager.
Once you have stack
installed, you can build kmonad
thusly:
stack build # To build only the binary
stack haddock # To build the binary and the docs
If you would like stack
to automatically copy the binary to a folder on your
$PATH
, you can use:
stack install # Builds *and* copies
If you use the Nix package manager, either
because you installed it yourself or because you are using NixOS, you can build
kmonad
using the following command.
nix-build nix
Another option with nix
is to use the nix-shell
to ensure you have the
correct environment to run stack
in. You can enter the development environment
using:
nix-shell nix/shell.nix
Note: we do also have to compile a little bit of C-code, so make sure gcc
is
installed as well.
Every now and then we compile and release a static binary for Linux that should
run on any Linux regardless of the installed libraries (i.e. ldd
returns not a dynamic executable
). If, for some reason, you want to compile a static
binary for the state of HEAD yourself, please copy the contents of
./nix/static
into the kmonad
project root, and then call:
$(nix-build --no-link -A fullBuildScript)
If you have Docker installed, you can build kmonad
from source without the
need to install anything else on your system, since the build container will
always have all the needed build tools and dependencies.
This is very convenient if no binaries are available and you want to try some
other branch, you don't want to install build tools or they're not available
for your OS, etc. You can even use the provided Dockerfile
for development
testing. As of now, the built image is not meant to run kmonad
, just to
build it.
Just do this from the Dockerfile
directory:
# Build the Docker image which will contain the binary.
docker build -t kmonad-builder .
# Spin up an ephemeral Docker container from the built image, to just copy the
# built binary to the host's current directory bind-mounted inside the
# container at /host/.
docker run --rm -it -v ${PWD}:/host/ kmonad-builder bash -c 'cp -vp /root/.local/bin/kmonad /host/'
# Clean up build image, since it is no longer needed.
docker rmi kmonad-builder
You will find a kmonad
binary in your current directory.
As an added bonus, with recent Docker versions you can build images straight from public repo URLs, whithout even needing to clone the repo. Do this as the build step (the first one) in the previous instructions:
docker build -t kmonad-builder github.com/kmonad/kmonad.git
I have little experience with Haskell under windows, but I managed to compile
kmonad
under Windows10 using a Haskell platform
installation. I also needed to install
mingw to provide gcc
. With both the Haskell platform and
mingw
building kmonad
under Windows10 should as simple as stack build
.
You also can install MSYS2, Haskell and stack via scoop. Simply run these commands in Windows PowerShell:
# install scoop (no admin rights required)
iwr -useb get.scoop.sh | iex
# install stack
scoop install stack
# clone the KMonad repository (assuming you have `git` installed)
cd $HOME\Downloads
git clone https://github.com/kmonad/kmonad.git
cd kmonad
# compile KMonad (this will first download GHC and msys2, it takes a while)
stack build
# the new kmonad.exe will be in .\.stack-work\install\xxxxxxx\bin\
kmonad supports macOS 10.12 to 10.15 (Sierra, High Sierra, Mojave, and Catalina) and macOS 11.0 (Big Sur).
Note: under macOS, kmonad
uses one of two "system extensions" to
post modified key events to the OS. For macOS Catalina and prior, we
use a kernel
extension
(kext), which is bundled with kmonad as a submodule in
c_src/mac/Karabiner-VirtualHIDDevice
. For macOS Catalina and later,
we use a driverkit-based
extension
(dext), bundled as
c_src/mac/Karabiner-DriverKit-VirtualHIDDevice
. Therefore, you must
install either the kext or dext based on your macOS version (Catalina
users can choose either one).
You can either build the kext from source or you can install it as a binary that is signed by its maintainer. Building from source is difficult, and macOS won't load your kext unless you sign it with an "Apple Developer ID," so we recommend installing the kext as a signed binary.
The kext used by kmonad is maintained as part of
Karabiner-Elements.
Therefore, if you use Karabiner-Elements, you already have the kext
installed (though maybe a different version number). Run kextstat | grep Karabiner
to check the version: if
org.pqrs.driver.Karabiner.VirtualHIDDevice.v061000 (6.10.0)
is
listed, then the installed kext is compatibile with kmonad and you can
move onto installing kmonad. If another version
is listed, this may work too (but has not been tested).
If you want to attempt building and signing the kext yourself, look to the documentation for instructions. Otherwise, to install the kext as a signed binary, run:
$ git clone --recursive https://github.com/kmonad/kmonad.git
$ cd c_src/mac/Karabiner-VirtualHIDDevice
$ make install
You can either build the dext from source or you can install it as a binary that is signed by its maintainer. Building from source is only possible with an "Apple Developer ID," unless you build an old version of the dext.
The dext used by kmonad is maintained as part of
Karabiner-Elements.
Therefore, if you use Karabiner-Elements, you may already have the
dext installed (though maybe a different version number). Run
defaults read /Applications/.Karabiner-VirtualHIDDevice-Manager.app/Contents/Info.plist CFBundleVersion
to check the version: if 1.15.0
is shown, then the
installed dext is compatibile with kmonad and you can move onto
installing kmonad. If another version is listed,
this may work too (but has not been tested).
If you want to attempt building and signing the dext yourself, look to the documentation for instructions.
To install the dext as a signed binary, initialize the dext git submodule, install the extension, and activate the extension.
$ git clone --recursive https://github.com/kmonad/kmonad.git
$ cd kmonad/
$ open c_src/mac/Karabiner-DriverKit-VirtualHIDDevice/dist/Karabiner-DriverKit-VirtualHIDDevice-1.15.0.pkg
$ /Applications/.Karabiner-VirtualHIDDevice-Manager.app/Contents/MacOS/Karabiner-VirtualHIDDevice-Manager activate
Compilation under Mac currently works with stack
. Compilation under
Mac via nix
is not tested or planned. Installation under Mac via
Hackage is not tested, but may work for the adveturous. To compile on
Mac, download the kmonad source:
$ git clone --recursive https://github.com/kmonad/kmonad.git
Then build kmonad with stack
. If you are building against the kext, run:
$ stack build --flag kmonad:kext --extra-include-dirs=c_src/mac/Karabiner-VirtualHIDDevice/dist/include
If you are building against the dext, run
$ stack build --flag kmonad:dext --extra-include-dirs=c_src/mac/Karabiner-DriverKit-VirtualHIDDevice/include/pqrs/karabiner/driverkit:c_src/mac/Karabiner-DriverKit-VirtualHIDDevice/src/Client/vendor/include
Since Mac OS X Leopard (10.5), intercepting key events
requires
root privilege. Therefore, you must run kmonad as root (using sudo
,
e.g.). In the future, privilege separation may be implemented so that
just a small part of kmonad requires root privilege to run.
Since macOS Catalina (10.15), capturing key events requires explicit
permission in System Preferences
. Enable the application(s) that you
will be using to execute kmonad in System Preferences
> Security & Privacy
> Privacy
> Input Monitoring
.
You can download binaries for Windows and Linux (64bit) from the releases page. Many thanks to these lovely people for making this possible.
Some people have gone out of their way to add kmonad
into the
package-managers of various distros. If you want to add kmonad
to your
distro and add a pull-request to update the documentation to reflect
that, please feel free.
NOTE: These packages might be out of date.
Kmonad is available in the Arch User Repository (AUR) as kmonad-bin.
You can install kmonad
via the guix
package manager. You will need to copy
the udev rules into place manually.
$ guix install kmonad
# cp <kmonad-path>/lib/udev/rules.d/70-kmonad.rules /lib/udev/rules.d/
According to Guix's package store mechanism, <kmonad-path>
will include a hash
that captures the exact KMonad version. By default, the path will follow the
pattern /gnu/store/<hash>-kmonad-<version>/
.
Use the guix build kmonad
command to identify the correct path. In case the
command returns multiple paths, go for the shortest one.
So, for instance, if build
returns
$ guix build kmonad
/gnu/store/9mx79afpjqxjiiqgh1xv3b7ckblnl4wk-kmonad-0.4.1
/gnu/store/al0bmdxvl3a8s11vxn13y2nkq4hbg4c8-kmonad-0.4.1-static
<kmonad-path>
will be
/gnu/store/9mx79afpjqxjiiqgh1xv3b7ckblnl4wk-kmonad-0.4.1
and the copy
operation will then be as follows
# cp \
/gnu/store/9mx79afpjqxjiiqgh1xv3b7ckblnl4wk-kmonad-0.4.1/lib/udev/rules.d/70-kmonad.rules \
/lib/udev/rules.d/
If you use the Guix System to manage your entire machine, you will instead want
to install udev rules using something like this in your config.scm
(use-modules (gnu packages haskell-apps))
(operating-system
;; ...
(services
(modify-services %desktop-services
(udev-service-type config =>
(udev-configuration (inherit config)
(rules (cons kmonad
(udev-configuration-rules config))))))))
You can install kmonad
via xbps-install
:
# xbps-install -S kmonad
There is not currently a kmonad
package in nixpkgs
, however the
following instructions show how to create your own adhoc derivation, and
how to configure udev rules in nixos. There is also a NixOS module
included in this repository that can be used instead of a manual
configuration.
Create a kmonad.nix
derivation such as this one which fetches a static
binary release of kmonad and packages it in the nix-store:
let
pkgs = import <nixpkgs> { };
kmonad-bin = pkgs.fetchurl {
url = "https://github.com/kmonad/kmonad/releases/download/0.3.0/kmonad-0.3.0-linux";
sha256 = "4545b0823dfcffe0c4f0613916a6f38a0ccead0fb828c837de54971708bafc0b";
};
in
pkgs.runCommand "kmonad" {}
''
#!${pkgs.stdenv.shell}
mkdir -p $out/bin
cp ${kmonad-bin} $out/bin/kmonad
chmod +x $out/bin/*
''
-
Import
kmonad.nix
into yourconfiguration.nix
file using alet
expression:let kmonad = import /path/to/kmonad.nix; in { <your_config> }
-
Add
kmonad
toenvironment.systemPackages
:environment.systemPackages = with pkgs; [ ... kmonad ... ];
-
Create the
uinput
group and add your user touinput
andinput
:users.groups = { uinput = {}; }; users.extraUsers.userName = { ... extraGroups = [ ... "input" "uinput" ]; };
-
Add
udev
rules:services.udev.extraRules = '' # KMonad user access to /dev/uinput KERNEL=="uinput", MODE="0660", GROUP="uinput", OPTIONS+="static_node=uinput" '';
-
Rebuild system:
# nixos-rebuild switch
-
Clone this repository or copy the file
nix/nixos-module.nix
somewhere to your system. -
Add
nixos-module.nix
into yourconfiguration.nix
as an import:imports = [ /path/to/nixos-module.nix; ];
-
Configure the module:
services.kmonad = { enable = true; # disable to not run kmonad at startup configfiles = [ /path/to/config.kbd ]; # Modify the following line if you copied nixos-module.nix elsewhere or if you want to use the derivation described above # package = import /pack/to/kmonad.nix; };
-
If you've set
enable = true;
at the previous step, do not put asetxkbmap
line in yourconfig.kbd
. Instead, set the options like this:services.xserver = { xkbOptions = "compose:ralt"; layout = "us"; };
-
If you want your main user to use kmonad, add it to the
uinput
andinput
groups:users.extraUsers.userName = { ... extraGroups = [ ... "input" "uinput" ]; };
-
Rebuild system:
# nixos-rebuild switch