ghcjs: properly wrap binaries in environment

This also:

 1  Builds Setup.hs with ghcjs, which (among other things) defines
    __GHCJS__ and ghcjs_HOST_OS during pre-processing.
 2  Fixes ghc-paths to point at ghcjs and use NIX_GHCJS_* env-vars.
 3  Boots ghcjs into $prefix/lib/$compiler.
This commit is contained in:
Charles Strahan 2015-05-06 15:56:02 -04:00
parent 9cb6ebe15e
commit 929dc4199a
6 changed files with 125 additions and 46 deletions

View File

@ -39,10 +39,6 @@
}:
let
version = "0.1.0";
ghcArch = if pkgs.stdenv.system == "i686-linux"
then "i386-linux"
else pkgs.stdenv.system;
libDir = "share/ghcjs/${ghcArch}-${version}-${ghc.version}/ghcjs";
ghcjsBoot = fetchgit {
url = git://github.com/ghcjs/ghcjs-boot.git;
rev = "ab8765edcb507b8b810e3c324fd5bd5af2b69d8f"; # 7.10 branch
@ -84,14 +80,19 @@ in mkDerivation (rec {
];
patches = [ ./ghcjs.patch ];
postPatch = ''
substituteInPlace Setup.hs --replace "/usr/bin/env" "${coreutils}/bin/env"
substituteInPlace src/Compiler/Info.hs --replace "@PREFIX@" "$out"
substituteInPlace Setup.hs \
--replace "/usr/bin/env" "${coreutils}/bin/env"
substituteInPlace src/Compiler/Info.hs \
--replace "@PREFIX@" "$out" \
--replace "@VERSION@" "${version}"
substituteInPlace src-bin/Boot.hs \
--replace "@PREFIX@" "$out" \
--replace "@CC@" "${stdenv.cc}/bin/cc"
'';
preBuild = ''
local topDir=$out/${libDir}
local topDir=$out/lib/ghcjs-${version}
mkdir -p $topDir
cp -r ${ghcjsBoot} $topDir/ghcjs-boot
@ -116,9 +117,9 @@ in mkDerivation (rec {
--with-gmp-libraries ${gmp}/lib
'';
passthru = {
inherit libDir;
isGhcjs = true;
nativeGhc = ghc;
inherit nodejs;
};
homepage = "https://github.com/ghcjs/ghcjs";

View File

@ -60,15 +60,21 @@ index 3c68dcf..64f3cf7 100644
, "--haddock-html"
-- workaround for hoogle support being broken in haddock for GHC 7.10RC1
diff --git a/src/Compiler/Info.hs b/src/Compiler/Info.hs
index 33a401f..5d09c86 100644
index 33a401f..79833c5 100644
--- a/src/Compiler/Info.hs
+++ b/src/Compiler/Info.hs
@@ -49,7 +49,7 @@ compilerInfo nativeToo dflags = do
@@ -48,13 +48,7 @@ compilerInfo nativeToo dflags = do
-- | the directory to use if started without -B flag
getDefaultTopDir :: IO FilePath
getDefaultTopDir = do
-getDefaultTopDir = do
- appdir <- getAppUserDataDirectory "ghcjs"
+ let appdir = "@PREFIX@/share/ghcjs"
return (appdir </> subdir </> "ghcjs")
where
targetARCH = arch
- return (appdir </> subdir </> "ghcjs")
- where
- targetARCH = arch
- targetOS = os
- subdir = targetARCH ++ '-':targetOS ++ '-':getFullCompilerVersion
+getDefaultTopDir = return "@PREFIX@/lib/ghcjs-@VERSION@"
getDefaultLibDir :: IO FilePath
getDefaultLibDir = getDefaultTopDir

View File

@ -99,4 +99,8 @@ self: super: {
buildDepends = [ self.base self.mtl self.text self.ghcjs-base ];
});
ghc-paths = overrideCabal super.ghc-paths (drv: {
patches = [ ./ghc-paths-nix-ghcjs.patch ];
});
}

View File

@ -114,7 +114,7 @@ let
ghcEnv = ghc.withPackages (p: haskellBuildInputs);
setupBuilder = if isGhcjs then "${ghc.nativeGhc}/bin/ghc" else "ghc";
setupCommand = if isGhcjs then "${ghc.nodejs}/bin/node ./Setup.jsexe/all.js" else "./Setup";
ghcCommand = if isGhcjs then "ghcjs" else "ghc";
in
@ -186,7 +186,7 @@ stdenv.mkDerivation ({
done
echo setupCompileFlags: $setupCompileFlags
${setupBuilder} $setupCompileFlags --make -o Setup -odir $TMPDIR -hidir $TMPDIR $i
${ghcCommand} $setupCompileFlags --make -o Setup -odir $TMPDIR -hidir $TMPDIR $i
runHook postCompileBuildDriver
'';
@ -197,7 +197,7 @@ stdenv.mkDerivation ({
unset GHC_PACKAGE_PATH # Cabal complains if this variable is set during configure.
echo configureFlags: $configureFlags
./Setup configure $configureFlags 2>&1 | ${coreutils}/bin/tee "$NIX_BUILD_TOP/cabal-configure.log"
${setupCommand} configure $configureFlags 2>&1 | ${coreutils}/bin/tee "$NIX_BUILD_TOP/cabal-configure.log"
if ${gnugrep}/bin/egrep -q '^Warning:.*depends on multiple versions' "$NIX_BUILD_TOP/cabal-configure.log"; then
echo >&2 "*** abort because of serious configure-time warning from Cabal"
exit 1
@ -210,20 +210,20 @@ stdenv.mkDerivation ({
buildPhase = ''
runHook preBuild
./Setup build ${buildTarget}
${setupCommand} build ${buildTarget}
runHook postBuild
'';
checkPhase = ''
runHook preCheck
./Setup test ${testTarget}
${setupCommand} test ${testTarget}
runHook postCheck
'';
haddockPhase = ''
runHook preHaddock
${optionalString (doHaddock && hasActiveLibrary) ''
./Setup haddock --html \
${setupCommand} haddock --html \
${optionalString doHoogle "--hoogle"} \
${optionalString (hasActiveLibrary && hyperlinkSource) "--hyperlink-source"}
''}
@ -233,12 +233,12 @@ stdenv.mkDerivation ({
installPhase = ''
runHook preInstall
${if !hasActiveLibrary then "./Setup install" else ''
./Setup copy
${if !hasActiveLibrary then "${setupCommand} install" else ''
${setupCommand} copy
local packageConfDir="$out/lib/${ghc.name}/package.conf.d"
local packageConfFile="$packageConfDir/${pname}-${version}.conf"
mkdir -p "$packageConfDir"
./Setup register --gen-pkg-config=$packageConfFile
${setupCommand} register --gen-pkg-config=$packageConfFile
local pkgId=$( ${gnused}/bin/sed -n -e 's|^id: ||p' $packageConfFile )
mv $packageConfFile $packageConfDir/$pkgId.conf
''}

View File

@ -0,0 +1,65 @@
diff --git a/GHC/Paths.hs b/GHC/Paths.hs
index c87565d..88b3db4 100644
--- a/GHC/Paths.hs
+++ b/GHC/Paths.hs
@@ -1,13 +1,35 @@
{-# LANGUAGE CPP #-}
+{-# LANGUAGE ScopedTypeVariables #-}
module GHC.Paths (
ghc, ghc_pkg, libdir, docdir
) where
+import Control.Exception as E
+import Data.Maybe
+import System.Environment
+import System.IO.Unsafe
+
+-- Yes, there's lookupEnv now, but we want to be compatible
+-- with older GHCs.
+checkEnv :: String -> IO (Maybe String)
+checkEnv var = E.catch (fmap Just (getEnv var))
+ (\ (e :: IOException) -> return Nothing)
+
+nixLibdir, nixDocdir, nixGhc, nixGhcPkg :: Maybe FilePath
+nixLibdir = unsafePerformIO (checkEnv "NIX_GHCJS_LIBDIR")
+nixDocdir = unsafePerformIO (checkEnv "NIX_GHCJS_DOCDIR")
+nixGhc = unsafePerformIO (checkEnv "NIX_GHCJS")
+nixGhcPkg = unsafePerformIO (checkEnv "NIX_GHCJSPKG")
+{-# NOINLINE nixLibdir #-}
+{-# NOINLINE nixDocdir #-}
+{-# NOINLINE nixGhc #-}
+{-# NOINLINE nixGhcPkg #-}
+
libdir, docdir, ghc, ghc_pkg :: FilePath
-libdir = GHC_PATHS_LIBDIR
-docdir = GHC_PATHS_DOCDIR
+libdir = fromMaybe GHC_PATHS_LIBDIR nixLibdir
+docdir = fromMaybe GHC_PATHS_DOCDIR nixDocdir
-ghc = GHC_PATHS_GHC
-ghc_pkg = GHC_PATHS_GHC_PKG
+ghc = fromMaybe GHC_PATHS_GHC nixGhc
+ghc_pkg = fromMaybe GHC_PATHS_GHC_PKG nixGhcPkg
diff --git a/Setup.hs b/Setup.hs
index fad5026..1651650 100644
--- a/Setup.hs
+++ b/Setup.hs
@@ -27,13 +27,13 @@ main = defaultMainWithHooks simpleUserHooks {
defaultPostConf :: Args -> ConfigFlags -> PackageDescription -> LocalBuildInfo -> IO ()
defaultPostConf args flags pkgdescr lbi = do
libdir_ <- rawSystemProgramStdoutConf (fromFlag (configVerbosity flags))
- ghcProgram (withPrograms lbi) ["--print-libdir"]
+ ghcjsProgram (withPrograms lbi) ["--print-libdir"]
let libdir = reverse $ dropWhile isSpace $ reverse libdir_
- ghc_pkg = case lookupProgram ghcPkgProgram (withPrograms lbi) of
+ ghc_pkg = case lookupProgram ghcjsPkgProgram (withPrograms lbi) of
Just p -> programPath p
Nothing -> error "ghc-pkg was not found"
- ghc = case lookupProgram ghcProgram (withPrograms lbi) of
+ ghc = case lookupProgram ghcjsProgram (withPrograms lbi) of
Just p -> programPath p
Nothing -> error "ghc was not found"

View File

@ -32,6 +32,7 @@ let
ghc761OrLater = isGhcjs || lib.versionOlder "7.6.1" ghc.version;
packageDBFlag = if ghc761OrLater then "--global-package-db" else "--global-conf";
ghcCommand = if isGhcjs then "ghcjs" else "ghc";
ghcCommandCaps= lib.toUpper ghcCommand;
libDir = "$out/lib/${ghcCommand}-${ghc.version}";
docDir = "$out/share/doc/ghc/html";
packageCfgDir = "${libDir}/package.conf.d";
@ -51,10 +52,6 @@ buildEnv {
postBuild = ''
. ${makeWrapper}/nix-support/setup-hook
${lib.optionalString isGhcjs ''
cp -r "${ghc}/${ghc.libDir}/"* ${libDir}/
''}
if test -L "$out/bin"; then
binTarget="$(readlink -f "$out/bin")"
rm "$out/bin"
@ -62,30 +59,36 @@ buildEnv {
chmod u+w "$out/bin"
fi
for prg in ghc ghci ghc-${ghc.version} ghci-${ghc.version}; do
rm -f $out/bin/$prg
makeWrapper ${ghc}/bin/$prg $out/bin/$prg \
--add-flags '"-B$NIX_GHC_LIBDIR"' \
--set "NIX_GHC" "$out/bin/${ghcCommand}" \
--set "NIX_GHCPKG" "$out/bin/${ghcCommand}-pkg" \
--set "NIX_GHC_DOCDIR" "${docDir}" \
--set "NIX_GHC_LIBDIR" "${libDir}" \
${lib.optionalString withLLVM ''--prefix "PATH" ":" "${llvm}"''}
for prg in ${ghcCommand} ${ghcCommand}i ${ghcCommand}-${ghc.version} ${ghcCommand}i-${ghc.version}; do
if [[ -x "${ghc}/bin/$prg" ]]; then
rm -f $out/bin/$prg
makeWrapper ${ghc}/bin/$prg $out/bin/$prg \
--add-flags '"-B$NIX_${ghcCommandCaps}_LIBDIR"' \
--set "NIX_${ghcCommandCaps}" "$out/bin/${ghcCommand}" \
--set "NIX_${ghcCommandCaps}PKG" "$out/bin/${ghcCommand}-pkg" \
--set "NIX_${ghcCommandCaps}_DOCDIR" "${docDir}" \
--set "NIX_${ghcCommandCaps}_LIBDIR" "${libDir}" \
${lib.optionalString withLLVM ''--prefix "PATH" ":" "${llvm}"''}
fi
done
for prg in runghc runhaskell; do
rm -f $out/bin/$prg
makeWrapper ${ghc}/bin/$prg $out/bin/$prg \
--add-flags "-f $out/bin/ghc" \
--set "NIX_GHC" "$out/bin/${ghcCommand}" \
--set "NIX_GHCPKG" "$out/bin/${ghcCommand}-pkg" \
--set "NIX_GHC_DOCDIR" "${docDir}" \
--set "NIX_GHC_LIBDIR" "${libDir}"
if [[ -x "${ghc}/bin/$prg" ]]; then
rm -f $out/bin/$prg
makeWrapper ${ghc}/bin/$prg $out/bin/$prg \
--add-flags "-f $out/bin/${ghcCommand}" \
--set "NIX_${ghcCommandCaps}" "$out/bin/${ghcCommand}" \
--set "NIX_${ghcCommandCaps}PKG" "$out/bin/${ghcCommand}-pkg" \
--set "NIX_${ghcCommandCaps}_DOCDIR" "${docDir}" \
--set "NIX_${ghcCommandCaps}_LIBDIR" "${libDir}"
fi
done
for prg in ${ghcCommand}-pkg ${ghcCommand}-pkg-${ghc.version}; do
rm -f $out/bin/$prg
makeWrapper ${ghc}/bin/$prg $out/bin/$prg --add-flags "${packageDBFlag}=${packageCfgDir}"
if [[ -x "${ghc}/bin/$prg" ]]; then
rm -f $out/bin/$prg
makeWrapper ${ghc}/bin/$prg $out/bin/$prg --add-flags "${packageDBFlag}=${packageCfgDir}"
fi
done
${lib.optionalString hasLibraries "$out/bin/${ghcCommand}-pkg recache"}