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 58355cd
Show file tree
Hide file tree
Showing 10 changed files with 83 additions and 26 deletions.
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 58355cd

Please sign in to comment.