diff --git a/internal/build/build.go b/internal/build/build.go index f079450f..abcdad40 100644 --- a/internal/build/build.go +++ b/internal/build/build.go @@ -291,7 +291,7 @@ func Do(args []string, conf *Config) ([]Package, error) { os.Setenv("PATH", env.BinDir()+":"+os.Getenv("PATH")) // TODO(xsw): check windows output := conf.OutFile != "" - export, err := crosscompile.UseCrossCompileSDK(conf.Goos, conf.Goarch) + export, err := crosscompile.UseCrossCompileSDK(conf.Goos, conf.Goarch, IsWasiThreadsEnabled()) check(err) ctx := &context{env, cfg, progSSA, prog, dedup, patches, make(map[string]none), initial, mode, 0, output, make(map[*packages.Package]bool), make(map[*packages.Package]bool), conf, export} pkgs, err := buildAllPkgs(ctx, initial, verbose) @@ -673,7 +673,6 @@ func buildLdflags(goos, goarch, targetTriple string) []string { // "-Wl,--import-memory,", // unknown import: `env::memory` has not been defined "-Wl,--export-memory", "-Wl,--initial-memory=16777216", // 16MB - // "-pthread", "-matomics", // undefined symbol: __atomic_load "-mbulk-memory", "-mmultimemory", "-lc", @@ -684,14 +683,23 @@ func buildLdflags(goos, goarch, targetTriple string) []string { // "-lxnet", // "-lresolv", "-lsetjmp", - // "-lpthread", "-lwasi-emulated-mman", "-lwasi-emulated-getpid", - // "-lwasi-emulated-pthread", "-lwasi-emulated-process-clocks", "-lwasi-emulated-signal", + "-fwasm-exceptions", "-mllvm", "-wasm-enable-sjlj", + // "-mllvm", "-wasm-enable-eh", ) + if IsWasiThreadsEnabled() { + args = append( + args, + "-lwasi-emulated-pthread", + "-lpthread", + "-pthread", + "-matomics", // undefined symbol: __atomic_load + ) + } default: // ld.lld (Unix) args = append( args, @@ -949,6 +957,7 @@ const llgoOptimize = "LLGO_OPTIMIZE" const llgoCheck = "LLGO_CHECK" const llgoRpathChange = "LLGO_RPATH_CHANGE" const llgoWasmRuntime = "LLGO_WASM_RUNTIME" +const llgoWasiThreads = "LLGO_WASI_THREADS" const defaultWasmRuntime = "wasmtime" @@ -992,6 +1001,10 @@ func IsRpathChangeEnabled() bool { return isEnvOn(llgoRpathChange, false) } +func IsWasiThreadsEnabled() bool { + return isEnvOn(llgoWasiThreads, true) +} + func WasmRuntime() string { return defaultEnv(llgoWasmRuntime, defaultWasmRuntime) } diff --git a/internal/crosscompile/cosscompile.go b/internal/crosscompile/cosscompile.go index f71a96a9..27cfe43f 100644 --- a/internal/crosscompile/cosscompile.go +++ b/internal/crosscompile/cosscompile.go @@ -23,7 +23,7 @@ func cacheDir() string { return filepath.Join(env.LLGoCacheDir(), "crosscompile") } -func UseCrossCompileSDK(goos, goarch string) (export Export, err error) { +func UseCrossCompileSDK(goos, goarch string, wasiThreads bool) (export Export, err error) { if runtime.GOOS == goos && runtime.GOARCH == goarch { // not cross compile return @@ -38,12 +38,16 @@ func UseCrossCompileSDK(goos, goarch string) (export Export, err error) { return } } + triple := "wasm32-wasip1" + if wasiThreads { + triple = "wasm32-wasip1-threads" + } // Set up flags for the SDK wasiSdkRoot := filepath.Join(sdkDir, "wasi-sdk-25.0-x86_64-macos") sysrootDir := filepath.Join(wasiSdkRoot, "share", "wasi-sysroot") libclangDir := filepath.Join(wasiSdkRoot, "lib", "clang", "19") - includeDir := filepath.Join(sysrootDir, "include", "wasm32-wasip1") - libDir := filepath.Join(sysrootDir, "lib", "wasm32-wasip1") + includeDir := filepath.Join(sysrootDir, "include", triple) + libDir := filepath.Join(sysrootDir, "lib", triple) export.CCFLAGS = []string{ "--sysroot=" + sysrootDir, diff --git a/internal/crosscompile/crosscompile_test.go b/internal/crosscompile/crosscompile_test.go index 35ffa192..9a32eff3 100644 --- a/internal/crosscompile/crosscompile_test.go +++ b/internal/crosscompile/crosscompile_test.go @@ -75,7 +75,7 @@ func TestUseCrossCompileSDK(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - export, err := UseCrossCompileSDK(tc.goos, tc.goarch) + export, err := UseCrossCompileSDK(tc.goos, tc.goarch, false) if err != nil { t.Fatalf("Unexpected error: %v", err)