最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

【2023】Cabal 簡易指南

2023-08-29 11:56 作者:李問道  | 我要投稿

本文使用的 Cabal 版本為 3.10.1.0。本文只包含它的簡易使用指南、簡易機(jī)制解惑和一些作者自己使用時遇到過的疑惑的簡單解答,不包括安裝教程。

作者推薦使用 GHCUP 進(jìn)行安裝與后續(xù)的版本管理。

Cabal 是一個應(yīng)用于 Haskell 開發(fā)的包管理器。它所安裝的包的默認(rèn)來源為 Haskell 社區(qū)中的包倉庫 Hackage (hackage.haskell.org)。因此,所有在Hackage上能夠被搜索到的包都可以使用 Cabal 進(jìn)行安裝。

1.0 簡易起步

要使用 Cabal 作為包管理器進(jìn)行 Haskell 程序開發(fā),首先你要使用 Cabal 創(chuàng)建對應(yīng)的工程目錄:

cabal init foldername

這條命令將會在指定目錄初始化相應(yīng)的工程項(xiàng)目,也就是一個 Cabal Package,一個包。 當(dāng)然,你也可以直接在當(dāng)前目錄下新建項(xiàng)目:

cd test cabal init

默認(rèn)情況下,cabal init 會默認(rèn)使用 --interactive 參數(shù)在交互模式下啟動。這一模式下,cabal會和 nodejs 社區(qū)的包管理器 npm 一樣,詳細(xì)詢問你相應(yīng)的配置項(xiàng):

-- 首先會詢問你想構(gòu)建的項(xiàng)目的類型
What does the package build:
 ? 1) Library -- 如果你是想創(chuàng)建其他 Haskell 項(xiàng)目可以復(fù)用的庫,選取此項(xiàng)
 * 2) Executable -- 如果你只是想創(chuàng)建一個 Haskell 程序,選取此項(xiàng)
 ? 3) Library and Executable -- 如果你構(gòu)建的項(xiàng)目同時包括程序與庫,選取此項(xiàng)
 ? 4) Test suite -- 測試單元
Your choice? [default: Executable] -- 默認(rèn)情況會是 Excutable,構(gòu)筑 Haskell 程序

-- 是否覆寫指定目錄現(xiàn)有的文件
Do you wish to overwrite existing files (backups will be created) (y/n)? [default: n]

-- 選擇projectname.cabal文件的詮釋版本
Please choose version of the Cabal specification to use:
 ? 1) 1.24 ?(legacy)
 ? 2) 2.0 ? (+ support for Backpack, internal sub-libs, '^>=' operator)
 ? 3) 2.2 ? (+ support for 'common', 'elif', redundant commas, SPDX)
 ? 4) 2.4 ? (+ support for '**' globbing)
 * 5) 3.0 ? (+ set notation for ==, common stanzas in ifs, more redundant commas, better pkgconfig-depends)
 ? 6) 3.4 ? (+ sublibraries in 'mixins', optional 'default-language')
Your choice? [default: 3.0]

-- 包的名稱,或者說項(xiàng)目的名稱
Package name? [default: test]

-- 包的版本
Package version? [default: 0.1.0.0]

-- 選擇對應(yīng)的開源許可證
Please choose a license:
 ? 1) BSD-2-Clause
 ? 2) BSD-3-Clause
 ? 3) Apache-2.0
 ? 4) MIT
 ? 5) MPL-2.0
 ? 6) ISC
 ? 7) GPL-2.0-only
 ? 8) GPL-3.0-only
 ? 9) LGPL-2.1-only
 ?10) LGPL-3.0-only
 ?11) AGPL-3.0-only
 ?12) GPL-2.0-or-later
 ?13) GPL-3.0-or-later
 ?14) LGPL-2.1-or-later
 ?15) LGPL-3.0-or-later
 ?16) AGPL-3.0-or-later
 ?17) Other (specify)
Your choice?

-- 包的作者名
Author name? [default: Wendaolee]

-- 維護(hù)者郵箱
Maintainer email? [default: leewendao@outlook.com]

-- 項(xiàng)目主頁地址
Project homepage URL? [optional]

-- 項(xiàng)目的簡介
Project synopsis? [optional]

-- 項(xiàng)目的類別
Project category:
 ? 1) Codec
 ? 2) Concurrency
 ? 3) Control
 ? 4) Data
 ? 5) Database
 ? 6) Development
 ? 7) Distribution
 ? 8) Game
 ? 9) Graphics
 ?10) Language
 ?11) Math
 ?12) Network
 ?13) Sound
 ?14) System
 ?15) Testing
 ?16) Text
 ?17) Web
 ?18) Other (specify)
Your choice? [default: (none)]

-- 入口文件
What is the main module of the executable:
 * 1) Main.hs
 ? 2) Main.lhs
 ? 3) Other (specify)
Your choice? [default: Main.hs]

-- 源代碼目錄
Application directory:
 * 1) app
 ? 2) exe
 ? 3) src-exe
 ? 4) Other (specify)
