aboutsummaryrefslogtreecommitdiffhomepage
path: root/loader
diff options
context:
space:
mode:
authorAyke van Laethem <[email protected]>2020-09-17 19:15:50 +0200
committerRon Evans <[email protected]>2020-09-21 10:43:46 +0200
commit7b601b3e3c87493a31f9548ca017ad3672c8fbe9 (patch)
tree453b6952c6b9ac85f06cbd708be4f07efcad115f /loader
parentec54e7763d11b06dca9c83c89c36906a8df7874b (diff)
downloadtinygo-7b601b3e3c87493a31f9548ca017ad3672c8fbe9.tar.gz
tinygo-7b601b3e3c87493a31f9548ca017ad3672c8fbe9.zip
loader: fix linkname in test binaries
This is an issue in particular in the math package, of which most functions are defined in the runtime package.
Diffstat (limited to 'loader')
-rw-r--r--loader/loader.go43
1 files changed, 36 insertions, 7 deletions
diff --git a/loader/loader.go b/loader/loader.go
index 42d212255..847acc258 100644
--- a/loader/loader.go
+++ b/loader/loader.go
@@ -51,8 +51,7 @@ type PackageJSON struct {
CFiles []string
// Dependency information
- Imports []string
- ImportMap map[string]string
+ Imports []string
// Error information
Error *struct {
@@ -169,6 +168,41 @@ func Load(config *compileopts.Config, inputPkgs []string, clangHeaders string, t
}
return nil, err
}
+ if config.TestConfig.CompileTestBinary {
+ // When creating a test binary, `go list` will list two or three
+ // packages used for testing the package. The first is the original
+ // package as if it were built normally, the second is the same
+ // package but with the *_test.go files included. A possible third
+ // may be included for _test packages (such as math_test), used to
+ // test the external API with no access to internal functions.
+ // All packages that are necessary for testing (including the to be
+ // tested package with *_test.go files, but excluding the original
+ // unmodified package) have a suffix added to the import path, for
+ // example the math package has import path "math [math.test]" and
+ // test dependencies such as fmt will have an import path of the
+ // form "fmt [math.test]".
+ // The code below removes this suffix, and if this results in a
+ // duplicate (which happens with the to-be-tested package without
+ // *.test.go files) the previous package is removed from the list of
+ // packages included in this build.
+ // This is necessary because the change in import paths results in
+ // breakage to //go:linkname. Additionally, the duplicated package
+ // slows down the build and so is best removed.
+ if pkg.ForTest != "" && strings.HasSuffix(pkg.ImportPath, " ["+pkg.ForTest+".test]") {
+ newImportPath := pkg.ImportPath[:len(pkg.ImportPath)-len(" ["+pkg.ForTest+".test]")]
+ if _, ok := p.Packages[newImportPath]; ok {
+ // Delete the previous package (that this package overrides).
+ delete(p.Packages, newImportPath)
+ for i, pkg := range p.sorted {
+ if pkg.ImportPath == newImportPath {
+ p.sorted = append(p.sorted[:i], p.sorted[i+1:]...) // remove element from slice
+ break
+ }
+ }
+ }
+ pkg.ImportPath = newImportPath
+ }
+ }
p.sorted = append(p.sorted, pkg)
p.Packages[pkg.ImportPath] = pkg
}
@@ -367,11 +401,6 @@ func (p *Package) Import(to string) (*types.Package, error) {
if to == "unsafe" {
return types.Unsafe, nil
}
- if replace, ok := p.ImportMap[to]; ok {
- // This import path should be replaced by another import path, according
- // to `go list`.
- to = replace
- }
if imported, ok := p.program.Packages[to]; ok {
return imported.Pkg, nil
} else {