aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAyke van Laethem <[email protected]>2021-07-10 23:15:58 +0200
committerRon Evans <[email protected]>2021-07-15 00:13:17 +0200
commit00ea0b1d57a7ae775df81d0913af7905f7d76e32 (patch)
treecce88fbc81106500a2e32a7c7cf89663566175cf
parentefa0410075ea492a1113224236a1210be74e1650 (diff)
downloadtinygo-00ea0b1d57a7ae775df81d0913af7905f7d76e32.tar.gz
tinygo-00ea0b1d57a7ae775df81d0913af7905f7d76e32.zip
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.
-rw-r--r--builder/build.go50
1 files changed, 26 insertions, 24 deletions
diff --git a/builder/build.go b/builder/build.go
index f17d26c72..5c38433bd 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{