From ef56d7257f95ef6366f0ad7048de8dcb98203a7a Mon Sep 17 00:00:00 2001 From: Rodrigo Mesquita Date: Thu, 20 Jun 2024 10:52:50 +0100 Subject: [PATCH] Cabal: Add flag to ignore build tool dependencies 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 #10061 --- .../Distribution/Utils/Structured.hs | 4 +- Cabal/src/Distribution/Simple/Configure.hs | 50 ++++++++++--------- Cabal/src/Distribution/Simple/Setup/Config.hs | 15 ++++++ .../src/Distribution/Client/Config.hs | 1 + .../Client/ProjectConfig/Legacy.hs | 2 + .../Distribution/Client/ProjectPlanning.hs | 1 + .../src/Distribution/Client/Setup.hs | 1 + .../PackageTests/IgnoreBuildTools/Hello.hs | 7 +++ .../IgnoreBuildTools/client.cabal | 13 +++++ .../PackageTests/IgnoreBuildTools/setup.out | 5 ++ .../IgnoreBuildTools/setup.test.hs | 5 ++ changelog.d/pr-10128 | 12 +++++ 12 files changed, 91 insertions(+), 25 deletions(-) create mode 100644 cabal-testsuite/PackageTests/IgnoreBuildTools/Hello.hs create mode 100644 cabal-testsuite/PackageTests/IgnoreBuildTools/client.cabal create mode 100644 cabal-testsuite/PackageTests/IgnoreBuildTools/setup.out create mode 100644 cabal-testsuite/PackageTests/IgnoreBuildTools/setup.test.hs create mode 100644 changelog.d/pr-10128 diff --git a/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs b/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs index d600a51fa05..63841cba729 100644 --- a/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs +++ b/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs @@ -41,7 +41,7 @@ md5CheckGenericPackageDescription proxy = md5Check proxy md5CheckLocalBuildInfo :: Proxy LocalBuildInfo -> Assertion md5CheckLocalBuildInfo proxy = md5Check proxy #if MIN_VERSION_base(4,19,0) - 0x31b94dc3e61eb01fea1a1c3c73d984ee + 0x6809d4d86ae1810f2a032bc90c952b76 #else - 0xdc2f5e7a9c696a4e0bd64f02a0140b74 + 0x9409dca80a2e1522b1c3a39356e9aaef #endif diff --git a/Cabal/src/Distribution/Simple/Configure.hs b/Cabal/src/Distribution/Simple/Configure.hs index aa0e2a3a438..cae6dd7d101 100644 --- a/Cabal/src/Distribution/Simple/Configure.hs +++ b/Cabal/src/Distribution/Simple/Configure.hs @@ -858,29 +858,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 diff --git a/Cabal/src/Distribution/Simple/Setup/Config.hs b/Cabal/src/Distribution/Simple/Setup/Config.hs index 88c970e162f..244f442af46 100644 --- a/Cabal/src/Distribution/Simple/Setup/Config.hs +++ b/Cabal/src/Distribution/Simple/Setup/Config.hs @@ -230,6 +230,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) @@ -322,7 +326,9 @@ instance Eq ConfigFlags where && equal configDebugInfo && equal configDumpBuildInfo && equal configUseResponseFiles + && equal configAllowDependingOnPrivateLibs && equal configCoverageFor + && equal configIgnoreBuildTools where equal f = on (==) f a b @@ -866,6 +872,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 = diff --git a/cabal-install/src/Distribution/Client/Config.hs b/cabal-install/src/Distribution/Client/Config.hs index 5930ca98c13..951155d365b 100644 --- a/cabal-install/src/Distribution/Client/Config.hs +++ b/cabal-install/src/Distribution/Client/Config.hs @@ -546,6 +546,7 @@ instance Semigroup SavedConfig where , configAllowDependingOnPrivateLibs = combine configAllowDependingOnPrivateLibs , configCoverageFor = combine configCoverageFor + , configIgnoreBuildTools = combine configIgnoreBuildTools } where combine = combine' savedConfigureFlags diff --git a/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs b/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs index 3d4dc29d8a0..0de745526c1 100644 --- a/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs +++ b/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs @@ -1114,6 +1114,7 @@ convertToLegacyAllPackageConfig , configDumpBuildInfo = mempty , configAllowDependingOnPrivateLibs = mempty , configCoverageFor = mempty + , configIgnoreBuildTools = mempty } haddockFlags = @@ -1191,6 +1192,7 @@ convertToLegacyPerPackageConfig PackageConfig{..} = , configDumpBuildInfo = packageConfigDumpBuildInfo , configAllowDependingOnPrivateLibs = mempty , configCoverageFor = mempty + , configIgnoreBuildTools = mempty } installFlags = diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index 0b099dac37c..19f9907703c 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -4047,6 +4047,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 diff --git a/cabal-install/src/Distribution/Client/Setup.hs b/cabal-install/src/Distribution/Client/Setup.hs index 0df20fb4569..a8db5c98106 100644 --- a/cabal-install/src/Distribution/Client/Setup.hs +++ b/cabal-install/src/Distribution/Client/Setup.hs @@ -718,6 +718,7 @@ filterConfigureFlags' flags cabalLibVersion flags_latest { -- Building profiled shared libraries configProfShared = NoFlag + , configIgnoreBuildTools = NoFlag } flags_3_11_0 = diff --git a/cabal-testsuite/PackageTests/IgnoreBuildTools/Hello.hs b/cabal-testsuite/PackageTests/IgnoreBuildTools/Hello.hs new file mode 100644 index 00000000000..4c2772407db --- /dev/null +++ b/cabal-testsuite/PackageTests/IgnoreBuildTools/Hello.hs @@ -0,0 +1,7 @@ +module Main where + +a :: String +a = "0000" + +main :: IO () +main = putStrLn a diff --git a/cabal-testsuite/PackageTests/IgnoreBuildTools/client.cabal b/cabal-testsuite/PackageTests/IgnoreBuildTools/client.cabal new file mode 100644 index 00000000000..fc69b378236 --- /dev/null +++ b/cabal-testsuite/PackageTests/IgnoreBuildTools/client.cabal @@ -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 diff --git a/cabal-testsuite/PackageTests/IgnoreBuildTools/setup.out b/cabal-testsuite/PackageTests/IgnoreBuildTools/setup.out new file mode 100644 index 00000000000..de3c1b9d6bc --- /dev/null +++ b/cabal-testsuite/PackageTests/IgnoreBuildTools/setup.out @@ -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... diff --git a/cabal-testsuite/PackageTests/IgnoreBuildTools/setup.test.hs b/cabal-testsuite/PackageTests/IgnoreBuildTools/setup.test.hs new file mode 100644 index 00000000000..0a0297ad454 --- /dev/null +++ b/cabal-testsuite/PackageTests/IgnoreBuildTools/setup.test.hs @@ -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" [] diff --git a/changelog.d/pr-10128 b/changelog.d/pr-10128 new file mode 100644 index 00000000000..8c7cc45d204 --- /dev/null +++ b/changelog.d/pr-10128 @@ -0,0 +1,12 @@ +synopsis: Add flag ignore-build-tools +packages: Cabal +prs: #10128 + +description: { + +- Adds flag --ignore-build-tools which allows a user to ignore the tool + dependencies declared in build-tool-depends. For general use, this flag + should never be needed, but it may be useful for packagers. + +} +