diff --git a/Cabal.cabal b/Cabal.cabal
--- a/Cabal.cabal
+++ b/Cabal.cabal
@@ -1,5 +1,5 @@
 name: Cabal
-version: 1.24.1.0
+version: 1.24.2.0
 copyright: 2003-2006, Isaac Jones
            2005-2011, Duncan Coutts
 license: BSD3
@@ -80,6 +80,8 @@
   tests/PackageTests/BuildDeps/TargetSpecificDeps3/MyLibrary.hs
   tests/PackageTests/BuildDeps/TargetSpecificDeps3/lemon.hs
   tests/PackageTests/BuildDeps/TargetSpecificDeps3/my.cabal
+  tests/PackageTests/BuildTargetErrors/BuildTargetErrors.cabal
+  tests/PackageTests/BuildTargetErrors/Main.hs
   tests/PackageTests/BuildTestSuiteDetailedV09/Dummy2.hs
   tests/PackageTests/BuildableField/BuildableField.cabal
   tests/PackageTests/BuildableField/Main.hs
@@ -187,11 +189,11 @@
     bytestring >= 0.9 && < 1,
     containers >= 0.4 && < 0.6,
     deepseq    >= 1.3 && < 1.5,
-    directory  >= 1.1 && < 1.3,
+    directory  >= 1.1 && < 1.4,
     filepath   >= 1.3 && < 1.5,
     pretty     >= 1.1 && < 1.2,
     process    >= 1.1.0.1 && < 1.5,
-    time       >= 1.4 && < 1.7
+    time       >= 1.4 && < 1.8
 
   if flag(bundled-binary-generic)
     build-depends: binary >= 0.5 && < 0.7
diff --git a/Distribution/PackageDescription/Configuration.hs b/Distribution/PackageDescription/Configuration.hs
--- a/Distribution/PackageDescription/Configuration.hs
+++ b/Distribution/PackageDescription/Configuration.hs
@@ -229,7 +229,7 @@
     -- dependencies to dependency maps.
     simplifiedTrees :: [CondTree FlagName DependencyMap PDTagged]
     simplifiedTrees = map ( mapTreeConstrs toDepMap  -- convert to maps
-                          . addBuildableCondition pdTaggedBuildInfo
+                          . addBuildableConditionPDTagged
                           . mapTreeConds (fst . simplifyWithSysParams os arch impl))
                           trees
 
@@ -278,13 +278,6 @@
     env :: FlagAssignment -> FlagName -> Either FlagName Bool
     env flags flag = (maybe (Left flag) Right . lookup flag) flags
 
-    pdTaggedBuildInfo :: PDTagged -> BuildInfo
-    pdTaggedBuildInfo (Lib l) = libBuildInfo l
-    pdTaggedBuildInfo (Exe _ e) = buildInfo e
-    pdTaggedBuildInfo (Test _ t) = testBuildInfo t
-    pdTaggedBuildInfo (Bench _ b) = benchmarkBuildInfo b
-    pdTaggedBuildInfo PDNull = mempty
-
 -- | Transforms a 'CondTree' by putting the input under the "then" branch of a
 -- conditional that is True when Buildable is True. If 'addBuildableCondition'
 -- can determine that Buildable is always True, it returns the input unchanged.
@@ -297,6 +290,35 @@
     Lit True  -> t
     Lit False -> CondNode mempty mempty []
     c         -> CondNode mempty mempty [(c, t, Nothing)]
+
+-- | This is a special version of 'addBuildableCondition' for the 'PDTagged'
+-- type.
+--
+-- It is not simply a specialisation. It is more complicated than it
+-- ought to be because of the way the 'PDTagged' monoid instance works. The
+-- @mempty = 'PDNull'@ forgets the component type, which has the effect of
+-- completely deleting components that are not buildable.
+--
+-- See <https://github.com/haskell/cabal/pull/4094> for more details.
+--
+addBuildableConditionPDTagged :: (Eq v, Monoid c) =>
+                                 CondTree v c PDTagged
+                              -> CondTree v c PDTagged
+addBuildableConditionPDTagged t =
+    case extractCondition (buildable . getInfo) t of
+      Lit True  -> t
+      Lit False -> deleteConstraints t
+      c         -> CondNode mempty mempty [(c, t, Just (deleteConstraints t))]
+  where
+    deleteConstraints = mapTreeConstrs (const mempty)
+
+    getInfo :: PDTagged -> BuildInfo
+    getInfo (Lib l) = libBuildInfo l
+    getInfo (Exe _ e) = buildInfo e
+    getInfo (Test _ test) = testBuildInfo test
+    getInfo (Bench _ b) = benchmarkBuildInfo b
+    getInfo PDNull = mempty
+
 
 -- Note: extracting buildable conditions.
 -- --------------------------------------
