Cara menjalankan haskell yang dapat dieksekusi (proyek cabal) tanpa cabal atau ghc diinstal

Dec 01 2020

Saya telah membangun aplikasi di haskell dengan komplotan rahasia. Saya dapat menjalankan eksekusi dengan mengetik ke dalam command prompt "cabal run [cabal file]". Sekarang saya ingin membagikan aplikasi ini ke teman-teman saya, dan lebih disukai tidak harus menginstal komplotan rahasia di mesin mereka. Saya dapat menemukan file .exe untuk proyek tersebut di direktori build, tetapi file .txt yang disertakan dengan program tersebut tidak dimuat. File .exe juga membuka terminal saat runtime yang tidak dilakukan ketika saya menjalankannya dengan komplotan rahasia (seperti yang seharusnya dilakukan). Itu memberi tahu saya bahwa ada sesuatu yang hilang dan oleh karena itu saya tidak dapat membagikan .exe dengan sendirinya. Apa solusi untuk menjalankan aplikasi saya tanpa cabal atau ghc diinstal?

Jawaban

3 JonPurdy Dec 01 2020 at 03:34

Ada beberapa kemungkinan solusi di sini.

Secara default ketika Anda membuka file dari program Anda menggunakan jalur relatif, itu relatif terhadap direktori kerja saat ini dari program, yang bukan tempat tinggal file yang dapat dieksekusi, tetapi tempat eksekusi dijalankan . Jika Anda ingin menemukan file yang berhubungan dengan jalur yang dapat dieksekusi atau direktori instalasi, Anda perlu melakukannya secara eksplisit. Ada dua cara dasar untuk melakukannya: gunakan secara manual System.Environment.getExecutablePathuntuk mendapatkan direktori program, dan gabungkan dengan jalur ke file Anda:

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

Anda juga dapat menggunakan data-filesfield dalam file Cabal Anda untuk menambahkan file ke proyek Anda; ini akan menghasilkan modul yang mengekspor beberapa fungsi seperti yang menjalankan fungsi yang sama seperti tindakan yang saya definisikan di atas. Kemudian jika Anda menginstal proyek dengan , itu akan menyalin file data ke direktori instalasi dan program Anda akan dapat menemukannya saat runtime. Namun, ini bergantung pada penginstalan program menggunakan Cabal, karena ia menghasilkan jalur absolut dengan direktori penginstalan yang telah dimasukkan.Paths_projectNamegetDataFileName :: FilePath -> IO FilePathinstallRelativecabal install

Jika Anda menggunakan cabal installuntuk menginstal program di lokasi standar pada mesin Anda, seperti direktori "program files", maka tidak masalah bahwa jalur tersebut di-hardcode, dan Anda cukup menyalin file yang dapat dieksekusi dan mendukung ke dalam arsip dan minta pengguna untuk mengekstraknya di direktori file program mereka.

Alih-alih arsip ZIP, Anda dapat membuat penginstal Windows sebagai gantinya. Atau, Anda dapat menghindari memuat apa pun pada waktu proses dengan menyematkan file di file yang dapat dieksekusi secara langsung menggunakan file-embedpaket.

Adapun cara mencegah terminal terbuka, lihat jawaban saya untuk pertanyaan Anda secara khusus tentang ini.