From 7e8df050a123823ed1330ce6795c7ac8133bf059 Mon Sep 17 00:00:00 2001 From: Li Jie Date: Thu, 21 Aug 2025 14:13:42 +0800 Subject: [PATCH] fix cross compilation --- internal/clang/clang.go | 22 +++--- internal/crosscompile/crosscompile.go | 59 ++++------------ internal/crosscompile/crosscompile_test.go | 81 +++++----------------- 3 files changed, 42 insertions(+), 120 deletions(-) diff --git a/internal/clang/clang.go b/internal/clang/clang.go index 916b49b2..11304d60 100644 --- a/internal/clang/clang.go +++ b/internal/clang/clang.go @@ -96,46 +96,46 @@ func (c *Cmd) Link(args ...string) error { // mergeCompilerFlags merges environment CCFLAGS/CFLAGS with crossCompile flags. func (c *Cmd) mergeCompilerFlags() []string { var flags []string - + // Add environment CCFLAGS if envCCFlags := os.Getenv("CCFLAGS"); envCCFlags != "" { flags = append(flags, safesplit.SplitPkgConfigFlags(envCCFlags)...) } - + // Add environment CFLAGS if envCFlags := os.Getenv("CFLAGS"); envCFlags != "" { flags = append(flags, safesplit.SplitPkgConfigFlags(envCFlags)...) } - + // Add crossCompile CCFLAGS flags = append(flags, c.crossCompile.CCFLAGS...) - + // Add crossCompile CFLAGS flags = append(flags, c.crossCompile.CFLAGS...) - + return flags } // mergeLinkerFlags merges environment CCFLAGS/LDFLAGS with crossCompile flags. func (c *Cmd) mergeLinkerFlags() []string { var flags []string - + // Add environment CCFLAGS (for linker) if envCCFlags := os.Getenv("CCFLAGS"); envCCFlags != "" { flags = append(flags, safesplit.SplitPkgConfigFlags(envCCFlags)...) } - + // Add environment LDFLAGS if envLDFlags := os.Getenv("LDFLAGS"); envLDFlags != "" { flags = append(flags, safesplit.SplitPkgConfigFlags(envLDFlags)...) } - + // Add crossCompile CCFLAGS (for linker) flags = append(flags, c.crossCompile.CCFLAGS...) - + // Add crossCompile LDFLAGS flags = append(flags, c.crossCompile.LDFLAGS...) - + return flags } @@ -183,4 +183,4 @@ func (c *Cmd) CheckLinkArgs(cmdArgs []string, wasm bool) error { // Execute the command with linker flags return c.Link(args...) -} \ No newline at end of file +} diff --git a/internal/crosscompile/crosscompile.go b/internal/crosscompile/crosscompile.go index 5665f62d..c543be34 100644 --- a/internal/crosscompile/crosscompile.go +++ b/internal/crosscompile/crosscompile.go @@ -339,11 +339,21 @@ func useTarget(targetName string) (export Export, err error) { target = llvm.GetTargetTriple(config.GOOS, config.GOARCH) } - ccflags = append(ccflags, "-Wno-override-module", "--target="+config.LLVMTarget) + cflags := []string{"-Wno-override-module"} + if config.LLVMTarget != "" { + cflags = append(cflags, "--target="+config.LLVMTarget) + ccflags = append(ccflags, "--target="+config.LLVMTarget) + } + cflags = append(cflags, config.CFlags...) // Inspired by tinygo cpu := config.CPU if cpu != "" { + if config.Linker == "ld.lld" { + ldflags = append(ldflags, "-mllvm", "-mcpu="+cpu) + } + + // Always add CPU to CCFLAGS for proper compilation if strings.HasPrefix(target, "i386") || strings.HasPrefix(target, "x86_64") { ccflags = append(ccflags, "-march="+cpu) } else if strings.HasPrefix(target, "avr") { @@ -351,10 +361,6 @@ func useTarget(targetName string) (export Export, err error) { } else { ccflags = append(ccflags, "-mcpu="+cpu) } - // Only add -mllvm flags for non-WebAssembly linkers - if config.Linker == "ld.lld" { - ldflags = append(ldflags, "-mllvm", "-mcpu="+cpu) - } } // Handle Features @@ -375,7 +381,7 @@ func useTarget(targetName string) (export Export, err error) { ldflags = append(ldflags, "-L", env.LLGoROOT()) // search targets/*.ld // Combine with config flags - export.CFLAGS = config.CFlags + export.CFLAGS = cflags export.CCFLAGS = ccflags export.LDFLAGS = append(ldflags, config.LDFlags...) @@ -390,44 +396,3 @@ func Use(goos, goarch string, wasiThreads bool, targetName string) (export Expor } return use(goos, goarch, wasiThreads) } - -// filterCompatibleLDFlags filters out linker flags that are incompatible with clang/lld -func filterCompatibleLDFlags(ldflags []string) []string { - if len(ldflags) == 0 { - return ldflags - } - - var filtered []string - - incompatiblePrefixes := []string{ - "--defsym=", // Use -Wl,--defsym= instead - "-T", // Linker script, needs special handling - } - - i := 0 - for i < len(ldflags) { - flag := ldflags[i] - - // Check incompatible prefixes - skip := false - for _, prefix := range incompatiblePrefixes { - if strings.HasPrefix(flag, prefix) { - skip = true - break - } - } - if skip { - // Skip -T and its argument if separate - if flag == "-T" && i+1 < len(ldflags) { - i += 2 // Skip both -T and the script path - } else { - i++ - } - continue - } - filtered = append(filtered, flag) - i++ - } - - return filtered -} diff --git a/internal/crosscompile/crosscompile_test.go b/internal/crosscompile/crosscompile_test.go index 26cfeed5..f85267bc 100644 --- a/internal/crosscompile/crosscompile_test.go +++ b/internal/crosscompile/crosscompile_test.go @@ -230,20 +230,33 @@ func TestUseTarget(t *testing.T) { } } - // Check if CPU is in CCFLAGS + // Check if CPU is in LDFLAGS (for ld.lld linker) or CCFLAGS (for other cases) if tc.expectCPU != "" { found := false - expectedFlags := []string{"-mmcu=" + tc.expectCPU, "-mcpu=" + tc.expectCPU} - for _, flag := range export.CCFLAGS { - for _, expectedFlag := range expectedFlags { - if flag == expectedFlag { + // First check LDFLAGS for -mllvm -mcpu= pattern + for i, flag := range export.LDFLAGS { + if flag == "-mllvm" && i+1 < len(export.LDFLAGS) { + nextFlag := export.LDFLAGS[i+1] + if nextFlag == "-mcpu="+tc.expectCPU { found = true break } } } + // If not found in LDFLAGS, check CCFLAGS for direct CPU flags if !found { - t.Errorf("Expected CPU %s in CCFLAGS, got %v", tc.expectCPU, export.CCFLAGS) + expectedFlags := []string{"-mmcu=" + tc.expectCPU, "-mcpu=" + tc.expectCPU} + for _, flag := range export.CCFLAGS { + for _, expectedFlag := range expectedFlags { + if flag == expectedFlag { + found = true + break + } + } + } + } + if !found { + t.Errorf("Expected CPU %s in LDFLAGS or CCFLAGS, got LDFLAGS=%v, CCFLAGS=%v", tc.expectCPU, export.LDFLAGS, export.CCFLAGS) } } @@ -277,59 +290,3 @@ func TestUseWithTarget(t *testing.T) { t.Error("Expected LDFLAGS to be set for native build") } } - -func TestFilterCompatibleLDFlags(t *testing.T) { - testCases := []struct { - name string - input []string - expected []string - }{ - { - name: "Empty flags", - input: []string{}, - expected: []string{}, - }, - { - name: "Compatible flags only", - input: []string{"-lm", "-lpthread"}, - expected: []string{"-lm", "-lpthread"}, - }, - { - name: "Incompatible flags filtered", - input: []string{"--gc-sections", "-lm", "--emit-relocs", "-lpthread"}, - expected: []string{"--gc-sections", "-lm", "--emit-relocs", "-lpthread"}, - }, - { - name: "Defsym flags filtered", - input: []string{"--defsym=_stack_size=512", "-lm", "--defsym=_bootloader_size=512"}, - expected: []string{"-lm"}, - }, - { - name: "Linker script flags filtered", - input: []string{"-T", "script.ld", "-lm"}, - expected: []string{"-lm"}, - }, - { - name: "Mixed compatible and incompatible", - input: []string{"-lm", "--gc-sections", "--defsym=test=1", "-lpthread", "--no-demangle"}, - expected: []string{"-lm", "--gc-sections", "-lpthread", "--no-demangle"}, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - result := filterCompatibleLDFlags(tc.input) - - if len(result) != len(tc.expected) { - t.Errorf("Expected %d flags, got %d: %v", len(tc.expected), len(result), result) - return - } - - for i, expected := range tc.expected { - if result[i] != expected { - t.Errorf("Expected flag[%d] = %s, got %s", i, expected, result[i]) - } - } - }) - } -}