From ebf9edbcb13b6bb754194b60f688d39b7c75c7b0 Mon Sep 17 00:00:00 2001 From: Nevkontakte Date: Mon, 3 May 2021 15:42:27 +0100 Subject: [PATCH] Improve Mac OS (darwin) support. Changes in this commit ensure that we can at least build supported standard library packages with GOOS=darwin. In theory, GOOS shouldn't even matter, since we always target the same platform (nodejs or browser), but for historical reasons, it does matter and we need to take extra steps to make it work. See https://github.com/gopherjs/gopherjs/issues/693 for more details. --- build/build.go | 25 ++++++++++++++++--- compiler/linkname.go | 9 +++++++ .../natives/src/syscall/syscall_darwin.go | 4 --- 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/build/build.go b/build/build.go index 7a8acc1e3..c75280067 100644 --- a/build/build.go +++ b/build/build.go @@ -175,10 +175,11 @@ func importWithSrcDir(bctx build.Context, path string, srcDir string, mode build switch path { case "os": pkg.GoFiles = excludeExecutable(pkg.GoFiles) // Need to exclude executable implementation files, because some of them contain package scope variables that perform (indirectly) syscalls on init. - // Prefer dirent_js.go version, since it targets a similar environment to - // ours. Arguably this file should be excluded by the build tags (see - // https://github.com/gopherjs/gopherjs/issues/693). - pkg.GoFiles = exclude(pkg.GoFiles, "dirent_linux.go") + // Prefer the dirent_${GOOS}.go version, to make the build pass on both linux + // and darwin. + // In the long term, our builds should produce the same output regardless + // of the host OS: https://github.com/gopherjs/gopherjs/issues/693. + pkg.GoFiles = exclude(pkg.GoFiles, "dirent_js.go") case "runtime": pkg.GoFiles = []string{} // Package sources are completely replaced in natives. case "runtime/internal/sys": @@ -194,6 +195,16 @@ func importWithSrcDir(bctx build.Context, path string, srcDir string, mode build case "crypto/rand": pkg.GoFiles = []string{"rand.go", "util.go"} pkg.TestGoFiles = exclude(pkg.TestGoFiles, "rand_linux_test.go") // Don't want linux-specific tests (since linux-specific package files are excluded too). + case "crypto/x509": + // GopherJS doesn't support loading OS root certificates regardless of the + // OS. The substitution below allows to avoid build dependency on Mac OS + // implementation, which won't be used anyway. + // + // Just like above, https://github.com/gopherjs/gopherjs/issues/693 is + // probably the best long-term option. + pkg.GoFiles = include( + exclude(pkg.GoFiles, fmt.Sprintf("root_%s.go", bctx.GOOS)), + "root_unix.go", "root_js.go") } if len(pkg.CgoFiles) > 0 { @@ -249,6 +260,12 @@ Outer: return s } +func include(files []string, includes ...string) []string { + files = exclude(files, includes...) // Ensure there won't be duplicates. + files = append(files, includes...) + return files +} + // ImportDir is like Import but processes the Go package found in the named // directory. func ImportDir(dir string, mode build.ImportMode, installSuffix string, buildTags []string) (*PackageData, error) { diff --git a/compiler/linkname.go b/compiler/linkname.go index 63023beab..d0738b370 100644 --- a/compiler/linkname.go +++ b/compiler/linkname.go @@ -101,6 +101,15 @@ func parseGoLinknames(fset *token.FileSet, pkgPath string, file *ast.File) ([]Go obj := file.Scope.Lookup(localName) if obj == nil { + if pkgPath == "syscall" { + // Syscall uses go:cgo_import_dynamic pragma to import symbols from + // dynamic libraries when build with GOOS=darwin, which GopherJS doesn't + // support. Silently ignore such directives. + // + // In the long term https://github.com/gopherjs/gopherjs/issues/693 is a + // preferred solution. + return nil + } return fmt.Errorf("//go:linkname local symbol %q is not found in the current source file", localName) } diff --git a/compiler/natives/src/syscall/syscall_darwin.go b/compiler/natives/src/syscall/syscall_darwin.go index 632fa93d5..d0ff19906 100644 --- a/compiler/natives/src/syscall/syscall_darwin.go +++ b/compiler/natives/src/syscall/syscall_darwin.go @@ -20,10 +20,6 @@ func funcPC(f func()) uintptr { return SYS_CHDIR case js.InternalObject(libc_rmdir_trampoline): return SYS_RMDIR - case js.InternalObject(libc___getdirentries64_trampoline): - return SYS_GETDIRENTRIES64 - case js.InternalObject(libc_getattrlist_trampoline): - return SYS_GETATTRLIST case js.InternalObject(libc_symlink_trampoline): return SYS_SYMLINK case js.InternalObject(libc_readlink_trampoline):