diff --git a/Cabal/Cabal.cabal b/Cabal/Cabal.cabal index 7dd7bec5b06..52f1c1b09e0 100644 --- a/Cabal/Cabal.cabal +++ b/Cabal/Cabal.cabal @@ -88,6 +88,7 @@ library Distribution.Simple Distribution.Simple.Bench Distribution.Simple.Build + Distribution.Simple.Build.ExtraSources Distribution.Simple.Build.Macros Distribution.Simple.Build.Monad Distribution.Simple.Build.PackageInfoModule diff --git a/Cabal/src/Distribution/Simple/Build.hs b/Cabal/src/Distribution/Simple/Build.hs index 429afced1ba..afe571d7196 100644 --- a/Cabal/src/Distribution/Simple/Build.hs +++ b/Cabal/src/Distribution/Simple/Build.hs @@ -161,7 +161,7 @@ build pkg_descr lbi flags suffixes = do NoFlag -> Serial mb_ipi <- buildComponent - verbosity + flags par_strat pkg_descr lbi' @@ -301,7 +301,7 @@ repl pkg_descr lbi flags suffixes args = do lbi' = lbiForComponent comp lbi preBuildComponent verbosity lbi subtarget buildComponent - verbosity + mempty{buildVerbosity = toFlag verbosity} NoFlag pkg_descr lbi' @@ -316,9 +316,8 @@ repl pkg_descr lbi flags suffixes args = do let clbi = targetCLBI target comp = targetComponent target lbi' = lbiForComponent comp lbi - replFlags = replReplOptions flags preBuildComponent verbosity lbi target - replComponent replFlags verbosity pkg_descr lbi' suffixes comp clbi distPref + replComponent flags verbosity pkg_descr lbi' suffixes comp clbi distPref -- | Start an interpreter without loading any package files. startInterpreter @@ -335,7 +334,7 @@ startInterpreter verbosity programDb comp platform packageDBs = _ -> dieWithException verbosity REPLNotSupported buildComponent - :: Verbosity + :: BuildFlags -> Flag ParStrat -> PackageDescription -> LocalBuildInfo @@ -344,12 +343,12 @@ buildComponent -> ComponentLocalBuildInfo -> FilePath -> IO (Maybe InstalledPackageInfo) -buildComponent verbosity _ _ _ _ (CTest TestSuite{testInterface = TestSuiteUnsupported tt}) _ _ = - dieWithException verbosity $ NoSupportBuildingTestSuite tt -buildComponent verbosity _ _ _ _ (CBench Benchmark{benchmarkInterface = BenchmarkUnsupported tt}) _ _ = - dieWithException verbosity $ NoSupportBuildingBenchMark tt +buildComponent flags _ _ _ _ (CTest TestSuite{testInterface = TestSuiteUnsupported tt}) _ _ = + dieWithException (fromFlag $ buildVerbosity flags) $ NoSupportBuildingTestSuite tt +buildComponent flags _ _ _ _ (CBench Benchmark{benchmarkInterface = BenchmarkUnsupported tt}) _ _ = + dieWithException (fromFlag $ buildVerbosity flags) $ NoSupportBuildingBenchMark tt buildComponent - verbosity + flags numJobs pkg_descr lbi0 @@ -364,6 +363,7 @@ buildComponent -- built. distPref = do + let verbosity = fromFlag $ buildVerbosity flags pwd <- getCurrentDirectory let (pkg, lib, libClbi, lbi, ipi, exe, exeClbi) = testSuiteLibV09AsLibAndExe pkg_descr test clbi lbi0 distPref pwd @@ -378,7 +378,7 @@ buildComponent (maybeComponentInstantiatedWith clbi) let libbi = libBuildInfo lib lib' = lib{libBuildInfo = addSrcDir (addExtraOtherModules libbi generatedExtras) genDir} - buildLib verbosity numJobs pkg lbi lib' libClbi + buildLib flags numJobs pkg lbi lib' libClbi -- NB: need to enable multiple instances here, because on 7.10+ -- the package name is the same as the library, and we still -- want the registration to go through. @@ -399,7 +399,7 @@ buildComponent buildExe verbosity numJobs pkg_descr lbi exe' exeClbi return Nothing -- Can't depend on test suite buildComponent - verbosity + flags numJobs pkg_descr lbi @@ -408,6 +408,7 @@ buildComponent clbi distPref = do + let verbosity = fromFlag $ buildVerbosity flags preprocessComponent pkg_descr comp lbi clbi False verbosity suffixes extras <- preprocessExtras verbosity comp lbi setupMessage' @@ -430,7 +431,7 @@ buildComponent libbi } - buildLib verbosity numJobs pkg_descr lbi lib' clbi + buildLib flags numJobs pkg_descr lbi lib' clbi let oneComponentRequested (OneComponentRequestedSpec _) = True oneComponentRequested _ = False @@ -573,7 +574,7 @@ addSrcDir bi extra = bi{hsSourceDirs = new} new = ordNub (unsafeMakeSymbolicPath extra : hsSourceDirs bi) replComponent - :: ReplOptions + :: ReplFlags -> Verbosity -> PackageDescription -> LocalBuildInfo @@ -604,7 +605,7 @@ replComponent extras <- preprocessExtras verbosity comp lbi let libbi = libBuildInfo lib lib' = lib{libBuildInfo = libbi{cSources = cSources libbi ++ extras}} - replLib replFlags verbosity pkg lbi lib' libClbi + replLib replFlags pkg lbi lib' libClbi replComponent replFlags verbosity @@ -621,23 +622,23 @@ replComponent CLib lib -> do let libbi = libBuildInfo lib lib' = lib{libBuildInfo = libbi{cSources = cSources libbi ++ extras}} - replLib replFlags verbosity pkg_descr lbi lib' clbi + replLib replFlags pkg_descr lbi lib' clbi CFLib flib -> - replFLib replFlags verbosity pkg_descr lbi flib clbi + replFLib replFlags pkg_descr lbi flib clbi CExe exe -> do let ebi = buildInfo exe exe' = exe{buildInfo = ebi{cSources = cSources ebi ++ extras}} - replExe replFlags verbosity pkg_descr lbi exe' clbi + replExe replFlags pkg_descr lbi exe' clbi CTest test@TestSuite{testInterface = TestSuiteExeV10{}} -> do let exe = testSuiteExeV10AsExe test let ebi = buildInfo exe exe' = exe{buildInfo = ebi{cSources = cSources ebi ++ extras}} - replExe replFlags verbosity pkg_descr lbi exe' clbi + replExe replFlags pkg_descr lbi exe' clbi CBench bm@Benchmark{benchmarkInterface = BenchmarkExeV10{}} -> do let exe = benchmarkExeV10asExe bm let ebi = buildInfo exe exe' = exe{buildInfo = ebi{cSources = cSources ebi ++ extras}} - replExe replFlags verbosity pkg_descr lbi exe' clbi + replExe replFlags pkg_descr lbi exe' clbi #if __GLASGOW_HASKELL__ < 811 -- silence pattern-match warnings prior to GHC 9.0 _ -> error "impossible" @@ -822,20 +823,21 @@ addInternalBuildTools pkg lbi bi progs = -- TODO: build separate libs in separate dirs so that we can build -- multiple libs, e.g. for 'LibTest' library-style test suites buildLib - :: Verbosity + :: BuildFlags -> Flag ParStrat -> PackageDescription -> LocalBuildInfo -> Library -> ComponentLocalBuildInfo -> IO () -buildLib verbosity numJobs pkg_descr lbi lib clbi = - case compilerFlavor (compiler lbi) of - GHC -> GHC.buildLib verbosity numJobs pkg_descr lbi lib clbi - GHCJS -> GHCJS.buildLib verbosity numJobs pkg_descr lbi lib clbi - UHC -> UHC.buildLib verbosity pkg_descr lbi lib clbi - HaskellSuite{} -> HaskellSuite.buildLib verbosity pkg_descr lbi lib clbi - _ -> dieWithException verbosity BuildingNotSupportedWithCompiler +buildLib flags numJobs pkg_descr lbi lib clbi = + let verbosity = fromFlag $ buildVerbosity flags + in case compilerFlavor (compiler lbi) of + GHC -> GHC.buildLib flags numJobs pkg_descr lbi lib clbi + GHCJS -> GHCJS.buildLib verbosity numJobs pkg_descr lbi lib clbi + UHC -> UHC.buildLib verbosity pkg_descr lbi lib clbi + HaskellSuite{} -> HaskellSuite.buildLib verbosity pkg_descr lbi lib clbi + _ -> dieWithException verbosity BuildingNotSupportedWithCompiler -- | Build a foreign library -- @@ -870,47 +872,48 @@ buildExe verbosity numJobs pkg_descr lbi exe clbi = _ -> dieWithException verbosity BuildingNotSupportedWithCompiler replLib - :: ReplOptions - -> Verbosity + :: ReplFlags -> PackageDescription -> LocalBuildInfo -> Library -> ComponentLocalBuildInfo -> IO () -replLib replFlags verbosity pkg_descr lbi lib clbi = - case compilerFlavor (compiler lbi) of - -- 'cabal repl' doesn't need to support 'ghc --make -j', so we just pass - -- NoFlag as the numJobs parameter. - GHC -> GHC.replLib replFlags verbosity NoFlag pkg_descr lbi lib clbi - GHCJS -> GHCJS.replLib (replOptionsFlags replFlags) verbosity NoFlag pkg_descr lbi lib clbi - _ -> dieWithException verbosity REPLNotSupported +replLib replFlags pkg_descr lbi lib clbi = + let verbosity = fromFlag $ replVerbosity replFlags + opts = replReplOptions replFlags + in case compilerFlavor (compiler lbi) of + -- 'cabal repl' doesn't need to support 'ghc --make -j', so we just pass + -- NoFlag as the numJobs parameter. + GHC -> GHC.replLib replFlags NoFlag pkg_descr lbi lib clbi + GHCJS -> GHCJS.replLib (replOptionsFlags opts) verbosity NoFlag pkg_descr lbi lib clbi + _ -> dieWithException verbosity REPLNotSupported replExe - :: ReplOptions - -> Verbosity + :: ReplFlags -> PackageDescription -> LocalBuildInfo -> Executable -> ComponentLocalBuildInfo -> IO () -replExe replFlags verbosity pkg_descr lbi exe clbi = - case compilerFlavor (compiler lbi) of - GHC -> GHC.replExe replFlags verbosity NoFlag pkg_descr lbi exe clbi - GHCJS -> GHCJS.replExe (replOptionsFlags replFlags) verbosity NoFlag pkg_descr lbi exe clbi - _ -> dieWithException verbosity REPLNotSupported +replExe flags pkg_descr lbi exe clbi = + let verbosity = fromFlag $ replVerbosity flags + in case compilerFlavor (compiler lbi) of + GHC -> GHC.replExe flags NoFlag pkg_descr lbi exe clbi + GHCJS -> GHCJS.replExe (replOptionsFlags $ replReplOptions flags) verbosity NoFlag pkg_descr lbi exe clbi + _ -> dieWithException verbosity REPLNotSupported replFLib - :: ReplOptions - -> Verbosity + :: ReplFlags -> PackageDescription -> LocalBuildInfo -> ForeignLib -> ComponentLocalBuildInfo -> IO () -replFLib replFlags verbosity pkg_descr lbi exe clbi = - case compilerFlavor (compiler lbi) of - GHC -> GHC.replFLib replFlags verbosity NoFlag pkg_descr lbi exe clbi - _ -> dieWithException verbosity REPLNotSupported +replFLib flags pkg_descr lbi exe clbi = + let verbosity = fromFlag $ replVerbosity flags + in case compilerFlavor (compiler lbi) of + GHC -> GHC.replFLib flags NoFlag pkg_descr lbi exe clbi + _ -> dieWithException verbosity REPLNotSupported -- | Pre-build steps for a component: creates the autogenerated files -- for a particular configured component. diff --git a/Cabal/src/Distribution/Simple/Build/ExtraSources.hs b/Cabal/src/Distribution/Simple/Build/ExtraSources.hs new file mode 100644 index 00000000000..82391c91743 --- /dev/null +++ b/Cabal/src/Distribution/Simple/Build/ExtraSources.hs @@ -0,0 +1,230 @@ +{-# LANGUAGE BlockArguments #-} +{-# LANGUAGE DisambiguateRecordFields #-} +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE NamedFieldPuns #-} + +module Distribution.Simple.Build.ExtraSources where + +import Control.Monad +import Data.Foldable +import Distribution.Simple.Flag +import qualified Distribution.Simple.GHC.Internal as Internal +import Distribution.Simple.Program.GHC +import Distribution.Simple.Utils + +import Distribution.Simple.Program.Builtin (ghcProgram) +import Distribution.Types.BuildInfo +import Distribution.Types.Component +import Distribution.Types.TargetInfo + +import Distribution.Simple.GHC.Build +import Distribution.Simple.LocalBuildInfo +import Distribution.Simple.Program (requireProgram) +import Distribution.Types.ComponentName (componentNameRaw) +import Distribution.Types.Executable +import Distribution.Verbosity (Verbosity) +import System.FilePath + +import Distribution.Simple.Build.Monad + +buildAllExtraSources :: BuildM () +buildAllExtraSources = + sequence_ + [ buildCSources + , buildCxxSources + , buildJsSources + , buildAsmSources + , buildCmmSources + ] + +-- ROMES:TODO: +-- unless (not hasJsSupport || null jsSrcs) $ ... and (not has_code) +-- where has_code = not (componentIsIndefinite clbi) + +-- ROMES:PATCH:NOTE: Worry about mimicking the current behaviour first, and only +-- later worry about dependency tracking and ghc -M, gcc -M, or ghc -optc-MD ... + +-- ROMES:TODO: +-- How should we handle a C source depending on a stub generated from a foreign export? + +buildCSources + , buildCxxSources + , buildJsSources + , buildAsmSources + , buildCmmSources + :: BuildM () +-- Currently, an executable main file may be a C++ or C file, in which case we want to +-- compile it alongside other C/C++ sources. Eventually, we may be able to +-- compile other main files as build sources (e.g. ObjC...). This functionality +-- may also be provided in standalone packages, since nothing precludes users +-- from writing their own build rules for declared foreign modules in main-is +-- and eventually custom stanzas. +buildCSources = + buildExtraSources + "C Sources" + Internal.componentCcGhcOptions + True + ( \c -> + cSources (componentBuildInfo c) + ++ case c of + CExe exe | isC (modulePath exe) -> [modulePath exe] + _otherwise -> [] + ) +buildCxxSources = + buildExtraSources + "C++ Sources" + Internal.componentCxxGhcOptions + True + ( \c -> + cxxSources (componentBuildInfo c) + ++ case c of + CExe exe | isCxx (modulePath exe) -> [modulePath exe] + _otherwise -> [] + ) +buildJsSources = + buildExtraSources + "JS Sources" + Internal.componentJsGhcOptions + False + (jsSources . componentBuildInfo) +buildAsmSources = + buildExtraSources + "Assembler Sources" + Internal.componentAsmGhcOptions + True + (asmSources . componentBuildInfo) +buildCmmSources = + buildExtraSources + "C-- Sources" + Internal.componentCmmGhcOptions + True + (cmmSources . componentBuildInfo) + +-- | Create 'PreBuildComponentRules' for a given type of extra build sources +-- which are compiled via a GHC invocation with the given options. Used to +-- define built-in extra sources, such as, C, Cxx, Js, Asm, and Cmm sources. +buildExtraSources + :: String + -- ^ String describing the extra sources being built, for printing. + -> (Verbosity -> LocalBuildInfo -> BuildInfo -> ComponentLocalBuildInfo -> FilePath -> FilePath -> GhcOptions) + -- ^ Function to determine the @'GhcOptions'@ for the + -- invocation of GHC when compiling these extra sources (e.g. + -- @'Internal.componentCxxGhcOptions'@, + -- @'Internal.componentCmmGhcOptions'@) + -> Bool + -- ^ Want dynamic? + -> (Component -> [FilePath]) + -- ^ View the extra sources of a component, typically from + -- the build info (e.g. @'asmSources'@, @'cSources'@). + -- @'Executable'@ components might additionally add the + -- program entry point (@main-is@ file) to the extra sources, + -- if it should be compiled as the rest of them. + -> BuildM () +buildExtraSources description componentSourceGhcOptions wantDyn viewSources = + BuildM \PreBuildComponentInputs{buildingWhat, localBuildInfo = lbi, targetInfo} -> + let + bi = componentBuildInfo (targetComponent targetInfo) + verbosity = buildingWhatVerbosity buildingWhat + clbi = targetCLBI targetInfo + + sources = viewSources (targetComponent targetInfo) + + comp = compiler lbi + platform = hostPlatform lbi + isGhcDynamic = isDynamic comp + doingTH = usesTemplateHaskellOrQQ bi + forceSharedLib = doingTH && isGhcDynamic + + buildAction sourceFile = do + (ghcProg, _) <- requireProgram verbosity ghcProgram (withPrograms lbi) + let runGhcProg = runGHC verbosity ghcProg comp platform + + let baseSrcOpts = + componentSourceGhcOptions + verbosity + lbi + bi + clbi + buildDir' + sourceFile + vanillaSrcOpts + -- Dynamic GHC requires C sources to be built + -- with -fPIC for REPL to work. See #2207. + | isGhcDynamic && wantDyn = baseSrcOpts{ghcOptFPic = toFlag True} + | otherwise = baseSrcOpts + profSrcOpts = + vanillaSrcOpts + `mappend` mempty + { ghcOptProfilingMode = toFlag True + } + sharedSrcOpts = + vanillaSrcOpts + `mappend` mempty + { ghcOptFPic = toFlag True + , ghcOptDynLinkMode = toFlag GhcDynamicOnly + } + -- TODO: Placing all Haskell, C, & C++ objects in a single directory + -- Has the potential for file collisions. In general we would + -- consider this a user error. However, we should strive to + -- add a warning if this occurs. + odir = fromFlag (ghcOptObjDir vanillaSrcOpts) + compileIfNeeded opts = do + needsRecomp <- checkNeedsRecompilation sourceFile opts + when needsRecomp $ runGhcProg opts + + createDirectoryIfMissingVerbose verbosity True odir + case targetComponent targetInfo of + -- For libraries, we compile extra objects in the three ways: vanilla, shared, and profiled. + -- We suffix shared objects with .dyn_o and profiled ones with .p_o. + -- + -- ROMES:TODO: Should we use those suffixes for extra sources for + -- executables too? We use those suffixes for haskell objects for + -- executables ... (see gbuild) + CLib _lib + -- Unless for repl, in which case we only need the vanilla way + | BuildRepl _ <- buildingWhat -> + compileIfNeeded vanillaSrcOpts + | otherwise -> + do + compileIfNeeded vanillaSrcOpts + when (wantDyn && (forceSharedLib || withSharedLib lbi)) $ + compileIfNeeded sharedSrcOpts{ghcOptObjSuffix = toFlag "dyn_o"} + when (withProfLib lbi) $ + compileIfNeeded profSrcOpts{ghcOptObjSuffix = toFlag "p_o"} + + -- For foreign libraries, we determine with which options to build the + -- objects (vanilla vs shared vs profiled) + CFLib flib + | withProfExe lbi -> -- ROMES: hmm... doesn't sound right. + compileIfNeeded profSrcOpts + | flibIsDynamic flib -> + compileIfNeeded sharedSrcOpts + | otherwise -> + compileIfNeeded vanillaSrcOpts + -- For the remaining component types (Exec, Test, Bench), we also + -- determine with which options to build the objects (vanilla vs shared vs + -- profiled), but predicate is the same for the three kinds. + _exeLike + | withProfExe lbi -> + compileIfNeeded profSrcOpts + | withDynExe lbi -> + compileIfNeeded sharedSrcOpts + | otherwise -> + compileIfNeeded vanillaSrcOpts + + -- Until we get rid of the "exename-tmp" directory within the executable + -- build dir, we need to accommodate that fact (see eg @tmpDir@ in @gbuild@) + -- This is a workaround for #9498 until it is fixed. + cname = componentName (targetComponent targetInfo) + buildDir' + | CLibName{} <- cname = + componentBuildDir lbi clbi + | CNotLibName{} <- cname = + componentBuildDir lbi clbi + componentNameRaw cname <> "-tmp" + in + do + -- build any sources + unless (null sources) $ do + info verbosity ("Building " ++ description ++ "...") + traverse_ buildAction sources diff --git a/Cabal/src/Distribution/Simple/GHC.hs b/Cabal/src/Distribution/Simple/GHC.hs index 1a6d0d5d86d..f239eb9a824 100644 --- a/Cabal/src/Distribution/Simple/GHC.hs +++ b/Cabal/src/Distribution/Simple/GHC.hs @@ -57,7 +57,7 @@ module Distribution.Simple.GHC , hcPkgInfo , registerPackage , componentGhcOptions - , componentCcGhcOptions + , Internal.componentCcGhcOptions , getGhcAppDir , getLibDir , isDynamic @@ -144,6 +144,8 @@ import System.Posix (createSymbolicLink) import Distribution.Simple.GHC.BuildGeneric (GBuildMode (..), gbuild) import Distribution.Simple.GHC.BuildOrRepl (buildOrReplLib) +import Distribution.Simple.Setup (BuildingWhat (..)) +import Distribution.Simple.Setup.Build -- ----------------------------------------------------------------------------- -- Configuring @@ -570,25 +572,24 @@ getInstalledPackagesMonitorFiles verbosity platform progdb = -- Building a library buildLib - :: Verbosity + :: BuildFlags -> Flag ParStrat -> PackageDescription -> LocalBuildInfo -> Library -> ComponentLocalBuildInfo -> IO () -buildLib = buildOrReplLib Nothing +buildLib = buildOrReplLib . Left replLib - :: ReplOptions - -> Verbosity + :: ReplFlags -> Flag ParStrat -> PackageDescription -> LocalBuildInfo -> Library -> ComponentLocalBuildInfo -> IO () -replLib = buildOrReplLib . Just +replLib = buildOrReplLib . Right -- | Start a REPL without loading any source files. startInterpreter @@ -620,19 +621,18 @@ buildFLib -> ForeignLib -> ComponentLocalBuildInfo -> IO () -buildFLib v njobs pkg lbi = gbuild v njobs pkg lbi . GBuildFLib +buildFLib v njobs pkg lbi = gbuild (BuildNormal mempty{buildVerbosity = toFlag v}) njobs pkg lbi . GBuildFLib replFLib - :: ReplOptions - -> Verbosity + :: ReplFlags -> Flag ParStrat -> PackageDescription -> LocalBuildInfo -> ForeignLib -> ComponentLocalBuildInfo -> IO () -replFLib replFlags v njobs pkg lbi = - gbuild v njobs pkg lbi . GReplFLib replFlags +replFLib replFlags njobs pkg lbi = + gbuild (BuildRepl replFlags) njobs pkg lbi . GReplFLib (replReplOptions replFlags) -- | Build an executable with GHC. buildExe @@ -643,19 +643,18 @@ buildExe -> Executable -> ComponentLocalBuildInfo -> IO () -buildExe v njobs pkg lbi = gbuild v njobs pkg lbi . GBuildExe +buildExe v njobs pkg lbi = gbuild (BuildNormal mempty{buildVerbosity = toFlag v}) njobs pkg lbi . GBuildExe replExe - :: ReplOptions - -> Verbosity + :: ReplFlags -> Flag ParStrat -> PackageDescription -> LocalBuildInfo -> Executable -> ComponentLocalBuildInfo -> IO () -replExe replFlags v njobs pkg lbi = - gbuild v njobs pkg lbi . GReplExe replFlags +replExe replFlags njobs pkg lbi = + gbuild (BuildRepl replFlags) njobs pkg lbi . GReplExe (replReplOptions replFlags) -- | Extracts a String representing a hash of the ABI of a built -- library. It can fail if the library has not yet been built. @@ -713,20 +712,6 @@ libAbiHash verbosity _pkg_descr lbi lib clbi = do return (takeWhile (not . isSpace) hash) -componentCcGhcOptions - :: Verbosity - -> LocalBuildInfo - -> BuildInfo - -> ComponentLocalBuildInfo - -> FilePath - -> FilePath - -> GhcOptions -componentCcGhcOptions verbosity lbi = - Internal.componentCcGhcOptions verbosity implInfo lbi - where - comp = compiler lbi - implInfo = getImplInfo comp - -- ----------------------------------------------------------------------------- -- Installing @@ -863,47 +848,47 @@ installLib verbosity lbi targetDir dynlibTargetDir _builtDir pkg lib clbi = do whenGHCi $ installOrdinary builtDir targetDir ghciProfLibName whenShared $ if - -- The behavior for "extra-bundled-libraries" changed in version 2.5.0. - -- See ghc issue #15837 and Cabal PR #5855. - | specVersion pkg < CabalSpecV3_0 -> do - sequence_ - [ installShared - builtDir - dynlibTargetDir - (mkGenericSharedLibName platform compiler_id (l ++ f)) - | l <- getHSLibraryName uid : extraBundledLibs (libBuildInfo lib) - , f <- "" : extraDynLibFlavours (libBuildInfo lib) - ] - | otherwise -> do - sequence_ - [ installShared - builtDir - dynlibTargetDir - ( mkGenericSharedLibName - platform - compiler_id - (getHSLibraryName uid ++ f) - ) - | f <- "" : extraDynLibFlavours (libBuildInfo lib) - ] - sequence_ - [ do - files <- getDirectoryContents builtDir - let l' = - mkGenericSharedBundledLibName - platform - compiler_id - l - forM_ files $ \file -> - when (l' `isPrefixOf` file) $ do - isFile <- doesFileExist (builtDir file) - when isFile $ do - installShared - builtDir - dynlibTargetDir - file - | l <- extraBundledLibs (libBuildInfo lib) - ] + -- The behavior for "extra-bundled-libraries" changed in version 2.5.0. + -- See ghc issue #15837 and Cabal PR #5855. + | specVersion pkg < CabalSpecV3_0 -> do + sequence_ + [ installShared + builtDir + dynlibTargetDir + (mkGenericSharedLibName platform compiler_id (l ++ f)) + | l <- getHSLibraryName uid : extraBundledLibs (libBuildInfo lib) + , f <- "" : extraDynLibFlavours (libBuildInfo lib) + ] + | otherwise -> do + sequence_ + [ installShared + builtDir + dynlibTargetDir + ( mkGenericSharedLibName + platform + compiler_id + (getHSLibraryName uid ++ f) + ) + | f <- "" : extraDynLibFlavours (libBuildInfo lib) + ] + sequence_ + [ do + files <- getDirectoryContents builtDir + let l' = + mkGenericSharedBundledLibName + platform + compiler_id + l + forM_ files $ \file -> + when (l' `isPrefixOf` file) $ do + isFile <- doesFileExist (builtDir file) + when isFile $ do + installShared + builtDir + dynlibTargetDir + file + | l <- extraBundledLibs (libBuildInfo lib) + ] where builtDir = componentBuildDir lbi clbi diff --git a/Cabal/src/Distribution/Simple/GHC/Build.hs b/Cabal/src/Distribution/Simple/GHC/Build.hs index 4afd2a03a2f..a00a0afaabd 100644 --- a/Cabal/src/Distribution/Simple/GHC/Build.hs +++ b/Cabal/src/Distribution/Simple/GHC/Build.hs @@ -6,9 +6,14 @@ module Distribution.Simple.GHC.Build , componentGhcOptions , supportsDynamicToo , isDynamic + , findExecutableMain , flibBuildName , flibTargetName + , flibIsDynamic , exeTargetName + , isCxx + , isC + , isHaskell ) where @@ -35,6 +40,7 @@ import Distribution.Simple.Setup.Repl import Distribution.Simple.Utils import Distribution.System import Distribution.Utils.NubList +import Distribution.Utils.Path (getSymbolicPath) import Distribution.Verbosity import Distribution.Version import System.Directory @@ -55,6 +61,18 @@ exeTargetName platform exe = unUnqualComponentName (exeName exe) `withExt` exeEx withExt :: FilePath -> String -> FilePath withExt fp ext = fp <.> if takeExtension fp /= ('.' : ext) then ext else "" +-- | Find the path to the entry point of an executable (typically specified in +-- @main-is@, and found in @hs-source-dirs@). +findExecutableMain + :: Verbosity + -> FilePath + -- ^ Build directory + -> Executable + -> IO FilePath + -- ^ The path to the main source file. +findExecutableMain verbosity bdir Executable{buildInfo = bnfo, modulePath = modPath} = + findFileEx verbosity (bdir : map getSymbolicPath (hsSourceDirs bnfo)) modPath + -- | Target name for a foreign library (the actual file name) -- -- We do not use mkLibName and co here because the naming for foreign libraries @@ -127,12 +145,34 @@ flibBuildName lbi flib nm :: String nm = unUnqualComponentName $ foreignLibName flib +flibIsDynamic :: ForeignLib -> Bool +flibIsDynamic flib = + case foreignLibType flib of + ForeignLibNativeShared -> + ForeignLibStandalone `notElem` foreignLibOptions flib + ForeignLibNativeStatic -> + False + ForeignLibTypeUnknown -> + cabalBug "unknown foreign lib type" + supportsDynamicToo :: Compiler -> Bool supportsDynamicToo = Internal.ghcLookupProperty "Support dynamic-too" isDynamic :: Compiler -> Bool isDynamic = Internal.ghcLookupProperty "GHC Dynamic" +-- | Is this file a C++ source file, i.e. ends with .cpp, .cxx, or .c++? +isCxx :: FilePath -> Bool +isCxx fp = elem (takeExtension fp) [".cpp", ".cxx", ".c++"] + +-- | Is this a C source file, i.e. ends with .c? +isC :: FilePath -> Bool +isC fp = elem (takeExtension fp) [".c"] + +-- | FilePath has a Haskell extension: .hs or .lhs +isHaskell :: FilePath -> Bool +isHaskell fp = elem (takeExtension fp) [".hs", ".lhs"] + componentGhcOptions :: Verbosity -> LocalBuildInfo diff --git a/Cabal/src/Distribution/Simple/GHC/BuildGeneric.hs b/Cabal/src/Distribution/Simple/GHC/BuildGeneric.hs index 330cc656d04..d9aa0f62c31 100644 --- a/Cabal/src/Distribution/Simple/GHC/BuildGeneric.hs +++ b/Cabal/src/Distribution/Simple/GHC/BuildGeneric.hs @@ -1,3 +1,5 @@ +{-# LANGUAGE LambdaCase #-} + module Distribution.Simple.GHC.BuildGeneric ( GBuildMode (..) , gbuild @@ -17,21 +19,11 @@ import Distribution.Package import Distribution.PackageDescription as PD import Distribution.PackageDescription.Utils (cabalBug) import Distribution.Pretty +import Distribution.Simple.Build.ExtraSources +import Distribution.Simple.Build.Monad import Distribution.Simple.BuildPaths import Distribution.Simple.Compiler import Distribution.Simple.GHC.Build - ( checkNeedsRecompilation - , componentGhcOptions - , exeTargetName - , flibBuildName - , flibTargetName - , getRPaths - , isDynamic - , replNoLoad - , runReplOrWriteFlags - , supportsDynamicToo - ) -import Distribution.Simple.GHC.ImplInfo import qualified Distribution.Simple.GHC.Internal as Internal import qualified Distribution.Simple.Hpc as Hpc import Distribution.Simple.LocalBuildInfo @@ -45,7 +37,6 @@ import Distribution.System import Distribution.Types.PackageName.Magic import Distribution.Types.ParStrat import Distribution.Utils.NubList -import Distribution.Utils.Path import Distribution.Verbosity import Distribution.Version import System.Directory @@ -56,7 +47,6 @@ import System.Directory ) import System.FilePath ( replaceExtension - , takeExtension , () ) @@ -147,17 +137,15 @@ gbuildNeedDynamic lbi bm = case bm of GBuildExe _ -> withDynExe lbi GReplExe _ _ -> withDynExe lbi - GBuildFLib flib -> withDynFLib flib - GReplFLib _ flib -> withDynFLib flib - where - withDynFLib flib = - case foreignLibType flib of - ForeignLibNativeShared -> - ForeignLibStandalone `notElem` foreignLibOptions flib - ForeignLibNativeStatic -> - False - ForeignLibTypeUnknown -> - cabalBug "unknown foreign lib type" + GBuildFLib flib -> flibIsDynamic flib + GReplFLib _ flib -> flibIsDynamic flib + +gbuildComp :: GBuildMode -> Component +gbuildComp = \case + GBuildExe exe -> CExe exe + GReplExe _ exe -> CExe exe + GBuildFLib flib -> CFLib flib + GReplFLib _ flib -> CFLib flib -- | Locate and return the 'BuildSources' required to build and link. gbuildSources @@ -175,8 +163,8 @@ gbuildSources verbosity pkgId specVer tmpDir bm = GReplFLib _ flib -> return $ flibSources flib where exeSources :: Executable -> IO BuildSources - exeSources exe@Executable{buildInfo = bnfo, modulePath = modPath} = do - main <- findFileEx verbosity (tmpDir : map getSymbolicPath (hsSourceDirs bnfo)) modPath + exeSources exe@Executable{buildInfo = bnfo} = do + main <- findExecutableMain verbosity tmpDir exe let mainModName = fromMaybe ModuleName.main $ exeMainModuleName exe otherModNames = exeModules exe @@ -254,9 +242,6 @@ gbuildSources verbosity pkgId specVer tmpDir bm = , inputSourceModules = foreignLibModules flib } - isCxx :: FilePath -> Bool - isCxx fp = elem (takeExtension fp) [".cpp", ".cxx", ".c++"] - -- | Extract (and compute) information about the RTS library -- -- TODO: This hardcodes the name as @HSrts-ghc@. I don't know if we can @@ -306,10 +291,6 @@ hasThreaded bi = elem "-threaded" ghc where PerCompilerFlavor ghc _ = options bi --- | FilePath has a Haskell extension: .hs or .lhs -isHaskell :: FilePath -> Bool -isHaskell fp = elem (takeExtension fp) [".hs", ".lhs"] - -- | "Main" module name when overridden by @ghc-options: -main-is ...@ -- or 'Nothing' if no @-main-is@ flag could be found. -- @@ -364,14 +345,15 @@ decodeMainIsArg arg -- | Generic build function. See comment for 'GBuildMode'. gbuild - :: Verbosity + :: BuildingWhat -> Flag ParStrat -> PackageDescription -> LocalBuildInfo -> GBuildMode -> ComponentLocalBuildInfo -> IO () -gbuild verbosity numJobs pkg_descr lbi bm clbi = do +gbuild what numJobs pkg_descr lbi bm clbi = do + let verbosity = buildingWhatVerbosity what (ghcProg, _) <- requireProgram verbosity ghcProgram (withPrograms lbi) let replFlags = case bm of GReplExe flags _ -> flags @@ -380,7 +362,6 @@ gbuild verbosity numJobs pkg_descr lbi bm clbi = do GBuildFLib{} -> mempty comp = compiler lbi platform = hostPlatform lbi - implInfo = getImplInfo comp runGhcProg = runGHC verbosity ghcProg comp platform let bnfo = gbuildInfo bm @@ -596,74 +577,7 @@ gbuild verbosity numJobs pkg_descr lbi bm clbi = do , ghcOptNumJobs = numJobs } - let - buildExtraSources mkSrcOpts wantDyn = traverse_ $ buildExtraSource mkSrcOpts wantDyn - buildExtraSource mkSrcOpts wantDyn filename = do - let baseSrcOpts = - mkSrcOpts - verbosity - implInfo - lbi - bnfo - clbi - tmpDir - filename - vanillaSrcOpts = - if isGhcDynamic && wantDyn - then -- Dynamic GHC requires C/C++ sources to be built - -- with -fPIC for REPL to work. See #2207. - baseSrcOpts{ghcOptFPic = toFlag True} - else baseSrcOpts - profSrcOpts = - vanillaSrcOpts - `mappend` mempty - { ghcOptProfilingMode = toFlag True - } - sharedSrcOpts = - vanillaSrcOpts - `mappend` mempty - { ghcOptFPic = toFlag True - , ghcOptDynLinkMode = toFlag GhcDynamicOnly - } - opts - | needProfiling = profSrcOpts - | needDynamic && wantDyn = sharedSrcOpts - | otherwise = vanillaSrcOpts - -- TODO: Placing all Haskell, C, & C++ objects in a single directory - -- Has the potential for file collisions. In general we would - -- consider this a user error. However, we should strive to - -- add a warning if this occurs. - odir = fromFlag (ghcOptObjDir opts) - - createDirectoryIfMissingVerbose verbosity True odir - needsRecomp <- checkNeedsRecompilation filename opts - when needsRecomp $ - runGhcProg opts - - -- build any C++ sources - unless (null cxxSrcs) $ do - info verbosity "Building C++ Sources..." - buildExtraSources Internal.componentCxxGhcOptions True cxxSrcs - - -- build any C sources - unless (null cSrcs) $ do - info verbosity "Building C Sources..." - buildExtraSources Internal.componentCcGhcOptions True cSrcs - - -- build any JS sources - unless (not hasJsSupport || null jsSrcs) $ do - info verbosity "Building JS Sources..." - buildExtraSources Internal.componentJsGhcOptions False jsSrcs - - -- build any ASM sources - unless (null asmSrcs) $ do - info verbosity "Building Assembler Sources..." - buildExtraSources Internal.componentAsmGhcOptions True asmSrcs - - -- build any Cmm sources - unless (null cmmSrcs) $ do - info verbosity "Building C-- Sources..." - buildExtraSources Internal.componentCmmGhcOptions True cmmSrcs + runBuildM what lbi (TargetInfo clbi (gbuildComp bm)) buildAllExtraSources -- TODO: problem here is we need the .c files built first, so we can load them -- with ghci, but .c files can depend on .h files generated by ghc by ffi diff --git a/Cabal/src/Distribution/Simple/GHC/BuildOrRepl.hs b/Cabal/src/Distribution/Simple/GHC/BuildOrRepl.hs index 64a8f0a6c40..1f87d081107 100644 --- a/Cabal/src/Distribution/Simple/GHC/BuildOrRepl.hs +++ b/Cabal/src/Distribution/Simple/GHC/BuildOrRepl.hs @@ -3,15 +3,15 @@ module Distribution.Simple.GHC.BuildOrRepl (buildOrReplLib) where import Distribution.Compat.Prelude import Prelude () -import Control.Monad (forM_) import qualified Distribution.ModuleName as ModuleName import Distribution.Package import Distribution.PackageDescription as PD +import Distribution.Simple.Build.ExtraSources +import Distribution.Simple.Build.Monad import Distribution.Simple.BuildPaths import Distribution.Simple.Compiler import Distribution.Simple.GHC.Build - ( checkNeedsRecompilation - , componentGhcOptions + ( componentGhcOptions , getRPaths , isDynamic , replNoLoad @@ -26,14 +26,15 @@ import Distribution.Simple.Program import qualified Distribution.Simple.Program.Ar as Ar import Distribution.Simple.Program.GHC import qualified Distribution.Simple.Program.Ld as Ld +import Distribution.Simple.Setup.Build import Distribution.Simple.Setup.Common import Distribution.Simple.Setup.Repl import Distribution.Simple.Utils import Distribution.System import Distribution.Types.ComponentLocalBuildInfo import Distribution.Types.ParStrat +import Distribution.Types.TargetInfo import Distribution.Utils.NubList -import Distribution.Verbosity import Distribution.Version import System.Directory ( doesDirectoryExist @@ -45,16 +46,15 @@ import System.FilePath ) buildOrReplLib - :: Maybe ReplOptions - -> Verbosity + :: BuildingWhat -> Flag ParStrat -> PackageDescription -> LocalBuildInfo -> Library -> ComponentLocalBuildInfo -> IO () -buildOrReplLib mReplFlags verbosity numJobs pkg_descr lbi lib clbi = do - let uid = componentUnitId clbi +buildOrReplLib what numJobs pkg_descr lbi lib clbi = do + let uid = componentUnitId clbi libTargetDir = componentBuildDir lbi clbi whenVanillaLib forceVanilla = when (forceVanilla || withVanillaLib lbi) @@ -64,15 +64,16 @@ buildOrReplLib mReplFlags verbosity numJobs pkg_descr lbi lib clbi = do whenStaticLib forceStatic = when (forceStatic || withStaticLib lbi) whenGHCiLib = when (withGHCiLib lbi) - forRepl = maybe False (const True) mReplFlags - whenReplLib = forM_ mReplFlags - replFlags = fromMaybe mempty mReplFlags + forRepl = case what of BuildRepl{} -> True; _ -> False + whenReplLib f = case what of BuildRepl flags -> f (replReplOptions flags); _ -> pure () + replFlags = case what of BuildRepl flags -> replReplOptions flags; _ -> mempty comp = compiler lbi ghcVersion = compilerVersion comp implInfo = getImplInfo comp platform@(Platform hostArch hostOS) = hostPlatform lbi hasJsSupport = hostArch == JavaScript has_code = not (componentIsIndefinite clbi) + verbosity = buildingWhatVerbosity what relLibTargetDir <- makeRelativeToCurrentDirectory libTargetDir @@ -240,72 +241,7 @@ buildOrReplLib mReplFlags verbosity numJobs pkg_descr lbi lib clbi = do else do vanilla; shared whenProfLib (runGhcProg profOpts) - let - buildExtraSources mkSrcOpts wantDyn = traverse_ $ buildExtraSource mkSrcOpts wantDyn - buildExtraSource mkSrcOpts wantDyn filename = do - let baseSrcOpts = - mkSrcOpts - verbosity - implInfo - lbi - libBi - clbi - relLibTargetDir - filename - vanillaSrcOpts - -- Dynamic GHC requires C sources to be built - -- with -fPIC for REPL to work. See #2207. - | isGhcDynamic && wantDyn = baseSrcOpts{ghcOptFPic = toFlag True} - | otherwise = baseSrcOpts - runGhcProgIfNeeded opts = do - needsRecomp <- checkNeedsRecompilation filename opts - when needsRecomp $ runGhcProg opts - profSrcOpts = - vanillaSrcOpts - `mappend` mempty - { ghcOptProfilingMode = toFlag True - , ghcOptObjSuffix = toFlag "p_o" - } - sharedSrcOpts = - vanillaSrcOpts - `mappend` mempty - { ghcOptFPic = toFlag True - , ghcOptDynLinkMode = toFlag GhcDynamicOnly - , ghcOptObjSuffix = toFlag "dyn_o" - } - odir = fromFlag (ghcOptObjDir vanillaSrcOpts) - - createDirectoryIfMissingVerbose verbosity True odir - runGhcProgIfNeeded vanillaSrcOpts - unless (forRepl || not wantDyn) $ - whenSharedLib forceSharedLib (runGhcProgIfNeeded sharedSrcOpts) - unless forRepl $ - whenProfLib (runGhcProgIfNeeded profSrcOpts) - - -- Build any C++ sources separately. - unless (not has_code || null (cxxSources libBi)) $ do - info verbosity "Building C++ Sources..." - buildExtraSources Internal.componentCxxGhcOptions True (cxxSources libBi) - - -- build any C sources - unless (not has_code || null (cSources libBi)) $ do - info verbosity "Building C Sources..." - buildExtraSources Internal.componentCcGhcOptions True (cSources libBi) - - -- build any JS sources - unless (not has_code || not hasJsSupport || null (jsSources libBi)) $ do - info verbosity "Building JS Sources..." - buildExtraSources Internal.componentJsGhcOptions False (jsSources libBi) - - -- build any ASM sources - unless (not has_code || null (asmSources libBi)) $ do - info verbosity "Building Assembler Sources..." - buildExtraSources Internal.componentAsmGhcOptions True (asmSources libBi) - - -- build any Cmm sources - unless (not has_code || null (cmmSources libBi)) $ do - info verbosity "Building C-- Sources..." - buildExtraSources Internal.componentCmmGhcOptions True (cmmSources libBi) + runBuildM what lbi (TargetInfo clbi (CLib lib)) buildAllExtraSources -- TODO: problem here is we need the .c files built first, so we can load them -- with ghci, but .c files can depend on .h files generated by ghc by ffi diff --git a/Cabal/src/Distribution/Simple/GHC/Internal.hs b/Cabal/src/Distribution/Simple/GHC/Internal.hs index 322a227adfd..893d23210bf 100644 --- a/Cabal/src/Distribution/Simple/GHC/Internal.hs +++ b/Cabal/src/Distribution/Simple/GHC/Internal.hs @@ -333,14 +333,13 @@ getExtensions verbosity implInfo ghcProg = do componentCcGhcOptions :: Verbosity - -> GhcImplInfo -> LocalBuildInfo -> BuildInfo -> ComponentLocalBuildInfo -> FilePath -> FilePath -> GhcOptions -componentCcGhcOptions verbosity _implInfo lbi bi clbi odir filename = +componentCcGhcOptions verbosity lbi bi clbi odir filename = mempty { -- Respect -v0, but don't crank up verbosity on GHC if -- Cabal verbosity is requested. For that, use --ghc-option=-v instead! @@ -383,14 +382,13 @@ componentCcGhcOptions verbosity _implInfo lbi bi clbi odir filename = componentCxxGhcOptions :: Verbosity - -> GhcImplInfo -> LocalBuildInfo -> BuildInfo -> ComponentLocalBuildInfo -> FilePath -> FilePath -> GhcOptions -componentCxxGhcOptions verbosity _implInfo lbi bi clbi odir filename = +componentCxxGhcOptions verbosity lbi bi clbi odir filename = mempty { -- Respect -v0, but don't crank up verbosity on GHC if -- Cabal verbosity is requested. For that, use --ghc-option=-v instead! @@ -433,14 +431,13 @@ componentCxxGhcOptions verbosity _implInfo lbi bi clbi odir filename = componentAsmGhcOptions :: Verbosity - -> GhcImplInfo -> LocalBuildInfo -> BuildInfo -> ComponentLocalBuildInfo -> FilePath -> FilePath -> GhcOptions -componentAsmGhcOptions verbosity _implInfo lbi bi clbi odir filename = +componentAsmGhcOptions verbosity lbi bi clbi odir filename = mempty { -- Respect -v0, but don't crank up verbosity on GHC if -- Cabal verbosity is requested. For that, use --ghc-option=-v instead! @@ -478,14 +475,13 @@ componentAsmGhcOptions verbosity _implInfo lbi bi clbi odir filename = componentJsGhcOptions :: Verbosity - -> GhcImplInfo -> LocalBuildInfo -> BuildInfo -> ComponentLocalBuildInfo -> FilePath -> FilePath -> GhcOptions -componentJsGhcOptions verbosity _implInfo lbi bi clbi odir filename = +componentJsGhcOptions verbosity lbi bi clbi odir filename = mempty { -- Respect -v0, but don't crank up verbosity on GHC if -- Cabal verbosity is requested. For that, use --ghc-option=-v instead! @@ -607,14 +603,13 @@ toGhcOptimisation MaximumOptimisation = toFlag GhcMaximumOptimisation componentCmmGhcOptions :: Verbosity - -> GhcImplInfo -> LocalBuildInfo -> BuildInfo -> ComponentLocalBuildInfo -> FilePath -> FilePath -> GhcOptions -componentCmmGhcOptions verbosity _implInfo lbi bi clbi odir filename = +componentCmmGhcOptions verbosity lbi bi clbi odir filename = mempty { -- Respect -v0, but don't crank up verbosity on GHC if -- Cabal verbosity is requested. For that, use --ghc-option=-v instead! diff --git a/Cabal/src/Distribution/Simple/GHCJS.hs b/Cabal/src/Distribution/Simple/GHCJS.hs index 12860ca104f..43ef50ba82c 100644 --- a/Cabal/src/Distribution/Simple/GHCJS.hs +++ b/Cabal/src/Distribution/Simple/GHCJS.hs @@ -23,7 +23,7 @@ module Distribution.Simple.GHCJS , hcPkgInfo , registerPackage , componentGhcOptions - , componentCcGhcOptions + , Internal.componentCcGhcOptions , getLibDir , isDynamic , getGlobalPackageDB @@ -1214,7 +1214,6 @@ gbuild verbosity numJobs pkg_descr lbi bm clbi = do GBuildFLib{} -> mempty comp = compiler lbi platform = hostPlatform lbi - implInfo = getImplInfo comp runGhcProg = runGHC verbosity ghcjsProg comp platform let (bnfo, threaded) = case bm of @@ -1418,7 +1417,6 @@ gbuild verbosity numJobs pkg_descr lbi bm clbi = do let baseCxxOpts = Internal.componentCxxGhcOptions verbosity - implInfo lbi bnfo clbi @@ -1465,7 +1463,6 @@ gbuild verbosity numJobs pkg_descr lbi bm clbi = do let baseCcOpts = Internal.componentCcGhcOptions verbosity - implInfo lbi bnfo clbi @@ -1787,20 +1784,6 @@ componentGhcOptions verbosity lbi bi clbi odir = { ghcOptExtra = ghcOptExtra opts `mappend` hcOptions GHCJS bi } -componentCcGhcOptions - :: Verbosity - -> LocalBuildInfo - -> BuildInfo - -> ComponentLocalBuildInfo - -> FilePath - -> FilePath - -> GhcOptions -componentCcGhcOptions verbosity lbi = - Internal.componentCcGhcOptions verbosity implInfo lbi - where - comp = compiler lbi - implInfo = getImplInfo comp - -- ----------------------------------------------------------------------------- -- Installing diff --git a/Cabal/src/Distribution/Simple/Setup.hs b/Cabal/src/Distribution/Simple/Setup.hs index fe05e882089..cd8f10aff3c 100644 --- a/Cabal/src/Distribution/Simple/Setup.hs +++ b/Cabal/src/Distribution/Simple/Setup.hs @@ -2,6 +2,7 @@ {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE LambdaCase #-} {-# LANGUAGE RankNTypes #-} ----------------------------------------------------------------------------- diff --git a/Cabal/src/Distribution/Simple/Utils.hs b/Cabal/src/Distribution/Simple/Utils.hs index f05957bc271..64b22c5abee 100644 --- a/Cabal/src/Distribution/Simple/Utils.hs +++ b/Cabal/src/Distribution/Simple/Utils.hs @@ -1198,7 +1198,7 @@ findFileCwd verbosity cwd searchPath fileName = findFirstFile (cwd ) [ path fileName - | path <- nub searchPath + | path <- ordNub searchPath ] >>= maybe (dieWithException verbosity $ FindFileCwd fileName) return @@ -1214,7 +1214,7 @@ findFileEx verbosity searchPath fileName = findFirstFile id [ path fileName - | path <- nub searchPath + | path <- ordNub searchPath ] >>= maybe (dieWithException verbosity $ FindFileEx fileName) return @@ -1230,8 +1230,8 @@ findFileWithExtension extensions searchPath baseName = findFirstFile id [ path baseName <.> ext - | path <- nub searchPath - , ext <- nub extensions + | path <- ordNub searchPath + , ext <- ordNub extensions ] -- | @since 3.4.0.0 @@ -1245,8 +1245,8 @@ findFileCwdWithExtension cwd extensions searchPath baseName = findFirstFile (cwd ) [ path baseName <.> ext - | path <- nub searchPath - , ext <- nub extensions + | path <- ordNub searchPath + , ext <- ordNub extensions ] -- | @since 3.4.0.0 @@ -1264,8 +1264,8 @@ findAllFilesCwdWithExtension cwd extensions searchPath basename = findAllFiles (cwd ) [ path basename <.> ext - | path <- nub searchPath - , ext <- nub extensions + | path <- ordNub searchPath + , ext <- ordNub extensions ] findAllFilesWithExtension @@ -1277,8 +1277,8 @@ findAllFilesWithExtension extensions searchPath basename = findAllFiles id [ path basename <.> ext - | path <- nub searchPath - , ext <- nub extensions + | path <- ordNub searchPath + , ext <- ordNub extensions ] -- | Like 'findFileWithExtension' but returns which element of the search path @@ -1292,8 +1292,8 @@ findFileWithExtension' extensions searchPath baseName = findFirstFile (uncurry ()) [ (path, baseName <.> ext) - | path <- nub searchPath - , ext <- nub extensions + | path <- ordNub searchPath + , ext <- ordNub extensions ] findFirstFile :: (a -> FilePath) -> [a] -> IO (Maybe a) @@ -1535,7 +1535,7 @@ copyFilesWith -> IO () copyFilesWith doCopy verbosity targetDir srcFiles = withFrozenCallStack $ do -- Create parent directories for everything - let dirs = map (targetDir ) . nub . map (takeDirectory . snd) $ srcFiles + let dirs = map (targetDir ) . ordNub . map (takeDirectory . snd) $ srcFiles traverse_ (createDirectoryIfMissingVerbose verbosity True) dirs -- Copy all the files