diff options
author | Ayke van Laethem <[email protected]> | 2020-04-01 23:13:16 +0200 |
---|---|---|
committer | Ron Evans <[email protected]> | 2021-11-04 17:15:38 +0100 |
commit | 403d93560b78a7eb6cc3bc2853d80cb7dfadc239 (patch) | |
tree | acc51a31099783f35b3ea7dbaa82a19c635de025 /compileopts | |
parent | b344d657819827d54936c88df6c66c56331ef0b6 (diff) | |
download | tinygo-403d93560b78a7eb6cc3bc2853d80cb7dfadc239.tar.gz tinygo-403d93560b78a7eb6cc3bc2853d80cb7dfadc239.zip |
builder: build static binaries using musl on Linux
This commit adds support for musl-libc and uses it by default on Linux.
The main benefit of it is that binaries are always statically linked
instead of depending on the host libc, even when using CGo.
Advantages:
- The resulting binaries are always statically linked.
- No need for any tools on the host OS, like a compiler, linker, or
libc in a release build of TinyGo.
- This also simplifies cross compilation as no cross compiler is
needed (it's all built into the TinyGo release build).
Disadvantages:
- Binary size increases by 5-6 kilobytes if -no-debug is used. Binary
size increases by a much larger margin when debugging symbols are
included (the default behavior) because musl is built with debugging
symbols enabled.
- Musl does things a bit differently than glibc, and some CGo code
might rely on the glibc behavior.
- The first build takes a bit longer because musl needs to be built.
As an additional bonus, time is now obtained from the system in a way
that fixes the Y2038 problem because musl has been a bit more agressive
in switching to 64-bit time_t.
Diffstat (limited to 'compileopts')
-rw-r--r-- | compileopts/config.go | 19 | ||||
-rw-r--r-- | compileopts/target.go | 17 |
2 files changed, 26 insertions, 10 deletions
diff --git a/compileopts/config.go b/compileopts/config.go index 9664d2770..bdbdd0d20 100644 --- a/compileopts/config.go +++ b/compileopts/config.go @@ -198,6 +198,16 @@ func (c *Config) RP2040BootPatch() bool { return false } +// MuslArchitecture returns the architecture name as used in musl libc. It is +// usually the same as the first part of the LLVM triple, but not always. +func MuslArchitecture(triple string) string { + arch := strings.Split(triple, "-")[0] + if strings.HasPrefix(arch, "arm") || strings.HasPrefix(arch, "thumb") { + arch = "arm" + } + return arch +} + // LibcPath returns the path to the libc directory. The libc path will be either // a precompiled libc shipped with a TinyGo build, or a libc path in the cache // directory (which might not yet be built). @@ -238,6 +248,15 @@ func (c *Config) CFlags() []string { "-Xclang", "-internal-isystem", "-Xclang", filepath.Join(picolibcDir, "include"), "-Xclang", "-internal-isystem", "-Xclang", filepath.Join(picolibcDir, "tinystdio"), ) + case "musl": + root := goenv.Get("TINYGOROOT") + path, _ := c.LibcPath("musl") + arch := MuslArchitecture(c.Triple()) + cflags = append(cflags, + "--sysroot="+path, + "-Xclang", "-internal-isystem", "-Xclang", filepath.Join(root, "lib", "musl", "arch", arch), + "-Xclang", "-internal-isystem", "-Xclang", filepath.Join(root, "lib", "musl", "include"), + ) case "wasi-libc": root := goenv.Get("TINYGOROOT") cflags = append(cflags, "--sysroot="+root+"/lib/wasi-libc/sysroot") diff --git a/compileopts/target.go b/compileopts/target.go index 88beb7a0a..0293f2b4f 100644 --- a/compileopts/target.go +++ b/compileopts/target.go @@ -234,6 +234,11 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) { if goos == "darwin" { spec.CFlags = append(spec.CFlags, "-isysroot", "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk") spec.LDFlags = append(spec.LDFlags, "-Wl,-dead_strip") + } else if goos == "linux" { + spec.Linker = "ld.lld" + spec.RTLib = "compiler-rt" + spec.Libc = "musl" + spec.LDFlags = append(spec.LDFlags, "--gc-sections") } else { spec.LDFlags = append(spec.LDFlags, "-no-pie", "-Wl,--gc-sections") // WARNING: clang < 5.0 requires -nopie } @@ -245,18 +250,10 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) { // Some educated guesses as to how to invoke helper programs. spec.GDB = []string{"gdb-multiarch"} if goarch == "arm" && goos == "linux" { - spec.CFlags = append(spec.CFlags, "--sysroot=/usr/arm-linux-gnueabihf") - spec.Linker = "arm-linux-gnueabihf-gcc" - spec.Emulator = []string{"qemu-arm", "-L", "/usr/arm-linux-gnueabihf"} + spec.Emulator = []string{"qemu-arm"} } if goarch == "arm64" && goos == "linux" { - spec.CFlags = append(spec.CFlags, "--sysroot=/usr/aarch64-linux-gnu") - spec.Linker = "aarch64-linux-gnu-gcc" - spec.Emulator = []string{"qemu-aarch64", "-L", "/usr/aarch64-linux-gnu"} - } - if goarch == "386" && runtime.GOARCH == "amd64" { - spec.CFlags = append(spec.CFlags, "-m32") - spec.LDFlags = append(spec.LDFlags, "-m32") + spec.Emulator = []string{"qemu-aarch64"} } } return &spec, nil |