微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

当 cabal 构建软件包时,“遗留回退”是什么意思?

如何解决当 cabal 构建软件包时,“遗留回退”是什么意思?

使用 cabal 构建 Haskell 包时,似乎将某些包标记legacy fallback

$ cabal build
Resolving dependencies...
Build profile: -w ghc-9.0.1 -O1
In order,the following will be built (use -v for more details):
 - appar-0.1.8 (lib:appar) (requires build)
 - auto-update-0.1.6 (lib) (requires build)
 - base-compat-0.11.2 (lib) (requires build)
...
Building     base-orphans-0.8.4 (lib)
Building     appar-0.1.8 (all,legacy fallback)
Downloaded   memory-0.16.0
Downloading  cryptonite-0.29
Installing   base-orphans-0.8.4 (lib)
Downloaded   cryptonite-0.29
Downloading  some-1.0.3
...

您可以看到,对于某些库,它们被专门标记(lib),但其他库被标记(all,legacy fallback)

这两者有什么区别? legacy fallback 是什么意思?


我使用的是 cabal-install 版本 3.4.0.0:

$ cabal --version
cabal-install version 3.4.0.0
compiled using version 3.4.0.0 of the Cabal library 

解决方法

我深入研究了源代码。错误消息来自 here:

    dispname = case elabPkgOrComp pkg of
        ElabPackage _ -> prettyShow pkgid
            ++ " (all,legacy fallback)"
        ElabComponent comp -> prettyShow pkgid
            ++ " (" ++ maybe "custom" prettyShow (compComponentName comp) ++ ")"

所以我开始寻找构建 ElabPackage 的地方。我找到了this

    elaborateSolverToPackage
        ...
      where
        ...
        elab1 = elab0 {
                elabUnitId = newSimpleUnitId pkgInstalledId,elabComponentId = pkgInstalledId,elabLinkedInstantiatedWith = Map.empty,elabPkgOrComp = ElabPackage $ ElaboratedPackage {..},elabModuleShape = modShape
            }

这反过来用于here

    elaborateSolverToComponents mapDep spkg@(SolverPackage _ _ _ deps0 exe_deps0)
        = case mkComponentsGraph (elabEnabledSpec elab0) pd of
           Right g -> do
            ...
            let not_per_component_reasons = why_not_per_component src_comps
            if null not_per_component_reasons
                then return comps
                else do checkPerPackageOk comps not_per_component_reasons
                        return [elaborateSolverToPackage spkg g $
                                comps ++ maybeToList setupComponent]

现在 why_not_per_component 非常有趣,因为该函数决定何时使用旧回退。它被定义为 here:

        -- You are eligible to per-component build if this list is empty
        why_not_per_component g
            = cuz_buildtype ++ cuz_spec ++ cuz_length ++ cuz_flag ++ cuz_coverage

在下面的代码中,我们可以看到它可能是由以下原因引起的:

  • 构建类型是自定义或配置
  • cabal 版本小于 1.8
  • 没有可构建的组件
  • 您通过了 --disable-per-component 标志。
  • 已启用计划覆盖

所以对于 appar 库,这是因为 cabal-version 是 1.6,低于 1.8,请参阅 https://github.com/kazu-yamamoto/appar/blob/v0.1.8/appar.cabal#L10

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。