@@ -13,6 +13,7 @@
1313, configFiles # The component's "config" derivation
1414, postInstall ? ""
1515, enableDWARF
16+, plugins
1617}:
1718
1819let
@@ -37,31 +38,70 @@ in runCommand "${componentName}-${ghc.name}-env" {
3738 ''
3839 . ${makeWrapper}/nix-support/setup-hook
3940
40− # Start with a ghc...
41+ ''
42+ # Start with a ghc and remove all of the package directories
43+ + ''
4144 mkdir -p $out/bin
4245 ${lndir}/bin/lndir -silent ${ghc} $out
43− # ... remove all of the package directories
4446 rm -rf ${libDir}/*/
45− # ... but retain the lib/ghc/bin directory. This contains `unlit' and friends.
47+ ''
48+ # ... but retain the lib/ghc/bin directory. This contains `unlit' and friends.
49+ + ''
4650 ln -s ${ghc}/lib/${ghcCommand}-${ghc.version}/bin ${libDir}
47− # ... and the ghcjs shim's if they are available ...
51+ ''
52+ # ... and the ghcjs shim's if they are available ...
53+ + ''
4854 if [ -d ${ghc}/lib/${ghcCommand}-${ghc.version}/shims ]; then
4955 ln -s ${ghc}/lib/${ghcCommand}-${ghc.version}/shims ${libDir}
5056 fi
51− # ... and node modules ...
57+ ''
58+ # ... and node modules ...
59+ + ''
5260 if [ -d ${ghc}/lib/${ghcCommand}-${ghc.version}/ghcjs-node ]; then
5361 ln -s ${ghc}/lib/${ghcCommand}-${ghc.version}/ghcjs-node ${libDir}
5462 fi
55− # Replace the package database with the one from target package config.
63+ ''
64+ # Replace the package database with the one from target package config.
65+ + ''
5666 ln -s ${configFiles}/${packageCfgDir} $out/${packageCfgDir}
5767
58− # now the tricky bit. For GHCJS (to make plugins work), we need a special
59− # file called ghc_libdir. That points to the build ghc's lib.
60− echo "${ghc.buildGHC or ghc}/lib/${(ghc.buildGHC or ghc).name}" > "${libDir}/ghc_libdir"
68+ ''
69+ # Set the GHC_PLUGINS environment variable according to the plugins for the component.
70+ # GHC will automatically load the relevant symbols from the given libraries and
71+ # initialize them with the given arguments.
72+ #
73+ # GHC_PLUGINS is a `read`able [(FilePath,String,String,[String])], where the
74+ # first component is a path to the shared library, the second is the package ID,
75+ # the third is the module name, and the fourth is the plugin arguments.
76+ + ''
77+ GHC_PLUGINS="["
78+ LIST_PREFIX=""
79+ ${builtins.concatStringsSep "\n" (map (plugin: ''
80+ id=$(${ghc}/bin/ghc-pkg --package-db ${plugin.library}/package.conf.d field ${plugin.library.package.identifier.name} id --simple-output)
81+ lib_dir=$(${ghc}/bin/ghc-pkg --package-db ${plugin.library}/package.conf.d field ${plugin.library.package.identifier.name} dynamic-library-dirs --simple-output)
82+ lib_base=$(${ghc}/bin/ghc-pkg --package-db ${plugin.library}/package.conf.d field ${plugin.library.package.identifier.name} hs-libraries --simple-output)
83+ lib="$(echo ''${lib_dir}/lib''${lib_base}*)"
84+ GHC_PLUGINS="''${GHC_PLUGINS}''${LIST_PREFIX}(\"''${lib}\",\"''${id}\",\"${plugin.moduleName}\",["
85+ LIST_PREFIX=""
86+ ${builtins.concatStringsSep "\n" (map (arg: ''
87+ GHC_PLUGINS="''${GHC_PLUGINS}''${LIST_PREFIX}\"${arg}\""
88+ LIST_PREFIX=","
89+ '') plugin.args)}
90+ GHC_PLUGINS="''${GHC_PLUGINS}])"
91+ LIST_PREFIX=","
92+ '') plugins)}
93+ GHC_PLUGINS="''${GHC_PLUGINS}]"
6194
62− # Wrap compiler executables with correct env variables.
63− # The NIX_ variables are used by the patched Paths_ghc module.
95+ ''
96+ # now the tricky bit. For GHCJS (to make plugins work), we need a special
97+ # file called ghc_libdir. That points to the build ghc's lib.
98+ + ''
99+ echo "${ghc.buildGHC or ghc}/lib/${(ghc.buildGHC or ghc).name}" > "${libDir}/ghc_libdir"
64100
101+ ''
102+ # Wrap compiler executables with correct env variables.
103+ # The NIX_ variables are used by the patched Paths_ghc module.
104+ + ''
65105 for prg in ${ghcCommand} ${ghcCommand}i ${ghcCommand}-${ghc.version} ${ghcCommand}i-${ghc.version}; do
66106 if [[ -x "${ghc}/bin/$prg" ]]; then
67107 rm -f $out/bin/$prg
@@ -70,6 +110,7 @@ in runCommand "${componentName}-${ghc.name}-env" {
70110 --set "NIX_${ghcCommandCaps}" "$out/bin/${ghcCommand}" \
71111 --set "NIX_${ghcCommandCaps}PKG" "$out/bin/${ghcCommand}-pkg" \
72112 --set "NIX_${ghcCommandCaps}_DOCDIR" "${docDir}" \
113+ --set "GHC_PLUGINS" "$GHC_PLUGINS" \
73114 --set "NIX_${ghcCommandCaps}_LIBDIR" "${libDir}"
74115 fi
75116 done
@@ -82,11 +123,14 @@ in runCommand "${componentName}-${ghc.name}-env" {
82123 --set "NIX_${ghcCommandCaps}" "$out/bin/${ghcCommand}" \
83124 --set "NIX_${ghcCommandCaps}PKG" "$out/bin/${ghcCommand}-pkg" \
84125 --set "NIX_${ghcCommandCaps}_DOCDIR" "${docDir}" \
126+ --set "GHC_PLUGINS" "$GHC_PLUGINS" \
85127 --set "NIX_${ghcCommandCaps}_LIBDIR" "${libDir}"
86128 fi
87129 done
88130
89− # Wrap haddock, if the base GHC provides it.
131+ ''
132+ # Wrap haddock, if the base GHC provides it.
133+ + ''
90134 if [[ -x "${haddock}/bin/haddock" ]]; then
91135 rm -f $out/bin/haddock
92136 makeWrapper ${haddock}/bin/haddock $out/bin/haddock \
@@ -94,9 +138,10 @@ in runCommand "${componentName}-${ghc.name}-env" {
94138 --set "NIX_${ghcCommandCaps}_LIBDIR" "${libDir}"
95139 fi
96140
97− # Point ghc-pkg to the package database of the component using the
98− # --global-package-db flag.
99−
141+ ''
142+ # Point ghc-pkg to the package database of the component using the
143+ # --global-package-db flag.
144+ + ''
100145 for prg in ${ghcCommand}-pkg ${ghcCommand}-pkg-${ghc.version}; do
101146 if [[ -x "${ghc}/bin/$prg" ]]; then
102147 rm -f $out/bin/$prg