Skip to content

Commit

Permalink
Cabal: Add flag to ignore build tool dependencies
Browse files Browse the repository at this point in the history
Add a flag to disable the hard requirement on the
build-tools-(depends) declared on the Cabal package.

When this flag is enabled (--ignore-build-tools), a build-tool which
can't be found does not block compilation.

Fixes haskell#10061
  • Loading branch information
alt-romes committed Jun 20, 2024
1 parent 1c00507 commit a178c23
Show file tree
Hide file tree
Showing 11 changed files with 84 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ md5CheckGenericPackageDescription proxy = md5Check proxy
md5CheckLocalBuildInfo :: Proxy LocalBuildInfo -> Assertion
md5CheckLocalBuildInfo proxy = md5Check proxy
#if MIN_VERSION_base(4,19,0)
0xdff58fe5e7f9568c67cd982eaba7edc2
0x7698165c53daaa3058415d0c89870fb8
#else
0x4e50a4a95779b862edde3d6696797251
#endif
50 changes: 27 additions & 23 deletions Cabal/src/Distribution/Simple/Configure.hs
Original file line number Diff line number Diff line change
Expand Up @@ -848,29 +848,33 @@ configurePackage cfg lbc0 pkg_descr00 flags enabled comp platform programDb0 pac
-- right before calling configurePackage?

-- Configure certain external build tools, see below for which ones.
let requiredBuildTools = do
bi <- enabledBuildInfos pkg_descr0 enabled
-- First, we collect any tool dep that we know is external. This is,
-- in practice:
--
-- 1. `build-tools` entries on the whitelist
--
-- 2. `build-tool-depends` that aren't from the current package.
let externBuildToolDeps =
[ LegacyExeDependency (unUnqualComponentName eName) versionRange
| buildTool@(ExeDependency _ eName versionRange) <-
getAllToolDependencies pkg_descr0 bi
, not $ isInternal pkg_descr0 buildTool
]
-- Second, we collect any build-tools entry we don't know how to
-- desugar. We'll never have any idea how to build them, so we just
-- hope they are already on the PATH.
let unknownBuildTools =
[ buildTool
| buildTool <- buildTools bi
, Nothing == desugarBuildTool pkg_descr0 buildTool
]
externBuildToolDeps ++ unknownBuildTools
let requiredBuildTools
-- If --ignore-build-tools is set, no build tool is required:
| fromFlagOrDefault False $ configIgnoreBuildTools cfg =
[]
| otherwise = do
bi <- enabledBuildInfos pkg_descr0 enabled
-- First, we collect any tool dep that we know is external. This is,
-- in practice:
--
-- 1. `build-tools` entries on the whitelist
--
-- 2. `build-tool-depends` that aren't from the current package.
let externBuildToolDeps =
[ LegacyExeDependency (unUnqualComponentName eName) versionRange
| buildTool@(ExeDependency _ eName versionRange) <-
getAllToolDependencies pkg_descr0 bi
, not $ isInternal pkg_descr0 buildTool
]
-- Second, we collect any build-tools entry we don't know how to
-- desugar. We'll never have any idea how to build them, so we just
-- hope they are already on the PATH.
let unknownBuildTools =
[ buildTool
| buildTool <- buildTools bi
, Nothing == desugarBuildTool pkg_descr0 buildTool
]
externBuildToolDeps ++ unknownBuildTools

programDb1 <-
configureAllKnownPrograms (lessVerbose verbosity) programDb0
Expand Down
15 changes: 15 additions & 0 deletions Cabal/src/Distribution/Simple/Setup/Config.hs
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,10 @@ data ConfigFlags = ConfigFlags
-- testsuites run with @--enable-coverage@. Notably, this list must exclude
-- indefinite libraries and instantiations because HPC does not support
-- backpack (Nov. 2023).
, configIgnoreBuildTools :: Flag Bool
-- ^ When this flag is set, all tools declared in `build-tool`s and
-- `build-tool-depends` will be ignored. This allows a Cabal package with
-- build-tool-dependencies to be built even if the tool is not found.
}
deriving (Generic, Read, Show, Typeable)

Expand Down Expand Up @@ -319,7 +323,9 @@ instance Eq ConfigFlags where
&& equal configDebugInfo
&& equal configDumpBuildInfo
&& equal configUseResponseFiles
&& equal configAllowDependingOnPrivateLibs
&& equal configCoverageFor
&& equal configIgnoreBuildTools
where
equal f = on (==) f a b

