From 18e822708d68dc87a4ec74d796260c81167b546c Mon Sep 17 00:00:00 2001 From: "Edward Z. Yang" Date: Fri, 21 Oct 2016 17:07:55 -0700 Subject: [PATCH] Do an early check for unbuildable deps, and give good error. When a library/executable is unbuildable, the solver may still return a reference to it. Handle this gracefully in ProjectPlanning with a nice error message, rather than an assert failure. Fixes #3978. Signed-off-by: Edward Z. Yang --- .../Distribution/Client/ProjectPlanning.hs | 22 ++++++++++++++++++- cabal-install/cabal-install.cabal | 5 +++++ .../IntegrationTests/new-build/T3978.err | 1 + .../tests/IntegrationTests/new-build/T3978.sh | 3 +++ .../new-build/T3978/cabal.project | 2 ++ .../new-build/T3978/p/p.cabal | 7 ++++++ .../new-build/T3978/q/q.cabal | 7 ++++++ 7 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 cabal-install/tests/IntegrationTests/new-build/T3978.err create mode 100644 cabal-install/tests/IntegrationTests/new-build/T3978.sh create mode 100644 cabal-install/tests/IntegrationTests/new-build/T3978/cabal.project create mode 100644 cabal-install/tests/IntegrationTests/new-build/T3978/p/p.cabal create mode 100644 cabal-install/tests/IntegrationTests/new-build/T3978/q/q.cabal diff --git a/cabal-install/Distribution/Client/ProjectPlanning.hs b/cabal-install/Distribution/Client/ProjectPlanning.hs index 3827a8e22a6..5e942108a96 100644 --- a/cabal-install/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/Distribution/Client/ProjectPlanning.hs @@ -130,7 +130,7 @@ import Distribution.Text import qualified Distribution.Compat.Graph as Graph import Distribution.Compat.Graph(IsNode(..)) -import Text.PrettyPrint (text, (<+>)) +import Text.PrettyPrint hiding ((<>)) import qualified Data.Map as Map import Data.Set (Set) import qualified Data.Set as Set @@ -1142,6 +1142,21 @@ elaborateInstallPlan verbosity platform compiler compilerprogdb pkgConfigDB Map ComponentId FilePath), ElaboratedConfiguredPackage) buildComponent (cc_map, lc_map, exe_map) comp = do + -- Before we get too far, check if we depended on something + -- unbuildable. If we did, give a good error. (If we don't + -- check, the 'toConfiguredComponent' will assert fail, see #3978). + case unbuildable_external_lib_deps of + [] -> return () + deps -> failProgress $ + text "The package" <+> disp pkgid <+> + text "depends on unbuildable libraries:" <+> + hsep (punctuate comma (map (disp.solverSrcId) deps)) + case unbuildable_external_exe_deps of + [] -> return () + deps -> failProgress $ + text "The package" <+> disp pkgid <+> + text "depends on unbuildable executables:" <+> + hsep (punctuate comma (map (disp.solverSrcId) deps)) infoProgress $ dispConfiguredComponent cc let -- Use of invariant: DefUnitId indicates that if -- there is no hash, it must have an empty @@ -1270,6 +1285,11 @@ elaborateInstallPlan verbosity platform compiler compilerprogdb pkgConfigDB external_cc_map = Map.fromList (map mkPkgNameMapping external_lib_dep_pkgs) external_lc_map = Map.fromList (map mkShapeMapping external_lib_dep_pkgs) + unbuildable_external_lib_deps = + filter (null . elaborateLibSolverId mapDep) external_lib_dep_sids + unbuildable_external_exe_deps = + filter (null . elaborateExeSolverId mapDep) external_exe_dep_sids + mkPkgNameMapping :: ElaboratedPlanPackage -> (PackageName, (ComponentId, PackageId)) mkPkgNameMapping dpkg = diff --git a/cabal-install/cabal-install.cabal b/cabal-install/cabal-install.cabal index 319a7fb6439..538024b014a 100644 --- a/cabal-install/cabal-install.cabal +++ b/cabal-install/cabal-install.cabal @@ -134,6 +134,11 @@ Extra-Source-Files: tests/IntegrationTests/new-build/T3460/sub-package-B/B.hs tests/IntegrationTests/new-build/T3460/sub-package-B/Setup.hs tests/IntegrationTests/new-build/T3460/sub-package-B/sub-package-B.cabal + tests/IntegrationTests/new-build/T3978.err + tests/IntegrationTests/new-build/T3978.sh + tests/IntegrationTests/new-build/T3978/cabal.project + tests/IntegrationTests/new-build/T3978/p/p.cabal + tests/IntegrationTests/new-build/T3978/q/q.cabal tests/IntegrationTests/new-build/executable/Main.hs tests/IntegrationTests/new-build/executable/Setup.hs tests/IntegrationTests/new-build/executable/Test.hs diff --git a/cabal-install/tests/IntegrationTests/new-build/T3978.err b/cabal-install/tests/IntegrationTests/new-build/T3978.err new file mode 100644 index 00000000000..0617e278030 --- /dev/null +++ b/cabal-install/tests/IntegrationTests/new-build/T3978.err @@ -0,0 +1 @@ +RE:^cabal(\.exe)?: The package q-1.0 depends on unbuildable libraries: p-1.0 diff --git a/cabal-install/tests/IntegrationTests/new-build/T3978.sh b/cabal-install/tests/IntegrationTests/new-build/T3978.sh new file mode 100644 index 00000000000..9136f120c83 --- /dev/null +++ b/cabal-install/tests/IntegrationTests/new-build/T3978.sh @@ -0,0 +1,3 @@ +. ./common.sh +cd T3978 +! cabal new-build q diff --git a/cabal-install/tests/IntegrationTests/new-build/T3978/cabal.project b/cabal-install/tests/IntegrationTests/new-build/T3978/cabal.project new file mode 100644 index 00000000000..0ff2443d338 --- /dev/null +++ b/cabal-install/tests/IntegrationTests/new-build/T3978/cabal.project @@ -0,0 +1,2 @@ +packages: p q +allow-older: p:base diff --git a/cabal-install/tests/IntegrationTests/new-build/T3978/p/p.cabal b/cabal-install/tests/IntegrationTests/new-build/T3978/p/p.cabal new file mode 100644 index 00000000000..104ed91e9df --- /dev/null +++ b/cabal-install/tests/IntegrationTests/new-build/T3978/p/p.cabal @@ -0,0 +1,7 @@ +name: p +version: 1.0 +build-type: Simple +cabal-version: >= 1.10 + +library + buildable: False diff --git a/cabal-install/tests/IntegrationTests/new-build/T3978/q/q.cabal b/cabal-install/tests/IntegrationTests/new-build/T3978/q/q.cabal new file mode 100644 index 00000000000..3ad14746c18 --- /dev/null +++ b/cabal-install/tests/IntegrationTests/new-build/T3978/q/q.cabal @@ -0,0 +1,7 @@ +name: q +version: 1.0 +build-type: Simple +cabal-version: >= 1.10 + +library + build-depends: p