diff --git a/Cabal/src/Distribution/Simple/Configure.hs b/Cabal/src/Distribution/Simple/Configure.hs index 9e561e791c6..8d90b0d8822 100644 --- a/Cabal/src/Distribution/Simple/Configure.hs +++ b/Cabal/src/Distribution/Simple/Configure.hs @@ -2210,55 +2210,77 @@ configureRequiredProgram verbosity progdb (LegacyExeDependency progName verRange) = - case lookupKnownProgram progName progdb of - Nothing -> - -- Try to configure it as a 'simpleProgram' automatically - -- - -- There's a bit of a story behind this line. In old versions - -- of Cabal, there were only internal build-tools dependencies. So the - -- behavior in this case was: - -- - -- - If a build-tool dependency was internal, don't do - -- any checking. - -- - -- - If it was external, call 'configureRequiredProgram' to - -- "configure" the executable. In particular, if - -- the program was not "known" (present in 'ProgramDb'), - -- then we would just error. This was fine, because - -- the only way a program could be executed from 'ProgramDb' - -- is if some library code from Cabal actually called it, - -- and the pre-existing Cabal code only calls known - -- programs from 'defaultProgramDb', and so if it - -- is calling something else, you have a Custom setup - -- script, and in that case you are expected to register - -- the program you want to call in the ProgramDb. - -- - -- OK, so that was fine, until I (ezyang, in 2016) refactored - -- Cabal to support per-component builds. In this case, what - -- was previously an internal build-tool dependency now became - -- an external one, and now previously "internal" dependencies - -- are now external. But these are permitted to exist even - -- when they are not previously configured (something that - -- can only occur by a Custom script.) + case lookupProgramByName progName progdb of + Just prog -> + -- If the program has already been configured, use it + -- (as long as the version is compatible). -- - -- So, I decided, "Fine, let's just accept these in any - -- case." Thus this line. The alternative would have been to - -- somehow detect when a build-tools dependency was "internal" (by - -- looking at the unflattened package description) but this - -- would also be incompatible with future work to support - -- external executable dependencies: we definitely cannot - -- assume they will be preinitialized in the 'ProgramDb'. - configureProgram verbosity (simpleProgram progName) progdb - Just prog - -- requireProgramVersion always requires the program have a version - -- but if the user says "build-depends: foo" ie no version constraint - -- then we should not fail if we cannot discover the program version. - | verRange == anyVersion -> do - (_, progdb') <- requireProgram verbosity prog progdb - return progdb' - | otherwise -> do - (_, _, progdb') <- requireProgramVersion verbosity prog verRange progdb - return progdb' + -- Not doing so means falling back to the "simpleProgram" path below, + -- which might fail if the program has custom logic to find a version + -- (such as hsc2hs). + let loc = locationPath $ programLocation prog + in case programVersion prog of + Nothing + | verRange == anyVersion -> + return progdb + | otherwise -> + dieWithException verbosity $! + UnknownVersionDb (programId prog) verRange loc + Just version + | withinRange version verRange -> + return progdb + | otherwise -> + dieWithException verbosity $! + BadVersionDb (programId prog) version verRange loc + Nothing -> + -- Otherwise, try to configure it as a 'simpleProgram' automatically + case lookupKnownProgram progName progdb of + Nothing -> + -- There's a bit of a story behind this line. In old versions + -- of Cabal, there were only internal build-tools dependencies. So the + -- behavior in this case was: + -- + -- - If a build-tool dependency was internal, don't do + -- any checking. + -- + -- - If it was external, call 'configureRequiredProgram' to + -- "configure" the executable. In particular, if + -- the program was not "known" (present in 'ProgramDb'), + -- then we would just error. This was fine, because + -- the only way a program could be executed from 'ProgramDb' + -- is if some library code from Cabal actually called it, + -- and the pre-existing Cabal code only calls known + -- programs from 'defaultProgramDb', and so if it + -- is calling something else, you have a Custom setup + -- script, and in that case you are expected to register + -- the program you want to call in the ProgramDb. + -- + -- OK, so that was fine, until I (ezyang, in 2016) refactored + -- Cabal to support per-component builds. In this case, what + -- was previously an internal build-tool dependency now became + -- an external one, and now previously "internal" dependencies + -- are now external. But these are permitted to exist even + -- when they are not previously configured (something that + -- can only occur by a Custom script.) + -- + -- So, I decided, "Fine, let's just accept these in any + -- case." Thus this line. The alternative would have been to + -- somehow detect when a build-tools dependency was "internal" (by + -- looking at the unflattened package description) but this + -- would also be incompatible with future work to support + -- external executable dependencies: we definitely cannot + -- assume they will be preinitialized in the 'ProgramDb'. + configureProgram verbosity (simpleProgram progName) progdb + Just prog + -- requireProgramVersion always requires the program have a version + -- but if the user says "build-depends: foo" ie no version constraint + -- then we should not fail if we cannot discover the program version. + | verRange == anyVersion -> do + (_, progdb') <- requireProgram verbosity prog progdb + return progdb' + | otherwise -> do + (_, _, progdb') <- requireProgramVersion verbosity prog verRange progdb + return progdb' -- ----------------------------------------------------------------------------- -- Configuring pkg-config package dependencies diff --git a/Cabal/src/Distribution/Simple/Program/Builtin.hs b/Cabal/src/Distribution/Simple/Program/Builtin.hs index e79e676d8cc..65501111a7e 100644 --- a/Cabal/src/Distribution/Simple/Program/Builtin.hs +++ b/Cabal/src/Distribution/Simple/Program/Builtin.hs @@ -226,21 +226,13 @@ hpcProgram = -- during the configure phase. haskellSuiteProgram :: Program haskellSuiteProgram = - (simpleProgram "haskell-suite") - { -- pretend that the program exists, otherwise it won't be in the - -- "configured" state - programFindLocation = \_verbosity _searchPath -> - return $ Just ("haskell-suite-dummy-location", []) - } + simpleProgram "haskell-suite" -- This represent a haskell-suite package manager. See the comments for -- haskellSuiteProgram. haskellSuitePkgProgram :: Program haskellSuitePkgProgram = - (simpleProgram "haskell-suite-pkg") - { programFindLocation = \_verbosity _searchPath -> - return $ Just ("haskell-suite-pkg-dummy-location", []) - } + simpleProgram "haskell-suite-pkg" happyProgram :: Program happyProgram = diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index 43c835f7a0d..6b77531b8a5 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -483,7 +483,7 @@ configureCompiler let extraPath = fromNubList packageConfigProgramPathExtra progdb <- liftIO $ prependProgramSearchPath verbosity extraPath [] defaultProgramDb let progdb' = userSpecifyPaths (Map.toList (getMapLast packageConfigProgramPaths)) progdb - result@(_, _, progdb'') <- + (comp, plat, progdb'') <- liftIO $ Cabal.configCompilerEx hcFlavor @@ -500,7 +500,12 @@ configureCompiler -- programs it cares about, and those are the ones we monitor here. monitorFiles (programsMonitorFiles progdb'') - return result + -- 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'' + + return (comp, plat, finalProgDb) where hcFlavor = flagToMaybe projectConfigHcFlavor hcPath = flagToMaybe projectConfigHcPath diff --git a/cabal-install/src/Distribution/Client/SetupWrapper.hs b/cabal-install/src/Distribution/Client/SetupWrapper.hs index b214cabfc23..936412cf4fb 100644 --- a/cabal-install/src/Distribution/Client/SetupWrapper.hs +++ b/cabal-install/src/Distribution/Client/SetupWrapper.hs @@ -90,7 +90,8 @@ import Distribution.Simple.Program , runDbProgramCwd ) import Distribution.Simple.Program.Db - ( prependProgramSearchPath + ( configureAllKnownPrograms + , prependProgramSearchPath , progOverrideEnv ) import Distribution.Simple.Program.Find @@ -1035,11 +1036,19 @@ getExternalSetupMethod verbosity options pkg bt = do createDirectoryIfMissingVerbose verbosity True setupCacheDir installExecutableFile verbosity src cachedSetupProgFile -- Do not strip if we're using GHCJS, since the result may be a script - when (maybe True ((/= GHCJS) . compilerFlavor) $ useCompiler options') $ + when (maybe True ((/= GHCJS) . compilerFlavor) $ useCompiler options') $ do + -- Add the relevant PATH overrides for the package to the + -- program database. + setupProgDb + <- prependProgramSearchPath verbosity + (useExtraPathEnv options) + (useExtraEnvOverrides options) + (useProgramDb options') + >>= configureAllKnownPrograms verbosity Strip.stripExe verbosity platform - (useProgramDb options') + setupProgDb cachedSetupProgFile return cachedSetupProgFile where diff --git a/cabal-testsuite/PackageTests/ExtraProgPath/setup.out b/cabal-testsuite/PackageTests/ExtraProgPath/setup.out index 1011c8899ed..c3755d7e8c7 100644 --- a/cabal-testsuite/PackageTests/ExtraProgPath/setup.out +++ b/cabal-testsuite/PackageTests/ExtraProgPath/setup.out @@ -1,8 +1,6 @@ # cabal v2-build Warning: cannot determine version of /pkg-config : "" -Warning: cannot determine version of /pkg-config : -"" Resolving dependencies... Error: [Cabal-7107] Could not resolve dependencies: