Skip to content

Commit

Permalink
Generate dummy-ghc from raw ghc source (#2183)
Browse files Browse the repository at this point in the history
* Generate dummy-ghc from raw ghc source

This should be fast and will avoid us having to maintain the `materialized/dummy-ghc` files.
  • Loading branch information
hamishmack committed Apr 30, 2024
1 parent c893a36 commit dfd39f4
Show file tree
Hide file tree
Showing 18 changed files with 521 additions and 124 deletions.
2 changes: 1 addition & 1 deletion ci.nix
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ dimension "Nixpkgs version" nixpkgsVersions (nixpkgsName: pinnedNixpkgsSrc:
// pkgs.lib.optionalAttrs (ifdLevel >= 2 && crossSystemName != "ghcjs")
pkgs.haskell-nix.iserv-proxy-exes.${compiler-nix-name}
// pkgs.lib.optionalAttrs (ifdLevel >= 3) {
hello = (pkgs.haskell-nix.hackage-package { name = "hello"; version = "1.0.0.2"; inherit compiler-nix-name; }).getComponent "exe:hello";
hello = (pkgs.haskell-nix.hackage-package { name = "hello"; version = "1.0.0.2"; inherit evalPackages compiler-nix-name; }).getComponent "exe:hello";
})
))
)
Expand Down
11 changes: 11 additions & 0 deletions compiler/ghc/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,17 @@ stdenv.mkDerivation (rec {
# We could add `configured-src` as an output of the ghc derivation, but
# having it as its own derivation means it can be accessed quickly without
# building GHC.
raw-src = stdenv.mkDerivation {
name = name + "-raw-src";
inherit
version
patches
src;
installPhase = ''
cp -r . $out
'';
phases = [ "unpackPhase" "patchPhase" "installPhase"];
};
configured-src = stdenv.mkDerivation ({
name = name + "-configured-src";
inherit
Expand Down
16 changes: 8 additions & 8 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

159 changes: 148 additions & 11 deletions lib/call-cabal-project-to-nix.nix
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,9 @@ let

fixedProject = replaceSourceRepos rawCabalProject;

inherit (ghc) dummy-ghc-data;
ghcSrc = ghc.raw-src or ghc.buildGHC.raw-src;

fixPlatformString = x: builtins.replaceStrings ["-linux-gnu"] ["-linux"] x;

# Dummy `ghc` that uses the captured output
dummy-ghc = evalPackages.writeTextFile {
Expand All @@ -299,30 +301,54 @@ let
#!${evalPackages.runtimeShell}
case "$*" in
--version*)
cat ${dummy-ghc-data}/ghc/version
echo "The Glorious Glasgow Haskell Compilation System, version ${ghc.version}"
;;
--numeric-version*)
cat ${dummy-ghc-data}/ghc/numeric-version
echo "${ghc.version}"
;;
${pkgs.lib.optionalString (ghc.targetPrefix == "js-unknown-ghcjs-") ''
--numeric-ghc-version*)
cat ${dummy-ghc-data}/ghc/numeric-ghc-version
echo "${ghc.version}"
;;
--numeric-ghcjs-version*)
cat ${dummy-ghc-data}/ghc/numeric-ghcjs-version
echo "${ghc.version}"
;;
''}
--supported-languages*)
cat ${dummy-ghc-data}/ghc/supported-languages
cat ${import ./supported-languages.nix { inherit pkgs evalPackages ghc; }}
;;
--print-global-package-db*)
echo "$out/dumby-db"
;;
--info*)
cat ${dummy-ghc-data}/ghc/info
echo '[("target os", "${
if pkgs.stdenv.targetPlatform.isLinux
then "OSLinux"
else if pkgs.stdenv.targetPlatform.isDarwin
then "OSDarwin"
else if pkgs.stdenv.targetPlatform.isWindows
then "OSMinGW32"
else if pkgs.stdenv.targetPlatform.isGhcjs
then "OSGhcjs"
else throw "Unknown target os ${pkgs.stdenv.targetPlatform.config}"
}")'
echo ',("target arch","${
if pkgs.stdenv.targetPlatform.isx86_64
then "ArchX86_64"
else if pkgs.stdenv.targetPlatform.isAarch64
then "ArchAArch64"
else if pkgs.stdenv.targetPlatform.isJavaScript
then "ArchJavaScript"
else throw "Unknown target arch ${pkgs.stdenv.targetPlatform.config}"
}")'
echo ',("target platform string","${fixPlatformString pkgs.stdenv.targetPlatform.config}")'
echo ',("Build platform","${fixPlatformString pkgs.stdenv.buildPlatform.config}")'
echo ',("Host platform","${fixPlatformString pkgs.stdenv.hostPlatform.config}")'
echo ',("Target platform","${fixPlatformString pkgs.stdenv.targetPlatform.config}")'
echo ']'
;;
--print-libdir*)
echo ${dummy-ghc-data}/ghc/libdir
echo $out/ghc/libdir
;;
*)
echo "Unknown argument '$*'" >&2
Expand All @@ -333,6 +359,117 @@ let
'';
};

ghc-pkgs = [
"Cabal"
"Cabal-syntax"
"array"
"base"
"binary"
"bytestring"
"containers"
"deepseq"
"directory"
"exceptions"
"filepath"
"ghc"
"ghc-bignum"
"ghc-boot"
"ghc-boot-th"
"ghc-compact"
"ghc-experimental"
"ghc-heap"
"ghc-internal"
"ghc-platform"
"ghc-prim"
"ghc-toolchain"
"ghci"
"haskeline"
"hpc"
"integer-gmp"
"mtl"
"os-string"
"parsec"
"pretty"
"process"
"rts"
"semaphore-compat"
"stm"
"template-haskell"
"terminfo"
"text"
"time"
"transformers"
"xhtml"
] ++ (if pkgs.stdenv.targetPlatform.isWindows
then [ "Win32" ]
else [ "unix" ]
);

dummy-ghc-pkg-dump = evalPackages.runCommand "dummy-ghc-pkg-dump" {
nativeBuildInputs = [
evalPackages.haskell-nix.nix-tools-unchecked.exes.cabal2json
evalPackages.jq
];
} (let varname = x: builtins.replaceStrings ["-"] ["_"] x; in ''
PKGS=""
${pkgs.lib.concatStrings
(builtins.map (name: ''
cabal_file=""
if [ -f ${ghcSrc}/libraries/${name}/${name}.cabal ]; then
cabal_file=${ghcSrc}/libraries/${name}/${name}.cabal
elif [ -f ${ghcSrc}/libraries/Cabal/${name}/${name}.cabal ]; then
cabal_file=${ghcSrc}/libraries/Cabal/${name}/${name}.cabal
elif [ -f ${ghcSrc}/libraries/${name}/${name}/${name}.cabal ]; then
cabal_file=${ghcSrc}/libraries/${name}/${name}/${name}.cabal
elif [ -f ${ghcSrc}/compiler/${name}.cabal ]; then
cabal_file=${ghcSrc}/compiler/${name}.cabal
elif [ -f ${ghcSrc}/compiler/${name}.cabal.in ]; then
cabal_file=${ghcSrc}/compiler/${name}.cabal.in
elif [ -f ${ghcSrc}/libraries/${name}/${name}.cabal.in ]; then
cabal_file=${ghcSrc}/libraries/${name}/${name}.cabal.in
fi
if [[ "$cabal_file" != "" ]]; then
fixed_cabal_file=$(mktemp)
cat $cabal_file | sed -e 's/@ProjectVersionMunged@/${ghc.version}/g' -e 's/default: *@[A-Za-z0-9]*@/default: False/g' -e 's/@Suffix@//g' > $fixed_cabal_file
json_cabal_file=$(mktemp)
cabal2json $fixed_cabal_file > $json_cabal_file
EXPOSED_MODULES_${varname name}="$(jq -r '.library."exposed-modules"[]|select(type=="array")[]' $json_cabal_file | tr '\n' ' ')"
DEPS_${varname name}="$(jq -r '.library."build-depends"[]|select(type=="array")[],select(type=="object").then[]' $json_cabal_file | sed 's/^\([A-Za-z0-9-]*\).*$/\1/g' | sort -u | tr '\n' ' ')"
VER_${varname name}="$(jq -r '.version' $json_cabal_file)"
PKGS+=" ${name}"
LAST_PKG="${name}"
fi
'') ghc-pkgs)
}
${ # There is not .cabal file for system-cxx-std-lib
pkgs.lib.optionalString (builtins.compareVersions ghc.version "9.2" >= 0) (
let name="system-cxx-std-lib"; in ''
EXPOSED_MODULES_${varname name}=""
DEPS_${varname name}=""
VER_${varname name}="1.0"
PKGS+=" ${name}"
LAST_PKG="${name}"
'')}
for pkg in $PKGS; do
varname="$(echo $pkg | tr "-" "_")"
ver="VER_$varname"
exposed_mods="EXPOSED_MODULES_$varname"
deps="DEPS_$varname"
echo "name: $pkg" >> $out
echo "version: ''${!ver}" >> $out
echo "exposed-modules: ''${!exposed_mods}" >> $out
echo "depends:" >> $out
for dep in ''${!deps}; do
ver_dep="VER_$(echo $dep | tr "-" "_")"
if [[ "''${!ver_dep}" != "" ]]; then
echo " $dep-''${!ver_dep}" >> $out
fi
done
if [[ "$pkg" != "$LAST_PKG" ]]; then
echo '---' >> $out
fi
done
'');
# Dummy `ghc-pkg` that uses the captured output
dummy-ghc-pkg = evalPackages.writeTextFile {
name = "dummy-pkg-" + ghc.name;
Expand All @@ -342,15 +479,15 @@ let
#!${evalPackages.runtimeShell}
case "$*" in
--version)
cat ${dummy-ghc-data}/ghc-pkg/version
echo "GHC package manager version ${ghc.version}"
;;
${pkgs.lib.optionalString (ghc.targetPrefix == "js-unknown-ghcjs-") ''
--numeric-ghcjs-version)
cat ${dummy-ghc-data}/ghc-pkg/numeric-ghcjs-version
echo "${ghc.version}"
;;
''}
'dump --global -v0')
cat ${dummy-ghc-data}/ghc-pkg/dump-global
cat ${dummy-ghc-pkg-dump}
;;
*)
echo "Unknown argument '$*'. " >&2
Expand Down
5 changes: 0 additions & 5 deletions lib/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -570,11 +570,6 @@ in {
inherit (pkgs.buildPackages.buildPackages) lib runCommand;
};

makeDummyGhcData = import ./make-dummy-ghc-data.nix {
inherit pkgs;
inherit (pkgs.buildPackages.buildPackages) runCommand;
};

# Here we try to figure out which qemu to use based on the host platform.
# This guess can be overridden by passing qemuSuffix
qemuByHostPlatform = hostPlatform:
Expand Down
78 changes: 0 additions & 78 deletions lib/make-dummy-ghc-data.nix

This file was deleted.

0 comments on commit dfd39f4

Please sign in to comment.