1
- { stdenv , buildPackages , ghc , lib , pkgconfig , writeText , runCommand , haskellLib , nonReinstallablePkgs } :
1
+ { stdenv , buildPackages , ghc , lib , pkgconfig , writeText , runCommand , haskellLib , nonReinstallablePkgs , withPackage } :
2
2
3
3
{ componentId
4
4
, component
16
16
, preBuild ? null , postBuild ? null
17
17
, preCheck ? null , postCheck ? null
18
18
, preInstall ? null , postInstall ? null
19
+ , shellHook ? null
19
20
20
- , doCheck ? component . doCheck || componentId . ctype == "test"
21
+ , doCheck ? component . doCheck || haskellLib . isTest componentId
21
22
, doCrossCheck ? component . doCrossCheck || false
22
23
, dontPatchELF ? true
23
24
, dontStrip ? true
27
28
} :
28
29
29
30
let
30
- fullName = "${ name } -${ componentId . ctype } -${ componentId . cname } " ;
31
+ fullName = if haskellLib . isAll componentId
32
+ then "${ name } -all"
33
+ else "${ name } -${ componentId . ctype } -${ componentId . cname } " ;
31
34
32
35
flagsAndConfig = field : xs : lib . optionalString ( xs != [ ] ) ''
33
36
echo ${ lib . concatStringsSep " " ( map ( x : "--${ field } =${ x } " ) xs ) } >> $out/configure-flags
44
47
in map ( { val , ...} : val ) closure ;
45
48
46
49
exactDep = pdbArg : p : ''
47
- if id=$(${ ghc . targetPrefix } ghc -pkg -v0 ${ pdbArg } field ${ p } id --simple-output); then
50
+ if id=$(target -pkg ${ pdbArg } field ${ p } id --simple-output); then
48
51
echo "--dependency=${ p } =$id" >> $out/configure-flags
49
52
fi
50
- if ver=$(${ ghc . targetPrefix } ghc -pkg -v0 ${ pdbArg } field ${ p } version --simple-output); then
53
+ if ver=$(target -pkg ${ pdbArg } field ${ p } version --simple-output); then
51
54
echo "constraint: ${ p } == $ver" >> $out/cabal.config
52
55
echo "constraint: ${ p } installed" >> $out/cabal.config
53
56
fi
54
57
'' ;
55
58
59
+ envDep = pdbArg : p : ''
60
+ if id=$(target-pkg ${ pdbArg } field ${ p } id --simple-output); then
61
+ echo "package-id $id" >> $out/ghc-environment
62
+ fi
63
+ '' ;
64
+
56
65
configFiles = runCommand "${ fullName } -config" { nativeBuildInputs = [ ghc ] ; } ( ''
57
66
mkdir -p $out
58
- ${ ghc . targetPrefix } ghc-pkg -v0 init $out/package.conf.d
67
+
68
+ # Calls ghc-pkg for the target platform
69
+ target-pkg() {
70
+ ${ ghc . targetPrefix } ghc-pkg "$@"
71
+ }
72
+
73
+ target-pkg init $out/package.conf.d
59
74
60
75
${ lib . concatStringsSep "\n " ( lib . mapAttrsToList flagsAndConfig {
61
76
"extra-lib-dirs" = map ( p : "${ lib . getLib p } /lib" ) component . libs ;
67
82
# Note: we need to use --global-package-db with ghc-pkg to prevent it
68
83
# from looking into the implicit global package db when registering the package.
69
84
${ lib . concatMapStringsSep "\n " ( p : ''
70
- ${ ghc . targetPrefix } ghc -pkg -v0 describe ${ p } | ${ ghc . targetPrefix } ghc -pkg -v0 --force --global-package-db $out/package.conf.d register - || true
85
+ target -pkg describe ${ p } | target -pkg --force --global-package-db $out/package.conf.d register - || true
71
86
'' ) nonReinstallablePkgs }
72
87
73
88
${ lib . concatMapStringsSep "\n " ( p : ''
74
- ${ ghc . targetPrefix } ghc -pkg -v0 -- package-db ${ p } /package.conf.d dump | ${ ghc . targetPrefix } ghc -pkg -v0 --force --package-db $out/package.conf.d register -
89
+ target -pkg -- package-db ${ p } /package.conf.d dump | target -pkg --force --package-db $out/package.conf.d register -
75
90
'' ) flatDepends }
76
91
77
92
# Note: we pass `clear` first to ensure that we never consult the implicit global package db.
78
93
${ flagsAndConfig "package-db" [ "clear" "$out/package.conf.d" ] }
79
94
80
95
echo ${ lib . concatStringsSep " " ( lib . mapAttrsToList ( fname : val : "--flags=${ lib . optionalString ( ! val ) "-" + fname } " ) flags ) } >> $out/configure-flags
81
96
97
+ # Provide a GHC environment file
98
+ cat > $out/ghc-environment <<EOF
99
+ clear-package-db
100
+ package-db $out/package.conf.d
101
+ EOF
102
+ ${ lib . concatMapStringsSep "\n " ( p : envDep "--package-db ${ p . components . library } /package.conf.d" p . identifier . name ) component . depends }
103
+ ${ lib . concatMapStringsSep "\n " ( envDep "" ) ( lib . remove "ghc" nonReinstallablePkgs ) }
104
+
82
105
'' + lib . optionalString component . doExactConfig ''
83
106
echo "--exact-configuration" >> $out/configure-flags
84
107
echo "allow-newer: ${ package . identifier . name } :*" >> $out/cabal.config
@@ -115,14 +138,14 @@ let
115
138
sed -i "s,dynamic-library-dirs: .*,dynamic-library-dirs: $dynamicLinksDir," $f
116
139
done
117
140
'' + ''
118
- ${ ghc . targetPrefix } ghc -pkg -v0 --package-db $out/package.conf.d recache
141
+ target -pkg --package-db $out/package.conf.d recache
119
142
'' + ''
120
- ${ ghc . targetPrefix } ghc -pkg -v0 --package-db $out/package.conf.d check
143
+ target -pkg --package-db $out/package.conf.d check
121
144
'' ) ;
122
145
123
146
finalConfigureFlags = lib . concatStringsSep " " (
124
147
[ "--prefix=$out"
125
- "${ componentId . ctype } : ${ componentId . cname } "
148
+ "${ haskellLib . componentTarget componentId } "
126
149
"$(cat ${ configFiles } /configure-flags)"
127
150
# GHC
128
151
"--with-ghc=${ ghc . targetPrefix } ghc"
145
168
++ component . configureFlags
146
169
) ;
147
170
171
+ executableToolDepends = lib . concatMap ( c : if c . isHaskell or false
172
+ then builtins . attrValues ( c . components . exes or { } )
173
+ else [ c ] ) component . build-tools ;
174
+
175
+ # Unfortunately, we need to wrap ghc commands for cabal builds to
176
+ # work in the nix-shell. See ../doc/removing-with-package-wrapper.md.
177
+ shellWrappers = withPackage {
178
+ inherit package configFiles ;
179
+ } ;
180
+
148
181
in stdenv . mkDerivation ( {
149
182
name = fullName ;
150
183
@@ -154,6 +187,7 @@ in stdenv.mkDerivation ({
154
187
inherit ( package ) identifier ;
155
188
config = component ;
156
189
inherit configFiles ;
190
+ env = shellWrappers ;
157
191
} ;
158
192
159
193
meta = {
@@ -167,6 +201,7 @@ in stdenv.mkDerivation ({
167
201
} ;
168
202
169
203
CABAL_CONFIG = configFiles + /cabal.config ;
204
+ GHC_ENVIRONMENT = configFiles + /ghc-environment ;
170
205
LANG = "en_US.UTF-8" ; # GHC needs the locale configured during the Haddock phase.
171
206
LC_ALL = "en_US.UTF-8" ;
172
207
@@ -179,9 +214,7 @@ in stdenv.mkDerivation ({
179
214
nativeBuildInputs =
180
215
[ ghc ]
181
216
++ lib . optional ( component . pkgconfig != [ ] ) pkgconfig
182
- ++ lib . concatMap ( c : if c . isHaskell or false
183
- then builtins . attrValues ( c . components . exes or { } )
184
- else [ c ] ) component . build-tools ;
217
+ ++ executableToolDepends ;
185
218
186
219
SETUP_HS = setup + /bin/Setup ;
187
220
@@ -217,12 +250,12 @@ in stdenv.mkDerivation ({
217
250
installPhase = ''
218
251
runHook preInstall
219
252
$SETUP_HS copy ${ lib . concatStringsSep " " component . setupInstallFlags }
220
- ${ lib . optionalString ( haskellLib . isLibrary componentId ) ''
253
+ ${ lib . optionalString ( haskellLib . isLibrary componentId || haskellLib . isAll componentId ) ''
221
254
$SETUP_HS register --gen-pkg-config=${ name } .conf
222
255
${ ghc . targetPrefix } ghc-pkg -v0 init $out/package.conf.d
223
256
${ ghc . targetPrefix } ghc-pkg -v0 --package-db ${ configFiles } /package.conf.d -f $out/package.conf.d register ${ name } .conf
224
257
'' }
225
- ${ lib . optionalString ( componentId . ctype == "test" ) ''
258
+ ${ lib . optionalString ( haskellLib . isTest componentId || haskellLib . isAll componentId ) ''
226
259
mkdir -p $out/${ name }
227
260
if [ -f "dist/build/${ componentId . cname } /${ componentId . cname } " ]; then
228
261
cp dist/build/${ componentId . cname } /${ componentId . cname } $out/${ name } /
@@ -233,6 +266,11 @@ in stdenv.mkDerivation ({
233
266
'' }
234
267
runHook postInstall
235
268
'' ;
269
+
270
+ shellHook = ''
271
+ export PATH="${ shellWrappers } /bin:$PATH"
272
+ ${ toString shellHook }
273
+ '' ;
236
274
}
237
275
# patches can (if they like) depend on the version and revision of the package.
238
276
// lib . optionalAttrs ( patches != [ ] ) { patches = map ( p : if builtins . isFunction p then p { inherit ( package . identifier ) version ; inherit revision ; } else p ) patches ; }
0 commit comments