When using cabal to build a Haskell package, it appears to mark some packages as 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
...
You can see that for some libraries, they are specifically marked (lib), but other libraries are marked (all, legacy fallback).
What is the difference between these? What does legacy fallback mean?
I am using cabal-install version 3.4.0.0:
$ cabal --version
cabal-install version 3.4.0.0
compiled using version 3.4.0.0 of the Cabal library
I took a dive in the source code. The error message comes form here:
dispname = case elabPkgOrComp pkg of
ElabPackage _ -> prettyShow pkgid
++ " (all, legacy fallback)"
ElabComponent comp -> prettyShow pkgid
++ " (" ++ maybe "custom" prettyShow (compComponentName comp) ++ ")"
So I started looking for places where ElabPackage is constructed. I found this:
elaborateSolverToPackage
...
where
...
elab1 = elab0 {
elabUnitId = newSimpleUnitId pkgInstalledId,
elabComponentId = pkgInstalledId,
elabLinkedInstantiatedWith = Map.empty,
elabPkgOrComp = ElabPackage $ ElaboratedPackage {..},
elabModuleShape = modShape
}
This in turn is used 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]
Now the why_not_per_component is very interesting as that function determines when to use the legacy fallback. It is defined 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
There in the code right below that we can see that it can be caused by these reasons:
--disable-per-component flag.So for the appar library it is because the cabal-version is 1.6 which is lower than 1.8, see https://github.com/kazu-yamamoto/appar/blob/v0.1.8/appar.cabal#L10.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With