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

ill*_*out 6 haskell build 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
...
Run Code Online (Sandbox Code Playgroud)

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

这些有什么区别?什么legacy fallback意思?


我使用的是cabal-install3.4.0.0 版:

$ cabal --version
cabal-install version 3.4.0.0
compiled using version 3.4.0.0 of the Cabal library 
Run Code Online (Sandbox Code Playgroud)

Nou*_*are 7

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

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

所以我开始寻找ElabPackage建造的地方。我找到了这个

    elaborateSolverToPackage
        ...
      where
        ...
        elab1 = elab0 {
                elabUnitId = newSimpleUnitId pkgInstalledId,
                elabComponentId = pkgInstalledId,
                elabLinkedInstantiatedWith = Map.empty,
                elabPkgOrComp = ElabPackage $ ElaboratedPackage {..},
                elabModuleShape = modShape
            }
Run Code Online (Sandbox Code Playgroud)

这又在这里使用:

    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]
Run Code Online (Sandbox Code Playgroud)

现在why_not_per_component非常有趣,因为该函数确定何时使用旧后备。它在这里定义:

        -- 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
Run Code Online (Sandbox Code Playgroud)

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

  • 构建类型是自定义或配置
  • cabal版本低于1.8
  • 没有可构建的组件
  • 你通过了--disable-per-component旗帜。
  • 已启用节目覆盖

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