feat: support libc version
This commit is contained in:
@@ -3,9 +3,14 @@
|
||||
package crosscompile
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/goplus/llgo/internal/crosscompile/compile/libc"
|
||||
"github.com/goplus/llgo/internal/crosscompile/compile/rtlib"
|
||||
)
|
||||
|
||||
func TestGetLibcCompileConfigByName(t *testing.T) {
|
||||
@@ -13,22 +18,23 @@ func TestGetLibcCompileConfigByName(t *testing.T) {
|
||||
target := "armv7"
|
||||
mcpu := "cortex-m4"
|
||||
|
||||
needSkipDownload = true
|
||||
t.Run("EmptyName", func(t *testing.T) {
|
||||
_, err := getLibcCompileConfigByName(baseDir, "", target, mcpu)
|
||||
_, _, err := getLibcCompileConfigByName(baseDir, "", target, mcpu)
|
||||
if err == nil || err.Error() != "libc name cannot be empty" {
|
||||
t.Errorf("Expected empty name error, got: %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("UnsupportedLibc", func(t *testing.T) {
|
||||
_, err := getLibcCompileConfigByName(baseDir, "invalid", target, mcpu)
|
||||
_, _, err := getLibcCompileConfigByName(baseDir, "invalid", target, mcpu)
|
||||
if err == nil || err.Error() != "unsupported libc: invalid" {
|
||||
t.Errorf("Expected unsupported libc error, got: %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Picolibc", func(t *testing.T) {
|
||||
cfg, err := getLibcCompileConfigByName(baseDir, "picolibc", target, mcpu)
|
||||
_, cfg, err := getLibcCompileConfigByName(baseDir, "picolibc", target, mcpu)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
@@ -38,19 +44,19 @@ func TestGetLibcCompileConfigByName(t *testing.T) {
|
||||
}
|
||||
group := cfg.Groups[0]
|
||||
|
||||
expectedFile := filepath.Join(baseDir, "picolibc", "newlib", "libc", "string", "memmem.c")
|
||||
expectedFile := filepath.Join(baseDir, libc.GetPicolibcConfig().String(), "newlib", "libc", "string", "memmem.c")
|
||||
if !slices.Contains(group.Files, expectedFile) {
|
||||
t.Errorf("Expected files [%s], got: %v", expectedFile, group.Files)
|
||||
}
|
||||
|
||||
expectedFlag := "-I" + filepath.Join("/test", "base", "picolibc")
|
||||
expectedFlag := "-I" + filepath.Join("/test", "base", libc.GetPicolibcConfig().String())
|
||||
if !slices.Contains(group.CFlags, expectedFlag) {
|
||||
t.Errorf("Expected flags [%s], got: %v", expectedFlag, group.CFlags)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("NewlibESP32", func(t *testing.T) {
|
||||
cfg, err := getLibcCompileConfigByName(baseDir, "newlib-esp32", target, mcpu)
|
||||
_, cfg, err := getLibcCompileConfigByName(baseDir, "newlib-esp32", target, mcpu)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
@@ -60,12 +66,12 @@ func TestGetLibcCompileConfigByName(t *testing.T) {
|
||||
}
|
||||
group := cfg.Groups[0]
|
||||
|
||||
expectedFile := filepath.Join(baseDir, "newlib-esp32", "libgloss", "xtensa", "crt1-boards.S")
|
||||
expectedFile := filepath.Join(baseDir, libc.GetNewlibESP32Config().String(), "libgloss", "xtensa", "crt1-boards.S")
|
||||
if !slices.Contains(group.Files, expectedFile) {
|
||||
t.Errorf("Expected files [%s], got: %v", expectedFile, group.Files)
|
||||
}
|
||||
|
||||
expectedFlags := "-I" + filepath.Join(baseDir, "newlib-esp32", "libgloss")
|
||||
expectedFlags := "-I" + filepath.Join(baseDir, libc.GetNewlibESP32Config().String(), "libgloss")
|
||||
if !slices.Contains(group.CFlags, expectedFlags) {
|
||||
t.Errorf("Expected flags %v, got: %v", expectedFlags, group.CFlags)
|
||||
}
|
||||
@@ -75,23 +81,24 @@ func TestGetLibcCompileConfigByName(t *testing.T) {
|
||||
func TestGetRTCompileConfigByName(t *testing.T) {
|
||||
baseDir := "/test/base"
|
||||
target := "wasm32"
|
||||
needSkipDownload = true
|
||||
|
||||
t.Run("EmptyName", func(t *testing.T) {
|
||||
_, err := getRTCompileConfigByName(baseDir, "", target)
|
||||
_, _, err := getRTCompileConfigByName(baseDir, "", target)
|
||||
if err == nil || err.Error() != "rt name cannot be empty" {
|
||||
t.Errorf("Expected empty name error, got: %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("UnsupportedRT", func(t *testing.T) {
|
||||
_, err := getRTCompileConfigByName(baseDir, "invalid", target)
|
||||
_, _, err := getRTCompileConfigByName(baseDir, "invalid", target)
|
||||
if err == nil || err.Error() != "unsupported rt: invalid" {
|
||||
t.Errorf("Expected unsupported rt error, got: %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("CompilerRT", func(t *testing.T) {
|
||||
cfg, err := getRTCompileConfigByName(baseDir, "compiler-rt", target)
|
||||
_, cfg, err := getRTCompileConfigByName(baseDir, "compiler-rt", target)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
@@ -101,9 +108,302 @@ func TestGetRTCompileConfigByName(t *testing.T) {
|
||||
}
|
||||
group := cfg.Groups[0]
|
||||
|
||||
expectedFile := filepath.Join(baseDir, "compiler-rt", "lib", "builtins", "absvdi2.c")
|
||||
expectedFile := filepath.Join(baseDir, rtlib.GetCompilerRTConfig().String(), "lib", "builtins", "absvdi2.c")
|
||||
if !slices.Contains(group.Files, expectedFile) {
|
||||
t.Errorf("Expected files [%s], got: %v", expectedFile, group.Files)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// TestCompilerRTCompileConfigPaths tests that file paths in the CompileConfig
|
||||
// are correctly based on the provided baseDir for various target platforms.
|
||||
func TestCompilerRTCompileConfigPaths(t *testing.T) {
|
||||
// Define test cases for different target platforms
|
||||
tests := []struct {
|
||||
name string // Test case name
|
||||
baseDir string // Input base directory
|
||||
target string // Target platform
|
||||
expected string // Expected platform-specific file
|
||||
}{
|
||||
{
|
||||
name: "RISC-V 32",
|
||||
baseDir: "/test/base/dir",
|
||||
target: "riscv32-unknown-elf",
|
||||
expected: "riscv/mulsi3.S", // Expected platform file for RISC-V 32
|
||||
},
|
||||
{
|
||||
name: "RISC-V 64",
|
||||
baseDir: "/another/dir",
|
||||
target: "riscv64-unknown-elf",
|
||||
expected: "addtf3.c", // Expected platform file for RISC-V 64
|
||||
},
|
||||
{
|
||||
name: "ARM",
|
||||
baseDir: "/arm/dir",
|
||||
target: "armv7-unknown-linux-gnueabihf",
|
||||
expected: "arm/aeabi_cdcmp.S", // Expected platform file for ARM
|
||||
},
|
||||
{
|
||||
name: "AVR",
|
||||
baseDir: "/avr/dir",
|
||||
target: "avr",
|
||||
expected: "avr/divmodhi4.S", // Expected platform file for AVR
|
||||
},
|
||||
{
|
||||
name: "XTENSA",
|
||||
baseDir: "/xtensa/dir",
|
||||
target: "xtensa",
|
||||
expected: "xtensa/ieee754_sqrtf.S", // Expected platform file for XTENSA
|
||||
},
|
||||
}
|
||||
needSkipDownload = true
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// Get the compile configuration for this target
|
||||
cfg := rtlib.GetCompilerRTCompileConfig(tt.baseDir, tt.target)
|
||||
|
||||
// Verify there is at least one compile group
|
||||
if len(cfg.Groups) == 0 {
|
||||
t.Fatal("CompileConfig has no groups")
|
||||
}
|
||||
|
||||
group := cfg.Groups[0]
|
||||
found := false
|
||||
|
||||
// Check all files in the group
|
||||
for _, file := range group.Files {
|
||||
// Verify file path starts with baseDir
|
||||
if !strings.HasPrefix(file, tt.baseDir) {
|
||||
t.Errorf("File path %q should start with baseDir %q", file, tt.baseDir)
|
||||
}
|
||||
|
||||
// Verify file path contains the expected platform-specific file
|
||||
if strings.Contains(file, tt.expected) {
|
||||
found = true
|
||||
|
||||
// Construct the expected full path
|
||||
expectedPath := filepath.Join(tt.baseDir, "lib", "builtins", tt.expected)
|
||||
|
||||
// Verify the actual path matches the expected path
|
||||
if file != expectedPath {
|
||||
t.Errorf("Expected file path %q, got %q", expectedPath, file)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Verify the platform-specific file was found
|
||||
if !found {
|
||||
t.Errorf("Expected platform-specific file %q not found in file list", tt.expected)
|
||||
}
|
||||
|
||||
// Verify the output file name format
|
||||
expectedOutput := fmt.Sprintf("libclang_builtins-%s.a", tt.target)
|
||||
if !strings.HasSuffix(group.OutputFileName, expectedOutput) {
|
||||
t.Errorf("OutputFileName should end with %q, got %q", expectedOutput, group.OutputFileName)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestCompilerRTCompileConfigPathRelations tests the general path relationships
|
||||
// in the CompileConfig for a specific target.
|
||||
func TestCompilerRTCompileConfigPathRelations(t *testing.T) {
|
||||
baseDir := "/test/base/dir"
|
||||
target := "riscv64-unknown-elf"
|
||||
|
||||
// Get the compile configuration
|
||||
cfg := rtlib.GetCompilerRTCompileConfig(baseDir, target)
|
||||
|
||||
// Verify there is at least one compile group
|
||||
if len(cfg.Groups) == 0 {
|
||||
t.Fatal("CompileConfig has no groups")
|
||||
}
|
||||
needSkipDownload = true
|
||||
|
||||
group := cfg.Groups[0]
|
||||
|
||||
// Check all files in the group
|
||||
for _, file := range group.Files {
|
||||
// Verify file path starts with baseDir
|
||||
if !strings.HasPrefix(file, baseDir) {
|
||||
t.Errorf("File path %q should start with baseDir %q", file, baseDir)
|
||||
}
|
||||
|
||||
// Verify file path contains the expected subdirectory structure
|
||||
expectedSubdir := filepath.Join(baseDir, "lib", "builtins")
|
||||
if !strings.Contains(file, expectedSubdir) {
|
||||
t.Errorf("File path %q should contain %q", file, expectedSubdir)
|
||||
}
|
||||
}
|
||||
|
||||
// Verify the output file name format
|
||||
expectedOutput := fmt.Sprintf("libclang_builtins-%s.a", target)
|
||||
if !strings.HasSuffix(group.OutputFileName, expectedOutput) {
|
||||
t.Errorf("OutputFileName should end with %q, got %q", expectedOutput, group.OutputFileName)
|
||||
}
|
||||
}
|
||||
|
||||
// TestGetPicolibcCompileConfigPaths tests that all paths in the CompileConfig
|
||||
// are correctly based on the provided baseDir.
|
||||
func TestGetPicolibcCompileConfigPaths(t *testing.T) {
|
||||
// Define test cases with different base directories
|
||||
tests := []struct {
|
||||
name string
|
||||
baseDir string
|
||||
target string
|
||||
}{
|
||||
{
|
||||
name: "Unix-like path",
|
||||
baseDir: "/test/base/dir",
|
||||
target: "riscv64-unknown-elf",
|
||||
},
|
||||
{
|
||||
name: "Windows-like path",
|
||||
baseDir: "C:\\test\\base\\dir",
|
||||
target: "x86_64-pc-windows-msvc",
|
||||
},
|
||||
{
|
||||
name: "Relative path",
|
||||
baseDir: "test/base/dir",
|
||||
target: "armv7-unknown-linux-gnueabihf",
|
||||
},
|
||||
}
|
||||
needSkipDownload = true
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// Get the compile configuration
|
||||
cfg := libc.GetPicolibcCompileConfig(tt.baseDir, tt.target)
|
||||
|
||||
// Verify ExportCFlags paths
|
||||
for _, flag := range cfg.ExportCFlags {
|
||||
if strings.HasPrefix(flag, "-I") || strings.HasPrefix(flag, "-isystem") {
|
||||
path := strings.TrimPrefix(flag, "-I")
|
||||
path = strings.TrimPrefix(path, "-isystem")
|
||||
path = strings.TrimSpace(path)
|
||||
|
||||
if !strings.HasPrefix(path, tt.baseDir) {
|
||||
t.Errorf("ExportCFlags path %q should start with baseDir %q", path, tt.baseDir)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Verify there is at least one compile group
|
||||
if len(cfg.Groups) == 0 {
|
||||
t.Fatal("CompileConfig has no groups")
|
||||
}
|
||||
|
||||
group := cfg.Groups[0]
|
||||
|
||||
// Verify output file name format
|
||||
expectedOutput := fmt.Sprintf("libc-%s.a", tt.target)
|
||||
if group.OutputFileName != expectedOutput {
|
||||
t.Errorf("Expected OutputFileName %q, got %q", expectedOutput, group.OutputFileName)
|
||||
}
|
||||
|
||||
// Verify all file paths start with baseDir
|
||||
for _, file := range group.Files {
|
||||
if !strings.HasPrefix(file, tt.baseDir) {
|
||||
t.Errorf("File path %q should start with baseDir %q", file, tt.baseDir)
|
||||
}
|
||||
|
||||
// Verify file path contains expected subdirectories
|
||||
if !strings.Contains(file, filepath.Join(tt.baseDir, "newlib")) {
|
||||
t.Errorf("File path %q should contain 'newlib' subdirectory", file)
|
||||
}
|
||||
}
|
||||
|
||||
// Verify CFlags paths
|
||||
for _, flag := range group.CFlags {
|
||||
if strings.HasPrefix(flag, "-I") {
|
||||
path := strings.TrimPrefix(flag, "-I")
|
||||
path = strings.TrimSpace(path)
|
||||
|
||||
if !strings.HasPrefix(path, tt.baseDir) {
|
||||
t.Errorf("CFlags path %q should start with baseDir %q", path, tt.baseDir)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestGetPicolibcCompileConfigSpecificPaths tests specific path constructions
|
||||
// in the CompileConfig for a given baseDir and target.
|
||||
func TestGetPicolibcCompileConfigSpecificPaths(t *testing.T) {
|
||||
baseDir := "/test/base/dir"
|
||||
target := "riscv64-unknown-elf"
|
||||
needSkipDownload = true
|
||||
|
||||
// Get the compile configuration
|
||||
cfg := libc.GetPicolibcCompileConfig(baseDir, target)
|
||||
|
||||
// Verify ExportCFlags
|
||||
expectedInclude := filepath.Join(baseDir, "newlib", "libc", "include")
|
||||
foundInclude := false
|
||||
for _, flag := range cfg.ExportCFlags {
|
||||
if flag == "-I"+baseDir || flag == "-isystem"+expectedInclude {
|
||||
foundInclude = true
|
||||
}
|
||||
}
|
||||
if !foundInclude {
|
||||
t.Errorf("Expected ExportCFlags to contain -I%s and -isystem%s", baseDir, expectedInclude)
|
||||
}
|
||||
|
||||
// Verify there is at least one compile group
|
||||
if len(cfg.Groups) == 0 {
|
||||
t.Fatal("CompileConfig has no groups")
|
||||
}
|
||||
|
||||
group := cfg.Groups[0]
|
||||
|
||||
// Verify output file name
|
||||
expectedOutput := fmt.Sprintf("libc-%s.a", target)
|
||||
if group.OutputFileName != expectedOutput {
|
||||
t.Errorf("Expected OutputFileName %q, got %q", expectedOutput, group.OutputFileName)
|
||||
}
|
||||
|
||||
// Verify specific file paths
|
||||
expectedFiles := []string{
|
||||
filepath.Join(baseDir, "newlib", "libc", "string", "memcpy.c"),
|
||||
filepath.Join(baseDir, "newlib", "libc", "string", "strlen.c"),
|
||||
filepath.Join(baseDir, "newlib", "libc", "stdlib", "nano-malloc.c"),
|
||||
filepath.Join(baseDir, "newlib", "libc", "tinystdio", "printf.c"),
|
||||
}
|
||||
|
||||
for _, expected := range expectedFiles {
|
||||
found := false
|
||||
for _, file := range group.Files {
|
||||
if file == expected {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
t.Errorf("Expected file %q not found in file list", expected)
|
||||
}
|
||||
}
|
||||
|
||||
// Verify CFlags paths
|
||||
expectedCFlags := []string{
|
||||
"-I" + baseDir,
|
||||
"-isystem" + filepath.Join(baseDir, "newlib", "libc", "include"),
|
||||
"-I" + filepath.Join(baseDir, "newlib", "libm", "common"),
|
||||
"-I" + filepath.Join(baseDir, "newlib", "libc", "locale"),
|
||||
"-I" + filepath.Join(baseDir, "newlib", "libc", "tinystdio"),
|
||||
}
|
||||
|
||||
for _, expected := range expectedCFlags {
|
||||
found := false
|
||||
for _, flag := range group.CFlags {
|
||||
if flag == expected {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
t.Errorf("Expected CFlag %q not found", expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user