From 52087ac1c7f47ed82b9979ff6b8439fb8ad3efd0 Mon Sep 17 00:00:00 2001 From: Gershom Bazerman Date: Sun, 5 Sep 2021 16:27:25 -0400 Subject: [PATCH 1/3] Backtrack when no pkgconfigdb is present --- .../src/Distribution/Solver/Types/PkgConfigDb.hs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs b/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs index 725fb124bf5..1d0b64b9902 100644 --- a/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs +++ b/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs @@ -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. From 8d62bbe6c96753e985a606d219483d32ca485980 Mon Sep 17 00:00:00 2001 From: Gershom Bazerman Date: Thu, 9 Sep 2021 00:15:22 -0400 Subject: [PATCH 2/3] changelog and test --- .../Distribution/Solver/Types/PkgConfigDb.hs | 2 +- .../Solver/Modular/DSL/TestCaseUtils.hs | 18 +++++++++--------- .../Distribution/Solver/Modular/Solver.hs | 13 ++++++++----- changelog.d/pr-7621 | 10 ++++++++++ 4 files changed, 28 insertions(+), 15 deletions(-) create mode 100644 changelog.d/pr-7621 diff --git a/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs b/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs index 1d0b64b9902..14140104ffd 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 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 08b52121b7f..93af7178941 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 3abd45f5047..cd5b27196a4 100644 --- a/cabal-install/tests/UnitTests/Distribution/Solver/Modular/Solver.hs +++ b/cabal-install/tests/UnitTests/Distribution/Solver/Modular/Solver.hs @@ -253,10 +253,11 @@ 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 Nothing 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 "noPkgConfig" ["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 +1666,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 +1719,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 00000000000..4980160e3ae --- /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. + +} From 73eb6803dfa2e14b4e13c7f798bc619ddbbc9166 Mon Sep 17 00:00:00 2001 From: Gershom Bazerman Date: Thu, 9 Sep 2021 12:57:26 -0400 Subject: [PATCH 3/3] one more test --- .../tests/UnitTests/Distribution/Solver/Modular/Solver.hs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cabal-install/tests/UnitTests/Distribution/Solver/Modular/Solver.hs b/cabal-install/tests/UnitTests/Distribution/Solver/Modular/Solver.hs index cd5b27196a4..33e8b41a7d3 100644 --- a/cabal-install/tests/UnitTests/Distribution/Solver/Modular/Solver.hs +++ b/cabal-install/tests/UnitTests/Distribution/Solver/Modular/Solver.hs @@ -253,11 +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 Nothing dbPC1 "noPkgs" ["A"] anySolverFailure + 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 "noPkgConfig" ["D"] (solverSuccess [("D",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)])