Жесткий путь к каталогу данных при установке исполняемого файла

Проблема: у меня есть инструмент командной строки, написанный на Haskell, который читает файл данных. После установки программы я хотел бы, чтобы программа могла читать этот файл данных независимо от того, в каком каталоге я нахожусь. То есть при установке путь, который знает программа, должен быть выровнен с путем, который установщик выбирает.

Первоначальная попытка: меня перенаправили в раздел 7.6. Получив доступ к файлам данных из кода пакета в Cabal (библиотеке), я узнал, что могу импортировать getDataDir :: IO FilePath из Paths_myprog, если добавлю Paths_myprog к other-modules (хотя Hpack автоматически включает это по умолчанию), и что после установки моей программы я могу запустить ее с помощью:

myprog_datadir=~/tmp ~/.local/bin/myprog

Затем все, что мне нужно сделать, это заставить установщика переместить файл данных в этот каталог, поскольку myprog динамически обращается к этому пути, а не к какому-то жестко заданному значению. Но я не хочу указывать myprog_datadir=~/tmp в своей среде каждый раз, когда я запускаю программу, я хочу, чтобы она была жестко запрограммирована в двоичном коде! И кажется, что установка myprog_datadir=~/tmp при сборке и установке не устанавливает значение по умолчанию во время компиляции.

Итак: есть ли способ жестко указать этот путь при установке?

(Желательно, чтобы ответ относился к стеку, но ответ на установку клики также приветствуется.)


person Simon Shine    schedule 15.02.2021    source источник
comment
Файл указан как data-files: relative/path/to/file.txt, но когда я устанавливаю исполняемый файл и меняю каталог, этот относительный путь больше не существует. По умолчанию datadir что-то вроде /Users/simonshine/Projects/myprog/.stack-work/install/x86_64-osx/d6f6bad3f39945fab394a08b1bc4be948440a07b57dc3d9c354985b39ee09310/8.8.4/share/x86_64-osx-ghc-8.8.4/myprog-0.1.0, но я бы хотел, чтобы это было, например. /usr/local/share.   -  person Simon Shine    schedule 16.02.2021
comment
Рассматривали ли вы возможность жесткого кодирования самих данных в исполняемый файл, а не только пути к нему?   -  person leftaroundabout    schedule 16.02.2021


Ответы (1)


Файлы, перечисленные в data-files, уже автоматически установлены в правильном месте, чтобы Paths_pkg мог их найти. Вот минимальный пример:

% 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!
person Daniel Wagner    schedule 15.02.2021
comment
Но как мне это изменить? Если бы установщик был configure, я мог бы написать ./configure --prefix=/usr/local, а затем datarootdir было бы ${prefix}/share. Мой сценарий заключается в том, что я представляю, как какой-то упаковщик (на самом деле я сам) вызовет stack install и укажет пути, по которым затем пойдет мой инструмент для упаковки, и упакует его любым способом (например, PPA, AUR). - person Simon Shine; 16.02.2021
comment
Мне может понравиться эквивалент --prefix=~/.local, чтобы не только исполняемый файл заканчивался в ~/.local/bin, но и файлы данных заканчивались в ~/.local/share с myprog_datadir=~/.local/share по умолчанию вместо очень длинного имени с хешем в нем. - person Simon Shine; 16.02.2021
comment
@SimonShine ~/.cabal/config должен иметь строфы, помеченные install-dirs user и install-dirs global. - person Daniel Wagner; 16.02.2021