github.com/aykevl/tinygo@v0.5.0/linker-builtin.go (about) 1 // +build byollvm 2 3 package main 4 5 // This file provides a Link() function that uses the bundled lld if possible. 6 7 import ( 8 "errors" 9 "os" 10 "os/exec" 11 "unsafe" 12 ) 13 14 /* 15 #include <stdbool.h> 16 #include <stdlib.h> 17 bool tinygo_link_elf(int argc, char **argv); 18 bool tinygo_link_wasm(int argc, char **argv); 19 */ 20 import "C" 21 22 // Link invokes a linker with the given name and flags. 23 // 24 // This version uses the built-in linker when trying to use lld. 25 func Link(linker string, flags ...string) error { 26 switch linker { 27 case "ld.lld", commands["ld.lld"]: 28 flags = append([]string{"tinygo:" + linker}, flags...) 29 var cflag *C.char 30 buf := C.calloc(C.size_t(len(flags)), C.size_t(unsafe.Sizeof(cflag))) 31 cflags := (*[1 << 10]*C.char)(unsafe.Pointer(buf))[:len(flags):len(flags)] 32 for i, flag := range flags { 33 cflag := C.CString(flag) 34 cflags[i] = cflag 35 defer C.free(unsafe.Pointer(cflag)) 36 } 37 ok := C.tinygo_link_elf(C.int(len(flags)), (**C.char)(buf)) 38 if !ok { 39 return errors.New("failed to link using built-in ld.lld") 40 } 41 return nil 42 case "wasm-ld", commands["wasm-ld"]: 43 flags = append([]string{"tinygo:" + linker}, flags...) 44 var cflag *C.char 45 buf := C.calloc(C.size_t(len(flags)), C.size_t(unsafe.Sizeof(cflag))) 46 defer C.free(buf) 47 cflags := (*[1 << 10]*C.char)(unsafe.Pointer(buf))[:len(flags):len(flags)] 48 for i, flag := range flags { 49 cflag := C.CString(flag) 50 cflags[i] = cflag 51 defer C.free(unsafe.Pointer(cflag)) 52 } 53 ok := C.tinygo_link_wasm(C.int(len(flags)), (**C.char)(buf)) 54 if !ok { 55 return errors.New("failed to link using built-in wasm-ld") 56 } 57 return nil 58 default: 59 // Fall back to external command. 60 cmd := exec.Command(linker, flags...) 61 cmd.Stdout = os.Stdout 62 cmd.Stderr = os.Stderr 63 return cmd.Run() 64 } 65 }