Как запустить исполняемый файл haskell (проект cabal) без установки cabal или ghc

Dec 01 2020

Я создал приложение в haskell с помощью Cabal. Я могу запустить исполняемый файл, набрав в командной строке «cabal run [cabal file]». Теперь я хочу поделиться этим приложением со своими друзьями, и желательно без установки Cabal на их машины. Я могу найти файл .exe для проекта в каталоге сборки, но он не загружает файл .txt, поставляемый с программой. Файл .exe также открывает терминал во время выполнения, чего он не делает, когда я запускаю его с помощью cabal (как и должно быть). Это говорит мне, что чего-то не хватает, и поэтому я не могу поделиться файлом .exe отдельно. Какое решение для запуска моего приложения без установленных cabal или ghc?

Ответы

3 JonPurdy Dec 01 2020 at 03:34

Здесь есть несколько возможных решений.

По умолчанию, когда вы открываете файл из своей программы, используя относительный путь, он относительно текущего рабочего каталога программы, который находится не в том месте, где находится исполняемый файл, а в том, откуда исполняемый файл был запущен . Если вы хотите найти файл относительно пути к исполняемому файлу или установочного каталога, вам нужно сделать это явно. Есть два основных способа сделать это: вручную использовать, System.Environment.getExecutablePathчтобы получить каталог программы, и объединить его с путем к вашему файлу:

import System.Environment (getExecutablePath)
import System.FilePath ((</>))

installRelative :: FilePath -> IO FilePath
installRelative relative = do
  absolute <- getExecutablePath
  pure (absolute </> relative)

readInstalledFile :: FilePath -> IO String
readInstalledFile path = readFile =<< installRelative path

Вы также можете использовать data-filesполе в вашем файле Cabal, чтобы добавить файл в свой проект; это сгенерирует модуль, который экспортирует несколько функций, например, которые выполняют ту же функцию, что и действие, которое я определил выше. Затем, если вы установите проект с помощью , он скопирует файлы данных в каталог установки, и ваша программа сможет найти их во время выполнения. Однако это зависит от установки программы с помощью Cabal, поскольку она генерирует абсолютные пути с запеченным каталогом установки.Paths_projectNamegetDataFileName :: FilePath -> IO FilePathinstallRelativecabal install

Если вы используете cabal installдля установки программу в стандартном месте на вашем компьютере, таком как каталог «программных файлов», то не имеет значения, что путь жестко задан, и вы можете просто скопировать исполняемые и вспомогательные файлы в архив и попросите пользователей распаковать его в каталог с программными файлами.

Вместо ZIP-архива вы можете создать установщик Windows . В качестве альтернативы вы можете избежать загрузки чего-либо во время выполнения, встроив файлы в исполняемый файл напрямую с помощью file-embedпакета.

Что касается того, как запретить открытие терминала, смотрите мой ответ на ваш вопрос конкретно по этому поводу.