From 00ea0b1d57a7ae775df81d0913af7905f7d76e32 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Sat, 10 Jul 2021 23:15:58 +0200 Subject: [PATCH] build: list libraries at the end of the linker command Static libraries should be added at the end of the linker command, after all object files. If that isn't done, that's _usually_ not a problem, unless there are duplicate symbols. In that case, weird dependency issues can arise. To solve that, object files (that may include symbols to override symbols in the library) should be listed first on the command line and then the static libraries should be listed. This fixes an issue with overriding some symbols in wasi-libc. --- builder/build.go | 50 +++++++++++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/builder/build.go b/builder/build.go index f17d26c7..5c38433b 100644 --- a/builder/build.go +++ b/builder/build.go @@ -470,33 +470,10 @@ func Build(pkgName, outpath string, config *compileopts.Config, action func(Buil linkerDependencies = append(linkerDependencies, job) } - // Add libc dependency if needed. - root := goenv.Get("TINYGOROOT") - switch config.Target.Libc { - case "picolibc": - job, err := Picolibc.load(config.Triple(), config.CPU(), dir) - if err != nil { - return err - } - // The library needs to be compiled (cache miss). - jobs = append(jobs, job.dependencies...) - jobs = append(jobs, job) - linkerDependencies = append(linkerDependencies, job) - case "wasi-libc": - path := filepath.Join(root, "lib/wasi-libc/sysroot/lib/wasm32-wasi/libc.a") - if _, err := os.Stat(path); os.IsNotExist(err) { - return errors.New("could not find wasi-libc, perhaps you need to run `make wasi-libc`?") - } - ldflags = append(ldflags, path) - case "": - // no library specified, so nothing to do - default: - return fmt.Errorf("unknown libc: %s", config.Target.Libc) - } - // Add jobs to compile extra files. These files are in C or assembly and // contain things like the interrupt vector table and low level operations // such as stack switching. + root := goenv.Get("TINYGOROOT") for _, path := range config.ExtraFiles() { abspath := filepath.Join(root, path) job := &compileJob{ @@ -537,6 +514,31 @@ func Build(pkgName, outpath string, config *compileopts.Config, action func(Buil ldflags = append(ldflags, lprogram.LDFlags...) } + // Add libc dependency if needed. + switch config.Target.Libc { + case "picolibc": + job, err := Picolibc.load(config.Triple(), config.CPU(), dir) + if err != nil { + return err + } + // The library needs to be compiled (cache miss). + jobs = append(jobs, job.dependencies...) + jobs = append(jobs, job) + linkerDependencies = append(linkerDependencies, job) + case "wasi-libc": + path := filepath.Join(root, "lib/wasi-libc/sysroot/lib/wasm32-wasi/libc.a") + if _, err := os.Stat(path); os.IsNotExist(err) { + return errors.New("could not find wasi-libc, perhaps you need to run `make wasi-libc`?") + } + job := dummyCompileJob(path) + jobs = append(jobs, job) + linkerDependencies = append(linkerDependencies, job) + case "": + // no library specified, so nothing to do + default: + return fmt.Errorf("unknown libc: %s", config.Target.Libc) + } + // Create a linker job, which links all object files together and does some // extra stuff that can only be done after linking. jobs = append(jobs, &compileJob{