diff --git a/.stan.toml b/.stan.toml index 586019edb7..f5108a97ce 100644 --- a/.stan.toml +++ b/.stan.toml @@ -67,57 +67,57 @@ # Infinite: base/isSuffixOf # Usage of the 'isSuffixOf' function that hangs on infinite lists [[ignore]] - id = "OBS-STAN-0102-luLR/n-533:30" + id = "OBS-STAN-0102-luLR/n-540:30" # ✦ Category: #Infinite #List # ✦ File: src\Stack\New.hs # -# 532 ┃ -# 533 ┃ let isPkgSpec f = ".cabal" `L.isSuffixOf` f || "package.yaml" `L.isSuffixOf` f -# 534 ┃ ^^^^^^^^^^^^^^ +# 539 ┃ +# 540 ┃ let isPkgSpec f = ".cabal" `L.isSuffixOf` f || "package.yaml" `L.isSuffixOf` f +# 541 ┃ ^^^^^^^^^^^^^^ # Infinite: base/isSuffixOf # Usage of the 'isSuffixOf' function that hangs on infinite lists [[ignore]] - id = "OBS-STAN-0102-luLR/n-533:65" + id = "OBS-STAN-0102-luLR/n-540:65" # ✦ Category: #Infinite #List # ✦ File: src\Stack\New.hs # -# 532 ┃ -# 533 ┃ let isPkgSpec f = ".cabal" `L.isSuffixOf` f || "package.yaml" `L.isSuffixOf` f -# 534 ┃ ^^^^^^^^^^^^^^ +# 539 ┃ +# 540 ┃ let isPkgSpec f = ".cabal" `L.isSuffixOf` f || "package.yaml" `L.isSuffixOf` f +# 541 ┃ ^^^^^^^^^^^^^^ # Infinite: ghc-internal/isSuffixOf # Usage of the 'isSuffixOf' function that hangs on infinite lists [[ignore]] - id = "OBS-STAN-0102-8cspI6-400:41" + id = "OBS-STAN-0102-8cspI6-404:41" # ✦ Category: #Infinite #List # ✦ File: src\Stack\Coverage.hs # -# 399 ┃ -# 400 ┃ pure (filter ((".tix" `L.isSuffixOf`) . toFilePath) files) -# 401 ┃ ^^^^^^^^^^^^^^ +# 403 ┃ +# 404 ┃ pure (filter ((".tix" `L.isSuffixOf`) . toFilePath) files) +# 405 ┃ ^^^^^^^^^^^^^^ # Infinite: ghc-internal/isSuffixOf # Usage of the 'isSuffixOf' function that hangs on infinite lists [[ignore]] - id = "OBS-STAN-0102-8cspI6-433:31" + id = "OBS-STAN-0102-8cspI6-437:31" # ✦ Category: #Infinite #List # ✦ File: src\Stack\Coverage.hs # -# 432 ┃ -# 433 ┃ pure (filter ((".tix" `L.isSuffixOf`) . toFilePath) files) -# 434 ┃ ^^^^^^^^^^^^^^ +# 436 ┃ +# 437 ┃ pure (filter ((".tix" `L.isSuffixOf`) . toFilePath) files) +# 438 ┃ ^^^^^^^^^^^^^^ # Infinite: ghc-internal/isSuffixOf # Usage of the 'isSuffixOf' function that hangs on infinite lists [[ignore]] - id = "OBS-STAN-0102-8cspI6-664:30" + id = "OBS-STAN-0102-8cspI6-668:30" # ✦ Category: #Infinite #List # ✦ File: src\Stack\Coverage.hs # -# 663 ┃ -# 664 ┃ pure (filter ((".tix" `L.isSuffixOf`) . toFilePath) files) -# 665 ┃ ^^^^^^^^^^^^^^ +# 667 ┃ +# 668 ┃ pure (filter ((".tix" `L.isSuffixOf`) . toFilePath) files) +# 669 ┃ ^^^^^^^^^^^^^^ # Infinite: ghc-internal/isSuffixOf # Usage of the 'isSuffixOf' function that hangs on infinite lists @@ -140,25 +140,25 @@ # Anti-pattern: Data.ByteString.Char8.pack [[ignore]] - id = "OBS-STAN-0203-erw24B-1043:3" + id = "OBS-STAN-0203-erw24B-1079:3" # ✦ Description: Usage of 'pack' function that doesn't handle Unicode characters # ✦ Category: #AntiPattern # ✦ File: src\Stack\Build\ExecuteEnv.hs # -# 1042 ┃ -# 1043 ┃ S8.pack . formatTime defaultTimeLocale "%Y-%m-%dT%H:%M:%S%6Q" -# 1044 ┃ ^^^^^^^ +# 1078 ┃ +# 1079 ┃ S8.pack . formatTime defaultTimeLocale "%Y-%m-%dT%H:%M:%S%6Q" +# 1080 ┃ ^^^^^^^ # Anti-pattern: Data.ByteString.Char8.pack [[ignore]] - id = "OBS-STAN-0203-tuE+RG-249:24" + id = "OBS-STAN-0203-tuE+RG-250:24" # ✦ Description: Usage of 'pack' function that doesn't handle Unicode characters # ✦ Category: #AntiPattern # ✦ File: src\Stack\Build\ExecutePackage.hs # -# 248 ┃ -# 249 ┃ newConfigFileRoot <- S8.pack . toFilePath <$> view configFileRootL -# 250 ┃ ^^^^^^^ +# 249 ┃ +# 250 ┃ newConfigFileRoot <- S8.pack . toFilePath <$> view configFileRootL +# 251 ┃ ^^^^^^^ # Anti-pattern: Data.ByteString.Char8.pack [[ignore]] @@ -258,36 +258,36 @@ # Anti-pattern: unsafe functions [[ignore]] - id = "OBS-STAN-0212-FNS1cF-67:17" + id = "OBS-STAN-0212-FNS1cF-68:17" # ✦ Description: Usage of unsafe functions breaks referential transparency # ✦ Category: #Unsafe #AntiPattern # ✦ File: src\Stack\BuildOpts.hs # -# 66 ┃ -# 67 ┃ buildMonoid = undefined :: BuildOptsMonoid -# 68 ┃ ^^^^^^^^^ +# 67 ┃ +# 68 ┃ buildMonoid = undefined :: BuildOptsMonoid +# 69 ┃ ^^^^^^^^^ # Anti-pattern: unsafe functions [[ignore]] - id = "OBS-STAN-0212-FNS1cF-79:14" + id = "OBS-STAN-0212-FNS1cF-80:14" # ✦ Description: Usage of unsafe functions breaks referential transparency # ✦ Category: #Unsafe #AntiPattern # ✦ File: src\Stack\BuildOpts.hs # -# 78 ┃ -# 79 ┃ toMonoid = undefined :: TestOptsMonoid -# 80 ┃ ^^^^^^^^^ +# 79 ┃ +# 80 ┃ toMonoid = undefined :: TestOptsMonoid +# 81 ┃ ^^^^^^^^^ # Anti-pattern: unsafe functions [[ignore]] - id = "OBS-STAN-0212-FNS1cF-90:15" + id = "OBS-STAN-0212-FNS1cF-91:15" # ✦ Description: Usage of unsafe functions breaks referential transparency # ✦ Category: #Unsafe #AntiPattern # ✦ File: src/Stack/BuildOpts.hs # -# 89 ┃ -# 90 ┃ beoMonoid = undefined :: BenchmarkOptsMonoid -# 91 ┃ ^^^^^^^^^ +# 90 ┃ +# 91 ┃ beoMonoid = undefined :: BenchmarkOptsMonoid +# 92 ┃ ^^^^^^^^^ # Anti-pattern: Pattern matching on '_' # Pattern matching on '_' for sum types can create maintainability issues diff --git a/ChangeLog.md b/ChangeLog.md index 7bc39a1831..779d5e7aa3 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -12,6 +12,10 @@ Behavior changes: Other enhancements: +* Add flag `--[no-]semaphore` (default: disabled) to Stack's `build` command, + to allow GHC to use a system semaphore to perform compilation in parallel when + possible. Supported, by default, by GHC 9.10.1 or later. + Bug fixes: ## v3.9.3 - 2026-02-19 diff --git a/doc/commands/build_command.md b/doc/commands/build_command.md index 3515acd25d..f9245105e5 100644 --- a/doc/commands/build_command.md +++ b/doc/commands/build_command.md @@ -7,11 +7,12 @@ stack build [TARGET] [--dry-run] [--pedantic] [--fast] [--ghc-options OPTIONS] [--flag PACKAGE:[-]FLAG] [--dependencies-only | --only-snapshot | --only-dependencies | --only-locals] [--file-watch | --file-watch-poll] [--watch-all] [--exec COMMAND [ARGUMENT(S)]] - [--only-configure] [--trace] [--profile] [--no-strip] - [--[no-]library-profiling] [--[no-]executable-profiling] - [--[no-]library-stripping] [--[no-]executable-stripping] - [--[no-]haddock] [--haddock-arguments HADDOCK_ARGS] - [--[no-]open] [--[no-]haddock-deps] [--[no-]haddock-internal] + [--only-configure] [--[no-]semaphore] [--trace] [--profile] + [--no-strip] [--[no-]library-profiling] + [--[no-]executable-profiling] [--[no-]library-stripping] + [--[no-]executable-stripping] [--[no-]haddock] + [--haddock-arguments HADDOCK_ARGS] [--[no-]open] + [--[no-]haddock-deps] [--[no-]haddock-internal] [--[no-]haddock-hyperlink-source] [--[no-]haddock-for-hackage] [--[no-]copy-bins] [--[no-]copy-compiler-tool] [--[no-]prefetch] [--[no-]keep-going] [--[no-]keep-tmp-files] [--[no-]force-dirty] @@ -916,6 +917,23 @@ expressions, and generate a profiling report in tests or benchmarks. The flag affects the location of the local project installation directory. See the [`stack path --local-install-root`](path_command.md) command. +### `--[no]-semaphore` flag + +:octicons-tag-24: UNRELEASED + +Default: Disabled + +This flag allows GHC to use a system semaphore to perform compilation in +parallel when possible. + +!!! info + + GHC 9.8.1 and later can act as a jobserver client, which enables two or more + GHC processes running at once to share system resources with each other, + communicating via a system semaphore. This GHC feature is supported by + Cabal 3.12.0.0 (a boot package of GHC 9.10.1) and later. The flag is ignored + with a warning when the feature is unsupported. + ### `--[no-]split-objs` flag :octicons-beaker-24: Experimental @@ -1140,7 +1158,7 @@ where the test suite takes the form of an executable and the executable takes nothing on the standard input stream (`stdin`). Pass this flag to override that specification and allow the executable to receive input on that stream. If you pass `--no-tests-allow-stdin` and the executable seeks input on the standard -input stream, an exception will be thown. +input stream, an exception will be thrown. ## Examples diff --git a/doc/configure/yaml/non-project.md b/doc/configure/yaml/non-project.md index e05ccd93a7..8607963bdb 100644 --- a/doc/configure/yaml/non-project.md +++ b/doc/configure/yaml/non-project.md @@ -157,6 +157,11 @@ Default: ~~~yaml build: + # Since Stack UNRELEASED. Supported by GHC 9.8.1 or later with Cabal 3.12.0.0 + # (a boot package of GHC 9.10.1) or later. Ignored with a warning when + # unsupported. + semaphore: false + library-profiling: false executable-profiling: false library-stripping: true diff --git a/package.yaml b/package.yaml index 52cda3e04a..42f8aa4354 100644 --- a/package.yaml +++ b/package.yaml @@ -120,6 +120,7 @@ dependencies: - random - rio >= 0.1.22.0 && ( < 0.1.23.0 || > 0.1.23.0 ) - rio-prettyprint >= 0.1.8.0 +- semaphore-compat - split - stm - tar >= 0.6.2.0 diff --git a/src/Stack/Build/ExecuteEnv.hs b/src/Stack/Build/ExecuteEnv.hs index 11f4837b88..dfee2c548e 100644 --- a/src/Stack/Build/ExecuteEnv.hs +++ b/src/Stack/Build/ExecuteEnv.hs @@ -54,6 +54,7 @@ import qualified Distribution.Simple.Build.Macros as C import Distribution.System ( OS (..), Platform (..) ) import Distribution.Types.PackageName ( mkPackageName ) import Distribution.Verbosity ( showForCabal ) +import Distribution.Version ( mkVersion ) import Path ( PathException, (), parent, parseRelDir, parseRelFile ) import Path.Extra ( forgivingResolveFile, toFilePathNoTrailingSep ) @@ -86,7 +87,9 @@ import Stack.Types.BuildOpts ( BuildOpts (..) ) import Stack.Types.BuildOptsCLI ( BuildOptsCLI (..) ) import Stack.Types.BuildOptsMonoid ( CabalVerbosity (..) ) import Stack.Types.Compiler - ( WhichCompiler (..), compilerVersionString, whichCompilerL ) + ( WhichCompiler (..), compilerVersionString + , getGhcVersion, whichCompilerL + ) import Stack.Types.CompilerPaths ( CompilerPaths (..), HasCompiler (..), cabalVersionL , getCompilerPath @@ -115,6 +118,8 @@ import qualified System.Directory as D import System.Environment ( lookupEnv ) import System.FileLock ( SharedExclusive (..), withFileLock, withTryFileLock ) +import System.Semaphore + ( Semaphore, destroySemaphore, freshSemaphore ) -- | Type representing environments in which the @Setup.hs@ commands of Cabal -- (the library) can be executed. @@ -147,6 +152,8 @@ data ExecuteEnv = ExecuteEnv -- ^ For nicer interleaved output: track the largest package name size , pathEnvVar :: !Text -- ^ Value of the PATH environment variable + , semaphore :: !(Maybe Semaphore) + -- ^ The semaphore that is used for job control, if --semaphore is given } -- | Type representing setup executable circumstances. @@ -256,6 +263,9 @@ getSetupExe setupHs setupShimHs tmpdir = do renameFile tmpExePath exePath pure $ Just exePath +semaphorePrefix :: String +semaphorePrefix = "stack" + -- | Execute a function that takes an t'ExecuteEnv'. withExecuteEnv :: forall env a. HasEnvConfig env @@ -320,6 +330,8 @@ withExecuteEnv ignoringAbsence (removeFile setupO) ignoringAbsence (removeFile setupShimHi) ignoringAbsence (removeFile setupShimO) + compilerVersion <- view actualCompilerVersionL + let ghcVersion = getGhcVersion compilerVersion cabalPkgVer <- view cabalVersionL globalDB <- view $ compilerPathsL . to (.globalDB) let globalDumpPkgs = toDumpPackagesByGhcPkgId globalPackages @@ -330,6 +342,27 @@ withExecuteEnv logFiles <- liftIO $ atomically newTChan let totalWanted = length $ filter (.wanted) locals pathEnvVar <- liftIO $ maybe mempty T.pack <$> lookupEnv "PATH" + jobs <- view $ configL . to (.jobs) + let semaphoreSupported = + (cabalPkgVer >= mkVersion [3, 12, 0, 0]) + && (ghcVersion >= mkVersion [9, 8, 1]) + semaphoreUnsupportedWarning = + prettyWarnL + [ "The" + , style Shell "--semaphore" + , flow "flag was specified, which is supported by GHC 9.8.1 or \ + \later with Cabal 3.12.0.0 (a boot package of GHC 9.10.1) \ + \or later. GHC version" + , fromString (versionString ghcVersion) + , flow "and Cabal version" + , fromString (versionString cabalPkgVer) + , flow "was found. The flag will be ignored." + ] + semaphore <- if not buildOpts.semaphore + then pure Nothing + else if semaphoreSupported + then Just <$> liftIO (freshSemaphore semaphorePrefix jobs) + else semaphoreUnsupportedWarning >> pure Nothing inner ExecuteEnv { buildOpts , buildOptsCLI @@ -355,7 +388,10 @@ withExecuteEnv , customBuilt , largestPackageName , pathEnvVar - } `finally` dumpLogs logFiles totalWanted + , semaphore + } `finally` do + liftIO (whenJust semaphore destroySemaphore) + dumpLogs logFiles totalWanted where toDumpPackagesByGhcPkgId = Map.fromList . map (\dp -> (dp.ghcPkgId, dp)) diff --git a/src/Stack/Build/ExecutePackage.hs b/src/Stack/Build/ExecutePackage.hs index 33d95f05d2..b03d1d2b02 100644 --- a/src/Stack/Build/ExecutePackage.hs +++ b/src/Stack/Build/ExecutePackage.hs @@ -151,6 +151,7 @@ import System.IO.Error ( isDoesNotExistError ) import System.PosixCompat.Files ( createLink, getFileStatus, modificationTime ) import System.Random ( randomIO ) +import System.Semaphore ( Semaphore (..), SemaphoreName (..) ) -- | Generate the t'ConfigCache' value. getConfigCache :: @@ -569,7 +570,7 @@ realConfigAndBuild <> display actualCompiler ) config <- view configL - extraOpts <- extraBuildOptions wc ee.buildOpts + extraOpts <- extraBuildOptions wc ee.buildOpts ee.semaphore let stripTHLoading | config.hideTHLoading = ExcludeTHLoading | otherwise = KeepTHLoading @@ -1294,17 +1295,22 @@ extraBuildOptions :: (HasEnvConfig env, HasRunner env) => WhichCompiler -> BuildOpts + -> Maybe Semaphore -> RIO env [String] -extraBuildOptions wc bopts = do +extraBuildOptions wc bopts semaphore = do colorOpt <- appropriateGhcColorFlag let optsFlag = compilerOptionsCabalFlag wc + semaphoreFlag = maybe + [] + (("--semaphore":) . L.singleton . getSemaphoreName . semaphoreName) + semaphore baseOpts = maybe "" (" " ++) colorOpt if bopts.testOpts.coverage then do hpcIndexDir <- toFilePathNoTrailingSep <$> hpcRelativeDir - pure [optsFlag, "-hpcdir " ++ hpcIndexDir ++ baseOpts] + pure $ semaphoreFlag ++ [optsFlag, "-hpcdir " ++ hpcIndexDir ++ baseOpts] else - pure [optsFlag, baseOpts] + pure $ semaphoreFlag ++ [optsFlag, baseOpts] -- Library, sub-library, foreign library and executable build components. primaryComponentOptions :: LocalPackage -> [String] diff --git a/src/Stack/BuildOpts.hs b/src/Stack/BuildOpts.hs index 86d27dd834..649c26250e 100644 --- a/src/Stack/BuildOpts.hs +++ b/src/Stack/BuildOpts.hs @@ -62,6 +62,7 @@ defaultBuildOpts = BuildOpts , interleavedOutput = defaultFirstTrue buildMonoid.interleavedOutput , progressBar = CappedBar , ddumpDir = Nothing + , semaphore = defaultFirstFalse buildMonoid.semaphore } where buildMonoid = undefined :: BuildOptsMonoid diff --git a/src/Stack/Config/Build.hs b/src/Stack/Config/Build.hs index 8a43b8df21..afd020a9f8 100644 --- a/src/Stack/Config/Build.hs +++ b/src/Stack/Config/Build.hs @@ -95,6 +95,7 @@ buildOptsFromMonoid buildMonoid = BuildOpts , interleavedOutput = fromFirstTrue buildMonoid.interleavedOutput , progressBar = fromFirst CappedBar buildMonoid.progressBar , ddumpDir = getFirst buildMonoid.ddumpDir + , semaphore = fromFirstFalse buildMonoid.semaphore } where isHaddockFromHackage = fromFirstFalse buildMonoid.haddockForHackage diff --git a/src/Stack/Options/BuildMonoidParser.hs b/src/Stack/Options/BuildMonoidParser.hs index 640836e7c1..7de4eeaa78 100644 --- a/src/Stack/Options/BuildMonoidParser.hs +++ b/src/Stack/Options/BuildMonoidParser.hs @@ -36,7 +36,8 @@ import Stack.Types.ComponentUtils ( unqualCompFromString ) -- | Parse command line arguments for build configuration. buildOptsMonoidParser :: GlobalOptsContext -> Parser BuildOptsMonoid buildOptsMonoidParser hide0 = BuildOptsMonoid - <$> trace' + <$> semaphore + <*> trace' <*> profile <*> noStrip <*> libProfiling @@ -244,6 +245,11 @@ buildOptsMonoidParser hide0 = BuildOptsMonoid <> help "Specify output directory for ddump-files." <> hide )) + semaphore = firstBoolFlagsFalse + "semaphore" + "the use of a system semaphore to perform compilation in parallel when \ + \possible. Supported, by default, by GHC 9.10.1 or later." + hide -- | Parser for Cabal verbosity options cabalVerbosityOptsParser :: Bool -> Parser (First CabalVerbosity) diff --git a/src/Stack/Types/BuildOpts.hs b/src/Stack/Types/BuildOpts.hs index 1a7da7eddd..bdff5a886a 100644 --- a/src/Stack/Types/BuildOpts.hs +++ b/src/Stack/Types/BuildOpts.hs @@ -18,6 +18,7 @@ module Stack.Types.BuildOpts , BenchmarkOpts (..) , buildOptsHaddockL , buildOptsInstallExesL + , buildOptsSemaphoreL ) where import Stack.Prelude @@ -95,6 +96,9 @@ data BuildOpts = BuildOpts , progressBar :: !ProgressBarFormat -- ^ Format of the progress bar , ddumpDir :: !(Maybe Text) + , semaphore :: !Bool + -- ^ Use Cabal's --semaphore=SEMAPHORE option to build modules of the same + -- package in parallel. } deriving Show @@ -131,3 +135,7 @@ buildOptsInstallExesL = buildOptsHaddockL :: Lens' BuildOpts Bool buildOptsHaddockL = lens (.buildHaddocks) (\bopts t -> bopts {buildHaddocks = t}) + +buildOptsSemaphoreL :: Lens' BuildOpts Bool +buildOptsSemaphoreL = + lens (.semaphore) (\bopts t -> bopts {semaphore = t}) diff --git a/src/Stack/Types/BuildOptsMonoid.hs b/src/Stack/Types/BuildOptsMonoid.hs index 8d02a106e3..a6f378f60c 100644 --- a/src/Stack/Types/BuildOptsMonoid.hs +++ b/src/Stack/Types/BuildOptsMonoid.hs @@ -24,6 +24,7 @@ module Stack.Types.BuildOptsMonoid , buildOptsMonoidTestsL , buildOptsMonoidBenchmarksL , buildOptsMonoidInstallExesL + , buildOptsMonoidSemaphoreL , toFirstCabalVerbosity , readProgressBarFormat ) where @@ -43,7 +44,8 @@ import Stack.Types.ComponentUtils ( StackUnqualCompName ) -- | Build options that may be specified as non-project specific configuration -- options under the build key (with certain exceptions) or from the CLI. data BuildOptsMonoid = BuildOptsMonoid - { trace :: !Any + { semaphore :: !FirstFalse + , trace :: !Any -- ^ Cannot be specified under the build key , profile :: !Any -- ^ Cannot be specified under the build key @@ -121,8 +123,10 @@ instance FromJSON (WithJSONWarnings BuildOptsMonoid) where interleavedOutput <- FirstTrue <$> o ..:? interleavedOutputName progressBar <- First <$> o ..:? progressBarName ddumpDir <- o ..:? ddumpDirName ..!= mempty + semaphore <- FirstFalse <$> o ..:? semaphoreArgName pure BuildOptsMonoid - { trace + { semaphore + , trace , profile , noStrip , libProfile @@ -254,6 +258,9 @@ progressBarName = "progress-bar" ddumpDirName :: Text ddumpDirName = "ddump-dir" +semaphoreArgName :: Text +semaphoreArgName = "semaphore" + instance Semigroup BuildOptsMonoid where (<>) = mappenddefault @@ -403,6 +410,11 @@ buildOptsMonoidInstallExesL = lens (.installExes.firstFalse) (\buildMonoid t -> buildMonoid {installExes = FirstFalse t}) +buildOptsMonoidSemaphoreL :: Lens' BuildOptsMonoid (Maybe Bool) +buildOptsMonoidSemaphoreL = + lens (.semaphore.firstFalse) + (\buildMonoid t -> buildMonoid {semaphore = FirstFalse t}) + -- Type representing formats of Stack's progress bar when building. data ProgressBarFormat = NoBar -- No progress bar at all. diff --git a/stack.cabal b/stack.cabal index 0a35d9cecb..58e9c912c0 100644 --- a/stack.cabal +++ b/stack.cabal @@ -1,6 +1,6 @@ cabal-version: 2.2 --- This file has been generated from package.yaml by hpack version 0.39.1. +-- This file has been generated from package.yaml by hpack version 0.38.1. -- -- see: https://github.com/sol/hpack @@ -473,6 +473,7 @@ library , random , rio >=0.1.22.0 && (<0.1.23.0 || >0.1.23.0) , rio-prettyprint >=0.1.8.0 + , semaphore-compat , split , stm , tar >=0.6.2.0 @@ -596,6 +597,7 @@ executable stack , random , rio >=0.1.22.0 && (<0.1.23.0 || >0.1.23.0) , rio-prettyprint >=0.1.8.0 + , semaphore-compat , split , stack , stm @@ -701,6 +703,7 @@ executable stack-integration-test , random , rio >=0.1.22.0 && (<0.1.23.0 || >0.1.23.0) , rio-prettyprint >=0.1.8.0 + , semaphore-compat , split , stm , tar >=0.6.2.0 @@ -819,6 +822,7 @@ test-suite stack-unit-test , raw-strings-qq , rio >=0.1.22.0 && (<0.1.23.0 || >0.1.23.0) , rio-prettyprint >=0.1.8.0 + , semaphore-compat , split , stack , stm diff --git a/tests/unit/Stack/ConfigSpec.hs b/tests/unit/Stack/ConfigSpec.hs index cbabbede89..0f66d79f45 100644 --- a/tests/unit/Stack/ConfigSpec.hs +++ b/tests/unit/Stack/ConfigSpec.hs @@ -61,6 +61,7 @@ buildOptsConfig = "snapshot: lts-24.24\n" ++ "packages: ['.']\n" ++ "build:\n" ++ + " semaphore: true\n" ++ " library-profiling: true\n" ++ " executable-profiling: true\n" ++ " library-stripping: false\n" ++ @@ -228,6 +229,7 @@ spec = beforeAll setup $ do writeFile (toFilePath stackDotYaml) buildOptsConfig loadConfig' $ \config -> liftIO $ do let bopts = config.build + bopts.semaphore `shouldBe` True bopts.libProfile `shouldBe` True bopts.exeProfile `shouldBe` True bopts.libStrip `shouldBe` False