From b9bf0aa0dade790f7b60726e4b53d4d49c91504f Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Sat, 22 Mar 2025 09:39:27 +0100 Subject: [PATCH] windows: add support for the Boehm-Demers-Weiser GC A few small changes were needed to make this work. In particular, I found a critical bug (see the previous commit) that needed to be fixed to make this work on Windows. --- GNUmakefile | 1 + builder/bdwgc.go | 18 ++++++++++++++++-- builder/build.go | 5 +++-- compileopts/config.go | 2 ++ compileopts/target.go | 2 +- 5 files changed, 23 insertions(+), 5 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index 1a97269e9..fcae9a205 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -1007,6 +1007,7 @@ endif @cp -rp lib/mingw-w64/mingw-w64-crt/stdio/ucrt_* build/release/tinygo/lib/mingw-w64/mingw-w64-crt/stdio @cp -rp lib/mingw-w64/mingw-w64-headers/crt/ build/release/tinygo/lib/mingw-w64/mingw-w64-headers @cp -rp lib/mingw-w64/mingw-w64-headers/defaults/include build/release/tinygo/lib/mingw-w64/mingw-w64-headers/defaults + @cp -rp lib/mingw-w64/mingw-w64-headers/include build/release/tinygo/lib/mingw-w64/mingw-w64-headers @cp -rp lib/nrfx/* build/release/tinygo/lib/nrfx @cp -rp lib/picolibc/newlib/libc/ctype build/release/tinygo/lib/picolibc/newlib/libc @cp -rp lib/picolibc/newlib/libc/include build/release/tinygo/lib/picolibc/newlib/libc diff --git a/builder/bdwgc.go b/builder/bdwgc.go index c7c797636..d283330f5 100644 --- a/builder/bdwgc.go +++ b/builder/bdwgc.go @@ -5,6 +5,7 @@ package builder import ( "path/filepath" + "strings" "github.com/tinygo-org/tinygo/goenv" ) @@ -25,6 +26,10 @@ var BoehmGC = Library{ "-DIGNORE_DYNAMIC_LOADING", // we don't support dynamic loading at the moment "-DNO_GETCONTEXT", // musl doesn't support getcontext() + // Use a minimal environment. + "-DNO_MSGBOX_ON_ERROR", // don't call MessageBoxA on Windows + "-DDONT_USE_ATEXIT", + // Special flag to work around the lack of __data_start in ld.lld. // TODO: try to fix this in LLVM/lld directly so we don't have to // work around it anymore. @@ -47,7 +52,7 @@ var BoehmGC = Library{ return filepath.Join(goenv.Get("TINYGOROOT"), "lib/bdwgc") }, librarySources: func(target string) ([]string, error) { - return []string{ + sources := []string{ "allchblk.c", "alloc.c", "blacklst.c", @@ -66,6 +71,15 @@ var BoehmGC = Library{ "pthread_stop_world.c", "pthread_support.c", "reclaim.c", - }, nil + } + if strings.Split(target, "-")[2] == "windows" { + // Due to how the linker on Windows works (that doesn't allow + // undefined functions), we need to include these extra files. + sources = append(sources, + "mallocx.c", + "ptr_chck.c", + ) + } + return sources, nil }, } diff --git a/builder/build.go b/builder/build.go index 9d73a0366..e2756a267 100644 --- a/builder/build.go +++ b/builder/build.go @@ -182,12 +182,13 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe defer unlock() libcDependencies = append(libcDependencies, libcJob) case "mingw-w64": - job, unlock, err := libMinGW.load(config, tmpdir, nil) + var unlock func() + libcJob, unlock, err = libMinGW.load(config, tmpdir, nil) if err != nil { return BuildResult{}, err } defer unlock() - libcDependencies = append(libcDependencies, job) + libcDependencies = append(libcDependencies, libcJob) libcDependencies = append(libcDependencies, makeMinGWExtraLibs(tmpdir, config.GOARCH())...) case "": // no library specified, so nothing to do diff --git a/compileopts/config.go b/compileopts/config.go index a9eb235ad..3d8a73627 100644 --- a/compileopts/config.go +++ b/compileopts/config.go @@ -395,8 +395,10 @@ func (c *Config) LibcCFlags() []string { "-nostdlibinc", "-isystem", filepath.Join(path, "include"), "-isystem", filepath.Join(root, "lib", "mingw-w64", "mingw-w64-headers", "crt"), + "-isystem", filepath.Join(root, "lib", "mingw-w64", "mingw-w64-headers", "include"), "-isystem", filepath.Join(root, "lib", "mingw-w64", "mingw-w64-headers", "defaults", "include"), "-D_UCRT", + "-D_WIN32_WINNT=0x0a00", // target Windows 10 } case "": // No libc specified, nothing to add. diff --git a/compileopts/target.go b/compileopts/target.go index 62d02963f..7a38d0f1f 100644 --- a/compileopts/target.go +++ b/compileopts/target.go @@ -427,7 +427,7 @@ func defaultTarget(options *Options) (*TargetSpec, error) { "src/runtime/runtime_unix.c", "src/runtime/signal.c") case "windows": - spec.GC = "precise" + spec.GC = "boehm" spec.Linker = "ld.lld" spec.Libc = "mingw-w64" // Note: using a medium code model, low image base and no ASLR