Cabal 无法找到本地来源(但已正确安装)的包
Cabal cannot find locally sourced (yet correctly installed) packages
我最近升级到 Cabal 3.2(和 GHC 8.10),我 运行 遇到一些重大问题,这些问题使我的某些项目不再可构建...
问题的详细描述
这是每次都失败的最小(不是)工作配置:
我从一个干净的 Cabal 配置开始(通过删除 ~/.cabal
);其原因稍后会出现在 post 中。我 运行 cabal update
重新创建 .cabal
目录并确保 Cabal 正常工作。
我使用 cabal init
创建了一个项目(我们称之为 test1
)。这是一个库项目,其中包含一个公开模块(方便命名为 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 安装了它们,并确保我的计算机上没有这些工具的其他版本。
请注意,我正在 运行ning Ubuntu 18.04.4 LTS(使用 XFCE,确切地说是 XUbuntu)。其他一切(似乎是这样)都是最新的。
最后一件事,关于我用于构建的 *.cabal
文件,它们几乎是由 cabal init
生成的文件,除了我将 executable xxx
切换为 library
对于库,我只是添加了一个 exposed-modules
字段来公开库的模块(因此 Test1
分别代表 test1
和 Test3
分别代表 test3
)。我还在 test2
中使用 build-depends
使项目依赖于 test1
。除此之外,它们几乎没有受到影响。
笔记和想法
我必须承认我是 Cabal 3 的新手;直到上周我还在使用 Cabal 1(因为我从来没有费心去更新它;是的,我知道这很糟糕)。使用 Cabal 1 我没有任何问题,我完全能够从本地源安装一个包并在其他项目中依赖它...
我觉得我做错了什么;也许我没有使用正确的 Cabal 命令?我在某处看到了一些关于 cabal new-build
和 cabal new-install
的东西,但它似乎只做 cabal build
和 cabal install
,至少在我的情况下是这样。我也想研究沙箱,但它似乎从 Cabal 的第 2 版开始就消失了。
这也有可能是 Cabal 错误,但我在错误跟踪器上没有发现任何可能与我的问题相关的相关问题...
你怎么看这件事?我究竟做错了什么?您是否看到任何替代或可能的修复方法?
非常感谢!
GHC 环境文件
GHC 安装附带 a certain number of packages out-of-the box. base is one of them but there are others, for example text。如果你单独安装 GHC(没有 cabal 或 stack)并打开 ghci,它应该让你 import Data.Text
没有问题。
如果你想让 GHC 或 ghci 知道你的文件系统中存在的其他编译包怎么办?您可以将 GHC 指向其他 package databases using command-line flags, but there's also the concept of package environment files.
环境是包含与包相关的 GHC 标志列表的纯文本文件。 ~/.ghc/$ARCH-$OS-$GHCVER/environments/default
可能有一个全局环境,也可能存在只影响同一文件夹内调用的 GHC 和 ghci 命令的本地环境。 exact rules for search 在 GHC 用户指南中有描述。
cabal install --lib实际上是做什么的?
默认情况下,它会修改 global 环境文件,以便 GHC 和 ghci 现在可以找到该库。这就是点 3) 起作用的原因。不过,库的实际编译二进制文件仍然驻留在 cabal 存储中。
我们还可以创建本地环境文件。例如 cabal install sop-core --lib --package-env .
将在当前文件夹中创建环境文件 .ghc.environment.xxx
,并且库将在 ghc 和 ghci 在那里被调用时可用。
为什么 test1 不能用于 test2?
现代 cabal 区分 local packages and external packages。
- local packages 是你们在一个项目中一起开发的包集,被反复编辑、重新编译和更改。它们是 "inplace" 构建的,在项目之外是看不到的。他们可以互相依赖。
- 外部包 是来自
build-depends:
的依赖项,其源代码是从包存储库下载的,并且在编译时放入 cabal 存储中,以便其他 Cabal项目可能会在不重新编译的情况下使用它们。
本地包列表和其他项目级配置详细信息在 cabal.project 文件中指定。但是如果你在一个单独的包上工作,你就不需要一个;默认的包列表只是 ./*.cabal
.
cabal要完全控制本地包的构建环境,会忽略全局环境文件。在您的情况下,您必须在同一项目中制作 test1 和 test2 本地包(可能是最佳选择)或发布 test1 并将其视为外部包。
请注意,"cabal project" 是一个仅在开发期间相关的概念。包是独立发布的,在 Hackage 或其他存储库中没有 "projects",只有包。
如果我想将 test1 视为外部而不将其发布到 Hackage 怎么办?
您将必须设置一个 本地包存储库 ,基本上是一个非 public Hackage。
你可以tell Cabal about additional package repositories在Cabal的配置文件中,也就是配置cabal本身的文件。它的位置在 cabal --help
.
的最后一行给出
但是如何设置存储库? hackage-repo-tool 可以提供帮助。
为什么 test3 失败了?为什么进一步的库安装失败?
这很奇怪,我不知道为什么会这样。您是否偶然删除了步骤 3) 和 5) 之间的 ~/.cabal
文件夹?如果删除全局 GHC 环境文件并重试会怎样?
我最近升级到 Cabal 3.2(和 GHC 8.10),我 运行 遇到一些重大问题,这些问题使我的某些项目不再可构建...
问题的详细描述
这是每次都失败的最小(不是)工作配置:
我从一个干净的 Cabal 配置开始(通过删除
~/.cabal
);其原因稍后会出现在 post 中。我 运行cabal update
重新创建.cabal
目录并确保 Cabal 正常工作。我使用
cabal init
创建了一个项目(我们称之为test1
)。这是一个库项目,其中包含一个公开模块(方便命名为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 安装了它们,并确保我的计算机上没有这些工具的其他版本。
请注意,我正在 运行ning Ubuntu 18.04.4 LTS(使用 XFCE,确切地说是 XUbuntu)。其他一切(似乎是这样)都是最新的。
最后一件事,关于我用于构建的 *.cabal
文件,它们几乎是由 cabal init
生成的文件,除了我将 executable xxx
切换为 library
对于库,我只是添加了一个 exposed-modules
字段来公开库的模块(因此 Test1
分别代表 test1
和 Test3
分别代表 test3
)。我还在 test2
中使用 build-depends
使项目依赖于 test1
。除此之外,它们几乎没有受到影响。
笔记和想法
我必须承认我是 Cabal 3 的新手;直到上周我还在使用 Cabal 1(因为我从来没有费心去更新它;是的,我知道这很糟糕)。使用 Cabal 1 我没有任何问题,我完全能够从本地源安装一个包并在其他项目中依赖它...
我觉得我做错了什么;也许我没有使用正确的 Cabal 命令?我在某处看到了一些关于 cabal new-build
和 cabal new-install
的东西,但它似乎只做 cabal build
和 cabal install
,至少在我的情况下是这样。我也想研究沙箱,但它似乎从 Cabal 的第 2 版开始就消失了。
这也有可能是 Cabal 错误,但我在错误跟踪器上没有发现任何可能与我的问题相关的相关问题...
你怎么看这件事?我究竟做错了什么?您是否看到任何替代或可能的修复方法?
非常感谢!
GHC 环境文件
GHC 安装附带 a certain number of packages out-of-the box. base is one of them but there are others, for example text。如果你单独安装 GHC(没有 cabal 或 stack)并打开 ghci,它应该让你 import Data.Text
没有问题。
如果你想让 GHC 或 ghci 知道你的文件系统中存在的其他编译包怎么办?您可以将 GHC 指向其他 package databases using command-line flags, but there's also the concept of package environment files.
环境是包含与包相关的 GHC 标志列表的纯文本文件。 ~/.ghc/$ARCH-$OS-$GHCVER/environments/default
可能有一个全局环境,也可能存在只影响同一文件夹内调用的 GHC 和 ghci 命令的本地环境。 exact rules for search 在 GHC 用户指南中有描述。
cabal install --lib实际上是做什么的?
默认情况下,它会修改 global 环境文件,以便 GHC 和 ghci 现在可以找到该库。这就是点 3) 起作用的原因。不过,库的实际编译二进制文件仍然驻留在 cabal 存储中。
我们还可以创建本地环境文件。例如 cabal install sop-core --lib --package-env .
将在当前文件夹中创建环境文件 .ghc.environment.xxx
,并且库将在 ghc 和 ghci 在那里被调用时可用。
为什么 test1 不能用于 test2?
现代 cabal 区分 local packages and external packages。
- local packages 是你们在一个项目中一起开发的包集,被反复编辑、重新编译和更改。它们是 "inplace" 构建的,在项目之外是看不到的。他们可以互相依赖。
- 外部包 是来自
build-depends:
的依赖项,其源代码是从包存储库下载的,并且在编译时放入 cabal 存储中,以便其他 Cabal项目可能会在不重新编译的情况下使用它们。
本地包列表和其他项目级配置详细信息在 cabal.project 文件中指定。但是如果你在一个单独的包上工作,你就不需要一个;默认的包列表只是 ./*.cabal
.
cabal要完全控制本地包的构建环境,会忽略全局环境文件。在您的情况下,您必须在同一项目中制作 test1 和 test2 本地包(可能是最佳选择)或发布 test1 并将其视为外部包。
请注意,"cabal project" 是一个仅在开发期间相关的概念。包是独立发布的,在 Hackage 或其他存储库中没有 "projects",只有包。
如果我想将 test1 视为外部而不将其发布到 Hackage 怎么办?
您将必须设置一个 本地包存储库 ,基本上是一个非 public Hackage。
你可以tell Cabal about additional package repositories在Cabal的配置文件中,也就是配置cabal本身的文件。它的位置在 cabal --help
.
但是如何设置存储库? hackage-repo-tool 可以提供帮助。
为什么 test3 失败了?为什么进一步的库安装失败?
这很奇怪,我不知道为什么会这样。您是否偶然删除了步骤 3) 和 5) 之间的 ~/.cabal
文件夹?如果删除全局 GHC 环境文件并重试会怎样?