
When building statically against LLVM, LLD is also included now. When included, the built in wasm-ld will automatically be used instead of the external command. There is also support for linking ELF files but because lld does not fully support armv6m this is not yet enabled (it produces a warning).
66 строки
1,7 КиБ
Go
66 строки
1,7 КиБ
Go
// +build byollvm
|
|
|
|
package main
|
|
|
|
// This file provides a Link() function that uses the bundled lld if possible.
|
|
|
|
import (
|
|
"errors"
|
|
"os"
|
|
"os/exec"
|
|
"unsafe"
|
|
)
|
|
|
|
/*
|
|
#include <stdbool.h>
|
|
#include <stdlib.h>
|
|
bool tinygo_link_elf(int argc, char **argv);
|
|
bool tinygo_link_wasm(int argc, char **argv);
|
|
*/
|
|
import "C"
|
|
|
|
// Link invokes a linker with the given name and flags.
|
|
//
|
|
// This version uses the built-in linker when trying to use lld.
|
|
func Link(dir, linker string, flags ...string) error {
|
|
switch linker {
|
|
case "ld.lld", commands["ld.lld"]:
|
|
flags = append([]string{"tinygo:" + linker}, flags...)
|
|
var cflag *C.char
|
|
buf := C.calloc(C.size_t(len(flags)), C.size_t(unsafe.Sizeof(cflag)))
|
|
cflags := (*[1 << 10]*C.char)(unsafe.Pointer(buf))[:len(flags):len(flags)]
|
|
for i, flag := range flags {
|
|
cflag := C.CString(flag)
|
|
cflags[i] = cflag
|
|
defer C.free(unsafe.Pointer(cflag))
|
|
}
|
|
ok := C.tinygo_link_elf(C.int(len(flags)), (**C.char)(buf))
|
|
if !ok {
|
|
return errors.New("failed to link using built-in ld.lld")
|
|
}
|
|
return nil
|
|
case "wasm-ld", commands["wasm-ld"]:
|
|
flags = append([]string{"tinygo:" + linker}, flags...)
|
|
var cflag *C.char
|
|
buf := C.calloc(C.size_t(len(flags)), C.size_t(unsafe.Sizeof(cflag)))
|
|
defer C.free(buf)
|
|
cflags := (*[1 << 10]*C.char)(unsafe.Pointer(buf))[:len(flags):len(flags)]
|
|
for i, flag := range flags {
|
|
cflag := C.CString(flag)
|
|
cflags[i] = cflag
|
|
defer C.free(unsafe.Pointer(cflag))
|
|
}
|
|
ok := C.tinygo_link_wasm(C.int(len(flags)), (**C.char)(buf))
|
|
if !ok {
|
|
return errors.New("failed to link using built-in wasm-ld")
|
|
}
|
|
return nil
|
|
default:
|
|
// Fall back to external command.
|
|
cmd := exec.Command(linker, flags...)
|
|
cmd.Stdout = os.Stdout
|
|
cmd.Stderr = os.Stderr
|
|
cmd.Dir = dir
|
|
return cmd.Run()
|
|
}
|
|
}
|