@@ -476,67 +476,85 @@ ensureCompiler sopts = do
476476-- | Determine which GHC build to use dependong on which shared libraries are available
477477-- on the system.
478478getGhcBuild
479- :: (MonadIO m , MonadBaseControl IO m , MonadCatch m , MonadLogger m , HasPlatform env , MonadReader env m )
479+ :: (MonadIO m , MonadBaseControl IO m , MonadCatch m , MonadLogger m , HasPlatform env , HasConfig env , MonadReader env m )
480480 => EnvOverride -> m CompilerBuild
481481getGhcBuild menv = do
482482
483- -- TODO: a more reliable, flexible, and data driven approach would be to actually download small
484- -- "test" executables (from setup-info) that link to the same gmp/tinfo versions
485- -- that GHC does (i.e. built in same environment as the GHC bindist). The algorithm would go
486- -- something like this:
487- --
488- -- check for previous 'uname -a'/`ldconfig -p` plus compiler version/variant in cache
489- -- if cached, then use that as suffix
490- -- otherwise:
491- -- download setup-info
492- -- go through all with right prefix for os/version/variant
493- -- first try "standard" (no extra suffix), then the rest
494- -- download "compatibility check" exe if not already downloaded
495- -- try running it
496- -- if successful, then choose that
497- -- cache compiler suffix with the uname -a and ldconfig -p output hash plus compiler version
498- --
499- -- Of course, could also try to make a static GHC bindist instead of all this rigamarole.
500-
501- platform <- asks getPlatform
502- case platform of
503- Platform _ Linux -> do
504- eldconfigOut <- tryProcessStdout Nothing menv " ldconfig" [" -p" ]
505- let firstWords = case eldconfigOut of
506- Right ldconfigOut -> mapMaybe (headMay . T. words ) $
507- T. lines $ T. decodeUtf8With T. lenientDecode ldconfigOut
508- Left _ -> []
509- checkLib lib
510- | libT `elem` firstWords = do
511- $ logDebug (" Found shared library " <> libT <> " in 'ldconfig -p' output" )
512- return True
483+ config <- asks getConfig
484+ case configGHCBuild config of
485+ Just ghcBuild -> return ghcBuild
486+ Nothing -> determineGhcBuild
487+ where
488+ determineGhcBuild = do
489+ -- TODO: a more reliable, flexible, and data driven approach would be to actually download small
490+ -- "test" executables (from setup-info) that link to the same gmp/tinfo versions
491+ -- that GHC does (i.e. built in same environment as the GHC bindist). The algorithm would go
492+ -- something like this:
493+ --
494+ -- check for previous 'uname -a'/`ldconfig -p` plus compiler version/variant in cache
495+ -- if cached, then use that as suffix
496+ -- otherwise:
497+ -- download setup-info
498+ -- go through all with right prefix for os/version/variant
499+ -- first try "standard" (no extra suffix), then the rest
500+ -- download "compatibility check" exe if not already downloaded
501+ -- try running it
502+ -- if successful, then choose that
503+ -- cache compiler suffix with the uname -a and ldconfig -p output hash plus compiler version
504+ --
505+ -- Of course, could also try to make a static GHC bindist instead of all this rigamarole.
506+
507+ platform <- asks getPlatform
508+ case platform of
509+ Platform _ Linux -> do
510+ eldconfigOut <- tryProcessStdout Nothing menv " ldconfig" [" -p" ]
511+ egccErrOut <- tryProcessStderrStdout Nothing menv " gcc" [" -v" ]
512+ let firstWords = case eldconfigOut of
513+ Right ldconfigOut -> mapMaybe (headMay . T. words ) $
514+ T. lines $ T. decodeUtf8With T. lenientDecode ldconfigOut
515+ Left _ -> []
516+ checkLib lib
517+ | libT `elem` firstWords = do
518+ $ logDebug (" Found shared library " <> libT <> " in 'ldconfig -p' output" )
519+ return True
513520#ifndef WINDOWS
514- -- (mkAbsDir "/usr/lib") fails to compile on Windows, thus the CPP
515- | otherwise = do
516- -- This is a workaround for the fact that libtinfo.so.6 doesn't appear in
517- -- the 'ldconfig -p' output on Arch even when it exists.
518- -- There doesn't seem to be an easy way to get the true list of directories
519- -- to scan for shared libs, but this works for our particular case.
520- e <- doesFileExist ($ (mkAbsDir " /usr/lib" ) </> lib)
521- if e
522- then $ logDebug (" Found shared library " <> libT <> " in /usr/lib" )
523- else $ logDebug (" Did not find shared library " <> libT)
524- return e
521+ -- (mkAbsDir "/usr/lib") fails to compile on Windows, thus the CPP
522+ | otherwise = do
523+ -- This is a workaround for the fact that libtinfo.so.6 doesn't appear in
524+ -- the 'ldconfig -p' output on Arch even when it exists.
525+ -- There doesn't seem to be an easy way to get the true list of directories
526+ -- to scan for shared libs, but this works for our particular case.
527+ e <- doesFileExist ($ (mkAbsDir " /usr/lib" ) </> lib)
528+ if e
529+ then $ logDebug (" Found shared library " <> libT <> " in /usr/lib" )
530+ else $ logDebug (" Did not find shared library " <> libT)
531+ return e
525532#endif
526- where
527- libT = T. pack (toFilePath lib)
528- hastinfo5 <- checkLib $ (mkRelFile " libtinfo.so.5" )
529- hastinfo6 <- checkLib $ (mkRelFile " libtinfo.so.6" )
530- hasncurses6 <- checkLib $ (mkRelFile " libncursesw.so.6" )
531- hasgmp5 <- checkLib $ (mkRelFile " libgmp.so.10" )
532- hasgmp4 <- checkLib $ (mkRelFile " libgmp.so.3" )
533- if | hastinfo5 && hasgmp5 -> useBuild CompilerBuildStandard
534- | hastinfo6 && hasgmp5 -> useBuild (CompilerBuildSpecialized " tinfo6" )
535- | hasncurses6 && hasgmp5 -> useBuild (CompilerBuildSpecialized " ncurses6" )
536- | hasgmp4 && hastinfo5 -> useBuild (CompilerBuildSpecialized " gmp4" )
537- | otherwise -> useBuild CompilerBuildStandard
538- _ -> useBuild CompilerBuildStandard
539- where
533+ where
534+ libT = T. pack (toFilePath lib)
535+ noPie = case egccErrOut of
536+ Right (gccErr,gccOut) ->
537+ " --enable-default-pie" `elem` (S8. words (gccOut <> gccErr))
538+ Left _ -> False
539+ hastinfo5 <- checkLib $ (mkRelFile " libtinfo.so.5" )
540+ hastinfo6 <- checkLib $ (mkRelFile " libtinfo.so.6" )
541+ hasncurses6 <- checkLib $ (mkRelFile " libncursesw.so.6" )
542+ hasgmp5 <- checkLib $ (mkRelFile " libgmp.so.10" )
543+ hasgmp4 <- checkLib $ (mkRelFile " libgmp.so.3" )
544+ let libComponents =
545+ if | hastinfo5 && hasgmp5 -> []
546+ | hastinfo6 && hasgmp5 -> [" tinfo6" ]
547+ | hasncurses6 && hasgmp5 -> [" ncurses6" ]
548+ | hasgmp4 && hastinfo5 -> [" gmp4" ]
549+ | otherwise -> []
550+ pieComponents =
551+ if noPie
552+ then [" nopie" ]
553+ else []
554+ case (concat [libComponents, pieComponents]) of
555+ [] -> useBuild CompilerBuildStandard
556+ components -> useBuild (CompilerBuildSpecialized (intercalate " -" components))
557+ _ -> useBuild CompilerBuildStandard
540558 useBuild CompilerBuildStandard = do
541559 $ logDebug " Using standard GHC build"
542560 return (CompilerBuildStandard )
@@ -774,7 +792,7 @@ downloadAndInstallCompiler ghcBuild si wanted@GhcVersion{} versionCheck mbindist
774792 _ -> throwM RequireCustomGHCVariant
775793 case wanted of
776794 GhcVersion version ->
777- return (version, DownloadInfo (T. pack bindistURL) Nothing Nothing )
795+ return (version, GHCDownloadInfo mempty mempty ( DownloadInfo (T. pack bindistURL) Nothing Nothing ) )
778796 _ ->
779797 throwM WantedMustBeGHC
780798 _ -> do
@@ -786,7 +804,7 @@ downloadAndInstallCompiler ghcBuild si wanted@GhcVersion{} versionCheck mbindist
786804 let installer =
787805 case configPlatform config of
788806 Platform _ Cabal. Windows -> installGHCWindows selectedVersion
789- _ -> installGHCPosix selectedVersion
807+ _ -> installGHCPosix selectedVersion downloadInfo
790808 $ logInfo $
791809 " Preparing to install GHC" <>
792810 (case ghcVariant of
@@ -799,7 +817,7 @@ downloadAndInstallCompiler ghcBuild si wanted@GhcVersion{} versionCheck mbindist
799817 $ logInfo " This will not interfere with any system-level installation."
800818 ghcPkgName <- parsePackageNameFromString (" ghc" ++ ghcVariantSuffix ghcVariant ++ compilerBuildSuffix ghcBuild)
801819 let tool = Tool $ PackageIdentifier ghcPkgName selectedVersion
802- downloadAndInstallTool (configLocalPrograms config) si downloadInfo tool installer
820+ downloadAndInstallTool (configLocalPrograms config) si (gdiDownloadInfo downloadInfo) tool installer
803821downloadAndInstallCompiler compilerBuild si wanted versionCheck _mbindistUrl = do
804822 config <- asks getConfig
805823 ghcVariant <- asks getGHCVariant
@@ -905,13 +923,14 @@ data ArchiveType
905923
906924installGHCPosix :: (MonadIO m , MonadMask m , MonadLogger m , MonadReader env m , HasConfig env , HasHttpManager env , MonadBaseControl IO m , HasTerminal env )
907925 => Version
926+ -> GHCDownloadInfo
908927 -> SetupInfo
909928 -> Path Abs File
910929 -> ArchiveType
911930 -> Path Abs Dir
912931 -> Path Abs Dir
913932 -> m ()
914- installGHCPosix version _ archiveFile archiveType tempDir destDir = do
933+ installGHCPosix version downloadInfo _ archiveFile archiveType tempDir destDir = do
915934 platform <- asks getPlatform
916935 menv0 <- getMinimalEnvOverride
917936 menv <- mkEnvOverride platform (removeHaskellEnvVars (unEnvOverride menv0))
@@ -942,8 +961,9 @@ installGHCPosix version _ archiveFile archiveType tempDir destDir = do
942961 parseRelDir $
943962 " ghc-" ++ versionString version
944963
945- let runStep step wd cmd args = do
946- result <- try (readProcessNull (Just wd) menv cmd args)
964+ let runStep step wd env cmd args = do
965+ menv' <- modifyEnvOverride menv (Map. union env)
966+ result <- try (readProcessNull (Just wd) menv' cmd args)
947967 case result of
948968 Right _ -> return ()
949969 Left ex -> do
@@ -962,13 +982,16 @@ installGHCPosix version _ archiveFile archiveType tempDir destDir = do
962982
963983 $ logSticky $ T. concat [" Unpacking GHC into " , T. pack . toFilePath $ tempDir, " ..." ]
964984 $ logDebug $ " Unpacking " <> T. pack (toFilePath archiveFile)
965- runStep " unpacking" tempDir tarTool [compOpt : " xf" , toFilePath archiveFile]
985+ runStep " unpacking" tempDir mempty tarTool [compOpt : " xf" , toFilePath archiveFile]
966986
967987 $ logSticky " Configuring GHC ..."
968- runStep " configuring" dir (toFilePath $ dir </> $ (mkRelFile " configure" )) [" --prefix=" ++ toFilePath destDir]
988+ runStep " configuring" dir
989+ (gdiConfigureEnv downloadInfo)
990+ (toFilePath $ dir </> $ (mkRelFile " configure" ))
991+ ((" --prefix=" ++ toFilePath destDir) : map T. unpack (gdiConfigureOpts downloadInfo))
969992
970993 $ logSticky " Installing GHC ..."
971- runStep " installing" dir makeTool [" install" ]
994+ runStep " installing" dir mempty makeTool [" install" ]
972995
973996 $ logStickyDone $ " Installed GHC."
974997 $ logDebug $ " GHC installed to " <> T. pack (toFilePath destDir)
0 commit comments