Skip to content

Commit

Permalink
'stack setup' detects libncursesw.so.6 and selects an appropriate GHC…
Browse files Browse the repository at this point in the history
… bindist
  • Loading branch information
borsboom committed Aug 23, 2016
1 parent d29b3fc commit e0b9b13
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 25 deletions.
5 changes: 3 additions & 2 deletions doc/MAINTAINER_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -226,8 +226,9 @@ set up.

### Building GHC

Set the `GHC_VERSION` environment variable to the version to build,
then run (from [here](https://ghc.haskell.org/trac/ghc/wiki/Newcomers)):
Set the `GHC_VERSION` environment variable to the version to build.

For GHC >= 7.10.2, run (from [here](https://ghc.haskell.org/trac/ghc/wiki/Newcomers)):

git config --global url."git://github.com/ghc/packages-".insteadOf git://github.com/ghc/packages/ && \
git clone -b ghc-${GHC_VERSION}-release --recursive git://github.com/ghc/ghc ghc-${GHC_VERSION} && \
Expand Down
13 changes: 10 additions & 3 deletions doc/install_and_upgrade.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,9 +230,13 @@ new releases by some days.
- [stack](https://www.archlinux.org/packages/community/x86_64/stack/) _latest stable version_
- [haskell-stack-git](https://aur.archlinux.org/packages/haskell-stack-git/) _git version_

In order to use `stack setup`, you will need the [ncurses5-compat-libs](https://aur.archlinux.org/packages/ncurses5-compat-libs/) AUR package installed. If this package is not installed, Stack will not be able to install GHC.
In order to use `stack setup`, you will need the
[libtinfo](https://aur.archlinux.org/packages/libtinfo/) AUR package installed.
If this package is not installed, Stack will not be able to install GHC.

If you use the [ArchHaskell repository](https://wiki.archlinux.org/index.php/ArchHaskell), you can also get the `haskell-stack-tool` package from there.
If you use the
[ArchHaskell repository](https://wiki.archlinux.org/index.php/ArchHaskell), you
can also get the `haskell-stack-tool` package from there.

## NixOS

Expand Down Expand Up @@ -280,7 +284,10 @@ Stack](http://nixos.org/nixpkgs/manual/#how-to-build-a-haskell-project-using-sta
* Debian / Ubuntu: `sudo apt-get install g++ gcc libc6-dev libffi-dev libgmp-dev make xz-utils zlib1g-dev git gnupg`
* Fedora / CentOS: `sudo dnf install perl make automake gcc gmp-devel libffi zlib xz tar git gnupg` (use `yum` instead of `dnf` on CentOS and Fedora <= 21)
* Arch Linux: `sudo pacman -S make gcc ncurses git gnupg xz zlib gmp libffi zlib`
* In order to use `stack setup`, you will need the [ncurses5-compat-libs](https://aur.archlinux.org/packages/ncurses5-compat-libs/) AUR package installed. If this package is not installed, Stack will not be able to install GHC.
* In order to use `stack setup`, you will need the
[libtinfo](https://aur.archlinux.org/packages/libtinfo/) AUR package
installed. If this package is not installed, Stack will not be able to
install GHC.
* Gentoo users, make sure to have the `ncurses` package with `USE=tinfo` (without it, stack will not be able to install GHC).

* Now you can run `stack` from the terminal.
Expand Down
60 changes: 40 additions & 20 deletions src/Stack/Setup.hs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE MultiWayIf #-}

module Stack.Setup
( setupEnv
Expand Down Expand Up @@ -472,7 +473,7 @@ getGhcBuild menv = do
-- that GHC does (i.e. built in same environment as the GHC bindist). The algorithm would go
-- something like this:
--
-- check for previous 'uname -a' plus compiler version/variant in cache
-- check for previous 'uname -a'/`ldconfig -p` plus compiler version/variant in cache
-- if cached, then use that as suffix
-- otherwise:
-- download setup-info
Expand All @@ -482,30 +483,49 @@ getGhcBuild menv = do
-- try running it
-- if successful, then choose that
-- cache compiler suffix with the uname -a and ldconfig -p output hash plus compiler version
--
-- Of course, could also try to make a static GHC bindist instead of all this rigamarole.

platform <- asks getPlatform
case platform of
Platform _ Linux -> do
eldconfigOut <- tryProcessStdout Nothing menv "ldconfig" ["-p"]
let efirstWords = fmap (mapMaybe (headMay . T.words) .
T.lines . T.decodeUtf8With T.lenientDecode) eldconfigOut
case efirstWords of
Right firstWords
| "libtinfo.so.6" `elem` firstWords
&& not ("libtinfo.so.5" `elem` firstWords) -> do
$logDebug "Found libtinfo.so.6; using tinfo6 GHC build"
return (CompilerBuildSpecialized "tinfo6")
| "libgmp.so.3" `elem` firstWords
&& not ("libgmp.so.10" `elem` firstWords) -> do
$logDebug "Found libgmp.so.3; using gmp4 GHC build"
return (CompilerBuildSpecialized "gmp4")
| otherwise -> do
$logDebug "Did not find libtinfo.so.6 or libgmp.so.3; using standard GHC build"
return CompilerBuildStandard
Left _ -> do
$logDebug "ldconfig -p failed; falling back to using standard GHC build"
return CompilerBuildStandard
_ -> return CompilerBuildStandard
let firstWords = case eldconfigOut of
Right ldconfigOut -> mapMaybe (headMay . T.words) $
T.lines $ T.decodeUtf8With T.lenientDecode ldconfigOut
Left _ -> []
checkLib lib
| libT `elem` firstWords = do
$logDebug ("Found shared library " <> libT <> " in 'ldconfig -p' output")
return True
| otherwise = do
-- There doesn't seem to be an easy way to get the true list of directories
-- to scan for shared libs, but this works for the case we care about here: Arch Linux
e <- doesFileExist ($(mkAbsDir "/usr/lib") </> lib)
if e
then $logDebug ("Found shared library " <> libT <> " in /usr/lib")
else $logDebug ("Did not find shared library " <> libT)
return e
where
libT = T.pack (toFilePath lib)
hastinfo5 <- checkLib $(mkRelFile "libtinfo.so.5")
hastinfo6 <- checkLib $(mkRelFile "libtinfo.so.6")
hasncurses6 <- checkLib $(mkRelFile "libncursesw.so.6")
hasgmp5 <- checkLib $(mkRelFile "libgmp.so.10")
hasgmp4 <- checkLib $(mkRelFile "libgmp.so.3")
if | hastinfo5 && hasgmp5 -> useBuild CompilerBuildStandard
| hastinfo6 && hasgmp5 -> useBuild (CompilerBuildSpecialized "tinfo6")
| hasncurses6 && hasgmp5 -> useBuild (CompilerBuildSpecialized "ncurses6")
| hasgmp4 && hastinfo5 -> useBuild (CompilerBuildSpecialized "gmp4")
| otherwise -> useBuild CompilerBuildStandard
_ -> useBuild CompilerBuildStandard
where
useBuild CompilerBuildStandard = do
$logDebug "Using standard GHC build"
return (CompilerBuildStandard)
useBuild (CompilerBuildSpecialized s) = do
$logDebug ("Using " <> T.pack s <> " GHC build")
return (CompilerBuildSpecialized s)

-- | Ensure Docker container-compatible 'stack' executable is downloaded
ensureDockerStackExe
Expand Down

0 comments on commit e0b9b13

Please sign in to comment.