The pkgs.nix
:
import (fetchTarball https://github.com/NixOS/nixpkgs-channels/archive/4df3426f5a5e78cef4835897a43abd9e2a092b74.tar.gz) {}
The default.nix
:
{
pkgs ? import ./pkgs.nix,
linuxPath ? "linuxPackages_4_17"
}:
with pkgs;
let
linux = lib.getAttrFromPath (lib.splitString "." linuxPath) pkgs;
in
stdenv.mkDerivation {
name = "awesome-package";
version = "0.0.1";
src = lib.cleanSource ./.;
buildInputs = [
linuxHeaders
];
propagatedBuildInputs = [
linux.bcc
];
}
The shell.nix
:
{
pkgs ? import ./pkgs.nix,
linuxPath ? "linuxPackages_4_17"
}:
with pkgs;
let
linux = lib.getAttrFromPath (lib.splitString "." linuxPath) pkgs;
drv = import ./default.nix { inherit pkgs linuxPath; };
in
drv.overrideAttrs (attrs: {
src = null;
shellHook = ''
echo 'Entering ${attrs.name}'
set -v
# include headers (this works even if the derivation doesn't have a dev output)
C_INCLUDE_PATH="${lib.makeSearchPathOutput "dev" "include" drv.buildInputs}"
# static linking
LIBRARY_PATH="${lib.makeLibraryPath drv.buildInputs}"
# dynamic linking
LD_LIBRARY_PATH="${lib.makeLibraryPath drv.propagatedBuildInputs}";
set +v
'';
})
In this particular shell.nix
we fully specified the LD_LIBRARY_PATH
. This works as long as your program doesn't depend on some global dynamic libraries. On NixOS, these are usually the video card drivers. In those cases, you want to instead use something like:
LD_LIBRARY_PATH="${lib.makeLibraryPath drv.propagatedBuildInputs}''${$LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
This will append the external :$LD_LIBRARY_PATH
but only if it exists.
Note that CPLUS_INCLUDE_PATH
is for C++.
See: https://gist.github.com/CMCDragonkai/8d91e90c47d810cffe7e65af15a6824c for more information on lib.cleanSource
.
It's also important to read: https://nixos.org/nixpkgs/manual/#ssec-setup-hooks and https://nixos.org/nixos/nix-pills/basic-dependencies-and-hooks.html
Usually these kinds of variables would be managed via setup hook. Like for example python
manages a setup hook for the PYTHONPATH
. But not every packaging system has this setup. Note it is the Python derivation itself that provides this setup hook which looks for every other buildInput
or propagatedBuildInput
.
Something that I didn't mention above is that you need to also consider
nativeBuildInputs
not justbuildInputs
and not justpropagatedBuildInputs
. Also most of the time any C based libraries will be linked in a dynamically shared way. Thus the compiled outputs will always be usingLD_LIBRARY_PATH
and notLIBRARY_PATH
, necessitating the upstream dependencies to be propagated on anyway. I'm not entirely sure how this works.