Jak uruchomić plik wykonywalny haskell (projekt cabal) bez zainstalowania cabal lub ghc

Dec 01 2020

Zbudowałem aplikację w haskell za pomocą cabal. Mogę uruchomić plik wykonywalny, wpisując w wierszu polecenia „cabal run [plik cabal]”. Teraz chcę udostępnić tę aplikację moim znajomym, najlepiej bez konieczności instalowania cabal na ich komputerach. Mogę zlokalizować plik .exe projektu w katalogu kompilacji, ale nie ładuje on pliku .txt, który jest dostarczany z programem. Plik .exe otwiera również terminal w czasie wykonywania, czego nie robi, gdy uruchamiam go z cabal (tak jak powinien). To mówi mi, że brakuje pewnych rzeczy i dlatego nie mogę sam udostępnić pliku .exe. Jakie jest rozwiązanie umożliwiające uruchamianie aplikacji bez zainstalowanej wersji Cabal lub GHC?

Odpowiedzi

3 JonPurdy Dec 01 2020 at 03:34

Istnieje kilka możliwych rozwiązań.

Domyślnie, gdy otwierasz plik z programu przy użyciu ścieżki względnej, jest ona względna w stosunku do bieżącego katalogu roboczego programu, który nie jest miejscem, w którym znajduje się plik wykonywalny, ale miejscem, z którego został wykonany plik wykonywalny . Jeśli chcesz znaleźć plik zależny od ścieżki wykonywalnej lub katalogu instalacyjnego, musisz to zrobić jawnie. Istnieją dwa podstawowe sposoby, aby to zrobić: ręcznie użyj, System.Environment.getExecutablePathaby uzyskać katalog programu i połącz go ze ścieżką do pliku:

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

Możesz również użyć data-filespola w pliku Cabal, aby dodać plik do projektu; wygeneruje to moduł, który eksportuje kilka funkcji, takich jak który wykonuje tę samą funkcję, co akcja, którą zdefiniowałem powyżej. Następnie, jeśli zainstalujesz projekt za pomocą , skopiuje on pliki danych do katalogu instalacyjnego, a Twój program będzie mógł je znaleźć w czasie wykonywania. Zależy to jednak od zainstalowania programu przy użyciu Cabal, ponieważ generuje on ścieżki bezwzględne z zapisanym katalogiem instalacyjnym.Paths_projectNamegetDataFileName :: FilePath -> IO FilePathinstallRelativecabal install

Jeśli używasz cabal installdo instalowania programu w standardowej lokalizacji na swoim komputerze, takiej jak katalog „program files”, nie będzie miało znaczenia, że ​​ścieżka jest zakodowana na stałe i możesz po prostu skopiować plik wykonywalny i pliki pomocnicze do archiwum i niech użytkownicy rozpakują go w katalogu plików programu.

Zamiast archiwum ZIP możesz zamiast tego zbudować instalator systemu Windows . Alternatywnie możesz uniknąć konieczności ładowania czegokolwiek w czasie wykonywania, osadzając pliki w pliku wykonywalnym bezpośrednio przy użyciu file-embedpakietu.

Jeśli chodzi o zapobieganie otwieraniu się terminala, zapoznaj się z moją odpowiedzią na twoje pytanie dotyczące tego.