1{ stdenv
2, lib
3, buildPackages
4, buildGoModule
5, fetchFromGitHub
6, makeWrapper
7, llvmPackages
8, go
9, xar
10, binaryen
11, avrdude
12, gdb
13, openocd
14, runCommand
15, tinygoTests ? [ "smoketest" ]
16}:
17
18let
19 llvmMajor = lib.versions.major llvm.version;
20 inherit (llvmPackages) llvm clang compiler-rt lld;
21
22 # only doing this because only on darwin placing clang.cc in nativeBuildInputs
23 # doesn't build
24 bootstrapTools = runCommand "tinygo-bootstrap-tools" { } ''
25 mkdir -p $out
26 ln -s ${lib.getBin clang.cc}/bin/clang $out/clang-${llvmMajor}
27 '';
28in
29
30buildGoModule rec {
31 pname = "tinygo";
32 version = "0.31.2";
33
34 src = fetchFromGitHub {
35 owner = "tinygo-org";
36 repo = "tinygo";
37 rev = "v${version}";
38 sha256 = "sha256-e0zXxIdAtJZXJdP/S6lHRnPm5Rsf638Fhox8XcqOWrk=";
39 fetchSubmodules = true;
40 };
41
42 vendorHash = "sha256-HZiyAgsTEBQv+Qp0T9RXTV1lkxvIGh7Q45rd45cfvjo=";
43
44 patches = [
45 ./0001-GNUmakefile.patch
46 ];
47
48 nativeCheckInputs = [ binaryen ];
49 nativeBuildInputs = [ makeWrapper lld ];
50 buildInputs = [ llvm clang.cc ]
51 ++ lib.optionals stdenv.isDarwin [ xar ];
52
53 doCheck = (stdenv.buildPlatform.canExecute stdenv.hostPlatform);
54 inherit tinygoTests;
55
56 allowGoReference = true;
57 ldflags = [
58 "-X github.com/tinygo-org/tinygo/goenv.TINYGOROOT=${placeholder "out"}/share/tinygo"
59 "-X github.com/tinygo-org/tinygo/goenv.clangResourceDir=${clang.cc.lib}/lib/clang/${llvmMajor}"
60 ];
61 subPackages = [ "." ];
62
63 # Output contains static libraries for different arm cpus
64 # and stripping could mess up these so only strip the compiler
65 stripDebugList = [ "bin" ];
66
67 postPatch = ''
68 # Borrow compiler-rt builtins from our source
69 # See https://github.com/tinygo-org/tinygo/pull/2471
70 mkdir -p lib/compiler-rt-builtins
71 cp -a ${compiler-rt.src}/compiler-rt/lib/builtins/* lib/compiler-rt-builtins/
72
73 substituteInPlace GNUmakefile \
74 --replace "build/release/tinygo/bin" "$out/bin" \
75 --replace "build/release/" "$out/share/"
76 '';
77
78 preBuild = ''
79 export PATH=${bootstrapTools}:$PATH
80 export HOME=$TMPDIR
81
82 ldflags=("''$ldflags[@]/\"-buildid=\"")
83 '';
84
85 postBuild = ''
86 # Move binary
87 mkdir -p build
88 mv $GOPATH/bin/tinygo build/tinygo
89
90 # Build our own custom wasi-libc.
91 # This is necessary because we modify the build a bit for our needs (disable
92 # heap, enable debug symbols, etc).
93 make wasi-libc \
94 CLANG="${lib.getBin clang.cc}/bin/clang -resource-dir ${clang.cc.lib}/lib/clang/${llvmMajor}" \
95 LLVM_AR=${lib.getBin llvm}/bin/llvm-ar \
96 LLVM_NM=${lib.getBin llvm}/bin/llvm-nm
97
98 make gen-device -j $NIX_BUILD_CORES
99
100 export TINYGOROOT=$(pwd)
101 '';
102
103 checkPhase = lib.optionalString (tinygoTests != [ ] && tinygoTests != null) ''
104 make ''${tinygoTests[@]} TINYGO="$(pwd)/build/tinygo" MD5SUM=md5sum XTENSA=0
105 '';
106
107 # GDB upstream does not support ARM darwin
108 runtimeDeps = [ go clang.cc lld avrdude openocd binaryen ]
109 ++ lib.optionals (!(stdenv.isDarwin && stdenv.isAarch64)) [ gdb ];
110
111 installPhase = ''
112 runHook preInstall
113
114 make build/release
115
116 wrapProgram $out/bin/tinygo \
117 --prefix PATH : ${lib.makeBinPath runtimeDeps }
118
119 runHook postInstall
120 '';
121
122 meta = with lib; {
123 homepage = "https://tinygo.org/";
124 description = "Go compiler for small places";
125 license = licenses.bsd3;
126 maintainers = with maintainers; [ Madouura muscaln ];
127 };
128}