aboutsummaryrefslogtreecommitdiffhomepage
path: root/builder/tools-builtin.go
blob: 4169ebc6170481191ac4060cdf6774ffc1eb20d6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
//go:build byollvm

package builder

import (
	"errors"
	"unsafe"
)

/*
#cgo CXXFLAGS: -fno-rtti
#include <stdbool.h>
#include <stdlib.h>
bool tinygo_clang_driver(int argc, char **argv);
bool tinygo_link(int argc, char **argv);
*/
import "C"

const hasBuiltinTools = true

// RunTool runs the given tool (such as clang).
//
// This version actually runs the tools because TinyGo was compiled while
// linking statically with LLVM (with the byollvm build tag).
func RunTool(tool string, args ...string) error {
	args = append([]string{tool}, args...)

	var cflag *C.char
	buf := C.calloc(C.size_t(len(args)), C.size_t(unsafe.Sizeof(cflag)))
	defer C.free(buf)
	cflags := (*[1 << 10]*C.char)(unsafe.Pointer(buf))[:len(args):len(args)]
	for i, flag := range args {
		cflag := C.CString(flag)
		cflags[i] = cflag
		defer C.free(unsafe.Pointer(cflag))
	}

	var ok C.bool
	switch tool {
	case "clang":
		ok = C.tinygo_clang_driver(C.int(len(args)), (**C.char)(buf))
	case "ld.lld", "wasm-ld":
		ok = C.tinygo_link(C.int(len(args)), (**C.char)(buf))
	default:
		return errors.New("unknown tool: " + tool)
	}
	if !ok {
		return errors.New("failed to run tool: " + tool)
	}
	return nil
}