Expand Down Expand Up @@ -856,6 +862,15 @@ configureOptions showOrParseArgs =
(Flag . (: []) . fromString)
(fmap prettyShow . fromFlagOrDefault [])
)
, option
""
["ignore-build-tools"]
( "Ignore build tool dependencies. "
++ "If set, declared build tools needn't be found for compilation to proceed."
)
configIgnoreBuildTools
(\v flags -> flags{configIgnoreBuildTools = v})
trueArg
]
where
liftInstallDirs =
Expand Down
1 change: 1 addition & 0 deletions cabal-install/src/Distribution/Client/Config.hs
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,7 @@ instance Semigroup SavedConfig where
, configAllowDependingOnPrivateLibs =
combine configAllowDependingOnPrivateLibs
, configCoverageFor = combine configCoverageFor
, configIgnoreBuildTools = combine configIgnoreBuildTools
}
where
combine = combine' savedConfigureFlags
Expand Down
2 changes: 2 additions & 0 deletions cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs
Original file line number Diff line number Diff line change
Expand Up @@ -1112,6 +1112,7 @@ convertToLegacyAllPackageConfig
, configDumpBuildInfo = mempty
, configAllowDependingOnPrivateLibs = mempty
, configCoverageFor = mempty
, configIgnoreBuildTools = mempty
}

haddockFlags =
Expand Down Expand Up @@ -1188,6 +1189,7 @@ convertToLegacyPerPackageConfig PackageConfig{..} =
, configDumpBuildInfo = packageConfigDumpBuildInfo
, configAllowDependingOnPrivateLibs = mempty
, configCoverageFor = mempty
, configIgnoreBuildTools = mempty
}

installFlags =
Expand Down
1 change: 1 addition & 0 deletions cabal-install/src/Distribution/Client/ProjectPlanning.hs
Original file line number Diff line number Diff line change
Expand Up @@ -3960,6 +3960,7 @@ setupHsConfigureFlags
configPrograms_ = mempty -- never use, shouldn't exist
configUseResponseFiles = mempty
configAllowDependingOnPrivateLibs = Flag $ not $ libraryVisibilitySupported pkgConfigCompiler
configIgnoreBuildTools = mempty

cidToGivenComponent :: ConfiguredId -> GivenComponent
cidToGivenComponent (ConfiguredId srcid mb_cn cid) = GivenComponent (packageName srcid) ln cid
Expand Down
10 changes: 7 additions & 3 deletions cabal-install/src/Distribution/Client/Setup.hs
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,7 @@ filterConfigureFlags' :: ConfigFlags -> Version -> ConfigFlags
filterConfigureFlags' flags cabalLibVersion
-- NB: we expect the latest version to be the most common case,
-- so test it first.
| cabalLibVersion >= mkVersion [3, 11, 0] = flags_latest
| cabalLibVersion >= mkVersion [3, 12, 0] = flags_latest
-- The naming convention is that flags_version gives flags with
-- all flags *introduced* in version eliminated.
-- It is NOT the latest version of Cabal library that
Expand All @@ -701,15 +701,19 @@ filterConfigureFlags' flags cabalLibVersion
| cabalLibVersion < mkVersion [2, 5, 0] = flags_2_5_0
| cabalLibVersion < mkVersion [3, 7, 0] = flags_3_7_0
| cabalLibVersion < mkVersion [3, 11, 0] = flags_3_11_0
| cabalLibVersion < mkVersion [3, 12, 0] = flags_3_12_0
| otherwise = error "the impossible just happened" -- see first guard
where
flags_latest =
flags
flags_latest = flags

flags_3_12_0 =
flags_latest
{ -- Cabal >= 1.19.1 uses '--dependency' and does not need '--constraint'.
-- Note: this is not in the wrong place. configConstraints gets
-- repopulated in flags_1_19_1 but it needs to be set to empty for
-- newer versions first.
configConstraints = []
, configIgnoreBuildTools = NoFlag
}

flags_3_11_0 =
Expand Down
7 changes: 7 additions & 0 deletions cabal-testsuite/PackageTests/IgnoreBuildTools/Hello.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module Main where

a :: String
a = "0000"

main :: IO ()
main = putStrLn a
13 changes: 13 additions & 0 deletions cabal-testsuite/PackageTests/IgnoreBuildTools/client.cabal
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
cabal-version: 3.0
name: client
version: 0.1.0.0
license: MIT
category: Testing
build-type: Simple

executable hello-world
main-is: Hello.hs
build-depends: base
build-tool-depends: pre-proc:zero-to-one, another:non-existent
-- build-tools: somethingnonexists
default-language: Haskell2010
5 changes: 5 additions & 0 deletions cabal-testsuite/PackageTests/IgnoreBuildTools/setup.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Setup configure
Configuring client-0.1.0.0...
# Setup build
Preprocessing executable 'hello-world' for client-0.1.0.0...
Building executable 'hello-world' for client-0.1.0.0...
5 changes: 5 additions & 0 deletions cabal-testsuite/PackageTests/IgnoreBuildTools/setup.test.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import Test.Cabal.Prelude
-- Test --ignore-build-tools ignores build-tools and build-tool-depends
main = setupTest $ do
setup "configure" ["--ignore-build-tools"]
setup "build" []

0 comments on commit a178c23

Please sign in to comment.