Skip to content

Commit bd93a64

Browse files
monyarmPetarKirov
authored andcommitted
fix(wasmd): switched to modified version of buildGoModule, which allows wasmd to build
For some (as of yet unknown) reason, the go-module derivation doesn't copy the modules to the correct dir. To fix the issue, we fork the buildGoModule implementation and adjust the `cp` command.
1 parent c334b5e commit bd93a64

File tree

2 files changed

+372
-2
lines changed

2 files changed

+372
-2
lines changed

packages/wasmd/default.nix

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
lib,
33
stdenv,
44
fetchFromGitHub,
5-
buildGoModule,
5+
go_1_19,
66
autoPatchelfHook,
7+
callPackage,
78
}: let
89
system = stdenv.targetPlatform.system;
910
libwasmvm_files = {
@@ -16,6 +17,7 @@
1617
aarch64-darwin = "libwasmvm.dylib";
1718
};
1819
so_name = libwasmvm_files.${system} or (throw "Unsupported system: ${system}");
20+
buildGoModule = callPackage ./module.nix {go = go_1_19;};
1921
in
2022
buildGoModule rec {
2123
pname = "wasmd";
@@ -29,7 +31,7 @@ in
2931
};
3032

3133
proxyVendor = true;
32-
vendorSha256 = "sha256-4GyLyDSBXcLAA6+jrk25+354eo2Z9CvNtgQiDer7UpQ=";
34+
vendorSha256 = "sha256-hRFnF/GmMYy8aOU4lPO6WQOTAmqsyyf+PI0hDEJWf8k=";
3335

3436
subPackages = ["cmd/wasmd"];
3537

packages/wasmd/module.nix

