feat: support compiler-rt

This commit is contained in:
Haolan
2025-08-29 11:30:25 +08:00
parent f3ecce86ee
commit 4639ee13e7
11 changed files with 497 additions and 119 deletions

View File

@@ -0,0 +1,99 @@
package compile
import (
"fmt"
"os"
"os/exec"
"path/filepath"
"slices"
"strings"
"github.com/goplus/llgo/internal/clang"
)
type CompileGroup struct {
OutputFileName string
Files []string // List of source files to compile
CFlags []string // C compiler flags
CCFlags []string
LDFlags []string // Linker flags
}
func (g CompileGroup) IsCompiled(outputDir string) bool {
archive := filepath.Join(outputDir, g.OutputFileName)
_, err := os.Stat(archive)
return !os.IsNotExist(err)
}
func (g CompileGroup) Compile(outputDir, cc, linkerName string, extraCCFlags, extraLDFlags []string) (err error) {
if g.IsCompiled(outputDir) {
return
}
tmpCompileDir, err := os.MkdirTemp("", "compile-group*")
if err != nil {
return
}
defer os.RemoveAll(tmpCompileDir)
compileLDFlags := append(slices.Clone(extraLDFlags), g.LDFlags...)
compileCCFlags := append(slices.Clone(extraCCFlags), g.CCFlags...)
cfg := clang.NewConfig(cc, compileCCFlags, g.CFlags, compileLDFlags, linkerName)
var objFiles []string
compiler := clang.NewCompiler(cfg)
compiler.Verbose = true
archive := filepath.Join(outputDir, g.OutputFileName)
fmt.Fprintf(os.Stderr, "Start to compile group %s to %s...\n", g.OutputFileName, archive)
for _, file := range g.Files {
var tempObjFile *os.File
tempObjFile, err = os.CreateTemp(tmpCompileDir, fmt.Sprintf("%s*.o", strings.ReplaceAll(file, string(os.PathSeparator), "-")))
if err != nil {
return
}
fmt.Fprintf(os.Stderr, "Compile file %s to %s...\n", file, tempObjFile.Name())
lang := "c"
if filepath.Ext(file) == ".S" {
lang = "assembler-with-cpp"
}
err = compiler.Compile("-o", tempObjFile.Name(), "-x", lang, "-c", file)
if err != nil {
return
}
objFiles = append(objFiles, tempObjFile.Name())
}
args := []string{"rcs", archive}
args = append(args, objFiles...)
ccDir := filepath.Dir(cc)
llvmAr := filepath.Join(ccDir, "llvm-ar")
cmd := exec.Command(llvmAr, args...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err = cmd.Run()
return
}
// CompileConfig represents compilation configuration
type CompileConfig struct {
Url string
Name string // compile name (e.g., "picolibc", "musl", "glibc")
Groups []CompileGroup
ArchiveSrcDir string
}
func (c CompileConfig) IsCompiled(outputDir string) bool {
for _, group := range c.Groups {
if !group.IsCompiled(outputDir) {
return false
}
}
return true
}

View File

@@ -1,20 +1,22 @@
package crosscompile
package libc
import (
"path/filepath"
"github.com/goplus/llgo/internal/crosscompile/compile"
)
// getNewlibESP32Config returns configuration for newlib esp32
func getNewlibESP32Config(baseDir, arch string) *compileLibcConfig {
func GetNewlibESP32Config(baseDir, arch string) *compile.CompileConfig {
libcDir := filepath.Join(baseDir, "newlib", "libc")
// headerFile, _ := os.Create(filepath.Join(baseDir, "picolibc.h"))
// headerFile.Close()
return &compileLibcConfig{
return &compile.CompileConfig{
Url: "https://github.com/MeteorsLiu/newlib-esp32/archive/refs/heads/esp-4.3.0.zip",
Name: "newlib-esp32",
Groups: []compileGroup{
Groups: []compile.CompileGroup{
{
OutputFileName: "libcrt0.a",
Files: []string{
@@ -23,7 +25,6 @@ func getNewlibESP32Config(baseDir, arch string) *compileLibcConfig {
filepath.Join(baseDir, "libgloss", "xtensa", "boards", "esp32", "board.c"),
filepath.Join(baseDir, "libgloss", "xtensa", "crt1-boards.S"),
filepath.Join(baseDir, "libgloss", "xtensa", "sleep.S"),
filepath.Join(baseDir, "libgloss", "xtensa", "window-vectors.S"),
},
CFlags: []string{
"-DHAVE_CONFIG_H",
@@ -974,7 +975,7 @@ func getNewlibESP32Config(baseDir, arch string) *compileLibcConfig {
"-I" + filepath.Join(libcDir, "posix"),
"-I" + filepath.Join(libcDir, "stdlib"),
},
LDFlags: []string{"-nostdlib", "-L" + baseDir, "-lgloss"},
LDFlags: []string{"-nostdlib"},
CCFlags: []string{
"-Oz",
"-fno-builtin",

View File

@@ -1,12 +1,14 @@
package crosscompile
package libc
import (
"os"
"path/filepath"
"github.com/goplus/llgo/internal/crosscompile/compile"
)
// getPicolibcConfig returns configuration for picolibc
func getPicolibcConfig(baseDir string) *compileLibcConfig {
func GetPicolibcConfig(baseDir string) *compile.CompileConfig {
libcIncludeDir := filepath.Join(baseDir, "libc", "include")
libmIncludeDir := filepath.Join(baseDir, "libm", "common")
localeIncludeDir := filepath.Join(baseDir, "libc", "locale")
@@ -16,10 +18,10 @@ func getPicolibcConfig(baseDir string) *compileLibcConfig {
headerFile, _ := os.Create(filepath.Join(baseDir, "picolibc.h"))
headerFile.Close()
return &compileLibcConfig{
return &compile.CompileConfig{
Url: "https://github.com/picolibc/picolibc/releases/download/1.8.10/picolibc-1.8.10.tar.xz",
Name: "picolibc",
Groups: []compileGroup{
Groups: []compile.CompileGroup{
{
OutputFileName: "libc.a",
Files: []string{

View File

@@ -0,0 +1,195 @@
package rtlib
import (
"path/filepath"
"github.com/goplus/llgo/internal/crosscompile/compile"
)
func GetCompilerRTConfig(baseDir, arch string) *compile.CompileConfig {
return &compile.CompileConfig{
Url: "https://github.com/MeteorsLiu/llvm-project/archive/refs/heads/compiler-rt.zip",
ArchiveSrcDir: "llvm-project-compiler-rt",
Groups: []compile.CompileGroup{
{
OutputFileName: "libclang_builtins.a",
Files: []string{
filepath.Join(baseDir, "lib", "builtins", "xtensa/ieee754_sqrtf.S"),
filepath.Join(baseDir, "lib", "builtins", "absvdi2.c"),
filepath.Join(baseDir, "lib", "builtins", "absvsi2.c"),
filepath.Join(baseDir, "lib", "builtins", "absvti2.c"),
filepath.Join(baseDir, "lib", "builtins", "adddf3.c"),
filepath.Join(baseDir, "lib", "builtins", "addsf3.c"),
filepath.Join(baseDir, "lib", "builtins", "addvdi3.c"),
filepath.Join(baseDir, "lib", "builtins", "addvsi3.c"),
filepath.Join(baseDir, "lib", "builtins", "addvti3.c"),
filepath.Join(baseDir, "lib", "builtins", "apple_versioning.c"),
filepath.Join(baseDir, "lib", "builtins", "ashldi3.c"),
filepath.Join(baseDir, "lib", "builtins", "ashlti3.c"),
filepath.Join(baseDir, "lib", "builtins", "ashrdi3.c"),
filepath.Join(baseDir, "lib", "builtins", "ashrti3.c"),
filepath.Join(baseDir, "lib", "builtins", "bswapdi2.c"),
filepath.Join(baseDir, "lib", "builtins", "bswapsi2.c"),
filepath.Join(baseDir, "lib", "builtins", "clzdi2.c"),
filepath.Join(baseDir, "lib", "builtins", "clzsi2.c"),
filepath.Join(baseDir, "lib", "builtins", "clzti2.c"),
filepath.Join(baseDir, "lib", "builtins", "cmpdi2.c"),
filepath.Join(baseDir, "lib", "builtins", "cmpti2.c"),
filepath.Join(baseDir, "lib", "builtins", "comparedf2.c"),
filepath.Join(baseDir, "lib", "builtins", "comparesf2.c"),
filepath.Join(baseDir, "lib", "builtins", "ctzdi2.c"),
filepath.Join(baseDir, "lib", "builtins", "ctzsi2.c"),
filepath.Join(baseDir, "lib", "builtins", "ctzti2.c"),
filepath.Join(baseDir, "lib", "builtins", "divdc3.c"),
filepath.Join(baseDir, "lib", "builtins", "divdf3.c"),
filepath.Join(baseDir, "lib", "builtins", "divdi3.c"),
filepath.Join(baseDir, "lib", "builtins", "divmoddi4.c"),
filepath.Join(baseDir, "lib", "builtins", "divmodsi4.c"),
filepath.Join(baseDir, "lib", "builtins", "divmodti4.c"),
filepath.Join(baseDir, "lib", "builtins", "divsc3.c"),
filepath.Join(baseDir, "lib", "builtins", "divsf3.c"),
filepath.Join(baseDir, "lib", "builtins", "divsi3.c"),
filepath.Join(baseDir, "lib", "builtins", "divti3.c"),
filepath.Join(baseDir, "lib", "builtins", "extendsfdf2.c"),
filepath.Join(baseDir, "lib", "builtins", "extendhfsf2.c"),
filepath.Join(baseDir, "lib", "builtins", "ffsdi2.c"),
filepath.Join(baseDir, "lib", "builtins", "ffssi2.c"),
filepath.Join(baseDir, "lib", "builtins", "ffsti2.c"),
filepath.Join(baseDir, "lib", "builtins", "fixdfdi.c"),
filepath.Join(baseDir, "lib", "builtins", "fixdfsi.c"),
filepath.Join(baseDir, "lib", "builtins", "fixdfti.c"),
filepath.Join(baseDir, "lib", "builtins", "fixsfdi.c"),
filepath.Join(baseDir, "lib", "builtins", "fixsfsi.c"),
filepath.Join(baseDir, "lib", "builtins", "fixsfti.c"),
filepath.Join(baseDir, "lib", "builtins", "fixunsdfdi.c"),
filepath.Join(baseDir, "lib", "builtins", "fixunsdfsi.c"),
filepath.Join(baseDir, "lib", "builtins", "fixunsdfti.c"),
filepath.Join(baseDir, "lib", "builtins", "fixunssfdi.c"),
filepath.Join(baseDir, "lib", "builtins", "fixunssfsi.c"),
filepath.Join(baseDir, "lib", "builtins", "fixunssfti.c"),
filepath.Join(baseDir, "lib", "builtins", "floatdidf.c"),
filepath.Join(baseDir, "lib", "builtins", "floatdisf.c"),
filepath.Join(baseDir, "lib", "builtins", "floatsidf.c"),
filepath.Join(baseDir, "lib", "builtins", "floatsisf.c"),
filepath.Join(baseDir, "lib", "builtins", "floattidf.c"),
filepath.Join(baseDir, "lib", "builtins", "floattisf.c"),
filepath.Join(baseDir, "lib", "builtins", "floatundidf.c"),
filepath.Join(baseDir, "lib", "builtins", "floatundisf.c"),
filepath.Join(baseDir, "lib", "builtins", "floatunsidf.c"),
filepath.Join(baseDir, "lib", "builtins", "floatunsisf.c"),
filepath.Join(baseDir, "lib", "builtins", "floatuntidf.c"),
filepath.Join(baseDir, "lib", "builtins", "floatuntisf.c"),
filepath.Join(baseDir, "lib", "builtins", "fp_mode.c"),
filepath.Join(baseDir, "lib", "builtins", "int_util.c"),
filepath.Join(baseDir, "lib", "builtins", "lshrdi3.c"),
filepath.Join(baseDir, "lib", "builtins", "lshrti3.c"),
filepath.Join(baseDir, "lib", "builtins", "moddi3.c"),
filepath.Join(baseDir, "lib", "builtins", "modsi3.c"),
filepath.Join(baseDir, "lib", "builtins", "modti3.c"),
filepath.Join(baseDir, "lib", "builtins", "muldc3.c"),
filepath.Join(baseDir, "lib", "builtins", "muldf3.c"),
filepath.Join(baseDir, "lib", "builtins", "muldi3.c"),
filepath.Join(baseDir, "lib", "builtins", "mulodi4.c"),
filepath.Join(baseDir, "lib", "builtins", "mulosi4.c"),
filepath.Join(baseDir, "lib", "builtins", "muloti4.c"),
filepath.Join(baseDir, "lib", "builtins", "mulsc3.c"),
filepath.Join(baseDir, "lib", "builtins", "mulsf3.c"),
filepath.Join(baseDir, "lib", "builtins", "multi3.c"),
filepath.Join(baseDir, "lib", "builtins", "mulvdi3.c"),
filepath.Join(baseDir, "lib", "builtins", "mulvsi3.c"),
filepath.Join(baseDir, "lib", "builtins", "mulvti3.c"),
filepath.Join(baseDir, "lib", "builtins", "negdf2.c"),
filepath.Join(baseDir, "lib", "builtins", "negdi2.c"),
filepath.Join(baseDir, "lib", "builtins", "negsf2.c"),
filepath.Join(baseDir, "lib", "builtins", "negti2.c"),
filepath.Join(baseDir, "lib", "builtins", "negvdi2.c"),
filepath.Join(baseDir, "lib", "builtins", "negvsi2.c"),
filepath.Join(baseDir, "lib", "builtins", "negvti2.c"),
filepath.Join(baseDir, "lib", "builtins", "os_version_check.c"),
filepath.Join(baseDir, "lib", "builtins", "paritydi2.c"),
filepath.Join(baseDir, "lib", "builtins", "paritysi2.c"),
filepath.Join(baseDir, "lib", "builtins", "parityti2.c"),
filepath.Join(baseDir, "lib", "builtins", "popcountdi2.c"),
filepath.Join(baseDir, "lib", "builtins", "popcountsi2.c"),
filepath.Join(baseDir, "lib", "builtins", "popcountti2.c"),
filepath.Join(baseDir, "lib", "builtins", "powidf2.c"),
filepath.Join(baseDir, "lib", "builtins", "powisf2.c"),
filepath.Join(baseDir, "lib", "builtins", "subdf3.c"),
filepath.Join(baseDir, "lib", "builtins", "subsf3.c"),
filepath.Join(baseDir, "lib", "builtins", "subvdi3.c"),
filepath.Join(baseDir, "lib", "builtins", "subvsi3.c"),
filepath.Join(baseDir, "lib", "builtins", "subvti3.c"),
filepath.Join(baseDir, "lib", "builtins", "trampoline_setup.c"),
filepath.Join(baseDir, "lib", "builtins", "truncdfhf2.c"),
filepath.Join(baseDir, "lib", "builtins", "truncdfsf2.c"),
filepath.Join(baseDir, "lib", "builtins", "truncsfhf2.c"),
filepath.Join(baseDir, "lib", "builtins", "ucmpdi2.c"),
filepath.Join(baseDir, "lib", "builtins", "ucmpti2.c"),
filepath.Join(baseDir, "lib", "builtins", "udivdi3.c"),
filepath.Join(baseDir, "lib", "builtins", "udivmoddi4.c"),
filepath.Join(baseDir, "lib", "builtins", "udivmodsi4.c"),
filepath.Join(baseDir, "lib", "builtins", "udivmodti4.c"),
filepath.Join(baseDir, "lib", "builtins", "udivsi3.c"),
filepath.Join(baseDir, "lib", "builtins", "udivti3.c"),
filepath.Join(baseDir, "lib", "builtins", "umoddi3.c"),
filepath.Join(baseDir, "lib", "builtins", "umodsi3.c"),
filepath.Join(baseDir, "lib", "builtins", "umodti3.c"),
filepath.Join(baseDir, "lib", "builtins", "gcc_personality_v0.c"),
filepath.Join(baseDir, "lib", "builtins", "clear_cache.c"),
filepath.Join(baseDir, "lib", "builtins", "addtf3.c"),
filepath.Join(baseDir, "lib", "builtins", "comparetf2.c"),
filepath.Join(baseDir, "lib", "builtins", "divtc3.c"),
filepath.Join(baseDir, "lib", "builtins", "divtf3.c"),
filepath.Join(baseDir, "lib", "builtins", "extenddftf2.c"),
filepath.Join(baseDir, "lib", "builtins", "extendhftf2.c"),
filepath.Join(baseDir, "lib", "builtins", "extendsftf2.c"),
filepath.Join(baseDir, "lib", "builtins", "fixtfdi.c"),
filepath.Join(baseDir, "lib", "builtins", "fixtfsi.c"),
filepath.Join(baseDir, "lib", "builtins", "fixtfti.c"),
filepath.Join(baseDir, "lib", "builtins", "fixunstfdi.c"),
filepath.Join(baseDir, "lib", "builtins", "fixunstfsi.c"),
filepath.Join(baseDir, "lib", "builtins", "fixunstfti.c"),
filepath.Join(baseDir, "lib", "builtins", "floatditf.c"),
filepath.Join(baseDir, "lib", "builtins", "floatsitf.c"),
filepath.Join(baseDir, "lib", "builtins", "floattitf.c"),
filepath.Join(baseDir, "lib", "builtins", "floatunditf.c"),
filepath.Join(baseDir, "lib", "builtins", "floatunsitf.c"),
filepath.Join(baseDir, "lib", "builtins", "floatuntitf.c"),
filepath.Join(baseDir, "lib", "builtins", "multc3.c"),
filepath.Join(baseDir, "lib", "builtins", "multf3.c"),
filepath.Join(baseDir, "lib", "builtins", "powitf2.c"),
filepath.Join(baseDir, "lib", "builtins", "subtf3.c"),
filepath.Join(baseDir, "lib", "builtins", "trunctfdf2.c"),
filepath.Join(baseDir, "lib", "builtins", "trunctfhf2.c"),
filepath.Join(baseDir, "lib", "builtins", "trunctfsf2.c"),
},
CFlags: []string{
"-DNDEBUG",
"-DVISIBILITY_HIDDEN",
},
CCFlags: []string{
"-Oz",
"-fno-ident",
"-Wno-unused-parameter",
"-fno-lto",
"-Werror=array-bounds",
"-Werror=uninitialized",
"-Werror=shadow",
"-Werror=empty-body",
"-Werror=sizeof-pointer-memaccess",
"-Werror=sizeof-array-argument",
"-Werror=suspicious-memaccess",
"-Werror=builtin-memcpy-chk-size",
"-Werror=array-bounds-pointer-arithmetic",
"-Werror=return-stack-address",
"-Werror=sizeof-array-decay",
"-Werror=format-insufficient-args",
"-Wformat -std=c11",
"-fno-builtin",
"-fvisibility=hidden",
"-fomit-frame-pointer",
},
},
},
}
}

View File

@@ -10,6 +10,7 @@ import (
"runtime"
"strings"
"github.com/goplus/llgo/internal/crosscompile/compile"
"github.com/goplus/llgo/internal/env"
"github.com/goplus/llgo/internal/targets"
"github.com/goplus/llgo/internal/xtool/llvm"
@@ -219,15 +220,8 @@ func ldFlagsFromFileName(fileName string) string {
return strings.TrimPrefix(strings.TrimSuffix(fileName, ".a"), "lib")
}
func getOrCompileLibc(cc, linkerName, libcName string, exportCCFlags, exportLDFlags []string) (ldflags []string, err error) {
baseDir := filepath.Join(cacheRoot(), "crosscompile")
outputDir := filepath.Join(baseDir, libcName)
compileConfig, err := getCompileLibcConfigByName(baseDir, libcName)
if err != nil {
return
}
if err = checkDownloadAndExtractLibc(compileConfig, compileConfig.Url, outputDir, compileConfig.ArchiveSrcDir); err != nil {
func getOrCompileWithConfig(compileConfig *compile.CompileConfig, outputDir, cc, linkerName, libName string, exportCCFlags, exportLDFlags []string) (ldflags []string, err error) {
if err = checkDownloadAndExtractLib(compileConfig, compileConfig.Url, outputDir, compileConfig.ArchiveSrcDir); err != nil {
return
}
ldflags = append(ldflags, "-nostdlib", "-L"+outputDir)
@@ -606,13 +600,38 @@ func useTarget(targetName string) (export Export, err error) {
if config.Libc != "" {
var libcLDFlags []string
libcLDFlags, err = getOrCompileLibc(export.CC, export.Linker, config.Libc, ccflags, ldflags)
var compileConfig *compile.CompileConfig
baseDir := filepath.Join(cacheRoot(), "crosscompile")
outputDir := filepath.Join(baseDir, config.Libc)
compileConfig, err = getLibcCompileConfigByName(baseDir, config.Libc)
if err != nil {
return
}
libcLDFlags, err = getOrCompileWithConfig(compileConfig, outputDir, export.CC, export.Linker, config.Libc, ccflags, ldflags)
if err != nil {
return
}
ldflags = append(ldflags, libcLDFlags...)
}
if config.RTLib != "" {
var rtLibLDFlags []string
var compileConfig *compile.CompileConfig
baseDir := filepath.Join(cacheRoot(), "crosscompile")
outputDir := filepath.Join(baseDir, config.RTLib)
compileConfig, err = getRTCompileConfigByName(baseDir, config.RTLib)
if err != nil {
return
}
rtLibLDFlags, err = getOrCompileWithConfig(compileConfig, outputDir, export.CC, export.Linker, config.RTLib, ccflags, ldflags)
if err != nil {
return
}
ldflags = append(ldflags, rtLibLDFlags...)
}
// Combine with config flags and expand template variables
export.CFLAGS = cflags
export.CCFLAGS = ccflags

View File

@@ -13,6 +13,8 @@ import (
"path/filepath"
"strings"
"syscall"
"github.com/goplus/llgo/internal/crosscompile/compile"
)
// checkDownloadAndExtractWasiSDK downloads and extracts WASI SDK
@@ -80,7 +82,7 @@ func checkDownloadAndExtractESPClang(platformSuffix, dir string) error {
return nil
}
func checkDownloadAndExtractLibc(cfg *compileLibcConfig, url, dstDir, internalArchiveSrcDir string) error {
func checkDownloadAndExtractLib(cfg *compile.CompileConfig, url, dstDir, internalArchiveSrcDir string) error {
// Check if already exists
if cfg.IsCompiled(dstDir) {
return nil
@@ -107,7 +109,7 @@ func checkDownloadAndExtractLibc(cfg *compileLibcConfig, url, dstDir, internalAr
if err := downloadAndExtractArchive(url, tempExtractDir, description); err != nil {
return err
}
// defer os.RemoveAll(tempExtractDir)
defer os.RemoveAll(tempExtractDir)
srcDir := tempExtractDir
@@ -115,6 +117,7 @@ func checkDownloadAndExtractLibc(cfg *compileLibcConfig, url, dstDir, internalAr
srcDir = filepath.Join(tempExtractDir, internalArchiveSrcDir)
}
os.RemoveAll(dstDir)
if err := os.Rename(srcDir, dstDir); err != nil {
return fmt.Errorf("failed to rename libc directory: %w", err)
}

View File

@@ -2,105 +2,16 @@ package crosscompile
import (
"fmt"
"os"
"os/exec"
"path/filepath"
"slices"
"strings"
"github.com/goplus/llgo/internal/clang"
"github.com/goplus/llgo/internal/crosscompile/compile"
"github.com/goplus/llgo/internal/crosscompile/compile/libc"
"github.com/goplus/llgo/internal/crosscompile/compile/rtlib"
)
type compileGroup struct {
OutputFileName string
Files []string // List of source files to compile
CFlags []string // C compiler flags specific to this libc
CCFlags []string
LDFlags []string // Linker flags
}
func (g compileGroup) IsCompiled(outputDir string) bool {
libcArchive := filepath.Join(outputDir, g.OutputFileName)
_, err := os.Stat(libcArchive)
return !os.IsNotExist(err)
}
func (g compileGroup) Compile(outputDir, cc, linkerName string, extraCCFlags, extraLDFlags []string) (err error) {
if g.IsCompiled(outputDir) {
return
}
tmpCompileDir, err := os.MkdirTemp("", "compile-libc-group*")
if err != nil {
return
}
defer os.RemoveAll(tmpCompileDir)
compileLDFlags := append(slices.Clone(extraLDFlags), g.LDFlags...)
compileCCFlags := append(slices.Clone(extraCCFlags), g.CCFlags...)
cfg := clang.NewConfig(cc, compileCCFlags, g.CFlags, compileLDFlags, linkerName)
var objFiles []string
compiler := clang.NewCompiler(cfg)
compiler.Verbose = true
libcArchive := filepath.Join(outputDir, g.OutputFileName)
fmt.Fprintf(os.Stderr, "Start to compile libc group %s to %s...\n", g.OutputFileName, libcArchive)
for _, file := range g.Files {
var tempObjFile *os.File
tempObjFile, err = os.CreateTemp(tmpCompileDir, fmt.Sprintf("%s*.o", strings.ReplaceAll(file, string(os.PathSeparator), "-")))
if err != nil {
return
}
fmt.Fprintf(os.Stderr, "Compile libc file %s to %s...\n", file, tempObjFile.Name())
lang := "c"
if filepath.Ext(file) == ".S" {
lang = "assembler-with-cpp"
}
err = compiler.Compile("-o", tempObjFile.Name(), "-x", lang, "-c", file)
if err != nil {
return
}
objFiles = append(objFiles, tempObjFile.Name())
}
args := []string{"rcs", libcArchive}
args = append(args, objFiles...)
ccDir := filepath.Dir(cc)
llvmAr := filepath.Join(ccDir, "llvm-ar")
cmd := exec.Command(llvmAr, args...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Run()
return
}
// CompileLibcConfig represents libc compilation configuration
type compileLibcConfig struct {
Url string
Name string // Libc name (e.g., "picolibc", "musl", "glibc")
Groups []compileGroup
ArchiveSrcDir string
}
func (c compileLibcConfig) IsCompiled(outputDir string) bool {
for _, group := range c.Groups {
if !group.IsCompiled(outputDir) {
return false
}
}
return true
}
// GetCompileLibcConfigByName retrieves libc compilation configuration by name
// GetCompileConfigByName retrieves libc compilation configuration by name
// Returns compilation file lists and corresponding cflags
func getCompileLibcConfigByName(baseDir, libcName string) (*compileLibcConfig, error) {
func getLibcCompileConfigByName(baseDir, libcName string) (*compile.CompileConfig, error) {
if libcName == "" {
return nil, fmt.Errorf("libc name cannot be empty")
}
@@ -108,10 +19,24 @@ func getCompileLibcConfigByName(baseDir, libcName string) (*compileLibcConfig, e
switch libcName {
case "picolibc":
return getPicolibcConfig(libcDir), nil
return libc.GetPicolibcConfig(libcDir), nil
case "newlib-esp32":
return getNewlibESP32Config(libcDir, "xtensa"), nil
return libc.GetNewlibESP32Config(libcDir, "xtensa"), nil
default:
return nil, fmt.Errorf("unsupported libc: %s", libcName)
}
}
func getRTCompileConfigByName(baseDir, rtName string) (*compile.CompileConfig, error) {
if rtName == "" {
return nil, fmt.Errorf("rt name cannot be empty")
}
rtDir := filepath.Join(baseDir, rtName)
switch rtName {
case "compiler-rt":
return rtlib.GetCompilerRTConfig(rtDir, "xtensa"), nil
default:
return nil, fmt.Errorf("unsupported rt: %s", rtName)
}
}