1{ stdenv
2, lib
3, buildPackages
4, buildGoModule
5, fetchFromGitHub
6, makeWrapper
7, substituteAll
8, llvmPackages
9, go
10, libffi
11, zlib
12, ncurses
13, libxml2
14, xar
15, wasi-libc
16, binaryen
17, avrdude
18, gdb
19, openocd
20, runCommand
21, tinygoTests ? [ "smoketest" ]
22}:
23
24let
25 llvmMajor = lib.versions.major llvm.version;
26 inherit (llvmPackages) llvm clang compiler-rt lld;
27
28 # only doing this because only on darwin placing clang.cc in nativeBuildInputs
29 # doesn't build
30 bootstrapTools = runCommand "tinygo-bootstap-tools" { } ''
31 mkdir -p $out
32 ln -s ${lib.getBin clang.cc}/bin/clang $out/clang-${llvmMajor}
33 ln -s ${lib.getBin lld}/bin/ld.lld $out/ld.lld-${llvmMajor}
34 ln -s ${lib.getBin lld}/bin/wasm-ld $out/wasm-ld-${llvmMajor}
35 # GDB upstream does not support ARM darwin
36 ${lib.optionalString (!(stdenv.isDarwin && stdenv.isAarch64)) "ln -s ${gdb}/bin/gdb $out/gdb-multiarch" }
37 '';
38in
39
40buildGoModule rec {
41 pname = "tinygo";
42 version = "0.30.0";
43
44 src = fetchFromGitHub {
45 owner = "tinygo-org";
46 repo = "tinygo";
47 rev = "v${version}";
48 sha256 = "sha256-hOccfMKuvTKYKDRcEgTJ8k/c/H+qNDpvotWIqk6p2u8=";
49 fetchSubmodules = true;
50 };
51
52 vendorHash = "sha256-2q3N6QhfRmwbs4CTWrFWr1wyhf2jPS2ECAn/wrrpXdM=";
53
54 patches = [
55 ./0001-Makefile.patch
56
57 # clang.cc does not have any paths in the include path.
58 # For TinyGo, we want to have no include paths, _except_ for the built-in
59 # Clang header files (things like stdint.h). That's why we use -nostdlibinc.
60 # So to make Clang work like we want, we will have to manually add this one
61 # include path.
62 # We can't use a regular clang command (something like
63 # llvmPackages.clangUseLLVM) because there are various bugs, see:
64 # https://github.com/NixOS/nixpkgs/issues/259397
65 # https://github.com/NixOS/nixpkgs/issues/259386
66 (substituteAll {
67 src = ./0002-Add-clang-header-path.patch;
68 clang_include = "${clang.cc.lib}/lib/clang/${llvmMajor}/include";
69 })
70
71 #TODO(muscaln): Find a better way to fix build ID on darwin
72 ./0003-Use-out-path-as-build-id-on-darwin.patch
73 ./0004-fix-darwin-build.patch
74 ];
75
76 nativeCheckInputs = [ binaryen ];
77 nativeBuildInputs = [ makeWrapper ];
78 buildInputs = [ llvm clang.cc ]
79 ++ lib.optionals stdenv.isDarwin [ zlib ncurses libffi libxml2 xar ];
80
81 doCheck = (stdenv.buildPlatform.canExecute stdenv.hostPlatform);
82 inherit tinygoTests;
83
84 allowGoReference = true;
85 tags = [ "llvm${llvmMajor}" ];
86 ldflags = [ "-X github.com/tinygo-org/tinygo/goenv.TINYGOROOT=${placeholder "out"}/share/tinygo" ];
87 subPackages = [ "." ];
88
89 # Output contains static libraries for different arm cpus
90 # and stripping could mess up these so only strip the compiler
91 stripDebugList = [ "bin" ];
92
93 postConfigure = lib.optionalString stdenv.isDarwin ''
94 for i in vendor/tinygo.org/x/go-llvm/llvm_config_darwin*; do
95 substituteInPlace $i --replace "curses" "ncurses"
96 done
97 '';
98
99 postPatch = ''
100 # Copy wasi-libc, symlink seems not working
101 rm -rf lib/wasi-libc/*
102 mkdir -p lib/wasi-libc/sysroot/lib/wasm32-wasi lib/wasi-libc/sysroot/include
103 cp -a ${wasi-libc}/lib/* lib/wasi-libc/sysroot/lib/wasm32-wasi/
104 cp -a ${wasi-libc.dev}/include/* lib/wasi-libc/sysroot/include/
105
106 # Borrow compiler-rt builtins from our source
107 # See https://github.com/tinygo-org/tinygo/pull/2471
108 mkdir -p lib/compiler-rt-builtins
109 cp -a ${compiler-rt.src}/compiler-rt/lib/builtins/* lib/compiler-rt-builtins/
110
111 substituteInPlace Makefile \
112 --replace "\$(TINYGO)" "$(pwd)/build/tinygo" \
113 --replace "@\$(MD5SUM)" "md5sum" \
114 --replace "build/release/tinygo/bin" "$out/bin" \
115 --replace "build/release/" "$out/share/"
116
117 substituteInPlace builder/buildid.go \
118 --replace "OUT_PATH" "$out"
119
120 # TODO: Fix mingw
121 # Disable windows cross-compile tests
122 sed -i "/GOOS=windows/d" Makefile
123 '' + lib.optionalString (stdenv.buildPlatform != stdenv.hostPlatform) ''
124 substituteInPlace Makefile \
125 --replace "./build/tinygo" "${buildPackages.tinygo}/bin/tinygo"
126 '';
127
128 preBuild = ''
129 export PATH=${bootstrapTools}:$PATH
130 export HOME=$TMPDIR
131 '';
132
133 postBuild = ''
134 # Move binary
135 mkdir -p build
136 mv $GOPATH/bin/tinygo build/tinygo
137
138 make gen-device -j $NIX_BUILD_CORES
139
140 export TINYGOROOT=$(pwd)
141 '';
142
143 checkPhase = lib.optionalString (tinygoTests != [ ] && tinygoTests != null) ''
144 make ''${tinygoTests[@]} XTENSA=0
145 '';
146
147 installPhase = ''
148 runHook preInstall
149
150 make build/release
151
152 wrapProgram $out/bin/tinygo \
153 --prefix PATH : ${lib.makeBinPath [ go avrdude openocd binaryen ]}:${bootstrapTools}
154
155 runHook postInstall
156 '';
157
158 disallowedReferences = [ wasi-libc ];
159
160 meta = with lib; {
161 homepage = "https://tinygo.org/";
162 description = "Go compiler for small places";
163 license = licenses.bsd3;
164 maintainers = with maintainers; [ Madouura muscaln ];
165 };
166}