diff --git a/Distribution/Simple/BuildPaths.hs b/Distribution/Simple/BuildPaths.hs
--- a/Distribution/Simple/BuildPaths.hs
+++ b/Distribution/Simple/BuildPaths.hs
@@ -13,7 +13,8 @@
 
 module Distribution.Simple.BuildPaths (
     defaultDistPref, srcPref,
-    haddockDirName, hscolourPref, haddockPref,
+    haddockDirName,
+    hscolourPref, hscolourPref', haddockPref, haddockPref',
     autogenModulesDir,
 
     autogenModuleName,
@@ -48,9 +49,14 @@
 srcPref :: FilePath -> FilePath
 srcPref distPref = distPref </> "src"
 
-hscolourPref :: HaddockTarget -> FilePath -> PackageDescription -> FilePath
-hscolourPref = haddockPref
+-- Backwards compat, see #4123.
+haddockPref, hscolourPref :: FilePath -> PackageDescription -> FilePath
+haddockPref  = haddockPref' ForDevelopment
+hscolourPref = haddockPref' ForDevelopment
 
+hscolourPref' :: HaddockTarget -> FilePath -> PackageDescription -> FilePath
+hscolourPref' = haddockPref'
+
 -- | This is the name of the directory in which the generated haddocks
 -- should be stored. It does not include the @<dist>/doc/html@ prefix.
 haddockDirName :: HaddockTarget -> PackageDescription -> FilePath
@@ -58,8 +64,8 @@
 haddockDirName ForHackage = (++ "-docs") . display . packageId
 
 -- | The directory to which generated haddock documentation should be written.
-haddockPref :: HaddockTarget -> FilePath -> PackageDescription -> FilePath
-haddockPref haddockTarget distPref pkg_descr
+haddockPref' :: HaddockTarget -> FilePath -> PackageDescription -> FilePath
+haddockPref' haddockTarget distPref pkg_descr
     = distPref </> "doc" </> "html" </> haddockDirName haddockTarget pkg_descr
 
 -- |The directory in which we put auto-generated modules
diff --git a/Distribution/Simple/Haddock.hs b/Distribution/Simple/Haddock.hs
--- a/Distribution/Simple/Haddock.hs
+++ b/Distribution/Simple/Haddock.hs
@@ -152,7 +152,7 @@
         htmlTemplate  = fmap toPathTemplate . flagToMaybe . haddockHtmlLocation
                         $ flags
         haddockTarget =
-          fromFlagOrDefault ForDevelopment (haddockForHackage flags')
+          haddockTargetFromFlag (haddockForHackage flags')
 
     setupMessage verbosity "Running Haddock for" (packageId pkg_descr)
     (confHaddock, version, _) <-
@@ -673,7 +673,7 @@
     go hscolourProg = do
       setupMessage verbosity "Running hscolour for" (packageId pkg_descr)
       createDirectoryIfMissingVerbose verbosity True $
-        hscolourPref haddockTarget distPref pkg_descr
+        hscolourPref' haddockTarget distPref pkg_descr
 
       let pre c = preprocessComponent pkg_descr c lbi False verbosity suffixes
       withAllComponentsInBuildOrder pkg_descr lbi $ \comp _ -> do
@@ -681,7 +681,7 @@
         let
           doExe com = case (compToExe com) of
             Just exe -> do
-              let outputDir = hscolourPref haddockTarget distPref pkg_descr
+              let outputDir = hscolourPref' haddockTarget distPref pkg_descr
                               </> exeName exe </> "src"
               runHsColour hscolourProg outputDir =<< getExeSourceFiles lbi exe
             Nothing -> do
@@ -690,7 +690,7 @@
               return ()
         case comp of
           CLib lib -> do
-            let outputDir = hscolourPref haddockTarget distPref pkg_descr </> "src"
+            let outputDir = hscolourPref' haddockTarget distPref pkg_descr </> "src"
             runHsColour hscolourProg outputDir =<< getLibSourceFiles lbi lib
           CExe   _ -> when (fromFlag (hscolourExecutables flags)) $ doExe comp
           CTest  _ -> when (fromFlag (hscolourTestSuites  flags)) $ doExe comp
diff --git a/Distribution/Simple/Install.hs b/Distribution/Simple/Install.hs
--- a/Distribution/Simple/Install.hs
+++ b/Distribution/Simple/Install.hs
@@ -19,7 +19,7 @@
 import Distribution.PackageDescription
 import Distribution.Package (Package(..))
 import Distribution.Simple.LocalBuildInfo
-import Distribution.Simple.BuildPaths (haddockName, haddockPref)
+import Distribution.Simple.BuildPaths (haddockName, haddockPref')
 import Distribution.Simple.Utils
          ( createDirectoryIfMissingVerbose
          , installDirectoryContents, installOrdinaryFile, isInSearchPath
@@ -75,8 +75,8 @@
 
   unless (hasLibs pkg_descr || hasExes pkg_descr) $
       die "No executables and no library found. Nothing to do."
-  docExists <- doesDirectoryExist $ haddockPref ForDevelopment distPref pkg_descr
-  info verbosity ("directory " ++ haddockPref ForDevelopment distPref pkg_descr ++
+  docExists <- doesDirectoryExist $ haddockPref' ForDevelopment distPref pkg_descr
+  info verbosity ("directory " ++ haddockPref' ForDevelopment distPref pkg_descr ++
                   " does exist: " ++ show docExists)
 
   installDataFiles verbosity pkg_descr dataPref
@@ -84,14 +84,14 @@
   when docExists $ do
       createDirectoryIfMissingVerbose verbosity True htmlPref
       installDirectoryContents verbosity
-          (haddockPref ForDevelopment distPref pkg_descr) htmlPref
+          (haddockPref' ForDevelopment distPref pkg_descr) htmlPref
       -- setPermissionsRecursive [Read] htmlPref
       -- The haddock interface file actually already got installed
       -- in the recursive copy, but now we install it where we actually
       -- want it to be (normally the same place). We could remove the
       -- copy in htmlPref first.
-      let haddockInterfaceFileSrc  = haddockPref ForDevelopment distPref pkg_descr
-                                                   </> haddockName pkg_descr
+      let haddockInterfaceFileSrc  = haddockPref' ForDevelopment distPref pkg_descr
+                                                  </> haddockName pkg_descr
           haddockInterfaceFileDest = interfacePref </> haddockName pkg_descr
       -- We only generate the haddock interface file for libs, So if the
       -- package consists only of executables there will not be one:
diff --git a/Distribution/Simple/Setup.hs b/Distribution/Simple/Setup.hs
--- a/Distribution/Simple/Setup.hs
+++ b/Distribution/Simple/Setup.hs
@@ -39,7 +39,7 @@
   configAbsolutePaths, readPackageDbList, showPackageDbList,
   CopyFlags(..),     emptyCopyFlags,     defaultCopyFlags,     copyCommand,
   InstallFlags(..),  emptyInstallFlags,  defaultInstallFlags,  installCommand,
-  HaddockTarget(..),
+  HaddockTarget(..), haddockTargetFromFlag,
   HaddockFlags(..),  emptyHaddockFlags,  defaultHaddockFlags,  haddockCommand,
   HscolourFlags(..), emptyHscolourFlags, defaultHscolourFlags, hscolourCommand,
   BuildFlags(..),    emptyBuildFlags,    defaultBuildFlags,    buildCommand,
@@ -1229,13 +1229,19 @@
 --    documentation in @<dist>/doc/html/<package id>-docs@.
 data HaddockTarget = ForHackage | ForDevelopment deriving (Eq, Show, Generic)
 
+-- | Convert '--for-hackage' to 'HaddockTarget'.
+haddockTargetFromFlag :: Flag Bool -> HaddockTarget
+haddockTargetFromFlag NoFlag       = ForDevelopment
+haddockTargetFromFlag (Flag False) = ForDevelopment
+haddockTargetFromFlag (Flag True)  = ForHackage
+
 data HaddockFlags = HaddockFlags {
     haddockProgramPaths :: [(String, FilePath)],
     haddockProgramArgs  :: [(String, [String])],
     haddockHoogle       :: Flag Bool,
     haddockHtml         :: Flag Bool,
     haddockHtmlLocation :: Flag String,
-    haddockForHackage   :: Flag HaddockTarget,
+    haddockForHackage   :: Flag Bool,
     haddockExecutables  :: Flag Bool,
     haddockTestSuites   :: Flag Bool,
     haddockBenchmarks   :: Flag Bool,
@@ -1257,7 +1263,7 @@
     haddockHoogle       = Flag False,
     haddockHtml         = Flag False,
     haddockHtmlLocation = NoFlag,
-    haddockForHackage   = Flag ForDevelopment,
+    haddockForHackage   = Flag False,
     haddockExecutables  = Flag False,
     haddockTestSuites   = Flag False,
     haddockBenchmarks   = Flag False,
@@ -1326,7 +1332,7 @@
   ,option "" ["for-hackage"]
    "Collection of flags to generate documentation suitable for upload to hackage"
    haddockForHackage (\v flags -> flags { haddockForHackage = v })
-   (noArg (Flag ForHackage))
+   trueArg
 
   ,option "" ["executables"]
    "Run haddock for Executables targets"
diff --git a/changelog b/changelog
--- a/changelog
+++ b/changelog
@@ -1,4 +1,9 @@
 -*-change-log-*-
+1.24.2.0 Mikhail Glushenkov <mikhail.glushenkov@gmail.com> December 2016
+	* Fixed a bug in the handling of non-buildable components (#4094).
+	* Reverted a PVP-noncompliant API change in 1.24.1.0 (#4123).
+	* Bumped the directory upper bound to < 1.4 (#4158).
+
 1.24.1.0 Ryan Thomas <ryan@ryant.org> October 2016
 	* API addition: 'differenceVersionRanges' (#3519).
 	* Fixed reexported-modules display mangling (#3928).
@@ -6,8 +11,6 @@
 	extra-doc-files field is present (#3825).
 	* Fixed an incorrect invocation of GetShortPathName that was
 	causing build failures on Windows (#3649).
-
-1.24.0.1 Ryan Thomas <ryan@ryant.org> May 2016
 	* Linker flags are now set correctly on GHC >= 7.8 (#3443).
 
 1.24.0.0 Ryan Thomas <ryan@ryant.org> May 2016
diff --git a/doc/index.markdown b/doc/index.markdown
--- a/doc/index.markdown
+++ b/doc/index.markdown
@@ -1,5 +1,5 @@
 % Cabal User Guide
-**Version: 1.24.1.0**
+**Version: 1.24.2.0**
 
 Cabal is the standard package system for [Haskell] software. It helps
 people to configure, build and install Haskell software and to
diff --git a/tests/PackageTests/BuildTargetErrors/BuildTargetErrors.cabal b/tests/PackageTests/BuildTargetErrors/BuildTargetErrors.cabal
new file mode 100644
--- /dev/null
+++ b/tests/PackageTests/BuildTargetErrors/BuildTargetErrors.cabal
@@ -0,0 +1,10 @@
+name: BuildTargetErrors
+version: 1.0
+build-type: Simple
+cabal-version: >= 1.9
+
+library
+
+executable not-buildable-exe
+    main-is: Main.hs
+    buildable: False
diff --git a/tests/PackageTests/BuildTargetErrors/Main.hs b/tests/PackageTests/BuildTargetErrors/Main.hs
new file mode 100644
--- /dev/null
+++ b/tests/PackageTests/BuildTargetErrors/Main.hs
@@ -0,0 +1,1 @@
+main = return ()
diff --git a/tests/PackageTests/Tests.hs b/tests/PackageTests/Tests.hs
--- a/tests/PackageTests/Tests.hs
+++ b/tests/PackageTests/Tests.hs
@@ -279,6 +279,13 @@
                     "tests/PackageTests/GhcPkgGuess/SymlinkGhcVersion/ghc" $
                     ghc_pkg_guess "ghc"
 
+  -- Test error message we report when a non-buildable target is
+  -- requested to be built
+  tc "BuildTargetErrors" $ do
+    cabal "configure" []
+    assertOutputContains "the component is marked as disabled"
+        =<< shouldFail (cabal' "build" ["not-buildable-exe"])
+
   where
     ghc_pkg_guess bin_name = do
         cwd <- packageDir
