diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index 8f2250257ff8bab44fffa602cb6247d787453fbd..39e87c046bb6adc6b009ef349c704ccd24d723eb 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -484,6 +484,7 @@ configureCompiler let fileMonitorCompiler = newFileMonitor $ distProjectCacheFile "compiler" progsearchpath <- liftIO $ getSystemSearchPath + rerunIfChanged verbosity fileMonitorCompiler @@ -499,7 +500,7 @@ configureCompiler let extraPath = fromNubList packageConfigProgramPathExtra progdb <- liftIO $ prependProgramSearchPath verbosity extraPath [] defaultProgramDb let progdb' = userSpecifyPaths (Map.toList (getMapLast packageConfigProgramPaths)) progdb - (comp, plat, progdb'') <- + result@(_, _, progdb'') <- liftIO $ Cabal.configCompilerEx hcFlavor @@ -516,17 +517,55 @@ configureCompiler -- programs it cares about, and those are the ones we monitor here. monitorFiles (programsMonitorFiles progdb'') - -- Configure the unconfigured programs in the program database, - -- as we can't serialise unconfigured programs. - -- See also #2241 and #9840. - finalProgDb <- liftIO $ configureAllKnownPrograms verbosity progdb'' + -- Note: There is currently a bug here: we are dropping unconfigured + -- programs from the 'ProgramDb' when we re-use the cache created by + -- 'rerunIfChanged'. + -- + -- See Note [Caching the result of configuring the compiler] - return (comp, plat, finalProgDb) + return result where hcFlavor = flagToMaybe projectConfigHcFlavor hcPath = flagToMaybe projectConfigHcPath hcPkg = flagToMaybe projectConfigHcPkg +{- Note [Caching the result of configuring the compiler] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +We can't straightforwardly cache anything that contains a 'ProgramDb', because +the 'Binary' instance for 'ProgramDb' discards all unconfigured programs. +See that instance, as well as 'restoreProgramDb', for a few more details. + +This means that if we try to cache the result of configuring the compiler (which +contains a 'ProgramDb'): + + - On the first run, we will obtain a 'ProgramDb' which may contain several + unconfigured programs. In particular, configuring GHC will add tools such + as `ar` and `ld` as unconfigured programs to the 'ProgramDb', with custom + logic for finding their location based on the location of the GHC binary. + - On subsequent runs, if we use the cache created by 'rerunIfChanged', we will + deserialise the 'ProgramDb' from disk, which means it won't include any + unconfigured programs, which might mean we are unable to find 'ar' or 'ld'. + +This is not currently a huge problem because, in the Cabal library, we eagerly +re-run the configureCompiler step (thus recovering any lost information), but +this is wasted work that we should stop doing in Cabal, given that cabal-install +has already figured out all the necessary information about the compiler. + +To fix this bug, we can't simply eagerly configure all unconfigured programs, +as was originally attempted, for a couple of reasons: + + - it does more work than necessary, by configuring programs that we may not + end up needing, + - it means that we prioritise system executables for built-in build tools + (such as `alex` and `happy`), instead of using the proper version for a + package or package component, as specified by a `build-tool-depends` stanza + or by package-level `extra-prog-path` arguments. + This lead to bug reports #10633 and #10692. + +See #9840 for more information about the problems surrounding the lossly +Binary ProgramDb instance. +-} + ------------------------------------------------------------------------------ -- * Deciding what to do: making an 'ElaboratedInstallPlan' diff --git a/cabal-testsuite/PackageTests/ExtraProgPath/setup.out b/cabal-testsuite/PackageTests/ExtraProgPath/setup.out index ed22f2510358c60949cefe661f065a93287a2ea5..13729def443b68d4c2a5af52158bdf9bc89f11e6 100644 --- a/cabal-testsuite/PackageTests/ExtraProgPath/setup.out +++ b/cabal-testsuite/PackageTests/ExtraProgPath/setup.out @@ -1,8 +1,10 @@ # cabal v2-build -Warning: cannot determine version of <ROOT>/pkg-config : -"" Configuration is affected by the following files: - cabal.project +Warning: cannot determine version of <ROOT>/pkg-config : +"" +Warning: cannot determine version of <ROOT>/pkg-config : +"" Resolving dependencies... Error: [Cabal-7107] Could not resolve dependencies: diff --git a/changelog.d/pr-10731 b/changelog.d/pr-10731 new file mode 100644 index 0000000000000000000000000000000000000000..7cc8054901f23ce32625aafa58659a485a145182 --- /dev/null +++ b/changelog.d/pr-10731 @@ -0,0 +1,4 @@ +synopsis: Fix regression where build-tool-depends are not used +packages: cabal-install +prs: #10731 +issues: #10633 #10692