Merge pull request #1384 from luoliwoshang/feature/export-different-names-1378

cl: support //export with different symbol names on embedded targets
This commit is contained in:
xushiwei
2025-11-17 08:10:09 +08:00
committed by GitHub
7 changed files with 395 additions and 9 deletions

View File

@@ -0,0 +1,67 @@
package main
import (
"github.com/goplus/lib/c"
)
// This demo shows how to use //export with different symbol names on embedded targets.
//
// On embedded targets, you can export Go functions with different C symbol names.
// This is useful for hardware interrupt handlers that require specific names.
// Standard Go export - same name
//
//export HelloWorld
func HelloWorld() {
c.Printf(c.Str("Hello from "))
c.Printf(c.Str("HelloWorld\n"))
}
// Embedded target export - different name
// Go function name: interruptLPSPI2
// Exported C symbol: LPSPI2_IRQHandler
//
//export LPSPI2_IRQHandler
func interruptLPSPI2() {
c.Printf(c.Str("LPSPI2 interrupt "))
c.Printf(c.Str("handler called\n"))
}
// Embedded target export - different name
// Go function name: systemTickHandler
// Exported C symbol: SysTick_Handler
//
//export SysTick_Handler
func systemTickHandler() {
c.Printf(c.Str("SysTick "))
c.Printf(c.Str("handler called\n"))
}
// Embedded target export - different name
// Go function name: Add
// Exported C symbol: AddFunc
//
//export AddFunc
func Add(a, b int) int {
result := a + b
c.Printf(c.Str("AddFunc(%d, %d) = %d\n"), a, b, result)
return result
}
func main() {
c.Printf(c.Str("=== Export Demo ===\n\n"))
// Call exported functions directly from Go
c.Printf(c.Str("Calling HelloWorld:\n"))
HelloWorld()
c.Printf(c.Str("\nSimulating hardware interrupts:\n"))
interruptLPSPI2()
systemTickHandler()
c.Printf(c.Str("\nTesting function with return value:\n"))
result := Add(10, 20)
c.Printf(c.Str("Result: %d\n"), result)
c.Printf(c.Str("\n=== Demo Complete ===\n"))
}

View File

@@ -0,0 +1,54 @@
#!/bin/bash
set -e
echo "Building for embedded target..."
# Build for embedded target as executable
# Use llgo directly instead of llgo.sh to avoid go.mod version check
llgo build -o test-verify --target=esp32 .
echo "Checking exported symbols..."
# Get exported symbols
exported_symbols=$(nm -gU ./test-verify.elf | grep -E "(HelloWorld|LPSPI2_IRQHandler|SysTick_Handler|AddFunc)" | awk '{print $NF}')
echo ""
echo "Exported symbols:"
echo "$exported_symbols" | awk '{print " " $0}'
echo ""
# Check expected symbols
expected=("HelloWorld" "LPSPI2_IRQHandler" "SysTick_Handler" "AddFunc")
missing=""
for symbol in "${expected[@]}"; do
if ! echo "$exported_symbols" | grep -q "^$symbol$"; then
missing="$missing $symbol"
fi
done
if [ -n "$missing" ]; then
echo "❌ Missing symbols:$missing"
exit 1
fi
echo "✅ Symbol name mapping verification:"
echo " HelloWorld -> HelloWorld"
echo " interruptLPSPI2 -> LPSPI2_IRQHandler"
echo " systemTickHandler -> SysTick_Handler"
echo " Add -> AddFunc"
echo ""
echo "🎉 All export symbols verified successfully!"
echo ""
echo "Testing that non-embedded target rejects different export names..."
# Build without --target should fail with panic
if llgo build -o test-notarget . 2>&1 | grep -q 'export comment has wrong name "LPSPI2_IRQHandler"'; then
echo "✅ Correctly rejected different export name on non-embedded target"
else
echo "❌ Should have panicked with 'export comment has wrong name' error"
exit 1
fi
echo ""
echo "Note: Different symbol names are only supported on embedded targets."