diff --git a/ChangeLog.md b/ChangeLog.md index ed0adfed0e..5d4c4c9197 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -79,6 +79,9 @@ Other enhancements: [#2235](https://github.com/commercialhaskell/stack/issues/2235) * Replace enclosed-exceptions with safe-exceptions. [#2768](https://github.com/commercialhaskell/stack/issues/2768) +* `stack build` and related commands now allow the user to disable debug symbol stripping + with new `--no-strip`, `--no-library-stripping`, and `--no-executable-shipping` flags, + closing [#877](https://github.com/commercialhaskell/stack/issues/877). Bug fixes: diff --git a/doc/GUIDE.md b/doc/GUIDE.md index 604f84d025..d3385a02bf 100644 --- a/doc/GUIDE.md +++ b/doc/GUIDE.md @@ -2105,10 +2105,11 @@ but adds the `+RTS -xc` runtime option. ### DWARF -`stack` currently doesn't support debugging and profiling with -[DWARF information](https://ghc.haskell.org/trac/ghc/wiki/DWARF) -as it strips executables automatically. This may change in the future (see -[#877](https://github.com/commercialhaskell/stack/issues/877)). +`stack` now supports debugging and profiling with +[DWARF information](https://ghc.haskell.org/trac/ghc/wiki/DWARF), +using the `--no-strip`, `--no-library-stripping`, and `--no-executable-shipping` +flags to disable the default behavior of removing such information from compiled +libraries and executables. ### Further reading diff --git a/src/Stack/Build.hs b/src/Stack/Build.hs index 0bdd8cb629..35617c21df 100644 --- a/src/Stack/Build.hs +++ b/src/Stack/Build.hs @@ -94,6 +94,7 @@ build :: (StackM env m, HasEnvConfig env, MonadBaseUnlift IO m) build setLocalFiles mbuildLk boptsCli = fixCodePage $ do bopts <- asks (configBuild . getConfig) let profiling = boptsLibProfile bopts || boptsExeProfile bopts + let symbols = boptsLibStrip bopts || boptsExeStrip bopts menv <- getMinimalEnvOverride (targets, mbp, locals, extraToBuild, extraDeps, sourceMap) <- loadSourceMapFull NeedTargets boptsCli @@ -109,7 +110,8 @@ build setLocalFiles mbuildLk boptsCli = fixCodePage $ do getInstalled menv GetInstalledOpts { getInstalledProfiling = profiling - , getInstalledHaddock = shouldHaddockDeps bopts } + , getInstalledHaddock = shouldHaddockDeps bopts + , getInstalledSymbols = symbols } sourceMap warnMissingExtraDeps installedMap extraDeps diff --git a/src/Stack/Build/ConstructPlan.hs b/src/Stack/Build/ConstructPlan.hs index add92d5af0..a32b4c55f2 100644 --- a/src/Stack/Build/ConstructPlan.hs +++ b/src/Stack/Build/ConstructPlan.hs @@ -150,7 +150,7 @@ constructPlan :: forall env m. (StackM env m, HasEnvConfig env) -> BaseConfigOpts -> [LocalPackage] -> Set PackageName -- ^ additional packages that must be built - -> [DumpPackage () ()] -- ^ locally registered + -> [DumpPackage () () ()] -- ^ locally registered -> (PackageName -> Version -> Map FlagName Bool -> [Text] -> IO Package) -- ^ load upstream package -> SourceMap -> InstalledMap diff --git a/src/Stack/Build/Execute.hs b/src/Stack/Build/Execute.hs index ff62ca8d52..18551cd12e 100644 --- a/src/Stack/Build/Execute.hs +++ b/src/Stack/Build/Execute.hs @@ -226,9 +226,9 @@ data ExecuteEnv = ExecuteEnv , eeWanted :: !(Set PackageName) , eeLocals :: ![LocalPackage] , eeGlobalDB :: !(Path Abs Dir) - , eeGlobalDumpPkgs :: !(Map GhcPkgId (DumpPackage () ())) - , eeSnapshotDumpPkgs :: !(TVar (Map GhcPkgId (DumpPackage () ()))) - , eeLocalDumpPkgs :: !(TVar (Map GhcPkgId (DumpPackage () ()))) + , eeGlobalDumpPkgs :: !(Map GhcPkgId (DumpPackage () () ())) + , eeSnapshotDumpPkgs :: !(TVar (Map GhcPkgId (DumpPackage () () ()))) + , eeLocalDumpPkgs :: !(TVar (Map GhcPkgId (DumpPackage () () ()))) , eeLogFiles :: !(TChan (Path Abs Dir, Path Abs File)) } @@ -326,9 +326,9 @@ withExecuteEnv :: (StackM env m, HasEnvConfig env) -> BuildOptsCLI -> BaseConfigOpts -> [LocalPackage] - -> [DumpPackage () ()] -- ^ global packages - -> [DumpPackage () ()] -- ^ snapshot packages - -> [DumpPackage () ()] -- ^ local packages + -> [DumpPackage () () ()] -- ^ global packages + -> [DumpPackage () () ()] -- ^ snapshot packages + -> [DumpPackage () () ()] -- ^ local packages -> (ExecuteEnv -> m a) -> m a withExecuteEnv menv bopts boptsCli baseConfigOpts locals globalPackages snapshotPackages localPackages inner = do @@ -443,9 +443,9 @@ executePlan :: (StackM env m, HasEnvConfig env) -> BuildOptsCLI -> BaseConfigOpts -> [LocalPackage] - -> [DumpPackage () ()] -- ^ global packages - -> [DumpPackage () ()] -- ^ snapshot packages - -> [DumpPackage () ()] -- ^ local packages + -> [DumpPackage () () ()] -- ^ global packages + -> [DumpPackage () () ()] -- ^ snapshot packages + -> [DumpPackage () () ()] -- ^ local packages -> InstalledMap -> Map PackageName SimpleTarget -> Plan @@ -1641,7 +1641,7 @@ taskComponents task = -- -- * https://github.com/commercialhaskell/stack/issues/949 addGlobalPackages :: Map PackageIdentifier GhcPkgId -- ^ dependencies of the package - -> [DumpPackage () ()] -- ^ global packages + -> [DumpPackage () () ()] -- ^ global packages -> Set GhcPkgId addGlobalPackages deps globals0 = res diff --git a/src/Stack/Build/Haddock.hs b/src/Stack/Build/Haddock.hs index 1b357e8574..fedfa1e459 100644 --- a/src/Stack/Build/Haddock.hs +++ b/src/Stack/Build/Haddock.hs @@ -122,7 +122,7 @@ generateLocalHaddockIndex => EnvOverride -> WhichCompiler -> BaseConfigOpts - -> Map GhcPkgId (DumpPackage () ()) -- ^ Local package dump + -> Map GhcPkgId (DumpPackage () () ()) -- ^ Local package dump -> [LocalPackage] -> m () generateLocalHaddockIndex envOverride wc bco localDumpPkgs locals = do @@ -148,9 +148,9 @@ generateDepsHaddockIndex => EnvOverride -> WhichCompiler -> BaseConfigOpts - -> Map GhcPkgId (DumpPackage () ()) -- ^ Global dump information - -> Map GhcPkgId (DumpPackage () ()) -- ^ Snapshot dump information - -> Map GhcPkgId (DumpPackage () ()) -- ^ Local dump information + -> Map GhcPkgId (DumpPackage () () ()) -- ^ Global dump information + -> Map GhcPkgId (DumpPackage () () ()) -- ^ Snapshot dump information + -> Map GhcPkgId (DumpPackage () () ()) -- ^ Local dump information -> [LocalPackage] -> m () generateDepsHaddockIndex envOverride wc bco globalDumpPkgs snapshotDumpPkgs localDumpPkgs locals = do @@ -193,8 +193,8 @@ generateSnapHaddockIndex => EnvOverride -> WhichCompiler -> BaseConfigOpts - -> Map GhcPkgId (DumpPackage () ()) -- ^ Global package dump - -> Map GhcPkgId (DumpPackage () ()) -- ^ Snapshot package dump + -> Map GhcPkgId (DumpPackage () () ()) -- ^ Global package dump + -> Map GhcPkgId (DumpPackage () () ()) -- ^ Snapshot package dump -> m () generateSnapHaddockIndex envOverride wc bco globalDumpPkgs snapshotDumpPkgs = generateHaddockIndex @@ -213,7 +213,7 @@ generateHaddockIndex -> EnvOverride -> WhichCompiler -> HaddockOpts - -> [DumpPackage () ()] + -> [DumpPackage () () ()] -> FilePath -> Path Abs Dir -> m () @@ -241,7 +241,7 @@ generateHaddockIndex descr envOverride wc hdopts dumpPackages docRelFP destDir = ["--gen-contents", "--gen-index"] ++ [x | (xs,_,_,_) <- interfaceOpts, x <- xs]) where - toInterfaceOpt :: DumpPackage a b -> IO (Maybe ([String], UTCTime, Path Abs File, Path Abs File)) + toInterfaceOpt :: DumpPackage a b c -> IO (Maybe ([String], UTCTime, Path Abs File, Path Abs File)) toInterfaceOpt DumpPackage {..} = case dpHaddockInterfaces of [] -> return Nothing @@ -294,8 +294,8 @@ generateHaddockIndex descr envOverride wc hdopts dumpPackages docRelFP destDir = -- | Find first DumpPackage matching the GhcPkgId lookupDumpPackage :: GhcPkgId - -> [Map GhcPkgId (DumpPackage () ())] - -> Maybe (DumpPackage () ()) + -> [Map GhcPkgId (DumpPackage () () ())] + -> Maybe (DumpPackage () () ()) lookupDumpPackage ghcPkgId dumpPkgs = listToMaybe $ mapMaybe (Map.lookup ghcPkgId) dumpPkgs diff --git a/src/Stack/Build/Installed.hs b/src/Stack/Build/Installed.hs index 2cd66d6c0c..499c588e72 100644 --- a/src/Stack/Build/Installed.hs +++ b/src/Stack/Build/Installed.hs @@ -1,7 +1,7 @@ {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE MultiParamTypeClasses #-} -{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TemplateHaskell #-} -- Determine which packages are already installed module Stack.Build.Installed @@ -52,6 +52,8 @@ data GetInstalledOpts = GetInstalledOpts -- ^ Require profiling libraries? , getInstalledHaddock :: !Bool -- ^ Require haddocks? + , getInstalledSymbols :: !Bool + -- ^ Require debugging symbols? } -- | Returns the new InstalledMap and all of the locally registered packages. @@ -60,9 +62,9 @@ getInstalled :: (StackM env m, HasEnvConfig env, PackageInstallInfo pii) -> GetInstalledOpts -> Map PackageName pii -- ^ does not contain any installed information -> m ( InstalledMap - , [DumpPackage () ()] -- globally installed - , [DumpPackage () ()] -- snapshot installed - , [DumpPackage () ()] -- locally installed + , [DumpPackage () () ()] -- globally installed + , [DumpPackage () () ()] -- snapshot installed + , [DumpPackage () () ()] -- locally installed ) getInstalled menv opts sourceMap = do $logDebug "Finding out which packages are already installed" @@ -132,11 +134,12 @@ loadDatabase :: (StackM env m, HasEnvConfig env, PackageInstallInfo pii) -> Map PackageName pii -- ^ to determine which installed things we should include -> Maybe (InstalledPackageLocation, Path Abs Dir) -- ^ package database, Nothing for global -> [LoadHelper] -- ^ from parent databases - -> m ([LoadHelper], [DumpPackage () ()]) + -> m ([LoadHelper], [DumpPackage () () ()]) loadDatabase menv opts mcache sourceMap mdb lhs0 = do wc <- getWhichCompiler + ver <- asks (bcWantedCompiler . getBuildConfig) (lhs1', dps) <- ghcPkgDump menv wc (fmap snd (maybeToList mdb)) - $ conduitDumpPackage =$ sink + $ conduitDumpPackage =$ sink ver let ghcjsHack = wc == Ghcjs && isNothing mdb lhs1 <- mapMaybeM (processLoadResult mdb ghcjsHack) lhs1' let lhs = pruneDeps @@ -159,13 +162,20 @@ loadDatabase menv opts mcache sourceMap mdb lhs0 = do -- Just an optimization to avoid calculating the haddock -- values when they aren't necessary _ -> CL.map (\dp -> dp { dpHaddock = False }) + conduitSymbolsCache ver = + case mcache of + Just cache | getInstalledSymbols opts -> addSymbols cache ver + -- Just an optimization to avoid calculating the debugging + -- symbol values when they aren't necessary + _ -> CL.map (\dp -> dp { dpSymbols = False }) mloc = fmap fst mdb - sinkDP = conduitProfilingCache - =$ conduitHaddockCache - =$ CL.map (isAllowed opts mcache sourceMap mloc &&& toLoadHelper mloc) - =$ CL.consume - sink = getZipSink $ (,) - <$> ZipSink sinkDP + sinkDP ver = conduitProfilingCache + =$ conduitHaddockCache + =$ conduitSymbolsCache ver + =$ CL.map (isAllowed opts mcache sourceMap mloc &&& toLoadHelper mloc) + =$ CL.consume + sink ver = getZipSink $ (,) + <$> ZipSink (sinkDP ver) <*> ZipSink CL.consume processLoadResult :: MonadLogger m @@ -198,6 +208,7 @@ processLoadResult mdb _ (reason, lh) = do Allowed -> " the impossible?!?!" NeedsProfiling -> " it needing profiling." NeedsHaddock -> " it needing haddocks." + NeedsSymbols -> " it needing debugging symbols." UnknownPkg -> " it being unknown to the resolver / extra-deps." WrongLocation mloc loc -> " wrong location: " <> T.pack (show (mloc, loc)) WrongVersion actual wanted -> T.concat @@ -213,6 +224,7 @@ data Allowed = Allowed | NeedsProfiling | NeedsHaddock + | NeedsSymbols | UnknownPkg | WrongLocation (Maybe InstalledPackageLocation) InstallLocation | WrongVersion Version Version @@ -226,13 +238,15 @@ isAllowed :: PackageInstallInfo pii -> Maybe InstalledCache -> Map PackageName pii -> Maybe InstalledPackageLocation - -> DumpPackage Bool Bool + -> DumpPackage Bool Bool Bool -> Allowed isAllowed opts mcache sourceMap mloc dp -- Check that it can do profiling if necessary | getInstalledProfiling opts && isJust mcache && not (dpProfiling dp) = NeedsProfiling -- Check that it has haddocks if necessary | getInstalledHaddock opts && isJust mcache && not (dpHaddock dp) = NeedsHaddock + -- Check that it has haddocks if necessary + | getInstalledSymbols opts && isJust mcache && not (dpSymbols dp) = NeedsSymbols | otherwise = case Map.lookup name sourceMap of Nothing -> @@ -263,7 +277,7 @@ data LoadHelper = LoadHelper } deriving Show -toLoadHelper :: Maybe InstalledPackageLocation -> DumpPackage Bool Bool -> LoadHelper +toLoadHelper :: Maybe InstalledPackageLocation -> DumpPackage Bool Bool Bool -> LoadHelper toLoadHelper mloc dp = LoadHelper { lhId = gid , lhDeps = diff --git a/src/Stack/Build/Source.hs b/src/Stack/Build/Source.hs index b5296a6efc..6de1072b07 100644 --- a/src/Stack/Build/Source.hs +++ b/src/Stack/Build/Source.hs @@ -197,6 +197,9 @@ getGhcOptions bconfig boptsCli name isTarget isLocal = concat , if boptsLibProfile bopts || boptsExeProfile bopts then ["-auto-all","-caf-all"] else [] + , if not $ boptsLibStrip bopts || boptsExeStrip bopts + then ["-g"] + else [] , if includeExtraOptions then boptsCLIGhcOptions boptsCli else [] diff --git a/src/Stack/Config/Build.hs b/src/Stack/Config/Build.hs index e0bb978020..0412f03b29 100644 --- a/src/Stack/Config/Build.hs +++ b/src/Stack/Config/Build.hs @@ -15,6 +15,12 @@ buildOptsFromMonoid BuildOptsMonoid{..} = BuildOpts , boptsExeProfile = fromFirst (boptsExeProfile defaultBuildOpts) buildMonoidExeProfile + , boptsLibStrip = fromFirst + (boptsLibStrip defaultBuildOpts) + buildMonoidLibStrip + , boptsExeStrip = fromFirst + (boptsExeStrip defaultBuildOpts) + buildMonoidExeStrip , boptsHaddock = fromFirst (boptsHaddock defaultBuildOpts) buildMonoidHaddock diff --git a/src/Stack/Dot.hs b/src/Stack/Dot.hs index 7ee82ad724..07573c779a 100644 --- a/src/Stack/Dot.hs +++ b/src/Stack/Dot.hs @@ -122,7 +122,7 @@ createDependencyGraph dotOpts = do let graph = Map.fromList (localDependencies dotOpts (filter lpWanted locals)) menv <- getMinimalEnvOverride installedMap <- fmap snd . fst4 <$> getInstalled menv - (GetInstalledOpts False False) + (GetInstalledOpts False False False) sourceMap withLoadPackage menv (\loader -> do let depLoader = diff --git a/src/Stack/Ghci.hs b/src/Stack/Ghci.hs index d804a85cde..66e4cb9a61 100644 --- a/src/Stack/Ghci.hs +++ b/src/Stack/Ghci.hs @@ -531,6 +531,7 @@ getGhciPkgInfos sourceMap addPkgs mfileTargets localTargets = do GetInstalledOpts { getInstalledProfiling = False , getInstalledHaddock = False + , getInstalledSymbols = False } sourceMap let localLibs = [name | (name, (_, target)) <- localTargets, hasLocalComp isCLib target] diff --git a/src/Stack/Options/BuildMonoidParser.hs b/src/Stack/Options/BuildMonoidParser.hs index c3f70def66..9b180d895c 100644 --- a/src/Stack/Options/BuildMonoidParser.hs +++ b/src/Stack/Options/BuildMonoidParser.hs @@ -13,14 +13,14 @@ import Stack.Types.Config.Build buildOptsMonoidParser :: GlobalOptsContext -> Parser BuildOptsMonoid buildOptsMonoidParser hide0 = - transform <$> trace <*> profile <*> options + transform <$> trace <*> profile <*> noStrip <*> options where hideBool = hide0 /= BuildCmdGlobalOpts hide = hideMods hideBool hideExceptGhci = hideMods (hide0 `notElem` [BuildCmdGlobalOpts, GhciCmdGlobalOpts]) - transform tracing profiling = + transform tracing profiling noStripping = enable where enable opts @@ -37,6 +37,11 @@ buildOptsMonoidParser hide0 = additionalArgs } } + | noStripping = + opts + { buildMonoidLibStrip = First (Just False) + , buildMonoidExeStrip = First (Just False) + } | otherwise = opts where @@ -75,13 +80,28 @@ buildOptsMonoidParser hide0 = \for all expressions and generate a backtrace on \ \exception" <> hideExceptGhci) + + noStrip = + flag + False + True + (long "no-strip" <> + help + "Disable DWARF debugging symbol stripping in libraries, \ + \executables, etc. for all expressions, producing \ + \larger executables but allowing the use of standard \ + \debuggers/profiling tools/other utilities that use \ + \debugging symbols." <> + hideExceptGhci) + options = - BuildOptsMonoid <$> libProfiling <*> exeProfiling <*> haddock <*> - haddockOptsParser hideBool <*> openHaddocks <*> haddockDeps <*> - haddockInternal <*> copyBins <*> preFetch <*> keepGoing <*> - forceDirty <*> tests <*> testOptsParser hideBool <*> benches <*> - benchOptsParser hideBool <*> reconfigure <*> - cabalVerbose <*> splitObjs + BuildOptsMonoid <$> libProfiling <*> exeProfiling <*> libStripping <*> + exeStripping <*> haddock <*> haddockOptsParser hideBool <*> + openHaddocks <*> haddockDeps <*> haddockInternal <*> copyBins <*> + preFetch <*> keepGoing <*> forceDirty <*> tests <*> + testOptsParser hideBool <*> benches <*> benchOptsParser hideBool <*> + reconfigure <*> cabalVerbose <*> splitObjs + libProfiling = firstBoolFlags "library-profiling" @@ -92,6 +112,16 @@ buildOptsMonoidParser hide0 = "executable-profiling" "executable profiling for TARGETs and all its dependencies" hide + libStripping = + firstBoolFlags + "library-stripping" + "library stripping for TARGETs and all its dependencies" + hide + exeStripping = + firstBoolFlags + "executable-stripping" + "executable stripping for TARGETs and all its dependencies" + hide haddock = firstBoolFlags "haddock" diff --git a/src/Stack/PackageDump.hs b/src/Stack/PackageDump.hs index 54921b36b8..4b1e1f10cd 100644 --- a/src/Stack/PackageDump.hs +++ b/src/Stack/PackageDump.hs @@ -19,6 +19,7 @@ module Stack.PackageDump , saveInstalledCache , addProfiling , addHaddock + , addSymbols , sinkMatching , pruneDeps ) where @@ -47,6 +48,7 @@ import Data.Store.VersionTagged import Data.Text (Text) import qualified Data.Text as T import Data.Typeable (Typeable) +import qualified Distribution.System as OS import Path import Path.Extra (toFilePathNoTrailingSep) import Prelude -- Fix AMP warning @@ -168,14 +170,16 @@ pruneDeps getName getId getDepends chooseBest = sinkMatching :: Monad m => Bool -- ^ require profiling? -> Bool -- ^ require haddock? + -> Bool -- ^ require debugging symbols? -> Map PackageName Version -- ^ allowed versions - -> Consumer (DumpPackage Bool Bool) + -> Consumer (DumpPackage Bool Bool Bool) m - (Map PackageName (DumpPackage Bool Bool)) -sinkMatching reqProfiling reqHaddock allowed = do + (Map PackageName (DumpPackage Bool Bool Bool)) +sinkMatching reqProfiling reqHaddock reqSymbols allowed = do dps <- CL.filter (\dp -> isAllowed (dpPackageIdent dp) && (not reqProfiling || dpProfiling dp) && - (not reqHaddock || dpHaddock dp)) + (not reqHaddock || dpHaddock dp) && + (not reqSymbols || dpSymbols dp)) =$= CL.consume return $ Map.fromList $ map (packageIdentifierName . dpPackageIdent &&& id) $ Map.elems $ pruneDeps id @@ -192,7 +196,7 @@ sinkMatching reqProfiling reqHaddock allowed = do -- | Add profiling information to the stream of @DumpPackage@s addProfiling :: MonadIO m => InstalledCache - -> Conduit (DumpPackage a b) m (DumpPackage Bool b) + -> Conduit (DumpPackage a b c) m (DumpPackage Bool b c) addProfiling (InstalledCache ref) = CL.mapM go where @@ -227,7 +231,7 @@ isProfiling content lib = -- | Add haddock information to the stream of @DumpPackage@s addHaddock :: MonadIO m => InstalledCache - -> Conduit (DumpPackage a b) m (DumpPackage a Bool) + -> Conduit (DumpPackage a b c) m (DumpPackage a Bool c) addHaddock (InstalledCache ref) = CL.mapM go where @@ -247,8 +251,44 @@ addHaddock (InstalledCache ref) = loop $ dpHaddockInterfaces dp return dp { dpHaddock = h } +-- | Add debugging symbol information to the stream of @DumpPackage@s +addSymbols :: MonadIO m + => InstalledCache + -> CompilerVersion + -> Conduit (DumpPackage a b c) m (DumpPackage a b Bool) +addSymbols (InstalledCache ref) ver = + CL.mapM go + where + ver' = versionString . getGhcVersion $ ver + go dp = do + InstalledCacheInner m <- liftIO $ readIORef ref + let gid = dpGhcPkgId dp + s <- case Map.lookup gid m of + Just installed -> return (installedCacheSymbols installed) + Nothing | null (dpLibraries dp) -> return True + Nothing -> do + let lib = T.unpack . head $ dpLibraries dp + liftM or . mapM (\dir -> liftIO $ hasDebuggingSymbols ver' dir lib) $ dpLibDirs dp + return dp { dpSymbols = s } + +hasDebuggingSymbols :: String -- ^ target compiler + -> FilePath -- ^ library directory + -> String -- ^ name of library + -> IO Bool +hasDebuggingSymbols ver dir lib = case OS.buildOS of + OS.OSX -> liftM (and . fmap ((/= '0') . head) . Prelude.take 30 . lines) $ + readProcess "dwarfdump" [concat [dir, "/lib", lib, "-ghc", ver, ".a"]] "" + OS.Linux -> liftM ((== "Contents") . head . words . (!! 2) . lines) $ + readProcess "readelf" ["--debug-dump=info", "--dwarf-depth=1", concat [dir, "/lib", lib, "-ghc", ver, ".a"]] "" + OS.FreeBSD -> liftM ((== "Contents") . head . words . (!! 2) . lines) $ + readProcess "readelf" ["--debug-dump=info", "--dwarf-depth=1", concat [dir, "/lib", lib, "-ghc", ver, ".a"]] "" + OS.Windows -> return False -- No support, so it can't be there. + OS.Ghcjs -> return False + _ -> return False + + -- | Dump information for a single package -data DumpPackage profiling haddock = DumpPackage +data DumpPackage profiling haddock symbols = DumpPackage { dpGhcPkgId :: !GhcPkgId , dpPackageIdent :: !PackageIdentifier , dpLibDirs :: ![FilePath] @@ -259,6 +299,7 @@ data DumpPackage profiling haddock = DumpPackage , dpHaddockHtml :: !(Maybe FilePath) , dpProfiling :: !profiling , dpHaddock :: !haddock + , dpSymbols :: !symbols , dpIsExposed :: !Bool } deriving (Show, Eq, Ord) @@ -280,7 +321,7 @@ instance Show PackageDumpException where -- | Convert a stream of bytes into a stream of @DumpPackage@s conduitDumpPackage :: MonadThrow m - => Conduit Text m (DumpPackage () ()) + => Conduit Text m (DumpPackage () () ()) conduitDumpPackage = (=$= CL.catMaybes) $ eachSection $ do pairs <- eachPair (\k -> (k, ) <$> CL.consume) =$= CL.consume let m = Map.fromList pairs @@ -339,6 +380,7 @@ conduitDumpPackage = (=$= CL.catMaybes) $ eachSection $ do , dpHaddockHtml = listToMaybe haddockHtml , dpProfiling = () , dpHaddock = () + , dpSymbols = () , dpIsExposed = exposed == ["True"] } diff --git a/src/Stack/SDist.hs b/src/Stack/SDist.hs index d4cd660f12..cb26cbfbba 100644 --- a/src/Stack/SDist.hs +++ b/src/Stack/SDist.hs @@ -137,6 +137,7 @@ getCabalLbs pvpBounds fp = do (installedMap, _, _, _) <- getInstalled menv GetInstalledOpts { getInstalledProfiling = False , getInstalledHaddock = False + , getInstalledSymbols = False } sourceMap let gpd' = gtraverseT (addBounds sourceMap installedMap) gpd diff --git a/src/Stack/Types/Build.hs b/src/Stack/Types/Build.hs index d83dae1742..cbc7247181 100644 --- a/src/Stack/Types/Build.hs +++ b/src/Stack/Types/Build.hs @@ -536,6 +536,8 @@ configureOptsNoDir econfig bco deps isLocal package = concat , let profFlag = "--enable-" <> concat ["executable-" | not newerCabal] <> "profiling" in [ profFlag | boptsExeProfile bopts && isLocal] , ["--enable-split-objs" | boptsSplitObjs bopts] + , ["--disable-library-stripping" | not $ boptsLibStrip bopts || boptsExeStrip bopts] + , ["--disable-executable-stripping" | not (boptsExeStrip bopts) && isLocal] , map (\(name,enabled) -> "-f" <> (if enabled diff --git a/src/Stack/Types/Config/Build.hs b/src/Stack/Types/Config/Build.hs index 0f7c997288..a04c4c0dda 100644 --- a/src/Stack/Types/Config/Build.hs +++ b/src/Stack/Types/Config/Build.hs @@ -44,6 +44,8 @@ import Stack.Types.PackageName data BuildOpts = BuildOpts {boptsLibProfile :: !Bool ,boptsExeProfile :: !Bool + ,boptsLibStrip :: !Bool + ,boptsExeStrip :: !Bool ,boptsHaddock :: !Bool -- ^ Build haddocks? ,boptsHaddockOpts :: !HaddockOpts @@ -88,6 +90,8 @@ defaultBuildOpts :: BuildOpts defaultBuildOpts = BuildOpts { boptsLibProfile = False , boptsExeProfile = False + , boptsLibStrip = True + , boptsExeStrip = True , boptsHaddock = False , boptsHaddockOpts = defaultHaddockOpts , boptsOpenHaddocks = False @@ -147,6 +151,8 @@ data BuildCommand data BuildOptsMonoid = BuildOptsMonoid { buildMonoidLibProfile :: !(First Bool) , buildMonoidExeProfile :: !(First Bool) + , buildMonoidLibStrip :: !(First Bool) + , buildMonoidExeStrip :: !(First Bool) , buildMonoidHaddock :: !(First Bool) , buildMonoidHaddockOpts :: !HaddockOptsMonoid , buildMonoidOpenHaddocks :: !(First Bool) @@ -169,6 +175,8 @@ instance FromJSON (WithJSONWarnings BuildOptsMonoid) where parseJSON = withObjectWarnings "BuildOptsMonoid" (\o -> do buildMonoidLibProfile <- First <$> o ..:? buildMonoidLibProfileArgName buildMonoidExeProfile <-First <$> o ..:? buildMonoidExeProfileArgName + buildMonoidLibStrip <- First <$> o ..:? buildMonoidLibStripArgName + buildMonoidExeStrip <-First <$> o ..:? buildMonoidExeStripArgName buildMonoidHaddock <- First <$> o ..:? buildMonoidHaddockArgName buildMonoidHaddockOpts <- jsonSubWarnings (o ..:? buildMonoidHaddockOptsArgName ..!= mempty) buildMonoidOpenHaddocks <- First <$> o ..:? buildMonoidOpenHaddocksArgName @@ -193,6 +201,12 @@ buildMonoidLibProfileArgName = "library-profiling" buildMonoidExeProfileArgName :: Text buildMonoidExeProfileArgName = "executable-profiling" +buildMonoidLibStripArgName :: Text +buildMonoidLibStripArgName = "library-stripping" + +buildMonoidExeStripArgName :: Text +buildMonoidExeStripArgName = "executable-stripping" + buildMonoidHaddockArgName :: Text buildMonoidHaddockArgName = "haddock" diff --git a/src/Stack/Types/PackageDump.hs b/src/Stack/Types/PackageDump.hs index 582bcd5595..dae0d095a3 100644 --- a/src/Stack/Types/PackageDump.hs +++ b/src/Stack/Types/PackageDump.hs @@ -27,9 +27,10 @@ newtype InstalledCacheInner = InstalledCacheInner (Map GhcPkgId InstalledCacheEn data InstalledCacheEntry = InstalledCacheEntry { installedCacheProfiling :: !Bool , installedCacheHaddock :: !Bool + , installedCacheSymbols :: !Bool , installedCacheIdent :: !PackageIdentifier } deriving (Eq, Generic, Show, Data, Typeable) instance Store InstalledCacheEntry installedCacheVC :: VersionConfig InstalledCacheInner -installedCacheVC = storeVersionConfig "installed-v1" "5yL7Ngpy4YKWDDCTUI6zAJ9UySI=" +installedCacheVC = storeVersionConfig "installed-v1" "GGyaE6qY9FOqeWtozuadKqS7_QM=" diff --git a/src/test/Stack/PackageDumpSpec.hs b/src/test/Stack/PackageDumpSpec.hs index 8dbf16f7d6..87f242b521 100644 --- a/src/test/Stack/PackageDumpSpec.hs +++ b/src/test/Stack/PackageDumpSpec.hs @@ -91,6 +91,7 @@ spec = do , dpHaddockHtml = Just "/opt/ghc/7.8.4/share/doc/ghc/html/libraries/haskell2010-1.1.2.0" , dpProfiling = () , dpHaddock = () + , dpSymbols = () , dpIsExposed = False } @@ -129,6 +130,7 @@ spec = do , dpHasExposedModules = True , dpProfiling = () , dpHaddock = () + , dpSymbols = () , dpIsExposed = False } it "ghc 7.8.4 (osx)" $ do @@ -164,6 +166,7 @@ spec = do , dpHasExposedModules = True , dpProfiling = () , dpHaddock = () + , dpSymbols = () , dpIsExposed = True } it "ghc HEAD" $ do @@ -193,6 +196,7 @@ spec = do , dpHasExposedModules = True , dpProfiling = () , dpHaddock = () + , dpSymbols = () , dpIsExposed = True } @@ -205,6 +209,7 @@ spec = do $ conduitDumpPackage =$ addProfiling icache =$ addHaddock icache + =$ fakeAddSymbols =$ CL.sinkNull it "sinkMatching" $ do @@ -215,7 +220,8 @@ spec = do $ conduitDumpPackage =$ addProfiling icache =$ addHaddock icache - =$ sinkMatching False False (Map.singleton $(mkPackageName "transformers") $(mkVersion "0.0.0.0.0.0.1")) + =$ fakeAddSymbols + =$ sinkMatching False False False (Map.singleton $(mkPackageName "transformers") $(mkVersion "0.0.0.0.0.0.1")) case Map.lookup $(mkPackageName "base") m of Nothing -> error "base not present" Just _ -> return () @@ -262,3 +268,7 @@ checkDepsPresent prunes selected = case Map.lookup ident depMap of Nothing -> error "checkDepsPresent: missing in depMap" Just deps -> Set.null $ Set.difference (Set.fromList deps) allIds + +-- addSymbols can't be reasonably tested like this +fakeAddSymbols :: Monad m => Conduit (DumpPackage a b c) m (DumpPackage a b Bool) +fakeAddSymbols = CL.map (\dp -> dp { dpSymbols = False })