1// +build byollvm
2
3package builder
4
5import (
6	"errors"
7	"unsafe"
8)
9
10/*
11#cgo CXXFLAGS: -fno-rtti
12#include <stdbool.h>
13#include <stdlib.h>
14bool tinygo_clang_driver(int argc, char **argv);
15bool tinygo_link_elf(int argc, char **argv);
16bool tinygo_link_wasm(int argc, char **argv);
17*/
18import "C"
19
20const hasBuiltinTools = true
21
22// RunTool runs the given tool (such as clang).
23//
24// This version actually runs the tools because TinyGo was compiled while
25// linking statically with LLVM (with the byollvm build tag).
26func RunTool(tool string, args ...string) error {
27	args = append([]string{"tinygo:" + tool}, args...)
28
29	var cflag *C.char
30	buf := C.calloc(C.size_t(len(args)), C.size_t(unsafe.Sizeof(cflag)))
31	defer C.free(buf)
32	cflags := (*[1 << 10]*C.char)(unsafe.Pointer(buf))[:len(args):len(args)]
33	for i, flag := range args {
34		cflag := C.CString(flag)
35		cflags[i] = cflag
36		defer C.free(unsafe.Pointer(cflag))
37	}
38
39	var ok C.bool
40	switch tool {
41	case "clang":
42		ok = C.tinygo_clang_driver(C.int(len(args)), (**C.char)(buf))
43	case "ld.lld":
44		ok = C.tinygo_link_elf(C.int(len(args)), (**C.char)(buf))
45	case "wasm-ld":
46		ok = C.tinygo_link_wasm(C.int(len(args)), (**C.char)(buf))
47	default:
48		return errors.New("unknown tool: " + tool)
49	}
50	if !ok {
51		return errors.New("failed to run tool: " + tool)
52	}
53	return nil
54}
55