Your choice? [default: app]

-- 在哪種 Haskell 標(biāo)準(zhǔn)上編寫程序
Choose a language for your executable:
 * 1) Haskell2010
 ? 2) Haskell98
 ? 3) GHC2021 (requires at least GHC 9.2)
 ? 4) Other (specify)
Your choice? [default: Haskell2010]

-- 是否在project.cabal文件中添加各個配置項(xiàng)的注釋(個人建議為y)
Add informative comments to each field in the cabal file. (y/n)? [default: y]


如果你只是單純想寫一個 Haskell 應(yīng)用,可以使用 cabal init --n ?(cabal init --non-interactive)。它會直接生成一個 Haskell 應(yīng)用的包目錄。

根據(jù)上面的步驟生成的目錄結(jié)構(gòu)如下:

│- ?CHANGELOG.md --應(yīng)用更改的更新日志模板
│- projectname.cabal -- cabal配置文件 
│
├─app ?-- 源代碼目錄,根據(jù)你在init時的值的設(shè)置的不同,源代碼目錄名也會不同
│ ? ? ?Main.hs
│
└─dist-newstyle -- 編譯后出現(xiàn)的輸出目錄

如果您想編譯您的項(xiàng)目,只需在當(dāng)前目錄下執(zhí)行:

cabal build

它會編譯您的項(xiàng)目,將可執(zhí)行文件生成于同目錄的 dist-newstyles/build/compile-info-paths... 之中。

如果您想運(yùn)行您的項(xiàng)目,則是執(zhí)行:

cabal run

它會編譯并運(yùn)行您的項(xiàng)目。

在通過cabal init生成的目錄里,唯一需要你注意的是 projectname.cabal 文件。它是 Cabal 管理你的包的重要憑證,就像是 package.json 之于 npm ,同時你可以在其中修改你在交互模式中填入的一些信息。

里面的內(nèi)容應(yīng)該初中生就能讀懂,在此不做詳細(xì)翻譯。唯一需要你注意的是這幾項(xiàng)配置:other-modules ,build-depends :

  1. other-modules 用于指定在程序中使用的模塊。也就是說,想要對代碼進(jìn)行模塊化,那么在使用 Cabal 的工程項(xiàng)目中必需把每個模塊在projectname.cabal文件中的other-modules項(xiàng)闡明。例如你要寫一個DataLayer.Type模塊,那么便需要在該項(xiàng)添加DataLayer.Type。

  2. build-depends 用于指定程序需要使用的第三方庫。cabalnpm是不一樣的。如果你要使用第三方庫,你需要手動在這一項(xiàng)中指定該庫。

build-depends這一配置項(xiàng)與cabal install 是令人迷惑的。習(xí)慣于使用類似npm的包管理器可能會通過npm install package-name為當(dāng)前項(xiàng)目安裝依賴,然而在 cabal 中您只能通過更改 projectname.cabal 文件的 build-depends 項(xiàng)來在自己的項(xiàng)目中使用第三方庫。

關(guān)于這一點(diǎn)在下面一節(jié)中會提供詳細(xì)的解釋。在這里,我只為您闡述清楚在自己的項(xiàng)目中如何引入第三方庫:

在終端里,運(yùn)行:

cabal install --lib libname ?

而后在 projectname.cabal中添加該庫:

-- Other library packages from which modules are imported.
-- 引入多個庫時,使用英文逗號分割。您同樣可以使用 = 、 ^>= 等符號指定庫的版本 ? ? 
build-depends: ? ?base ^>=4.14.3.0,libname

之后運(yùn)行 cabal buildcabal run 時,cabal會自動引入相關(guān)依賴庫完成編譯與程序的運(yùn)行。

當(dāng)然,您也可以直接在 projectname.cabal 文件的 build-depends 聲明該庫,cabal 會在執(zhí)行 buildrun 時自動安裝相關(guān)依賴庫完成編譯與程序的運(yùn)行。但是我個人推薦預(yù)先通過cabal install --lib libname 安裝庫,因?yàn)檫@樣你可以通過 LHS 在編寫程序時獲取相應(yīng)的庫的語法與類型支持。

2.0 簡易 cabal install 解惑:cabal 的包管理機(jī)制

Haskell是一門編譯型語言,這一特性間接使得 Cabal 不會和 npm 一樣,存在著存放在工程目錄的本地包文件夾 (如 npmnode_modules)。Cabal 的包永遠(yuǎn)是全局管理的。因此,在運(yùn)行 cabal install package時,它實(shí)質(zhì)上是在運(yùn)行cabal install --global package (就像是 npm install -g package,請注意這里只是“釋例”,cabal實(shí)際上并沒有--global參數(shù))。

