Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions _xtool/llcppsymg/internal/symg/symg.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ type Config struct {
}

func Do(conf *Config) (symbolTable []*llcppg.SymbolInfo, err error) {
symbols, err := fetchSymbols(conf.Libs, conf.libMode)
symbols, err := FetchSymbols(conf.Libs, conf.libMode)
if err != nil {
return
}
Expand Down Expand Up @@ -82,7 +82,7 @@ func Do(conf *Config) (symbolTable []*llcppg.SymbolInfo, err error) {
// libraries (like standard libs) are logged as warnings.
//
// Returns symbols and nil error if any symbols are found, or nil and error if none found.
func fetchSymbols(lib string, mode LibMode) ([]*nm.Symbol, error) {
func FetchSymbols(lib string, mode LibMode) ([]*nm.Symbol, error) {
if dbgSymbol {
fmt.Println("fetchSymbols:from", lib)
}
Expand Down
86 changes: 86 additions & 0 deletions _xtool/llcppsymg/internal/symg/symg_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"log"
"os"
"os/exec"
"path/filepath"
"reflect"
"runtime"
Expand All @@ -14,6 +15,7 @@ import (

"github.com/goplus/llcppg/_xtool/internal/clangtool"
"github.com/goplus/llcppg/_xtool/internal/header"
"github.com/goplus/llcppg/_xtool/internal/symbol"
"github.com/goplus/llcppg/_xtool/llcppsymg/internal/symg"
llcppg "github.com/goplus/llcppg/config"
"github.com/goplus/llcppg/internal/name"
Expand Down Expand Up @@ -537,3 +539,87 @@ func addSymbolPrefixUnder(name string, isCpp bool) string {
}
return prefix + name
}

func TestFetchSymbols(t *testing.T) {
tempDir, err := os.MkdirTemp("", "test_fetch_symbols_*")
if err != nil {
t.Fatal(err)
}
// todo(zzy): remove this after test,need llgo support
// defer os.RemoveAll(tempDir)

cSource := `
void test_function_1(void) {
return;
}

int test_function_2(int x) {
return x * 2;
}

const char* test_function_3(void) {
return "hello world";
}
`

cSourcePath := filepath.Join(tempDir, "test.c")
err = os.WriteFile(cSourcePath, []byte(cSource), os.ModePerm)
if err != nil {
t.Fatal(err)
}
defer os.Remove(cSourcePath)

var libPath string
var compileCmd []string
if runtime.GOOS == "darwin" {
libPath = filepath.Join(tempDir, "libtest.dylib")
compileCmd = []string{"clang", "-shared", "-fPIC", "-o", libPath, cSourcePath}
} else if runtime.GOOS == "linux" {
libPath = filepath.Join(tempDir, "libtest.so")
compileCmd = []string{"gcc", "-shared", "-fPIC", "-o", libPath, cSourcePath}
} else {
t.Skip("Unsupported platform for this test")
}

cmd := exec.Command(compileCmd[0], compileCmd[1:]...)
output, err := cmd.CombinedOutput()
if err != nil {
t.Fatalf("Failed to compile test library: %v\nOutput: %s", err, output)
}

if _, err := os.Stat(libPath); os.IsNotExist(err) {
t.Fatal("Dynamic library was not created")
}

libDir := tempDir
libFlag := fmt.Sprintf("-L%s -ltest", libDir)

symbols, err := symg.FetchSymbols(libFlag, symbol.ModeDynamic)
if err != nil {
t.Fatalf("FetchSymbols failed: %v", err)
}

if len(symbols) == 0 {
t.Fatal("No symbols found")
}

expectedSymbols := []string{"test_function_1", "test_function_2", "test_function_3"}
foundSymbols := make(map[string]bool)

for _, sym := range symbols {
// On Darwin, symbols have '_' prefix, so trim it
symName := sym.Name
if runtime.GOOS == "darwin" {
symName = strings.TrimPrefix(symName, "_")
}
foundSymbols[symName] = true
}

for _, expected := range expectedSymbols {
if !foundSymbols[expected] {
t.Errorf("Expected symbol %s not found in library symbols", expected)
}
}
Comment thread
MeteorsLiu marked this conversation as resolved.

t.Logf("Successfully found %d symbols including expected test functions", len(symbols))
}
Loading