gpt4 book ai didi

haskell - Cabal无法找到本地来源(尚未正确安装)的软件包

转载 作者:行者123 更新时间:2023-12-02 02:42:31 25 4
gpt4 key购买 nike

我最近升级到Cabal 3.2(和GHC 8.10),遇到了一些重大问题,这些问题使我的某些项目无法再构建...

问题的详尽描述

这是每次都会失败的最小(非)工作配置:

  • 我从一个干净的Cabal配置开始(通过删除~/.cabal);原因将在后面的文章中介绍。我运行cabal update来重新创建.cabal目录,并确保Cabal在工作。
  • 我使用test1创建一个项目(我们称之为cabal init)。这是一个库项目,带有一个公开的模块(通常称为Test1),该模块导出一些伪函数foo。我先运行cabal build,然后运行cabal install --lib;一切运行顺利,到目前为止一切顺利。
  • 可以肯定的是,我离开了项目目录并启动了GHCi。我输入:m Test1加载我之前创建的模块,它可以正常工作!我可以输入foo ...并查看我的函数已执行。另外,我列出了~/.cabal/store/ghc-8.10.xxx的内容,并看到test1-xxx目录在其中。
  • 然后我仍然使用test2创建一个新项目cabal init。这次,我将其配置为可执行文件,并添加test1作为依赖项(使用build-depends字段)。但是这一次,当我运行cabal build时,我遇到了一些问题:
  • ~/projects/haskell/test2> cabal build
    Resolving dependencies...
    cabal: Could not resolve dependencies:
    [__0] trying: test2-0.1.0.0 (user goal)
    [__1] unknown package: test1 (dependency of test2)
    [__1] fail (backjumping, conflict set: test1, test2)
    After searching the rest of the dependency tree exhaustively, these were the
    goals I've had most trouble fulfilling: test2, test1

    在我看来,找不到 test1软件包,但是我可以从GHCi(和GHC)访问它,它存在于 ~/.cabal/store中。

    但不幸的是还有更多。
  • 我创建了第三个项目test3。这是一个库,除了base以外,它什么都不依赖(因此特别是它不依赖于test1)。该库公开了一个模块Test3,其中导出了一个函数bar。我运行cabal build,这里没有问题。但是,当我想使用test3安装cabal install --lib时,我遇到了一些错误:
  • ~/projects/haskell/test3> cabal install --lib
    Wrote tarball sdist to
    /home/<user>/projects/haskell/test3/dist-newstyle/sdist/test3-0.1.0.0.tar.gz
    Resolving dependencies...
    cabal: Could not resolve dependencies:
    [__0] unknown package: test1 (user goal)
    [__0] fail (backjumping, conflict set: test1)
    After searching the rest of the dependency tree exhaustively, these were the
    goals I've had most trouble fulfilling: test1

    尽管已正确安装,但似乎找不到 test1;可能这是 test2构建失败的残余物,不过...
  • 可以肯定的是,我启动了GHCi并输入:m Test3,但是GHCi告诉我它找不到模块Test3(甚至暗示这是一个错字,我的意思是Test1),表明test3确实没有安装,尽管它已成功构建...
  • 好吧,对于这种情况,还有一个怪癖:我再次使用cabal init创建一个新项目,称为test4,这是一个可执行文件,(再次)除了base以外,都不依赖任何其他内容。我保留了默认的Main.hs(只显示“Hello,Haskell!”)。我运行cabal build:没问题。然后我运行cabal install并...没问题吗?我在随机位置运行test4,它会启动可执行文件,并显示“Hello,Haskell!”在终端...
  • 还有最后一件事:我去某个随机位置,然后运行cabal install xxx --lib,其中xxx是Hackage上可用的库程序包(例如xml),以及:
  • ~> cabal install xml --lib
    Resolving dependencies...
    cabal: Could not resolve dependencies:
    [__0] unknown package: test1 (user goal)
    [__0] fail (backjumping, conflict set: test1)
    After searching the rest of the dependency tree exhaustively, these were the
    goals I've had most trouble fulfilling: test1

    这就是为什么我需要定期核对 .cabal的原因...现在,我似乎处于某种陈旧状态,无法再安装任何库。

    技术配置和注意事项

    我正在运行Cabal 3.2.0.0和GHC 8.10.0.20200123。我从hvr / ghc PPA安装了它们,并确保计算机上的任何地方都没有这些工具的其他版本。

    谨记一下,我正在运行Ubuntu 18.04.4 LTS(使用XFCE,因此确切地说是XUbuntu)。其他所有内容(似乎都是这样)都是最新的。

    最后一件事,关于我用于构建的 *.cabal文件,它们几乎是由 cabal init生成的文件,除了在库的情况下我将 executable xxx切换为 library之外,我只是添加了 exposed-modules字段以公开用于库的模块(因此 Test1分别是 test1Test3test3)。我还使用 build-depends中的 test2来使项目依赖于 test1。除此之外,它们几乎保持不变。

    笔记和想法

    我必须承认我是Cabal 3的新手。直到上周为止,我一直在使用Cabal 1(因为我从不费心更新它;是的,我知道这很糟糕)。使用Cabal 1,我没有任何问题,我完全能够从本地来源安装软件包,并在其他项目中依赖它...

    我觉得自己做错了;也许我没有使用正确的Cabal命令?我在某处看到了有关 cabal new-buildcabal new-install的信息,但似乎至少对 cabal buildcabal install没什么作用,至少就我而言。我也想研究沙箱,但自Cabal版本2起,它似乎消失了。

    也有可能是Cabal错误,但我在错误跟踪器上没有发现任何可能与我的问题有关的相关问题...

    你怎么看待这件事?我究竟做错了什么?您是否看到任何替代或可能的修复方法?

    非常感谢!

    最佳答案

    GHC环境文件

    GHC安装随附a certain number of packages out-of-the boxbase是其中之一,但还有其他,例如text。如果您单独安装GHC(没有缆线或堆栈)并打开ghci,它将使您使用import Data.Text没问题。

    如果您希望GHC或ghci知道文件系统中存在的其他已编译软件包怎么办?您可以使用package databases将GHC指向其他command-line flags,但是还有package environment files的概念。

    环境是纯文本文件,其中包含与软件包相关的GHC标志的列表。 ~/.ghc/$ARCH-$OS-$GHCVER/environments/default可能存在一个全局环境,并且还可能存在仅影响在同一文件夹内调用的GHC和ghci命令的本地环境。 GHC用户指南中介绍了exact rules for search

    cabal install --lib实际做什么?

    默认情况下,它会修改全局环境文件,以便GHC和ghci现在可以找到该库。这就是第3点)起作用的原因。该库的实际已编译二进制文件仍然驻留在cabal存储中。

    我们还可以创建本地环境文件。例如,cabal install sop-core --lib --package-env .将在当前文件夹中创建环境文件.ghc.environment.xxx,当在ghc和ghci中调用该库时,该库将可供ghc和ghci使用。

    为什么test1不能用于test2?

    现代阴谋论区分local packages and external packages

  • 本地软件包是您在项目中一起开发,反复编辑,重新编译和更改的软件包的集合。它们是“就地”构建的,在项目外部看不到。他们可以互相依靠。
  • 外部软件包build-depends:的依赖项,其源代码是从软件包存储库中下载的,并且在编译时将其放在cabal存储中,以便其他Cabal项目可以使用它们而无需重新编译。

  • 本地软件包的列表和其他项目级别的配置详细信息在 cabal.project文件中指定。但是,如果您使用单个隔离的软件包,则不需要一个。默认的软件包列表就是 ./*.cabal

    cabal希望完全控制本地软件包的构建环境,并且将忽略全局环境文件。对于您的情况,您必须在同一项目中制作test1和test2本地软件包(可能是最佳选择),或者发布test1并将其视为外部软件包。

    注意,“项目计划”是仅在开发期间相关的概念。软件包是独立发布的,在Hackage或其他存储库中没有“项目”,只有软件包。

    如果我想将test1视为外部而不将其发布到Hackage怎么办?

    您将必须建立一个本地软件包存储库,基本上是一个非 public 的Hackage。

    您可以在Cabal配置文件(即配置Cabal本身的文件)中 tell Cabal about additional package repositories。它的位置在 cabal --help的最后一行中给出。

    但是如何建立存储库? hackage-repo-tool可以帮助您。

    为什么test3失败?为什么进一步的库安装失败?

    太奇怪了,我不知道为什么会这样。您是否有可能在步骤3)和5)之间删除了 ~/.cabal文件夹?如果删除全局GHC环境文件并重试,会发生什么?

    关于haskell - Cabal无法找到本地来源(尚未正确安装)的软件包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60650929/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com