3
votes

I have a haskell project that uses cabal.mkDerivation to make a Nix derivation.

When I run nix-build in the project root I get the expected result symlink after the build is successful.

If I enter that directory I have 4 directories:

  • bin
  • lib
  • nix-support
  • share

Where my executable exists inside bin. When I try to run my executable it cannot find my application files nor the dynamic libraries. I understand that this is due to to missing environment variables that set up all the paths of the package.

How can I run the executable of my package with the right environment variables without installing it?

I'm aware that I can use nix-shell to use cabal run to run the executable, but I want to run the executable in the deployed state.

Edit #1: More information

Here is my default.nix in my project:

{ haskellPackages ? (import <nixpkgs> {}).haskellPackages_ghc783_no_profiling }:

let
  inherit (haskellPackages)
    blazeHtml
    ... list of deps
    ;
in
  cabal.mkDerivation (self: {
    pname           = "myproject";
    version         = "0.0.1";
    src             = ./;
    enableSplitObjs = false;

    buildTools = [
      yesodBin
      cabalInstall
    ];

    buildDepends = [
      blazeHtml
      ... list of deps
    ];
})

Here is the relevant part of my cabal-file which contains the list of data files used by the application:

data-files: config/favicon.ico
          , config/robots.txt
          , config/settings.yml
          , static/css/*.css
          , static/fonts/*.eot
          , static/fonts/*.svg
          , static/fonts/*.ttf
          , static/fonts/*.woff
          , static/img/*.jpg

When the application is deployed by using cabal install the structure would be:

  myproject
▾ config
    favicon.ico
    robots.txt
    settings.yml 
▾ static
    ▸ css
    ▸ fonts
    ▸ img

The executable finds all files relatively to the current working directory.

2
How does your application normally find it's files? Do you use the _Paths module produced by cabal? - bennofs
@bennofs The directories config and static are in the root of the project. So when I run cabal run in the project root the files are looked up relatively. See my edit for more information. - rzetterberg

2 Answers

2
votes

Installing it would have the same problem. Wrap your binary with makeWrapper and set the necessary environment variables.

2
votes

The correct solution here is not to fix the nix expression. Instead, you should extend your application such that it uses getDataFileName which is provided by the cabal-generated Paths module to find it's files (you could use it as a fallback).

For more information about this see: http://neilmitchell.blogspot.de/2008/02/adding-data-files-using-cabal.html