Lines changed: 368 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,368 @@
1+
{
2+
go,
3+
cacert,
4+
git,
5+
lib,
6+
stdenv,
7+
}: {
8+
name ? "${args'.pname}-${args'.version}",
9+
src,
10+
buildInputs ? [],
11+
nativeBuildInputs ? [],
12+
passthru ? {},
13+
patches ? [],
14+
# Go linker flags, passed to go via -ldflags
15+
ldflags ? [],
16+
# Go tags, passed to go via -tag
17+
tags ? [],
18+
# A function to override the go-modules derivation
19+
overrideModAttrs ? (_oldAttrs: {}),
20+
# path to go.mod and go.sum directory
21+
modRoot ? "./",
22+
# vendorHash is the SRI hash of the vendored dependencies
23+
#
24+
# if vendorHash is null, then we won't fetch any dependencies and
25+
# rely on the vendor folder within the source.
26+
vendorHash ? "_unset",
27+
# same as vendorHash, but outputHashAlgo is hardcoded to sha256
28+
# so regular base32 sha256 hashes work
29+
vendorSha256 ? "_unset",
30+
# Whether to delete the vendor folder supplied with the source.
31+
deleteVendor ? false,
32+
# Whether to fetch (go mod download) and proxy the vendor directory.
33+
# This is useful if your code depends on c code and go mod tidy does not
34+
# include the needed sources to build or if any dependency has case-insensitive
35+
# conflicts which will produce platform dependant `vendorHash` checksums.
36+
proxyVendor ? false,
37+
# We want parallel builds by default
38+
enableParallelBuilding ? true,
39+
# Do not enable this without good reason
40+
# IE: programs coupled with the compiler
41+
allowGoReference ? false,
42+
CGO_ENABLED ? go.CGO_ENABLED,
43+
meta ? {},
44+
# Not needed with buildGoModule
45+
goPackagePath ? "",
46+
# needed for buildFlags{,Array} warning
47+
buildFlags ? "",
48+
buildFlagsArray ? "",
49+
...
50+
} @ args':
51+
with builtins;
52+
assert goPackagePath != "" -> throw "`goPackagePath` is not needed with `buildGoModule`";
53+
assert (vendorSha256 == "_unset" && vendorHash == "_unset") -> throw "either `vendorHash` or `vendorSha256` is required";
54+
assert (vendorSha256 != "_unset" && vendorHash != "_unset") -> throw "both `vendorHash` and `vendorSha256` set. only one can be set."; let
55+
hasAnyVendorHash = (vendorSha256 != null && vendorSha256 != "_unset") || (vendorHash != null && vendorHash != "_unset");
56+
vendorHashType =
57+
if hasAnyVendorHash
58+
then
59+
if vendorSha256 != null && vendorSha256 != "_unset"
60+
then "sha256"
61+
else "sri"
62+
else null;
63+
64+
args = removeAttrs args' ["overrideModAttrs" "vendorSha256" "vendorHash"];
65+
66+
go-modules =
67+
if hasAnyVendorHash
68+
then
69+
stdenv.mkDerivation (let
70+
modArgs = {
71+
name = "${name}-go-modules";
72+
73+
nativeBuildInputs = (args.nativeBuildInputs or []) ++ [go git cacert];
74+
75+
inherit (args) src;
76+
inherit (go) GOOS GOARCH;
77+
78+
prePatch = args.prePatch or "";
79+
patches = args.patches or [];
80+
patchFlags = args.patchFlags or [];
81+
postPatch = args.postPatch or "";
82+
preBuild = args.preBuild or "";
83+
postBuild = args.postBuild or "";
84+
sourceRoot = args.sourceRoot or "";
85+
86+
GO111MODULE = "on";
87+
88+
impureEnvVars =
89+
lib.fetchers.proxyImpureEnvVars
90+
++ [
91+
"GIT_PROXY_COMMAND"
92+
"SOCKS_SERVER"
93+
"GOPROXY"
94+
];
95+
96+
configurePhase =
97+
args.modConfigurePhase
98+
or ''
99+
runHook preConfigure
100+
export GOCACHE=$TMPDIR/go-cache
101+
export GOPATH="$TMPDIR/go"
102+
cd "${modRoot}"
103+
runHook postConfigure
104+
'';
105+
106+
buildPhase =
107+
args.modBuildPhase
108+
or ''
109+
runHook preBuild
110+
''
111+
+ lib.optionalString (deleteVendor == true) ''
112+
if [ ! -d vendor ]; then
113+
echo "vendor folder does not exist, 'deleteVendor' is not needed"
114+
exit 10
115+
else
116+
rm -rf vendor
117+
fi
118+
''
119+
+ ''
120+
if [ -d vendor ]; then
121+
echo "vendor folder exists, please set 'vendorHash = null;' or 'vendorSha256 = null;' in your expression"
122+
exit 10
123+
fi
124+
125+
${
126+
if proxyVendor
127+
then ''
128+
mkdir -p "''${GOPATH}/pkg/mod/cache/download"
129+
go mod download
130+
''
131+
else ''
132+
if (( "''${NIX_DEBUG:-0}" >= 1 )); then
133+
goModVendorFlags+=(-v)
134+
fi
135+
go mod vendor "''${goModVendorFlags[@]}"
136+
''
137+
}
138+
139+
mkdir -p vendor
140+
141+
runHook postBuild
142+
'';
143+
144+
installPhase =
145+
args.modInstallPhase
146+
or ''
147+
runHook preInstall
148+
149+
${
150+
if proxyVendor
151+
then ''
152+
rm -rf "''${GOPATH}/pkg/mod/cache/download/sumdb"
153+
cp -r --reflink=auto "''${GOPATH}/pkg/mod/cache/download/"* $out
154+
''
155+
else ''
156+
cp -r --reflink=auto vendor $out
157+
''
158+
}
159+
160+
if ! [ "$(ls -A $out)" ]; then
161+
echo "vendor folder is empty, please set 'vendorHash = null;' or 'vendorSha256 = null;' in your expression"
162+
exit 10
163+
fi
164+
165+
runHook postInstall
166+
'';
167+
168+
dontFixup = true;
169+
};
170+
in
171+
modArgs
172+
// (
173+
{
174+
outputHashMode = "recursive";
175+
}
176+
// (
177+
if (vendorHashType == "sha256")
178+
then {
179+
outputHashAlgo = "sha256";
180+
outputHash = vendorSha256;
181+
}
182+
else {
183+
outputHash = vendorHash;
184+
}
185+
)
186+
// (lib.optionalAttrs (vendorHashType == "sri" && vendorHash == "") {
187+
outputHashAlgo = "sha256";
188+
})
189+
)
190+
// overrideModAttrs modArgs)
191+
else "";
192+
193+
package = stdenv.mkDerivation (args
194+
// {
195+
nativeBuildInputs = [go] ++ nativeBuildInputs;
196+
197+
inherit (go) GOOS GOARCH;
198+
199+
GO111MODULE = "on";
200+
GOFLAGS = lib.optionals (!proxyVendor) ["-mod=vendor"] ++ lib.optionals (!allowGoReference) ["-trimpath"];
201+
inherit CGO_ENABLED;
202+
203+
configurePhase =
204+
args.configurePhase
205+
or ''
206+
runHook preConfigure
207+
208+
export GOCACHE=$TMPDIR/go-cache
209+
export GOPATH="$TMPDIR/go"
210+
export GOPROXY=off
211+
export GOSUMDB=off
212+
cd "$modRoot"
213+
''
214+
+ lib.optionalString hasAnyVendorHash ''
215+
${
216+
if proxyVendor
217+
then ''
218+
export GOPROXY=file://${go-modules}
219+
''
220+
else ''
221+
rm -rf vendor
222+
cp -r --reflink=auto ${go-modules} vendor
223+
''
224+
}
225+
''
226+
+ ''
227+
228+
# currently pie is only enabled by default in pkgsMusl
229+
# this will respect the `hardening{Disable,Enable}` flags if set
230+
if [[ $NIX_HARDENING_ENABLE =~ "pie" ]]; then
231+
export GOFLAGS="-buildmode=pie $GOFLAGS"
232+
fi
233+
234+
runHook postConfigure
235+
'';
236+
237+
buildPhase =
238+
args.buildPhase
239+
or ''
240+
runHook preBuild
241+
242+
exclude='\(/_\|examples\|Godeps\|testdata'
243+
if [[ -n "$excludedPackages" ]]; then
244+
IFS=' ' read -r -a excludedArr <<<$excludedPackages
245+
printf -v excludedAlternates '%s\\|' "''${excludedArr[@]}"
246+
excludedAlternates=''${excludedAlternates%\\|} # drop final \| added by printf
247+
exclude+='\|'"$excludedAlternates"
248+
fi
249+
exclude+='\)'
250+
251+
buildGoDir() {
252+
local cmd="$1" dir="$2"
253+
254+
. $TMPDIR/buildFlagsArray
255+
256+
declare -a flags
257+
flags+=($buildFlags "''${buildFlagsArray[@]}")
258+
flags+=(''${tags:+-tags=${lib.concatStringsSep "," tags}})
259+
flags+=(''${ldflags:+-ldflags="$ldflags"})
260+
flags+=("-p" "$NIX_BUILD_CORES")
261+
262+
if [ "$cmd" = "test" ]; then
263+
flags+=(-vet=off)
264+
flags+=($checkFlags)
265+
fi
266+
267+
local OUT
268+
if ! OUT="$(go $cmd "''${flags[@]}" $dir 2>&1)"; then
269+
if ! echo "$OUT" | grep -qE '(no( buildable| non-test)?|build constraints exclude all) Go (source )?files'; then
270+
echo "$OUT" >&2
271+
return 1
272+
fi
273+
fi
274+
if [ -n "$OUT" ]; then
275+
echo "$OUT" >&2
276+
fi
277+
return 0
278+
}
279+
280+
getGoDirs() {
281+
local type;
282+
type="$1"
283+
if [ -n "$subPackages" ]; then
284+
echo "$subPackages" | sed "s,\(^\| \),\1./,g"
285+
else
286+
find . -type f -name \*$type.go -exec dirname {} \; | grep -v "/vendor/" | sort --unique | grep -v "$exclude"
287+
fi
288+
}
289+
290+
if (( "''${NIX_DEBUG:-0}" >= 1 )); then
291+
buildFlagsArray+=(-x)
292+
fi
293+
294+
if [ ''${#buildFlagsArray[@]} -ne 0 ]; then
295+
declare -p buildFlagsArray > $TMPDIR/buildFlagsArray
296+
else
297+
touch $TMPDIR/buildFlagsArray
298+
fi
299+
if [ -z "$enableParallelBuilding" ]; then
300+
export NIX_BUILD_CORES=1
301+
fi
302+
for pkg in $(getGoDirs ""); do
303+
echo "Building subPackage $pkg"
304+
buildGoDir install "$pkg"
305+
done
306+
''
307+
+ lib.optionalString (stdenv.hostPlatform != stdenv.buildPlatform) ''
308+
# normalize cross-compiled builds w.r.t. native builds
309+
(
310+
dir=$GOPATH/bin/${go.GOOS}_${go.GOARCH}
311+
if [[ -n "$(shopt -s nullglob; echo $dir/*)" ]]; then
312+
mv $dir/* $dir/..
313+
fi
314+
if [[ -d $dir ]]; then
315+
rmdir $dir
316+
fi
317+
)
318+
''
319+
+ ''
320+
runHook postBuild
321+
'';
322+
323+
doCheck = args.doCheck or true;
324+
checkPhase =
325+
args.checkPhase
326+
or ''
327+
runHook preCheck
328+
# We do not set trimpath for tests, in case they reference test assets
329+
export GOFLAGS=''${GOFLAGS//-trimpath/}
330+
331+
for pkg in $(getGoDirs test); do
332+
buildGoDir test "$pkg"
333+
done
334+
335+
runHook postCheck
336+
'';
337+
338+
installPhase =
339+
args.installPhase
340+
or ''
341+
runHook preInstall
342+
343+
mkdir -p $out
344+
dir="$GOPATH/bin"
345+
[ -e "$dir" ] && cp -r $dir $out
346+
347+
runHook postInstall
348+
'';
349+
350+
strictDeps = true;
351+
352+
disallowedReferences = lib.optional (!allowGoReference) go;
353+
354+
passthru = passthru // {inherit go go-modules vendorSha256 vendorHash;};
355+
356+
enableParallelBuilding = enableParallelBuilding;
357+
358+
meta =
359+
{
360+
# Add default meta information
361+
platforms = go.meta.platforms or lib.platforms.all;
362+
}
363+
// meta;
364+
});
365+
in
366+
lib.warnIf (buildFlags != "" || buildFlagsArray != "")
367+
"Use the `ldflags` and/or `tags` attributes instead of `buildFlags`/`buildFlagsArray`"
368+
package

0 commit comments

Comments
 (0)