如何让Cabal使用本地版本的包作为Hackage包的依赖?
Cabal使用本地包作为Hackage依赖的通用方法及具体场景解决方案
我来帮你解决这个问题,分为通用方法和针对你场景的具体步骤两部分来说明:
通用技术问题:如何让Cabal使用本地版本的包作为Hackage包的依赖?
这里有几种常用的方法,你可以根据需求选择:
使用
cabal.project文件(推荐,持久化生效)
在你执行Cabal命令的目录下创建一个cabal.project文件,通过它指定本地包的路径或者强制使用已安装的版本:- 如果本地包在当前目录的子文件夹(比如
./attoparsec),可以写:
这样Cabal会直接将这个本地目录作为包源,优先使用其中的代码构建。packages: ./attoparsec - 如果已经本地安装了该包,想强制使用已安装版本,可以写:
比如constraints: 包名 installedconstraints: attoparsec installed,Cabal会跳过从Hackage拉取,直接使用本地已安装的版本。
- 如果本地包在当前目录的子文件夹(比如
临时通过命令行参数指定约束
在执行cabal install时,通过--constraint参数强制使用已安装的本地包:cabal install --constraint='包名 installed' [其他参数] 目标包这种方式只对当前命令生效,适合临时需求。
使用
cabal override命令覆盖包源
针对当前工作环境,执行以下命令让Cabal优先使用指定路径的本地包:cabal override add 包名 --source=./本地包路径这个命令会生成本地配置,后续Cabal命令都会优先使用该本地包。
具体实践场景解决方案
你之前的操作已经成功安装了带补丁的attoparsec,但Cabal仍然拉取Hackage版本的原因是:cabal install --lib默认会优先根据Hackage的包索引解析依赖,即使本地有安装包,只要Hackage上的版本满足依赖约束,它还是会尝试下载构建。
这里有几种适合你场景的解决步骤:
方法一:创建cabal.project文件(推荐)
- 在你执行
cabal install的目录下新建cabal.project文件 - 写入以下内容:
或者如果你还保留着本地克隆的attoparsec仓库,也可以写:constraints: attoparsec installedpackages: ./attoparsec - 再次执行你的安装命令:
这样Cabal就会优先使用你本地安装或本地仓库的attoparsec版本。cabal install --allow-newer --lib aeson
方法二:临时命令行指定约束
直接在安装命令中添加约束参数,无需额外文件:
cabal install --allow-newer --lib --constraint='attoparsec installed' aeson
这个命令会强制Cabal使用你本地已经安装好的attoparsec版本,而不是从Hackage拉取。
方法三:用cabal override配置本地源
如果你还保留着克隆的attoparsec仓库,执行以下命令:
cabal override add attoparsec --source=./attoparsec
配置完成后,再次执行你的安装命令,Cabal就会自动使用本地仓库的attoparsec来构建aeson了。
内容的提问来源于stack exchange,提问作者Joseph Sible-Reinstate Monica




