Problem: I've got a command-line tool written in Haskell that reads a data file. Upon installing the program, I'd like for the program to be able to read that data file regardless of the directory I find myself in. That is, upon installing, the path that the program knows should be aligned with the path that the installer chooses.
Initial attempt: I was directed to the section 7.6. Accessing data files from package code in Cabal (the library) and learned that I can import getDataDir :: IO FilePath
from Paths_myprog
, as long as I add Paths_myprog
to other-modules
(although Hpack auto-includes this by default) and that after installing my program, I can run it with:
myprog_datadir=~/tmp ~/.local/bin/myprog
Then all I need to do is have the installer move the data file to this directory, since myprog
dynamically accesses that path rather than some hardcoded value. But I don't want to have to specify myprog_datadir=~/tmp
in my environment every time I run the program, I want it hardcoded into the binary! And it seems that setting myprog_datadir=~/tmp
when building and installing doesn't set a compile-time default.
So: Is there a way I can hardcode this path upon installation?
(Preferrably, an answer that relates to Stack, but a cabal-install answer is also greatly appreciated.)
Files listed in data-files
are already automatically installed in the right location so that Paths_pkg
will find them. Here's a minimal example:
% cat Main.hs
import Paths_so_test
main :: IO ()
main = getDataDir >>= putStrLn
% cat so-test.cabal
cabal-version: >=1.10
name: so-test
version: 0.1.0.0
build-type: Simple
data-files: test
executable so-test
main-is: Main.hs
other-modules: Paths_so_test
autogen-modules: Paths_so_test
build-depends: base >=4.14 && <4.15
default-language: Haskell2010
% cat test
Hello, world!
% cabal install
Wrote tarball sdist to
/home/dmwit/projects/oneoff/tmp.dir/dist-newstyle/sdist/so-test-0.1.0.0.tar.gz
Resolving dependencies...
Up to date
Symlinking 'so-test'
% cat `so-test`/test
Hello, world!