diff --git a/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs b/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs index 725fb124bf56bcf7f756af42a6b4f7ee286b9926..14140104ffd8e192858920bb45cc27bd90bb07a3 100644 --- a/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs +++ b/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs @@ -12,7 +12,7 @@ -- Read the list of packages available to pkg-config. ----------------------------------------------------------------------------- module Distribution.Solver.Types.PkgConfigDb - ( PkgConfigDb + ( PkgConfigDb (..) , readPkgConfigDb , pkgConfigDbFromList , pkgConfigPkgIsPresent @@ -95,11 +95,12 @@ pkgConfigPkgIsPresent (PkgConfigDb db) pn vr = Nothing -> False -- Package not present in the DB. Just Nothing -> True -- Package present, but version unknown. Just (Just v) -> withinPkgconfigVersionRange v vr --- If we could not read the pkg-config database successfully we allow --- the check to succeed. The plan found by the solver may fail to be --- executed later on, but we have no grounds for rejecting the plan at --- this stage. -pkgConfigPkgIsPresent NoPkgConfigDb _ _ = True +-- If we could not read the pkg-config database successfully we fail. +-- The plan found by the solver can't be executed later, because pkg-config itself +-- is going to be called in the build phase to get the library location for linking +-- so even if there is a library, it would need to be passed manual flags anyway. +pkgConfigPkgIsPresent NoPkgConfigDb _ _ = False + -- | Query the version of a package in the @pkg-config@ database. diff --git a/cabal-install/tests/UnitTests/Distribution/Solver/Modular/DSL/TestCaseUtils.hs b/cabal-install/tests/UnitTests/Distribution/Solver/Modular/DSL/TestCaseUtils.hs index 08b52121b7f6c5ab228e56364e6b5c8d772b62b4..93af7178941f9588776a43d2f258925799830db8 100644 --- a/cabal-install/tests/UnitTests/Distribution/Solver/Modular/DSL/TestCaseUtils.hs +++ b/cabal-install/tests/UnitTests/Distribution/Solver/Modular/DSL/TestCaseUtils.hs @@ -43,7 +43,7 @@ import Distribution.Verbosity -- cabal-install import qualified Distribution.Solver.Types.PackagePath as P -import Distribution.Solver.Types.PkgConfigDb (PkgConfigDb, pkgConfigDbFromList) +import Distribution.Solver.Types.PkgConfigDb (PkgConfigDb (..), pkgConfigDbFromList) import Distribution.Solver.Types.Settings import Distribution.Solver.Types.Variable import Distribution.Client.Dependency (foldProgress) @@ -166,7 +166,7 @@ mkTest :: ExampleDb -> [String] -> SolverResult -> SolverTest -mkTest = mkTestExtLangPC Nothing Nothing [] +mkTest = mkTestExtLangPC Nothing Nothing (Just []) mkTestExts :: [Extension] -> ExampleDb @@ -174,7 +174,7 @@ mkTestExts :: [Extension] -> [String] -> SolverResult -> SolverTest -mkTestExts exts = mkTestExtLangPC (Just exts) Nothing [] +mkTestExts exts = mkTestExtLangPC (Just exts) Nothing (Just []) mkTestLangs :: [Language] -> ExampleDb @@ -182,25 +182,25 @@ mkTestLangs :: [Language] -> [String] -> SolverResult -> SolverTest -mkTestLangs langs = mkTestExtLangPC Nothing (Just langs) [] +mkTestLangs langs = mkTestExtLangPC Nothing (Just langs) (Just []) -mkTestPCDepends :: [(String, String)] +mkTestPCDepends :: Maybe [(String, String)] -> ExampleDb -> String -> [String] -> SolverResult -> SolverTest -mkTestPCDepends pkgConfigDb = mkTestExtLangPC Nothing Nothing pkgConfigDb +mkTestPCDepends mPkgConfigDb = mkTestExtLangPC Nothing Nothing mPkgConfigDb mkTestExtLangPC :: Maybe [Extension] -> Maybe [Language] - -> [(String, String)] + -> Maybe [(String, String)] -> ExampleDb -> String -> [String] -> SolverResult -> SolverTest -mkTestExtLangPC exts langs pkgConfigDb db label targets result = SolverTest { +mkTestExtLangPC exts langs mPkgConfigDb db label targets result = SolverTest { testLabel = label , testTargets = targets , testResult = result @@ -219,7 +219,7 @@ mkTestExtLangPC exts langs pkgConfigDb db label targets result = SolverTest { , testDb = db , testSupportedExts = exts , testSupportedLangs = langs - , testPkgConfigDb = pkgConfigDbFromList pkgConfigDb + , testPkgConfigDb = maybe NoPkgConfigDb pkgConfigDbFromList mPkgConfigDb , testEnableAllTests = EnableAllTests False } diff --git a/cabal-install/tests/UnitTests/Distribution/Solver/Modular/Solver.hs b/cabal-install/tests/UnitTests/Distribution/Solver/Modular/Solver.hs index 3abd45f5047ed3df0caec99a06caecf242421484..33e8b41a7d35c5d968291b17efbeb9dbb5feddc2 100644 --- a/cabal-install/tests/UnitTests/Distribution/Solver/Modular/Solver.hs +++ b/cabal-install/tests/UnitTests/Distribution/Solver/Modular/Solver.hs @@ -253,10 +253,12 @@ tests = [ , runTest $ mkTest dbBuildable2 "choose version that sets buildable to false" ["A"] (solverSuccess [("A", 1), ("B", 2)]) ] , testGroup "Pkg-config dependencies" [ - runTest $ mkTestPCDepends [] dbPC1 "noPkgs" ["A"] anySolverFailure - , runTest $ mkTestPCDepends [("pkgA", "0")] dbPC1 "tooOld" ["A"] anySolverFailure - , runTest $ mkTestPCDepends [("pkgA", "1.0.0"), ("pkgB", "1.0.0")] dbPC1 "pruneNotFound" ["C"] (solverSuccess [("A", 1), ("B", 1), ("C", 1)]) - , runTest $ mkTestPCDepends [("pkgA", "1.0.0"), ("pkgB", "2.0.0")] dbPC1 "chooseNewest" ["C"] (solverSuccess [("A", 1), ("B", 2), ("C", 1)]) + runTest $ mkTestPCDepends (Just []) dbPC1 "noPkgs" ["A"] anySolverFailure + , runTest $ mkTestPCDepends (Just [("pkgA", "0")]) dbPC1 "tooOld" ["A"] anySolverFailure + , runTest $ mkTestPCDepends (Just [("pkgA", "1.0.0"), ("pkgB", "1.0.0")]) dbPC1 "pruneNotFound" ["C"] (solverSuccess [("A", 1), ("B", 1), ("C", 1)]) + , runTest $ mkTestPCDepends (Just [("pkgA", "1.0.0"), ("pkgB", "2.0.0")]) dbPC1 "chooseNewest" ["C"] (solverSuccess [("A", 1), ("B", 2), ("C", 1)]) + , runTest $ mkTestPCDepends Nothing dbPC1 "noPkgConfigFailure" ["A"] anySolverFailure + , runTest $ mkTestPCDepends Nothing dbPC1 "noPkgConfigSuccess" ["D"] (solverSuccess [("D",1)]) ] , testGroup "Independent goals" [ runTest $ indep $ mkTest db16 "indepGoals1" ["A", "B"] (solverSuccess [("A", 1), ("B", 1), ("C", 1), ("D", 1), ("D", 2), ("E", 1)]) @@ -1665,7 +1667,7 @@ dbLangs1 = [ testBuildable :: String -> ExampleDependency -> TestTree testBuildable testName unavailableDep = runTest $ - mkTestExtLangPC (Just []) (Just [Haskell98]) [] db testName ["pkg"] expected + mkTestExtLangPC (Just []) (Just [Haskell98]) (Just []) db testName ["pkg"] expected where expected = solverSuccess [("false-dep", 1), ("pkg", 1)] db = [ @@ -1718,12 +1720,14 @@ dbBuildable2 = [ ] -- | Package databases for testing @pkg-config@ dependencies. +-- when no pkgconfig db is present, cabal must pick flag1 false and flag2 true to avoid the pkg dependency. dbPC1 :: ExampleDb dbPC1 = [ Right $ exAv "A" 1 [ExPkg ("pkgA", 1)] , Right $ exAv "B" 1 [ExPkg ("pkgB", 1), ExAny "A"] , Right $ exAv "B" 2 [ExPkg ("pkgB", 2), ExAny "A"] , Right $ exAv "C" 1 [ExAny "B"] + , Right $ exAv "D" 1 [exFlagged "flag1" [ExAny "A"] [], exFlagged "flag2" [] [ExAny "A"]] ] -- | Test for the solver's summarized log. The final conflict set is {A, F}, diff --git a/changelog.d/pr-7621 b/changelog.d/pr-7621 new file mode 100644 index 0000000000000000000000000000000000000000..4980160e3ae7f46a861ac364a6866045add1251f --- /dev/null +++ b/changelog.d/pr-7621 @@ -0,0 +1,10 @@ +synopsis: Backtrack when no pkg-config is present +packages: Cabal +prs: #7621 +issues: #7448 + +description: { + +When solving for pkgconfig-depends, when pkg-config is not present, the cabal solver will now backtrack and try a different automatic flag and dependency configuration, just as it does if pkg-config is present, but does not contain the specified package. + +}