17
17
18
18
# exactDep will pass --exact-configuration to the `SETUP_HS confiugre` command.
19
19
# This requires us to pass --dependency={dep name}={pkg id}. The dependency
20
- # name will usually be the name of the package `p`, that will have been located
21
- # in the suitable package db when the dependency (along with `exactDep` and `envDep`)
22
- # was built. Sublibs need a bit of special handling:
20
+ # name will usually be the name of the package `p`, which we can locate in the
21
+ # package-db, passed in via `pdbArg`. Thus querying the package-db for the
22
+ # id field for package `p`, will unsually provide is with the right value. Sublibs
23
+ # need a bit of special handling:
23
24
#
24
25
# - Sublibs: if the dependency is a sublibrary of a package, we need to use
25
26
# the sublibrary's name for the dep name, and lookup the sublibraries
30
31
31
32
getLibComponent = dep :
32
33
dep . components . library # Regular package dependency
33
- or dep ; # or a sublib
34
-
34
+ or dep ; # or a sublib
35
+
35
36
catPkgExactDep = p : ''
36
- cat ${ getLibComponent p } /exactDep/configure-flags >> $out/configure-flags
37
- cat ${ getLibComponent p } /exactDep/cabal.config >> $out/cabal.config
37
+ cat ${ p } /exactDep/configure-flags >> $out/configure-flags
38
+ cat ${ p } /exactDep/cabal.config >> $out/cabal.config
38
39
'' ;
39
40
40
41
catGhcPkgExactDep = p : ''
45
46
'' ;
46
47
47
48
catPkgEnvDep = p : ''
48
- cat ${ getLibComponent p } /envDep >> $out/ghc-environment
49
+ cat ${ p } /envDep >> $out/ghc-environment
49
50
'' ;
50
51
51
52
catGhcPkgEnvDep = p : ''
54
55
fi
55
56
'' ;
56
57
58
+ # Work our suitable packageCfgDir subdirectory
59
+ isGhcjs = ghc . isGhcjs or false ;
60
+ ghcCommand' = if isGhcjs then "ghcjs" else "ghc" ;
61
+ ghcCommand = "${ ghc . targetPrefix } ${ ghcCommand' } " ;
62
+ ghcCommandCaps = lib . toUpper ghcCommand' ;
63
+ libDir = "lib/${ ghcCommand } -${ ghc . version } " ;
64
+ packageCfgDir = "${ libDir } /package.conf.d" ;
65
+
57
66
in { identifier , component , fullName , flags ? { } } :
58
- runCommand "${ fullName } -config" { nativeBuildInputs = [ ghc ] ; } ( ''
67
+ # Filters out only library packages that for this GHC target
68
+ # TODO investigate why this is needed
69
+ let libDeps = lib . filter ( p : p . configFiles . targetPrefix == ghc . targetPrefix )
70
+ ( map getLibComponent component . depends ) ;
71
+ cfgFiles =
72
+ let xs = map
73
+ ( p : "${ p . configFiles } " )
74
+ libDeps ;
75
+ in lib . concatStringsSep "\" \" " xs ;
76
+ libs = lib . concatMapStringsSep "\" \" " ( p : "${ p } " ) libDeps ;
77
+ in
78
+ runCommand "${ ghc . targetPrefix } ${ fullName } -config" {
79
+ nativeBuildInputs = [ ghc ] ;
80
+ passthru = {
81
+ inherit ( ghc ) targetPrefix ;
82
+ inherit ghcCommand ghcCommandCaps libDir packageCfgDir ;
83
+ } ;
84
+ } ( ''
59
85
mkdir -p $out
60
86
61
- ${ target-pkg } init $out/package.conf.d
87
+ ${ target-pkg } init $out/${ packageCfgDir }
62
88
63
89
${ lib . concatStringsSep "\n " ( lib . mapAttrsToList flagsAndConfig {
64
90
"extra-lib-dirs" = map ( p : "${ lib . getLib p } /lib" ) component . libs ;
@@ -68,16 +94,22 @@ in { identifier, component, fullName, flags ? {} }:
68
94
69
95
# Copy over the nonReinstallablePkgs from the global package db.
70
96
${ lib . concatMapStringsSep "\n " ( p : ''
71
- find ${ ghc } /lib/${ ghc . name } /package.conf.d -name '${ p } *.conf' -exec cp -f {} $out/package.conf.d \;
97
+ find ${ ghc } /lib/${ ghc . name } /package.conf.d -name '${ p } *.conf' -exec cp -f {} $out/${ packageCfgDir } \;
72
98
'' ) nonReinstallablePkgs }
73
99
74
- ${ lib . concatMapStringsSep "\n " ( p : ''
75
- cp -f "${ ( getLibComponent p ) . configFiles } /package.conf.d/"*.conf $out/package.conf.d
76
- cp -f "${ getLibComponent p } /package.conf.d/"*.conf $out/package.conf.d
77
- '' ) component . depends }
100
+ for l in "${ cfgFiles } "; do
101
+ if [ -n "$l" ]; then
102
+ cp -f "$l/${ packageCfgDir } /"*.conf $out/${ packageCfgDir }
103
+ fi
104
+ done
105
+ for l in "${ libs } "; do
106
+ if [ -n "$l" ]; then
107
+ cp -f "$l/package.conf.d/"*.conf $out/${ packageCfgDir }
108
+ fi
109
+ done
78
110
79
111
# Note: we pass `clear` first to ensure that we never consult the implicit global package db.
80
- ${ flagsAndConfig "package-db" [ "clear" "$out/package.conf.d " ] }
112
+ ${ flagsAndConfig "package-db" [ "clear" "$out/${ packageCfgDir } " ] }
81
113
82
114
echo ${ lib . concatStringsSep " " ( lib . mapAttrsToList ( fname : val : "--flags=${ lib . optionalString ( ! val ) "-" + fname } " ) flags ) } >> $out/configure-flags
83
115
@@ -86,17 +118,17 @@ in { identifier, component, fullName, flags ? {} }:
86
118
87
119
# Provide a GHC environment file
88
120
cat > $out/ghc-environment <<EOF
89
- package-db $out/package.conf.d
121
+ package-db $out/${ packageCfgDir }
90
122
EOF
91
123
92
- ${ lib . concatMapStringsSep "\n " catPkgEnvDep component . depends }
124
+ ${ lib . concatMapStringsSep "\n " catPkgEnvDep libDeps }
93
125
${ lib . concatMapStringsSep "\n " catGhcPkgEnvDep ( lib . remove "ghc" nonReinstallablePkgs ) }
94
126
'' + lib . optionalString component . doExactConfig ''
95
127
echo "--exact-configuration" >> $out/configure-flags
96
128
echo "allow-newer: ${ identifier . name } :*" >> $out/cabal.config
97
129
echo "allow-older: ${ identifier . name } :*" >> $out/cabal.config
98
130
99
- ${ lib . concatMapStringsSep "\n " catPkgExactDep component . depends }
131
+ ${ lib . concatMapStringsSep "\n " catPkgExactDep libDeps }
100
132
${ lib . concatMapStringsSep "\n " catGhcPkgExactDep nonReinstallablePkgs }
101
133
102
134
''
@@ -116,10 +148,12 @@ in { identifier, component, fullName, flags ? {} }:
116
148
# (e.g. libiconv), and thus we don't want to fail, but just link it again.
117
149
#
118
150
# Confusing sed stuff:
119
- # '/^ ./{H;$!d} ; x' Groups lines that start with a space with the initial
120
- # line of a block. Needs a blank line added to the file
121
- # to terminate the last block.
122
- # 's/ /\n/g ; s/\n\n*/\n/g; s/^\n//;' Puts each field on its own line.
151
+ # '/^ ./{H;$!d} ; x' Groups lines that start with a space with the initial
152
+ # line of a block. Needs a blank line added to the file
153
+ # to terminate the last block.
154
+ # 's/ /\n/g ; s/\n\n*/\n/g; s/^\n//;' Puts each field on its own line.
155
+ # 's|/nix/store/|''${pkgroot}/../../../|' Convert store path to pkgroot relative path
156
+ # 's|''${pkgroot}/../../../|/nix/store/|' Convert pkgroot relative path to store path
123
157
+ lib . optionalString stdenv . isDarwin ''
124
158
# Work around a limit in the macOS Sierra linker on the number of paths
125
159
# referenced by any one dynamic library:
@@ -128,20 +162,25 @@ in { identifier, component, fullName, flags ? {} }:
128
162
# libraries) from all the dependencies.
129
163
local dynamicLinksDir="$out/lib/links"
130
164
mkdir -p $dynamicLinksDir
165
+ # Enumerate dynamic-library-dirs with '' ${pkgroot} expanded.
131
166
local dirsToLink=$(
132
- for f in "$out/package.conf.d /"*.conf; do
167
+ for f in "$out/${ packageCfgDir } /"*.conf; do
133
168
(cat $f; echo) | sed -En '/^ ./{H;$!d} ; x ; /^dynamic-library-dirs:/ {s/^dynamic-library-dirs:// ; s/ /\n/g ; s/\n\n*/\n/g; s/^\n//; p}'
134
- done | sort -u
169
+ done | sed 's| '' ${pkgroot}/../../../|/nix/store/|' | sort -u
135
170
)
136
171
for d in $dirsToLink; do
137
172
ln -f -s "$d/"*.dylib $dynamicLinksDir
138
173
done
139
174
# Edit the local package DB to reference the links directory.
140
- for f in "$out/package.conf.d /"*.conf; do
175
+ for f in "$out/${ packageCfgDir } /"*.conf; do
141
176
chmod +w $f
142
177
echo >> $f
143
178
sed -i -E "/^ ./{H;$!d} ; x ; s,^dynamic-library-dirs:.*,dynamic-library-dirs: $dynamicLinksDir," $f
144
179
done
145
180
'' + ''
146
- ${ target-pkg } -v0 --package-db $out/package.conf.d recache
181
+ # Use '' ${pkgroot} relative paths so that we can relocate the package database
182
+ # along with referenced packages and still have it work on systems with
183
+ # or without nix installed.
184
+ sed -i 's|/nix/store/|'' ${pkgroot}/../../../|' $out/${ packageCfgDir } /*.conf
185
+ ${ target-pkg } -v0 --package-db $out/${ packageCfgDir } recache
147
186
'' )
0 commit comments