一般來講,當(dāng)你鍵入 cabal install remote-package 時,會發(fā)生這些事:

  1. 從遠(yuǎn)程倉庫中下載對應(yīng)包的源碼,將源碼存放至 ~/cabal/packages目錄中 。

  2. 而后將會編譯這些源碼為 Haskell 的 .hi 中間文件,存放到 ~/cabal/store 目錄中。.hi 類似于 C 的 .o 文件,能夠提高后續(xù)的編譯速度。

  3. 如果你沒有鍵入 cabal install --lib remote-package ,即沒有在 cabal install 后補(bǔ)上 --lib 參數(shù),cabal默認(rèn)會將下載下來的源碼包視為一個 Haskell 程序包,而不是一個第三方的Haskell庫。因此它會嘗試將該包編譯為一個可執(zhí)行程序,而后將輸出的程序放到 cabal 的配置目錄中(老版本的cabal會將文件放至~/cabal/bin,更為現(xiàn)代化的cabal會將文件放至~/.local/bin,根據(jù)當(dāng)前cabal的配置而定)。

對于第三點(diǎn),你可能會有些困惑?,F(xiàn)在,讓我們把目光回到開頭。前邊我們說過,如果使用交互模式運(yùn)行cabal init,我們首先會得到初始化的包的類型:

What does the package build:
 ? 1) Library -- 如果你是想創(chuàng)建其他 Haskell 項(xiàng)目可以復(fù)用的庫,選取此項(xiàng)
 * 2) Executable -- 如果你只是想創(chuàng)建一個 Haskell 程序,選取此項(xiàng)
 ? 3) Library and Executable -- 如果你構(gòu)建的項(xiàng)目同時包括程序與庫,選取此項(xiàng)
 ? 4) Test suite -- 測試單元

也就是說,cabal的包主要是這三種類型:

  1. Haskell庫 (library)

  2. Haskell程序 (executable)

  3. 測試單元

默認(rèn)情況下,cabal install 實(shí)際上執(zhí)行的是 cabal install --executable (這也只是一個“釋例”!cabal install實(shí)際上并沒有--executable參數(shù))。它總是會嘗試將目標(biāo)的cabal包進(jìn)行編譯,而后嘗試生成一個可執(zhí)行程序。

這也是為什么當(dāng)你嘗試通過 cabal install lib 時,會出現(xiàn)這樣的報錯:

cabal install sqlite-simple
...
Error: cabal-3.10.1.0.exe: Cannot build the executables in the package
sqlite-simple because it does not contain any executables. Check the .cabal
file for the package and make sure that it properly declares the components
that you expect.

但實(shí)際上這并沒有什么影響。事實(shí)上在出現(xiàn)這一報錯時,相應(yīng)的庫已經(jīng)安裝到你的設(shè)備上了。

同理,當(dāng)你在一個 cabal 工程的根目錄下運(yùn)行 cabal install 時,它實(shí)際上會嘗試將該 cabal 工程生成為一個可執(zhí)行程序安裝到你的設(shè)備上。因此會發(fā)生這些事:

  1. 讀取分析 projectname.cabal 文件,嘗試引入 build-depends的庫,而后進(jìn)行編譯。對于沒有安裝到本地的庫,它會自動下載安裝。(相當(dāng)于 cabal build,這也是為什么 cabal install 也可以)

  2. 嘗試將編譯完的工程生成可執(zhí)行程序,輸出到相應(yīng)的配置目錄中。

這也同樣是 cabal installnpm install 的不同之處: cabal install 是直接編譯相應(yīng) cabal 包生成程序,這一過程中會自動下載安裝相應(yīng)的依賴庫;而 npm install 僅僅只是下載相應(yīng)的依賴庫。

總結(jié):

  1. 如果你想要安裝第三方的 Haskell 庫,可以使用 cabal install --lib libname

  2. 如果你要安裝其他的,使用 cabal install xxxx 。它也可以完成安裝庫的任務(wù),但它的語義并非是安裝庫。安裝相應(yīng)的依賴庫只是它附帶的。

  3. 如果你不確定你要安裝的是什么,無腦 cabal install 即可。

事實(shí)上,cabal已經(jīng)有計劃將安裝庫與安裝程序的命令進(jìn)行區(qū)分,詳情可見 Github Issue#6481。只是三年了依然沒有推進(jìn)......

3.0 參考 Reference

[1] What?cabal install?did when type this command.https://github.com/haskell/cabal/discussions/9210

[2]Cabal docs.https://cabal.readthedocs.io/en/latest/getting-started.html


【2023】Cabal 簡易指南的評論 (共 條)

分享到微博請遵守國家法律
社会| 平邑县| 太原市| 西峡县| 萍乡市| 蓬溪县| 九寨沟县| 阜阳市| 泸州市| 双鸭山市| 麻江县| 张家界市| 建瓯市| 通江县| 黎川县| 集安市| 芒康县| 开江县| 宜阳县| 绍兴市| 津南区| 丰台区| 古田县| 大姚县| 汉川市| 湘乡市| 婺源县| 扎兰屯市| 卓资县| 明星| 天等县| 绥阳县| 屏山县| 安仁县| 洛扎县| 阳谷县| 宣恩县| 宜章县| 长寿区| 鄂伦春自治旗| 靖边县|