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.
Should also incorporate pkg-config: https://www.freedesktop.org/wiki/Software/pkg-config/
Also see https://github.com/edolstra/nix-repl/blob/master/default.nix as inspiration for how to bind into more complex C/C++ libraries.