mirror of
https://github.com/goplus/llgo.git
synced 2025-09-26 19:51:21 +08:00
Merge branch 'main' of https://github.com/goplus/llgo into emb-runtime
This commit is contained in:
36
.github/actions/setup-deps/action.yml
vendored
36
.github/actions/setup-deps/action.yml
vendored
@@ -5,6 +5,10 @@ inputs:
|
||||
description: "LLVM version to install"
|
||||
required: true
|
||||
default: "19"
|
||||
install-llvm:
|
||||
description: "Whether to install LLVM"
|
||||
required: false
|
||||
default: "true"
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
@@ -14,9 +18,17 @@ runs:
|
||||
shell: bash
|
||||
run: |
|
||||
brew update
|
||||
brew install llvm@${{inputs.llvm-version}} lld@${{inputs.llvm-version}} bdw-gc openssl libffi libuv
|
||||
brew link --overwrite llvm@${{inputs.llvm-version}} lld@${{inputs.llvm-version}} libffi
|
||||
echo "$(brew --prefix llvm@${{inputs.llvm-version}})/bin" >> $GITHUB_PATH
|
||||
|
||||
# Install LLVM if requested
|
||||
if [[ "${{ inputs.install-llvm }}" == "true" ]]; then
|
||||
brew install llvm@${{inputs.llvm-version}} lld@${{inputs.llvm-version}}
|
||||
brew link --overwrite llvm@${{inputs.llvm-version}} lld@${{inputs.llvm-version}}
|
||||
echo "$(brew --prefix llvm@${{inputs.llvm-version}})/bin" >> $GITHUB_PATH
|
||||
fi
|
||||
|
||||
# Install common dependencies
|
||||
brew install bdw-gc openssl libffi libuv
|
||||
brew link --overwrite libffi
|
||||
|
||||
# Install optional deps for demos.
|
||||
#
|
||||
@@ -31,11 +43,19 @@ runs:
|
||||
if: runner.os == 'Linux'
|
||||
shell: bash
|
||||
run: |
|
||||
echo "deb http://apt.llvm.org/$(lsb_release -cs)/ llvm-toolchain-$(lsb_release -cs)-${{inputs.llvm-version}} main" | sudo tee /etc/apt/sources.list.d/llvm.list
|
||||
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y llvm-${{inputs.llvm-version}}-dev clang-${{inputs.llvm-version}} libclang-${{inputs.llvm-version}}-dev lld-${{inputs.llvm-version}} libunwind-${{inputs.llvm-version}}-dev libc++-${{inputs.llvm-version}}-dev pkg-config libgc-dev libssl-dev zlib1g-dev libffi-dev libcjson-dev libuv1-dev
|
||||
echo "PATH=/usr/lib/llvm-${{inputs.llvm-version}}/bin:$PATH" >> $GITHUB_ENV
|
||||
# Install LLVM if requested
|
||||
if [[ "${{ inputs.install-llvm }}" == "true" ]]; then
|
||||
echo "deb http://apt.llvm.org/$(lsb_release -cs)/ llvm-toolchain-$(lsb_release -cs)-${{inputs.llvm-version}} main" | sudo tee /etc/apt/sources.list.d/llvm.list
|
||||
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y llvm-${{inputs.llvm-version}}-dev clang-${{inputs.llvm-version}} libclang-${{inputs.llvm-version}}-dev lld-${{inputs.llvm-version}} libunwind-${{inputs.llvm-version}}-dev libc++-${{inputs.llvm-version}}-dev
|
||||
echo "PATH=/usr/lib/llvm-${{inputs.llvm-version}}/bin:$PATH" >> $GITHUB_ENV
|
||||
else
|
||||
sudo apt-get update
|
||||
fi
|
||||
|
||||
# Install common dependencies
|
||||
sudo apt-get install -y pkg-config libgc-dev libssl-dev zlib1g-dev libffi-dev libcjson-dev libuv1-dev
|
||||
|
||||
# Install optional deps for demos.
|
||||
#
|
||||
|
3
.github/actions/setup-goreleaser/action.yml
vendored
3
.github/actions/setup-goreleaser/action.yml
vendored
@@ -35,3 +35,6 @@ runs:
|
||||
- name: Check file
|
||||
run: tree .sysroot
|
||||
shell: bash
|
||||
- name: Get Esp clang
|
||||
run: bash .github/workflows/download_esp_clang.sh
|
||||
shell: bash
|
||||
|
14
.github/actions/test-helloworld/action.yml
vendored
14
.github/actions/test-helloworld/action.yml
vendored
@@ -38,7 +38,7 @@ runs:
|
||||
Hello, LLGo!
|
||||
Hello, LLGo!
|
||||
Hello LLGo by cpp/std.Str"
|
||||
OUTPUT=$(llgo run . 2>&1)
|
||||
OUTPUT=$(llgo run . 2>&1 | tee /dev/stderr)
|
||||
if echo "$OUTPUT" | grep -qF "$EXPECTED"; then
|
||||
echo "Basic test passed"
|
||||
else
|
||||
@@ -50,4 +50,14 @@ runs:
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#TODO(zzy): Test embed targets, need dispatch target dir
|
||||
cd ../..
|
||||
mkdir -p _test/emb && cd _test/emb
|
||||
cat > main.go << 'EOL'
|
||||
package main
|
||||
|
||||
func main() {
|
||||
}
|
||||
EOL
|
||||
llgo build -v -target esp32-coreboard-v2 -o demo.out .
|
||||
test -f demo.out.elf && echo "ESP32 cross-compilation test passed: demo.out.elf generated"
|
||||
exit $?
|
||||
|
67
.github/workflows/download_esp_clang.sh
vendored
Executable file
67
.github/workflows/download_esp_clang.sh
vendored
Executable file
@@ -0,0 +1,67 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
ESP_CLANG_VERSION="19.1.2_20250905-3"
|
||||
BASE_URL="https://github.com/goplus/espressif-llvm-project-prebuilt/releases/download/${ESP_CLANG_VERSION}"
|
||||
|
||||
get_esp_clang_platform() {
|
||||
local platform="$1"
|
||||
local os="${platform%-*}"
|
||||
local arch="${platform##*-}"
|
||||
|
||||
case "${os}" in
|
||||
"darwin")
|
||||
case "${arch}" in
|
||||
"amd64") echo "x86_64-apple-darwin" ;;
|
||||
"arm64") echo "aarch64-apple-darwin" ;;
|
||||
*) echo "Error: Unsupported darwin architecture: ${arch}" >&2; exit 1 ;;
|
||||
esac
|
||||
;;
|
||||
"linux")
|
||||
case "${arch}" in
|
||||
"amd64") echo "x86_64-linux-gnu" ;;
|
||||
"arm64") echo "aarch64-linux-gnu" ;;
|
||||
*) echo "Error: Unsupported linux architecture: ${arch}" >&2; exit 1 ;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
echo "Error: Unsupported OS: ${os}" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
get_filename() {
|
||||
local platform="$1"
|
||||
local platform_suffix=$(get_esp_clang_platform "${platform}")
|
||||
echo "clang-esp-${ESP_CLANG_VERSION}-${platform_suffix}.tar.xz"
|
||||
}
|
||||
|
||||
download_and_extract() {
|
||||
local platform="$1"
|
||||
local os="${platform%-*}"
|
||||
local arch="${platform##*-}"
|
||||
local filename=$(get_filename "${platform}")
|
||||
local download_url="${BASE_URL}/${filename}"
|
||||
|
||||
echo "Downloading ESP Clang for ${platform}..."
|
||||
echo " URL: ${download_url}"
|
||||
|
||||
mkdir -p ".sysroot/${os}/${arch}/crosscompile/clang"
|
||||
curl -fsSL "${download_url}" | tar -xJ -C ".sysroot/${os}/${arch}/crosscompile/clang" --strip-components=1
|
||||
|
||||
if [[ ! -f ".sysroot/${os}/${arch}/crosscompile/clang/bin/clang++" ]]; then
|
||||
echo "Error: clang++ not found in ${platform} toolchain"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "${platform} ESP Clang ready in .sysroot/${os}/${arch}/crosscompile/clang"
|
||||
}
|
||||
|
||||
echo "Downloading ESP Clang toolchain version ${ESP_CLANG_VERSION}..."
|
||||
|
||||
for platform in "darwin-amd64" "darwin-arm64" "linux-amd64" "linux-arm64"; do
|
||||
download_and_extract "${platform}"
|
||||
done
|
||||
|
||||
echo "ESP Clang toolchain completed successfully!"
|
5
.github/workflows/populate_linux_sysroot.sh
vendored
5
.github/workflows/populate_linux_sysroot.sh
vendored
@@ -139,7 +139,10 @@ populate_linux_sysroot() {
|
||||
/populate_linux_sysroot.sh
|
||||
}
|
||||
populate_linux_sysroot amd64 "${LINUX_AMD64_PREFIX}" &
|
||||
PID1=$!
|
||||
populate_linux_sysroot arm64 "${LINUX_ARM64_PREFIX}" &
|
||||
PID2=$!
|
||||
|
||||
# Wait for both background processes to complete
|
||||
wait
|
||||
wait $PID1 || exit $?
|
||||
wait $PID2 || exit $?
|
||||
|
16
.github/workflows/release-build.yml
vendored
16
.github/workflows/release-build.yml
vendored
@@ -23,11 +23,10 @@ jobs:
|
||||
- name: Calculate cache keys
|
||||
id: cache-keys
|
||||
run: |
|
||||
DARWIN_KEY="darwin-sysroot-${{ hashFiles('.github/workflows/populate_darwin_sysroot.sh', '.github/workflows/release-build.yml') }}"
|
||||
LINUX_KEY="linux-sysroot-${{ hashFiles('.github/workflows/populate_linux_sysroot.sh', '.github/workflows/release-build.yml') }}"
|
||||
DARWIN_KEY="darwin-sysroot-${{ hashFiles('.github/workflows/populate_darwin_sysroot.sh', '.github/workflows/release-build.yml') }}-v1.0.0"
|
||||
LINUX_KEY="linux-sysroot-${{ hashFiles('.github/workflows/populate_linux_sysroot.sh', '.github/workflows/release-build.yml') }}-v1.0.0"
|
||||
echo "darwin-key=$DARWIN_KEY" >> $GITHUB_OUTPUT
|
||||
echo "linux-key=$LINUX_KEY" >> $GITHUB_OUTPUT
|
||||
|
||||
populate-darwin-sysroot:
|
||||
runs-on: macos-latest
|
||||
timeout-minutes: 30
|
||||
@@ -107,7 +106,7 @@ jobs:
|
||||
-v $(pwd):/go/src/llgo \
|
||||
-w /go/src/llgo \
|
||||
ghcr.io/goreleaser/goreleaser-cross:v1.22 \
|
||||
release --skip=publish,nfpm,snapcraft --snapshot --clean
|
||||
release --verbose --skip=publish,nfpm,snapcraft --snapshot --clean
|
||||
|
||||
- name: Upload Darwin AMD64 Artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
@@ -179,8 +178,10 @@ jobs:
|
||||
- uses: actions/checkout@v5
|
||||
- name: Install dependencies
|
||||
uses: ./.github/actions/setup-deps
|
||||
with:
|
||||
install-llvm: false
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: ${{ matrix.go-version }}
|
||||
- name: Download Platform Artifact
|
||||
@@ -205,7 +206,8 @@ jobs:
|
||||
mod-version: ${{ matrix.go-mod-version }}
|
||||
|
||||
release:
|
||||
needs: [setup, build, test-artifacts]
|
||||
needs:
|
||||
[setup, test-artifacts, populate-darwin-sysroot, populate-linux-sysroot]
|
||||
runs-on: ubuntu-latest
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
steps:
|
||||
@@ -231,4 +233,4 @@ jobs:
|
||||
-v $(pwd):/go/src/llgo \
|
||||
-w /go/src/llgo \
|
||||
ghcr.io/goreleaser/goreleaser-cross:v1.22 \
|
||||
release --clean --skip nfpm,snapcraft
|
||||
release --clean --verbose --skip nfpm,snapcraft
|
||||
|
@@ -23,12 +23,11 @@ builds:
|
||||
ldflags:
|
||||
- -X github.com/goplus/llgo/internal/env.buildVersion=v{{.Version}}
|
||||
- -X github.com/goplus/llgo/internal/env.buildTime={{.Date}}
|
||||
- -X github.com/goplus/llgo/xtool/env/llvm.ldLLVMConfigBin=/usr/local/opt/llvm@19/bin/llvm-config
|
||||
env:
|
||||
- CC=o64-clang
|
||||
- CXX=o64-clang++
|
||||
- CGO_CPPFLAGS=-I{{.Env.SYSROOT_DARWIN_AMD64}}/usr/local/opt/llvm@19/include -mmacosx-version-min=10.13 -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
|
||||
- CGO_LDFLAGS=-L{{.Env.SYSROOT_DARWIN_AMD64}}/usr/local/opt/llvm@19/lib -mmacosx-version-min=10.13 -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM-19 -lz -lm
|
||||
- CGO_CPPFLAGS=-I{{.Env.SYSROOT_DARWIN_AMD64}}/crosscompile/clang/include -mmacosx-version-min=10.13 -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
|
||||
- CGO_LDFLAGS=-L{{.Env.SYSROOT_DARWIN_AMD64}}/crosscompile/clang/lib -mmacosx-version-min=10.13 -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM-19 -lz -lm -Wl,-rpath,@executable_path/../crosscompile/clang/lib
|
||||
targets:
|
||||
- darwin_amd64
|
||||
mod_timestamp: "{{.CommitTimestamp}}"
|
||||
@@ -40,12 +39,11 @@ builds:
|
||||
ldflags:
|
||||
- -X github.com/goplus/llgo/internal/env.buildVersion=v{{.Version}}
|
||||
- -X github.com/goplus/llgo/internal/env.buildTime={{.Date}}
|
||||
- -X github.com/goplus/llgo/xtool/env/llvm.ldLLVMConfigBin=/opt/homebrew/opt/llvm@19/bin/llvm-config
|
||||
env:
|
||||
- CC=oa64-clang
|
||||
- CXX=oa64-clang++
|
||||
- CGO_CPPFLAGS=-I{{.Env.SYSROOT_DARWIN_ARM64}}/opt/homebrew/opt/llvm@19/include -mmacosx-version-min=10.13 -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
|
||||
- CGO_LDFLAGS=-L{{.Env.SYSROOT_DARWIN_ARM64}}/opt/homebrew/opt/llvm@19/lib -mmacosx-version-min=10.13 -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM-19 -lz -lm
|
||||
- CGO_CPPFLAGS=-I{{.Env.SYSROOT_DARWIN_ARM64}}/crosscompile/clang/include -mmacosx-version-min=10.13 -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
|
||||
- CGO_LDFLAGS=-L{{.Env.SYSROOT_DARWIN_ARM64}}/crosscompile/clang/lib -mmacosx-version-min=10.13 -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM-19 -lz -lm -Wl,-rpath,@executable_path/../crosscompile/clang/lib
|
||||
targets:
|
||||
- darwin_arm64
|
||||
mod_timestamp: "{{.CommitTimestamp}}"
|
||||
@@ -57,12 +55,13 @@ builds:
|
||||
ldflags:
|
||||
- -X github.com/goplus/llgo/internal/env.buildVersion=v{{.Version}}
|
||||
- -X github.com/goplus/llgo/internal/env.buildTime={{.Date}}
|
||||
- -X github.com/goplus/llgo/xtool/env/llvm.ldLLVMConfigBin=/usr/lib/llvm-19/bin/llvm-config
|
||||
- '-extldflags=-Wl,-rpath,$ORIGIN/../crosscompile/clang/lib'
|
||||
env:
|
||||
- CC=x86_64-linux-gnu-gcc
|
||||
- CXX=x86_64-linux-gnu-g++
|
||||
- CGO_CPPFLAGS=--sysroot={{.Env.SYSROOT_LINUX_AMD64}} -I{{.Env.SYSROOT_LINUX_AMD64}}/usr/include/llvm-19 -I{{.Env.SYSROOT_LINUX_AMD64}}/usr/include/llvm-c-19 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
|
||||
- CGO_LDFLAGS=--sysroot={{.Env.SYSROOT_LINUX_AMD64}} -L{{.Env.SYSROOT_LINUX_AMD64}}/usr/lib/llvm-19/lib -lLLVM-19
|
||||
- CGO_CPPFLAGS=--sysroot={{.Env.SYSROOT_LINUX_AMD64}} -I{{.Env.SYSROOT_LINUX_AMD64}}/crosscompile/clang/include -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
|
||||
- CGO_LDFLAGS=--sysroot={{.Env.SYSROOT_LINUX_AMD64}} -L{{.Env.SYSROOT_LINUX_AMD64}}/crosscompile/clang/lib -lLLVM-19
|
||||
- CGO_LDFLAGS_ALLOW=--sysroot.*
|
||||
targets:
|
||||
- linux_amd64
|
||||
mod_timestamp: "{{.CommitTimestamp}}"
|
||||
@@ -74,12 +73,13 @@ builds:
|
||||
ldflags:
|
||||
- -X github.com/goplus/llgo/internal/env.buildVersion=v{{.Version}}
|
||||
- -X github.com/goplus/llgo/internal/env.buildTime={{.Date}}
|
||||
- -X github.com/goplus/llgo/xtool/env/llvm.ldLLVMConfigBin=/usr/lib/llvm-19/bin/llvm-config
|
||||
- '-extldflags=-Wl,-rpath,$ORIGIN/../crosscompile/clang/lib'
|
||||
env:
|
||||
- CC=aarch64-linux-gnu-gcc
|
||||
- CXX=aarch64-linux-gnu-g++
|
||||
- CGO_CPPFLAGS=--sysroot={{.Env.SYSROOT_LINUX_ARM64}} -I{{.Env.SYSROOT_LINUX_ARM64}}/usr/include/llvm-19 -I{{.Env.SYSROOT_LINUX_ARM64}}/usr/include/llvm-c-19 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
|
||||
- CGO_LDFLAGS=--sysroot={{.Env.SYSROOT_LINUX_ARM64}} -L{{.Env.SYSROOT_LINUX_ARM64}}/usr/lib/llvm-19/lib -lLLVM-19
|
||||
- CGO_CPPFLAGS=--sysroot={{.Env.SYSROOT_LINUX_ARM64}} -I{{.Env.SYSROOT_LINUX_ARM64}}/crosscompile/clang/include -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
|
||||
- CGO_LDFLAGS=--sysroot={{.Env.SYSROOT_LINUX_ARM64}} -L{{.Env.SYSROOT_LINUX_ARM64}}/crosscompile/clang/lib -lLLVM-19
|
||||
- CGO_LDFLAGS_ALLOW=--sysroot.*
|
||||
targets:
|
||||
- linux_arm64
|
||||
mod_timestamp: "{{.CommitTimestamp}}"
|
||||
@@ -93,7 +93,11 @@ archives:
|
||||
- LICENSE
|
||||
- README.md
|
||||
- runtime
|
||||
|
||||
- targets
|
||||
- src: ".sysroot/{{.Os}}/{{.Arch}}/crosscompile/clang"
|
||||
dst: crosscompile/clang
|
||||
info:
|
||||
mode: 0755
|
||||
checksum:
|
||||
name_template: "{{.ProjectName}}{{.Version}}.checksums.txt"
|
||||
|
||||
|
44
cl/_testrt/vamethod/in.go
Normal file
44
cl/_testrt/vamethod/in.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/goplus/lib/c"
|
||||
)
|
||||
|
||||
type T c.Char
|
||||
|
||||
//go:linkname Printf C.printf
|
||||
func Printf(format *c.Char, __llgo_va_list ...any) c.Int
|
||||
|
||||
//llgo:link (*T).Printf C.printf
|
||||
func (*T) Printf(__llgo_va_list ...any) c.Int { return 0 }
|
||||
|
||||
type CFmt struct {
|
||||
*T
|
||||
}
|
||||
|
||||
func (f *CFmt) SetFormat(fmt *c.Char) {
|
||||
f.T = (*T)(unsafe.Pointer(fmt))
|
||||
}
|
||||
|
||||
type IFmt interface {
|
||||
SetFormat(fmt *c.Char)
|
||||
Printf(__llgo_va_list ...any) c.Int
|
||||
}
|
||||
|
||||
func main() {
|
||||
cfmt := &CFmt{}
|
||||
cfmt.SetFormat(c.Str("%s (%d)\n"))
|
||||
cfmt.Printf(c.Str("hello"), 100)
|
||||
cfmt.SetFormat(c.Str("(%d) %s\n"))
|
||||
cfmt.Printf(200, c.Str("world"))
|
||||
|
||||
var i any = &CFmt{}
|
||||
ifmt, ok := i.(IFmt)
|
||||
if !ok {
|
||||
panic("error")
|
||||
}
|
||||
ifmt.SetFormat(c.Str("%s (%d,%d)\n"))
|
||||
ifmt.Printf(c.Str("ifmt"), 100, 200)
|
||||
}
|
486
cl/_testrt/vamethod/out.ll
Normal file
486
cl/_testrt/vamethod/out.ll
Normal file
@@ -0,0 +1,486 @@
|
||||
; ModuleID = 'github.com/goplus/llgo/cl/_testrt/vamethod'
|
||||
source_filename = "github.com/goplus/llgo/cl/_testrt/vamethod"
|
||||
|
||||
%"github.com/goplus/llgo/cl/_testrt/vamethod.CFmt" = type { ptr }
|
||||
%"github.com/goplus/llgo/runtime/internal/runtime.eface" = type { ptr, ptr }
|
||||
%"github.com/goplus/llgo/runtime/internal/runtime.String" = type { ptr, i64 }
|
||||
%"github.com/goplus/llgo/runtime/internal/runtime.iface" = type { ptr, ptr }
|
||||
%"github.com/goplus/llgo/runtime/internal/runtime.Slice" = type { ptr, i64, i64 }
|
||||
%"github.com/goplus/llgo/runtime/abi.Method" = type { %"github.com/goplus/llgo/runtime/internal/runtime.String", ptr, ptr, ptr }
|
||||
%"github.com/goplus/llgo/runtime/abi.StructField" = type { %"github.com/goplus/llgo/runtime/internal/runtime.String", ptr, i64, %"github.com/goplus/llgo/runtime/internal/runtime.String", i1 }
|
||||
%"github.com/goplus/llgo/runtime/abi.Imethod" = type { %"github.com/goplus/llgo/runtime/internal/runtime.String", ptr }
|
||||
|
||||
@"github.com/goplus/llgo/cl/_testrt/vamethod.init$guard" = global i1 false, align 1
|
||||
@0 = private unnamed_addr constant [9 x i8] c"%s (%d)\0A\00", align 1
|
||||
@1 = private unnamed_addr constant [6 x i8] c"hello\00", align 1
|
||||
@2 = private unnamed_addr constant [9 x i8] c"(%d) %s\0A\00", align 1
|
||||
@3 = private unnamed_addr constant [6 x i8] c"world\00", align 1
|
||||
@"_llgo_github.com/goplus/llgo/cl/_testrt/vamethod.CFmt" = linkonce global ptr null, align 8
|
||||
@4 = private unnamed_addr constant [42 x i8] c"github.com/goplus/llgo/cl/_testrt/vamethod", align 1
|
||||
@5 = private unnamed_addr constant [4 x i8] c"CFmt", align 1
|
||||
@"_llgo_github.com/goplus/llgo/cl/_testrt/vamethod.T" = linkonce global ptr null, align 8
|
||||
@6 = private unnamed_addr constant [1 x i8] c"T", align 1
|
||||
@_llgo_int8 = linkonce global ptr null, align 8
|
||||
@7 = private unnamed_addr constant [6 x i8] c"Printf", align 1
|
||||
@_llgo_any = linkonce global ptr null, align 8
|
||||
@"[]_llgo_any" = linkonce global ptr null, align 8
|
||||
@_llgo_int32 = linkonce global ptr null, align 8
|
||||
@"_llgo_func$sSO5Bw-E3E7TeJqIJF_OmmojTYyqWBhYrUwNYJNw7Bs" = linkonce global ptr null, align 8
|
||||
@"*_llgo_github.com/goplus/llgo/cl/_testrt/vamethod.T" = linkonce global ptr null, align 8
|
||||
@"_llgo_struct$quUppefyumGvUA5WNkqjeO0PomZGx9OI8NFZ2pfWLXw" = linkonce global ptr null, align 8
|
||||
@8 = private unnamed_addr constant [9 x i8] c"SetFormat", align 1
|
||||
@"*_llgo_int8" = linkonce global ptr null, align 8
|
||||
@"_llgo_func$vAfTC3ZLX0_lZI-ZNliu0_DkE266FSmKXxj_cqKPPkA" = linkonce global ptr null, align 8
|
||||
@"*_llgo_github.com/goplus/llgo/cl/_testrt/vamethod.CFmt" = linkonce global ptr null, align 8
|
||||
@"_llgo_github.com/goplus/llgo/cl/_testrt/vamethod.IFmt" = linkonce global ptr null, align 8
|
||||
@9 = private unnamed_addr constant [4 x i8] c"IFmt", align 1
|
||||
@"_llgo_iface$a85zs5wWQQoPIERm_en8plssh4spdIeeXZPC-E0TDh0" = linkonce global ptr null, align 8
|
||||
@10 = private unnamed_addr constant [12 x i8] c"%s (%d,%d)\0A\00", align 1
|
||||
@11 = private unnamed_addr constant [5 x i8] c"ifmt\00", align 1
|
||||
@12 = private unnamed_addr constant [5 x i8] c"error", align 1
|
||||
@_llgo_string = linkonce global ptr null, align 8
|
||||
|
||||
define i32 @"github.com/goplus/llgo/cl/_testrt/vamethod.CFmt.Printf"(%"github.com/goplus/llgo/cl/_testrt/vamethod.CFmt" %0, ...) {
|
||||
_llgo_0:
|
||||
%1 = alloca %"github.com/goplus/llgo/cl/_testrt/vamethod.CFmt", align 8
|
||||
call void @llvm.memset(ptr %1, i8 0, i64 8, i1 false)
|
||||
store %"github.com/goplus/llgo/cl/_testrt/vamethod.CFmt" %0, ptr %1, align 8
|
||||
%2 = getelementptr inbounds %"github.com/goplus/llgo/cl/_testrt/vamethod.CFmt", ptr %1, i32 0, i32 0
|
||||
%3 = load ptr, ptr %2, align 8
|
||||
%4 = call i32 (ptr, ...) @printf(ptr %3)
|
||||
ret i32 %4
|
||||
}
|
||||
|
||||
define i32 @"github.com/goplus/llgo/cl/_testrt/vamethod.(*CFmt).Printf"(ptr %0, ...) {
|
||||
_llgo_0:
|
||||
%1 = getelementptr inbounds %"github.com/goplus/llgo/cl/_testrt/vamethod.CFmt", ptr %0, i32 0, i32 0
|
||||
%2 = load ptr, ptr %1, align 8
|
||||
%3 = call i32 (ptr, ...) @printf(ptr %2)
|
||||
ret i32 %3
|
||||
}
|
||||
|
||||
define void @"github.com/goplus/llgo/cl/_testrt/vamethod.(*CFmt).SetFormat"(ptr %0, ptr %1) {
|
||||
_llgo_0:
|
||||
%2 = getelementptr inbounds %"github.com/goplus/llgo/cl/_testrt/vamethod.CFmt", ptr %0, i32 0, i32 0
|
||||
store ptr %1, ptr %2, align 8
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @"github.com/goplus/llgo/cl/_testrt/vamethod.init"() {
|
||||
_llgo_0:
|
||||
%0 = load i1, ptr @"github.com/goplus/llgo/cl/_testrt/vamethod.init$guard", align 1
|
||||
br i1 %0, label %_llgo_2, label %_llgo_1
|
||||
|
||||
_llgo_1: ; preds = %_llgo_0
|
||||
store i1 true, ptr @"github.com/goplus/llgo/cl/_testrt/vamethod.init$guard", align 1
|
||||
call void @"github.com/goplus/llgo/cl/_testrt/vamethod.init$after"()
|
||||
br label %_llgo_2
|
||||
|
||||
_llgo_2: ; preds = %_llgo_1, %_llgo_0
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @"github.com/goplus/llgo/cl/_testrt/vamethod.main"() {
|
||||
_llgo_0:
|
||||
%0 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.AllocZ"(i64 8)
|
||||
call void @"github.com/goplus/llgo/cl/_testrt/vamethod.(*CFmt).SetFormat"(ptr %0, ptr @0)
|
||||
%1 = getelementptr inbounds %"github.com/goplus/llgo/cl/_testrt/vamethod.CFmt", ptr %0, i32 0, i32 0
|
||||
%2 = load ptr, ptr %1, align 8
|
||||
%3 = call i32 (ptr, ...) @printf(ptr %2, ptr @1, i64 100)
|
||||
call void @"github.com/goplus/llgo/cl/_testrt/vamethod.(*CFmt).SetFormat"(ptr %0, ptr @2)
|
||||
%4 = getelementptr inbounds %"github.com/goplus/llgo/cl/_testrt/vamethod.CFmt", ptr %0, i32 0, i32 0
|
||||
%5 = load ptr, ptr %4, align 8
|
||||
%6 = call i32 (ptr, ...) @printf(ptr %5, i64 200, ptr @3)
|
||||
%7 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.AllocZ"(i64 8)
|
||||
%8 = load ptr, ptr @"_llgo_github.com/goplus/llgo/cl/_testrt/vamethod.CFmt", align 8
|
||||
%9 = load ptr, ptr @"*_llgo_github.com/goplus/llgo/cl/_testrt/vamethod.CFmt", align 8
|
||||
%10 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.eface" undef, ptr %9, 0
|
||||
%11 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.eface" %10, ptr %7, 1
|
||||
%12 = extractvalue %"github.com/goplus/llgo/runtime/internal/runtime.eface" %11, 0
|
||||
%13 = load ptr, ptr @"_llgo_github.com/goplus/llgo/cl/_testrt/vamethod.IFmt", align 8
|
||||
%14 = call i1 @"github.com/goplus/llgo/runtime/internal/runtime.Implements"(ptr %13, ptr %12)
|
||||
br i1 %14, label %_llgo_3, label %_llgo_4
|
||||
|
||||
_llgo_1: ; preds = %_llgo_5
|
||||
%15 = load ptr, ptr @_llgo_string, align 8
|
||||
%16 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.AllocU"(i64 16)
|
||||
store %"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @12, i64 5 }, ptr %16, align 8
|
||||
%17 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.eface" undef, ptr %15, 0
|
||||
%18 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.eface" %17, ptr %16, 1
|
||||
call void @"github.com/goplus/llgo/runtime/internal/runtime.Panic"(%"github.com/goplus/llgo/runtime/internal/runtime.eface" %18)
|
||||
unreachable
|
||||
|
||||
_llgo_2: ; preds = %_llgo_5
|
||||
%19 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.IfacePtrData"(%"github.com/goplus/llgo/runtime/internal/runtime.iface" %44)
|
||||
%20 = extractvalue %"github.com/goplus/llgo/runtime/internal/runtime.iface" %44, 0
|
||||
%21 = getelementptr ptr, ptr %20, i64 4
|
||||
%22 = load ptr, ptr %21, align 8
|
||||
%23 = insertvalue { ptr, ptr } undef, ptr %22, 0
|
||||
%24 = insertvalue { ptr, ptr } %23, ptr %19, 1
|
||||
%25 = extractvalue { ptr, ptr } %24, 1
|
||||
%26 = extractvalue { ptr, ptr } %24, 0
|
||||
call void %26(ptr %25, ptr @10)
|
||||
%27 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.IfacePtrData"(%"github.com/goplus/llgo/runtime/internal/runtime.iface" %44)
|
||||
%28 = extractvalue %"github.com/goplus/llgo/runtime/internal/runtime.iface" %44, 0
|
||||
%29 = getelementptr ptr, ptr %28, i64 3
|
||||
%30 = load ptr, ptr %29, align 8
|
||||
%31 = insertvalue { ptr, ptr } undef, ptr %30, 0
|
||||
%32 = insertvalue { ptr, ptr } %31, ptr %27, 1
|
||||
%33 = extractvalue { ptr, ptr } %32, 1
|
||||
%34 = extractvalue { ptr, ptr } %32, 0
|
||||
%35 = call i32 (ptr, ...) %34(ptr %33, ptr @11, i64 100, i64 200)
|
||||
ret void
|
||||
|
||||
_llgo_3: ; preds = %_llgo_0
|
||||
%36 = extractvalue %"github.com/goplus/llgo/runtime/internal/runtime.eface" %11, 1
|
||||
%37 = load ptr, ptr @"_llgo_iface$a85zs5wWQQoPIERm_en8plssh4spdIeeXZPC-E0TDh0", align 8
|
||||
%38 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.NewItab"(ptr %37, ptr %12)
|
||||
%39 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.iface" undef, ptr %38, 0
|
||||
%40 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.iface" %39, ptr %36, 1
|
||||
%41 = insertvalue { %"github.com/goplus/llgo/runtime/internal/runtime.iface", i1 } undef, %"github.com/goplus/llgo/runtime/internal/runtime.iface" %40, 0
|
||||
%42 = insertvalue { %"github.com/goplus/llgo/runtime/internal/runtime.iface", i1 } %41, i1 true, 1
|
||||
br label %_llgo_5
|
||||
|
||||
_llgo_4: ; preds = %_llgo_0
|
||||
br label %_llgo_5
|
||||
|
||||
_llgo_5: ; preds = %_llgo_4, %_llgo_3
|
||||
%43 = phi { %"github.com/goplus/llgo/runtime/internal/runtime.iface", i1 } [ %42, %_llgo_3 ], [ zeroinitializer, %_llgo_4 ]
|
||||
%44 = extractvalue { %"github.com/goplus/llgo/runtime/internal/runtime.iface", i1 } %43, 0
|
||||
%45 = extractvalue { %"github.com/goplus/llgo/runtime/internal/runtime.iface", i1 } %43, 1
|
||||
br i1 %45, label %_llgo_2, label %_llgo_1
|
||||
}
|
||||
|
||||
; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: write)
|
||||
declare void @llvm.memset(ptr nocapture writeonly, i8, i64, i1 immarg) #0
|
||||
|
||||
declare i32 @printf(ptr, ...)
|
||||
|
||||
declare ptr @"github.com/goplus/llgo/runtime/internal/runtime.AllocZ"(i64)
|
||||
|
||||
define void @"github.com/goplus/llgo/cl/_testrt/vamethod.init$after"() {
|
||||
_llgo_0:
|
||||
%0 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.NewNamed"(%"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @4, i64 42 }, %"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @5, i64 4 }, i64 25, i64 8, i64 1, i64 2)
|
||||
%1 = load ptr, ptr @"_llgo_github.com/goplus/llgo/cl/_testrt/vamethod.CFmt", align 8
|
||||
%2 = icmp eq ptr %1, null
|
||||
br i1 %2, label %_llgo_1, label %_llgo_2
|
||||
|
||||
_llgo_1: ; preds = %_llgo_0
|
||||
call void @"github.com/goplus/llgo/runtime/internal/runtime.SetDirectIface"(ptr %0)
|
||||
store ptr %0, ptr @"_llgo_github.com/goplus/llgo/cl/_testrt/vamethod.CFmt", align 8
|
||||
br label %_llgo_2
|
||||
|
||||
_llgo_2: ; preds = %_llgo_1, %_llgo_0
|
||||
%3 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.NewNamed"(%"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @4, i64 42 }, %"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @6, i64 1 }, i64 3, i64 1, i64 0, i64 1)
|
||||
%4 = load ptr, ptr @"_llgo_github.com/goplus/llgo/cl/_testrt/vamethod.T", align 8
|
||||
%5 = icmp eq ptr %4, null
|
||||
br i1 %5, label %_llgo_3, label %_llgo_4
|
||||
|
||||
_llgo_3: ; preds = %_llgo_2
|
||||
store ptr %3, ptr @"_llgo_github.com/goplus/llgo/cl/_testrt/vamethod.T", align 8
|
||||
br label %_llgo_4
|
||||
|
||||
_llgo_4: ; preds = %_llgo_3, %_llgo_2
|
||||
%6 = load ptr, ptr @_llgo_int8, align 8
|
||||
%7 = icmp eq ptr %6, null
|
||||
br i1 %7, label %_llgo_5, label %_llgo_6
|
||||
|
||||
_llgo_5: ; preds = %_llgo_4
|
||||
%8 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.Basic"(i64 35)
|
||||
store ptr %8, ptr @_llgo_int8, align 8
|
||||
br label %_llgo_6
|
||||
|
||||
_llgo_6: ; preds = %_llgo_5, %_llgo_4
|
||||
%9 = load ptr, ptr @_llgo_int8, align 8
|
||||
br i1 %5, label %_llgo_7, label %_llgo_8
|
||||
|
||||
_llgo_7: ; preds = %_llgo_6
|
||||
%10 = load ptr, ptr @_llgo_any, align 8
|
||||
%11 = icmp eq ptr %10, null
|
||||
br i1 %11, label %_llgo_9, label %_llgo_10
|
||||
|
||||
_llgo_8: ; preds = %_llgo_16, %_llgo_6
|
||||
%12 = load ptr, ptr @"_llgo_github.com/goplus/llgo/cl/_testrt/vamethod.T", align 8
|
||||
%13 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.NewNamed"(%"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @4, i64 42 }, %"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @6, i64 1 }, i64 3, i64 1, i64 0, i64 1)
|
||||
%14 = load ptr, ptr @"*_llgo_github.com/goplus/llgo/cl/_testrt/vamethod.T", align 8
|
||||
%15 = icmp eq ptr %14, null
|
||||
br i1 %15, label %_llgo_17, label %_llgo_18
|
||||
|
||||
_llgo_9: ; preds = %_llgo_7
|
||||
%16 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.AllocU"(i64 0)
|
||||
%17 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" undef, ptr %16, 0
|
||||
%18 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" %17, i64 0, 1
|
||||
%19 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" %18, i64 0, 2
|
||||
%20 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.Interface"(%"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @4, i64 42 }, %"github.com/goplus/llgo/runtime/internal/runtime.Slice" %19)
|
||||
store ptr %20, ptr @_llgo_any, align 8
|
||||
br label %_llgo_10
|
||||
|
||||
_llgo_10: ; preds = %_llgo_9, %_llgo_7
|
||||
%21 = load ptr, ptr @_llgo_any, align 8
|
||||
%22 = load ptr, ptr @"[]_llgo_any", align 8
|
||||
%23 = icmp eq ptr %22, null
|
||||
br i1 %23, label %_llgo_11, label %_llgo_12
|
||||
|
||||
_llgo_11: ; preds = %_llgo_10
|
||||
%24 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.AllocU"(i64 0)
|
||||
%25 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" undef, ptr %24, 0
|
||||
%26 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" %25, i64 0, 1
|
||||
%27 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" %26, i64 0, 2
|
||||
%28 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.Interface"(%"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @4, i64 42 }, %"github.com/goplus/llgo/runtime/internal/runtime.Slice" %27)
|
||||
%29 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.SliceOf"(ptr %28)
|
||||
store ptr %29, ptr @"[]_llgo_any", align 8
|
||||
br label %_llgo_12
|
||||
|
||||
_llgo_12: ; preds = %_llgo_11, %_llgo_10
|
||||
%30 = load ptr, ptr @"[]_llgo_any", align 8
|
||||
%31 = load ptr, ptr @_llgo_int32, align 8
|
||||
%32 = icmp eq ptr %31, null
|
||||
br i1 %32, label %_llgo_13, label %_llgo_14
|
||||
|
||||
_llgo_13: ; preds = %_llgo_12
|
||||
%33 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.Basic"(i64 37)
|
||||
store ptr %33, ptr @_llgo_int32, align 8
|
||||
br label %_llgo_14
|
||||
|
||||
_llgo_14: ; preds = %_llgo_13, %_llgo_12
|
||||
%34 = load ptr, ptr @_llgo_int32, align 8
|
||||
%35 = load ptr, ptr @"[]_llgo_any", align 8
|
||||
%36 = load ptr, ptr @_llgo_int32, align 8
|
||||
%37 = load ptr, ptr @"_llgo_func$sSO5Bw-E3E7TeJqIJF_OmmojTYyqWBhYrUwNYJNw7Bs", align 8
|
||||
%38 = icmp eq ptr %37, null
|
||||
br i1 %38, label %_llgo_15, label %_llgo_16
|
||||
|
||||
_llgo_15: ; preds = %_llgo_14
|
||||
%39 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.AllocU"(i64 8)
|
||||
%40 = getelementptr ptr, ptr %39, i64 0
|
||||
store ptr %35, ptr %40, align 8
|
||||
%41 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" undef, ptr %39, 0
|
||||
%42 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" %41, i64 1, 1
|
||||
%43 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" %42, i64 1, 2
|
||||
%44 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.AllocU"(i64 8)
|
||||
%45 = getelementptr ptr, ptr %44, i64 0
|
||||
store ptr %36, ptr %45, align 8
|
||||
%46 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" undef, ptr %44, 0
|
||||
%47 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" %46, i64 1, 1
|
||||
%48 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" %47, i64 1, 2
|
||||
%49 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.Func"(%"github.com/goplus/llgo/runtime/internal/runtime.Slice" %43, %"github.com/goplus/llgo/runtime/internal/runtime.Slice" %48, i1 true)
|
||||
call void @"github.com/goplus/llgo/runtime/internal/runtime.SetDirectIface"(ptr %49)
|
||||
store ptr %49, ptr @"_llgo_func$sSO5Bw-E3E7TeJqIJF_OmmojTYyqWBhYrUwNYJNw7Bs", align 8
|
||||
br label %_llgo_16
|
||||
|
||||
_llgo_16: ; preds = %_llgo_15, %_llgo_14
|
||||
%50 = load ptr, ptr @"_llgo_func$sSO5Bw-E3E7TeJqIJF_OmmojTYyqWBhYrUwNYJNw7Bs", align 8
|
||||
%51 = insertvalue %"github.com/goplus/llgo/runtime/abi.Method" { %"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @7, i64 6 }, ptr undef, ptr undef, ptr undef }, ptr %50, 1
|
||||
%52 = insertvalue %"github.com/goplus/llgo/runtime/abi.Method" %51, ptr @printf, 2
|
||||
%53 = insertvalue %"github.com/goplus/llgo/runtime/abi.Method" %52, ptr @printf, 3
|
||||
%54 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.AllocU"(i64 40)
|
||||
%55 = getelementptr %"github.com/goplus/llgo/runtime/abi.Method", ptr %54, i64 0
|
||||
store %"github.com/goplus/llgo/runtime/abi.Method" %53, ptr %55, align 8
|
||||
%56 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" undef, ptr %54, 0
|
||||
%57 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" %56, i64 1, 1
|
||||
%58 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" %57, i64 1, 2
|
||||
call void @"github.com/goplus/llgo/runtime/internal/runtime.InitNamed"(ptr %3, ptr %9, { ptr, i64, i64 } zeroinitializer, %"github.com/goplus/llgo/runtime/internal/runtime.Slice" %58)
|
||||
br label %_llgo_8
|
||||
|
||||
_llgo_17: ; preds = %_llgo_8
|
||||
%59 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.PointerTo"(ptr %13)
|
||||
call void @"github.com/goplus/llgo/runtime/internal/runtime.SetDirectIface"(ptr %59)
|
||||
store ptr %59, ptr @"*_llgo_github.com/goplus/llgo/cl/_testrt/vamethod.T", align 8
|
||||
br label %_llgo_18
|
||||
|
||||
_llgo_18: ; preds = %_llgo_17, %_llgo_8
|
||||
%60 = load ptr, ptr @"*_llgo_github.com/goplus/llgo/cl/_testrt/vamethod.T", align 8
|
||||
%61 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.NewNamed"(%"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @4, i64 42 }, %"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @6, i64 1 }, i64 3, i64 1, i64 0, i64 1)
|
||||
%62 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.PointerTo"(ptr %61)
|
||||
%63 = call %"github.com/goplus/llgo/runtime/abi.StructField" @"github.com/goplus/llgo/runtime/internal/runtime.StructField"(%"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @6, i64 1 }, ptr %62, i64 0, %"github.com/goplus/llgo/runtime/internal/runtime.String" zeroinitializer, i1 true)
|
||||
%64 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.AllocU"(i64 56)
|
||||
%65 = getelementptr %"github.com/goplus/llgo/runtime/abi.StructField", ptr %64, i64 0
|
||||
store %"github.com/goplus/llgo/runtime/abi.StructField" %63, ptr %65, align 8
|
||||
%66 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" undef, ptr %64, 0
|
||||
%67 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" %66, i64 1, 1
|
||||
%68 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" %67, i64 1, 2
|
||||
%69 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.Struct"(%"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @4, i64 42 }, i64 8, %"github.com/goplus/llgo/runtime/internal/runtime.Slice" %68)
|
||||
call void @"github.com/goplus/llgo/runtime/internal/runtime.SetDirectIface"(ptr %69)
|
||||
store ptr %69, ptr @"_llgo_struct$quUppefyumGvUA5WNkqjeO0PomZGx9OI8NFZ2pfWLXw", align 8
|
||||
%70 = load ptr, ptr @"_llgo_struct$quUppefyumGvUA5WNkqjeO0PomZGx9OI8NFZ2pfWLXw", align 8
|
||||
br i1 %2, label %_llgo_19, label %_llgo_20
|
||||
|
||||
_llgo_19: ; preds = %_llgo_18
|
||||
%71 = load ptr, ptr @"_llgo_func$sSO5Bw-E3E7TeJqIJF_OmmojTYyqWBhYrUwNYJNw7Bs", align 8
|
||||
%72 = insertvalue %"github.com/goplus/llgo/runtime/abi.Method" { %"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @7, i64 6 }, ptr undef, ptr undef, ptr undef }, ptr %71, 1
|
||||
%73 = insertvalue %"github.com/goplus/llgo/runtime/abi.Method" %72, ptr @"github.com/goplus/llgo/cl/_testrt/vamethod.(*CFmt).Printf", 2
|
||||
%74 = insertvalue %"github.com/goplus/llgo/runtime/abi.Method" %73, ptr @"github.com/goplus/llgo/cl/_testrt/vamethod.(*CFmt).Printf", 3
|
||||
%75 = insertvalue %"github.com/goplus/llgo/runtime/abi.Method" { %"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @7, i64 6 }, ptr undef, ptr undef, ptr undef }, ptr %71, 1
|
||||
%76 = insertvalue %"github.com/goplus/llgo/runtime/abi.Method" %75, ptr @"github.com/goplus/llgo/cl/_testrt/vamethod.(*CFmt).Printf", 2
|
||||
%77 = insertvalue %"github.com/goplus/llgo/runtime/abi.Method" %76, ptr @"github.com/goplus/llgo/cl/_testrt/vamethod.CFmt.Printf", 3
|
||||
%78 = load ptr, ptr @_llgo_int8, align 8
|
||||
%79 = load ptr, ptr @"*_llgo_int8", align 8
|
||||
%80 = icmp eq ptr %79, null
|
||||
br i1 %80, label %_llgo_21, label %_llgo_22
|
||||
|
||||
_llgo_20: ; preds = %_llgo_24, %_llgo_18
|
||||
%81 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.NewNamed"(%"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @4, i64 42 }, %"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @5, i64 4 }, i64 25, i64 8, i64 1, i64 2)
|
||||
%82 = load ptr, ptr @"*_llgo_github.com/goplus/llgo/cl/_testrt/vamethod.CFmt", align 8
|
||||
%83 = icmp eq ptr %82, null
|
||||
br i1 %83, label %_llgo_25, label %_llgo_26
|
||||
|
||||
_llgo_21: ; preds = %_llgo_19
|
||||
%84 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.Basic"(i64 35)
|
||||
%85 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.PointerTo"(ptr %84)
|
||||
call void @"github.com/goplus/llgo/runtime/internal/runtime.SetDirectIface"(ptr %85)
|
||||
store ptr %85, ptr @"*_llgo_int8", align 8
|
||||
br label %_llgo_22
|
||||
|
||||
_llgo_22: ; preds = %_llgo_21, %_llgo_19
|
||||
%86 = load ptr, ptr @"*_llgo_int8", align 8
|
||||
%87 = load ptr, ptr @"*_llgo_int8", align 8
|
||||
%88 = load ptr, ptr @"_llgo_func$vAfTC3ZLX0_lZI-ZNliu0_DkE266FSmKXxj_cqKPPkA", align 8
|
||||
%89 = icmp eq ptr %88, null
|
||||
br i1 %89, label %_llgo_23, label %_llgo_24
|
||||
|
||||
_llgo_23: ; preds = %_llgo_22
|
||||
%90 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.AllocU"(i64 8)
|
||||
%91 = getelementptr ptr, ptr %90, i64 0
|
||||
store ptr %87, ptr %91, align 8
|
||||
%92 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" undef, ptr %90, 0
|
||||
%93 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" %92, i64 1, 1
|
||||
%94 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" %93, i64 1, 2
|
||||
%95 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.AllocU"(i64 0)
|
||||
%96 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" undef, ptr %95, 0
|
||||
%97 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" %96, i64 0, 1
|
||||
%98 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" %97, i64 0, 2
|
||||
%99 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.Func"(%"github.com/goplus/llgo/runtime/internal/runtime.Slice" %94, %"github.com/goplus/llgo/runtime/internal/runtime.Slice" %98, i1 false)
|
||||
call void @"github.com/goplus/llgo/runtime/internal/runtime.SetDirectIface"(ptr %99)
|
||||
store ptr %99, ptr @"_llgo_func$vAfTC3ZLX0_lZI-ZNliu0_DkE266FSmKXxj_cqKPPkA", align 8
|
||||
br label %_llgo_24
|
||||
|
||||
_llgo_24: ; preds = %_llgo_23, %_llgo_22
|
||||
%100 = load ptr, ptr @"_llgo_func$vAfTC3ZLX0_lZI-ZNliu0_DkE266FSmKXxj_cqKPPkA", align 8
|
||||
%101 = insertvalue %"github.com/goplus/llgo/runtime/abi.Method" { %"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @8, i64 9 }, ptr undef, ptr undef, ptr undef }, ptr %100, 1
|
||||
%102 = insertvalue %"github.com/goplus/llgo/runtime/abi.Method" %101, ptr @"github.com/goplus/llgo/cl/_testrt/vamethod.(*CFmt).SetFormat", 2
|
||||
%103 = insertvalue %"github.com/goplus/llgo/runtime/abi.Method" %102, ptr @"github.com/goplus/llgo/cl/_testrt/vamethod.(*CFmt).SetFormat", 3
|
||||
%104 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.AllocU"(i64 40)
|
||||
%105 = getelementptr %"github.com/goplus/llgo/runtime/abi.Method", ptr %104, i64 0
|
||||
store %"github.com/goplus/llgo/runtime/abi.Method" %77, ptr %105, align 8
|
||||
%106 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" undef, ptr %104, 0
|
||||
%107 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" %106, i64 1, 1
|
||||
%108 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" %107, i64 1, 2
|
||||
%109 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.AllocU"(i64 80)
|
||||
%110 = getelementptr %"github.com/goplus/llgo/runtime/abi.Method", ptr %109, i64 0
|
||||
store %"github.com/goplus/llgo/runtime/abi.Method" %74, ptr %110, align 8
|
||||
%111 = getelementptr %"github.com/goplus/llgo/runtime/abi.Method", ptr %109, i64 1
|
||||
store %"github.com/goplus/llgo/runtime/abi.Method" %103, ptr %111, align 8
|
||||
%112 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" undef, ptr %109, 0
|
||||
%113 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" %112, i64 2, 1
|
||||
%114 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" %113, i64 2, 2
|
||||
call void @"github.com/goplus/llgo/runtime/internal/runtime.InitNamed"(ptr %0, ptr %70, %"github.com/goplus/llgo/runtime/internal/runtime.Slice" %108, %"github.com/goplus/llgo/runtime/internal/runtime.Slice" %114)
|
||||
br label %_llgo_20
|
||||
|
||||
_llgo_25: ; preds = %_llgo_20
|
||||
%115 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.PointerTo"(ptr %81)
|
||||
call void @"github.com/goplus/llgo/runtime/internal/runtime.SetDirectIface"(ptr %115)
|
||||
store ptr %115, ptr @"*_llgo_github.com/goplus/llgo/cl/_testrt/vamethod.CFmt", align 8
|
||||
br label %_llgo_26
|
||||
|
||||
_llgo_26: ; preds = %_llgo_25, %_llgo_20
|
||||
%116 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.NewNamedInterface"(%"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @4, i64 42 }, %"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @9, i64 4 })
|
||||
%117 = load ptr, ptr @"_llgo_github.com/goplus/llgo/cl/_testrt/vamethod.IFmt", align 8
|
||||
%118 = icmp eq ptr %117, null
|
||||
br i1 %118, label %_llgo_27, label %_llgo_28
|
||||
|
||||
_llgo_27: ; preds = %_llgo_26
|
||||
store ptr %116, ptr @"_llgo_github.com/goplus/llgo/cl/_testrt/vamethod.IFmt", align 8
|
||||
br label %_llgo_28
|
||||
|
||||
_llgo_28: ; preds = %_llgo_27, %_llgo_26
|
||||
%119 = load ptr, ptr @"[]_llgo_any", align 8
|
||||
%120 = load ptr, ptr @"_llgo_func$sSO5Bw-E3E7TeJqIJF_OmmojTYyqWBhYrUwNYJNw7Bs", align 8
|
||||
%121 = load ptr, ptr @"*_llgo_int8", align 8
|
||||
%122 = load ptr, ptr @"_llgo_func$vAfTC3ZLX0_lZI-ZNliu0_DkE266FSmKXxj_cqKPPkA", align 8
|
||||
br i1 %118, label %_llgo_29, label %_llgo_30
|
||||
|
||||
_llgo_29: ; preds = %_llgo_28
|
||||
%123 = insertvalue %"github.com/goplus/llgo/runtime/abi.Imethod" { %"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @7, i64 6 }, ptr undef }, ptr %120, 1
|
||||
%124 = insertvalue %"github.com/goplus/llgo/runtime/abi.Imethod" { %"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @8, i64 9 }, ptr undef }, ptr %122, 1
|
||||
%125 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.AllocU"(i64 48)
|
||||
%126 = getelementptr %"github.com/goplus/llgo/runtime/abi.Imethod", ptr %125, i64 0
|
||||
store %"github.com/goplus/llgo/runtime/abi.Imethod" %123, ptr %126, align 8
|
||||
%127 = getelementptr %"github.com/goplus/llgo/runtime/abi.Imethod", ptr %125, i64 1
|
||||
store %"github.com/goplus/llgo/runtime/abi.Imethod" %124, ptr %127, align 8
|
||||
%128 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" undef, ptr %125, 0
|
||||
%129 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" %128, i64 2, 1
|
||||
%130 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" %129, i64 2, 2
|
||||
call void @"github.com/goplus/llgo/runtime/internal/runtime.InitNamedInterface"(ptr %116, %"github.com/goplus/llgo/runtime/internal/runtime.Slice" %130)
|
||||
br label %_llgo_30
|
||||
|
||||
_llgo_30: ; preds = %_llgo_29, %_llgo_28
|
||||
%131 = load ptr, ptr @"_llgo_func$sSO5Bw-E3E7TeJqIJF_OmmojTYyqWBhYrUwNYJNw7Bs", align 8
|
||||
%132 = load ptr, ptr @"_llgo_func$vAfTC3ZLX0_lZI-ZNliu0_DkE266FSmKXxj_cqKPPkA", align 8
|
||||
%133 = load ptr, ptr @"_llgo_iface$a85zs5wWQQoPIERm_en8plssh4spdIeeXZPC-E0TDh0", align 8
|
||||
%134 = icmp eq ptr %133, null
|
||||
br i1 %134, label %_llgo_31, label %_llgo_32
|
||||
|
||||
_llgo_31: ; preds = %_llgo_30
|
||||
%135 = insertvalue %"github.com/goplus/llgo/runtime/abi.Imethod" { %"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @7, i64 6 }, ptr undef }, ptr %131, 1
|
||||
%136 = insertvalue %"github.com/goplus/llgo/runtime/abi.Imethod" { %"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @8, i64 9 }, ptr undef }, ptr %132, 1
|
||||
%137 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.AllocU"(i64 48)
|
||||
%138 = getelementptr %"github.com/goplus/llgo/runtime/abi.Imethod", ptr %137, i64 0
|
||||
store %"github.com/goplus/llgo/runtime/abi.Imethod" %135, ptr %138, align 8
|
||||
%139 = getelementptr %"github.com/goplus/llgo/runtime/abi.Imethod", ptr %137, i64 1
|
||||
store %"github.com/goplus/llgo/runtime/abi.Imethod" %136, ptr %139, align 8
|
||||
%140 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" undef, ptr %137, 0
|
||||
%141 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" %140, i64 2, 1
|
||||
%142 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" %141, i64 2, 2
|
||||
%143 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.Interface"(%"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @4, i64 42 }, %"github.com/goplus/llgo/runtime/internal/runtime.Slice" %142)
|
||||
store ptr %143, ptr @"_llgo_iface$a85zs5wWQQoPIERm_en8plssh4spdIeeXZPC-E0TDh0", align 8
|
||||
br label %_llgo_32
|
||||
|
||||
_llgo_32: ; preds = %_llgo_31, %_llgo_30
|
||||
%144 = load ptr, ptr @_llgo_string, align 8
|
||||
%145 = icmp eq ptr %144, null
|
||||
br i1 %145, label %_llgo_33, label %_llgo_34
|
||||
|
||||
_llgo_33: ; preds = %_llgo_32
|
||||
%146 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.Basic"(i64 24)
|
||||
store ptr %146, ptr @_llgo_string, align 8
|
||||
br label %_llgo_34
|
||||
|
||||
_llgo_34: ; preds = %_llgo_33, %_llgo_32
|
||||
ret void
|
||||
}
|
||||
|
||||
declare ptr @"github.com/goplus/llgo/runtime/internal/runtime.NewNamed"(%"github.com/goplus/llgo/runtime/internal/runtime.String", %"github.com/goplus/llgo/runtime/internal/runtime.String", i64, i64, i64, i64)
|
||||
|
||||
declare void @"github.com/goplus/llgo/runtime/internal/runtime.SetDirectIface"(ptr)
|
||||
|
||||
declare ptr @"github.com/goplus/llgo/runtime/internal/runtime.Basic"(i64)
|
||||
|
||||
declare void @"github.com/goplus/llgo/runtime/internal/runtime.InitNamed"(ptr, ptr, %"github.com/goplus/llgo/runtime/internal/runtime.Slice", %"github.com/goplus/llgo/runtime/internal/runtime.Slice")
|
||||
|
||||
declare ptr @"github.com/goplus/llgo/runtime/internal/runtime.Interface"(%"github.com/goplus/llgo/runtime/internal/runtime.String", %"github.com/goplus/llgo/runtime/internal/runtime.Slice")
|
||||
|
||||
declare ptr @"github.com/goplus/llgo/runtime/internal/runtime.AllocU"(i64)
|
||||
|
||||
declare ptr @"github.com/goplus/llgo/runtime/internal/runtime.SliceOf"(ptr)
|
||||
|
||||
declare ptr @"github.com/goplus/llgo/runtime/internal/runtime.Func"(%"github.com/goplus/llgo/runtime/internal/runtime.Slice", %"github.com/goplus/llgo/runtime/internal/runtime.Slice", i1)
|
||||
|
||||
declare ptr @"github.com/goplus/llgo/runtime/internal/runtime.PointerTo"(ptr)
|
||||
|
||||
declare ptr @"github.com/goplus/llgo/runtime/internal/runtime.Struct"(%"github.com/goplus/llgo/runtime/internal/runtime.String", i64, %"github.com/goplus/llgo/runtime/internal/runtime.Slice")
|
||||
|
||||
declare %"github.com/goplus/llgo/runtime/abi.StructField" @"github.com/goplus/llgo/runtime/internal/runtime.StructField"(%"github.com/goplus/llgo/runtime/internal/runtime.String", ptr, i64, %"github.com/goplus/llgo/runtime/internal/runtime.String", i1)
|
||||
|
||||
declare ptr @"github.com/goplus/llgo/runtime/internal/runtime.NewNamedInterface"(%"github.com/goplus/llgo/runtime/internal/runtime.String", %"github.com/goplus/llgo/runtime/internal/runtime.String")
|
||||
|
||||
declare void @"github.com/goplus/llgo/runtime/internal/runtime.InitNamedInterface"(ptr, %"github.com/goplus/llgo/runtime/internal/runtime.Slice")
|
||||
|
||||
declare i1 @"github.com/goplus/llgo/runtime/internal/runtime.Implements"(ptr, ptr)
|
||||
|
||||
declare ptr @"github.com/goplus/llgo/runtime/internal/runtime.NewItab"(ptr, ptr)
|
||||
|
||||
declare ptr @"github.com/goplus/llgo/runtime/internal/runtime.IfacePtrData"(%"github.com/goplus/llgo/runtime/internal/runtime.iface")
|
||||
|
||||
declare void @"github.com/goplus/llgo/runtime/internal/runtime.Panic"(%"github.com/goplus/llgo/runtime/internal/runtime.eface")
|
||||
|
||||
attributes #0 = { nocallback nofree nounwind willreturn memory(argmem: write) }
|
@@ -537,6 +537,9 @@ func isAllocVargs(ctx *context, v *ssa.Alloc) bool {
|
||||
default:
|
||||
return false
|
||||
}
|
||||
if call.IsInvoke() {
|
||||
return llssa.HasNameValist(call.Signature())
|
||||
}
|
||||
return ctx.funcKind(call.Value) == fnHasVArg
|
||||
}
|
||||
}
|
||||
@@ -935,6 +938,10 @@ func (p *context) compileVArg(ret []llssa.Expr, b llssa.Builder, v ssa.Value) []
|
||||
if v.Value == nil {
|
||||
return ret
|
||||
}
|
||||
case *ssa.Parameter:
|
||||
if llssa.HasNameValist(v.Parent().Signature) {
|
||||
return ret
|
||||
}
|
||||
}
|
||||
panic(fmt.Sprintf("compileVArg: unknown value - %T\n", v))
|
||||
}
|
||||
|
@@ -506,7 +506,11 @@ func (p *context) call(b llssa.Builder, act llssa.DoAction, call *ssa.CallCommon
|
||||
if mthd := call.Method; mthd != nil {
|
||||
o := p.compileValue(b, cv)
|
||||
fn := b.Imethod(o, mthd)
|
||||
args := p.compileValues(b, call.Args, fnNormal)
|
||||
hasVArg := fnNormal
|
||||
if llssa.HasNameValist(call.Signature()) {
|
||||
hasVArg = fnHasVArg
|
||||
}
|
||||
args := p.compileValues(b, call.Args, hasVArg)
|
||||
ret = b.Do(act, fn, args...)
|
||||
return
|
||||
}
|
||||
|
@@ -27,12 +27,16 @@ type CompileGroup struct {
|
||||
LDFlags []string // Linker flags
|
||||
}
|
||||
|
||||
// IsCompiled checks if the compile group has already been compiled by verifying
|
||||
// if the output archive file exists in the specified directory
|
||||
func (g CompileGroup) IsCompiled(outputDir string) bool {
|
||||
archive := filepath.Join(outputDir, filepath.Base(g.OutputFileName))
|
||||
_, err := os.Stat(archive)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// Compile compiles all source files in the group into a static library archive
|
||||
// If the archive already exists, compilation is skipped
|
||||
func (g CompileGroup) Compile(
|
||||
outputDir string, options CompileOptions,
|
||||
) (err error) {
|
||||
@@ -95,9 +99,19 @@ func (g CompileGroup) Compile(
|
||||
|
||||
// CompileConfig represents compilation configuration
|
||||
type CompileConfig struct {
|
||||
Url string
|
||||
Name string // compile name (e.g., "picolibc", "musl", "glibc")
|
||||
Groups []CompileGroup
|
||||
ArchiveSrcDir string
|
||||
LibcCFlags []string
|
||||
Groups []CompileGroup
|
||||
ExportCFlags []string
|
||||
}
|
||||
|
||||
type LibConfig struct {
|
||||
Url string
|
||||
Name string // Library name (e.g., "picolibc", "musl", "glibc")
|
||||
Version string
|
||||
ResourceSubDir string
|
||||
}
|
||||
|
||||
// String returns a string representation of the library configuration
|
||||
// in the format "name-version"
|
||||
func (cfg LibConfig) String() string {
|
||||
return fmt.Sprintf("%s-%s", cfg.Name, cfg.Version)
|
||||
}
|
||||
|
@@ -11,8 +11,8 @@ import (
|
||||
"github.com/goplus/llgo/xtool/nm"
|
||||
)
|
||||
|
||||
func TestIsCompile(t *testing.T) {
|
||||
t.Run("IsCompile Not Exists", func(t *testing.T) {
|
||||
func TestIsCompiled(t *testing.T) {
|
||||
t.Run("IsCompiled Not Exists", func(t *testing.T) {
|
||||
cfg := CompileConfig{
|
||||
Groups: []CompileGroup{
|
||||
{
|
||||
@@ -25,7 +25,7 @@ func TestIsCompile(t *testing.T) {
|
||||
t.Errorf("unexpected result: should false")
|
||||
}
|
||||
})
|
||||
t.Run("IsCompile Exists", func(t *testing.T) {
|
||||
t.Run("IsCompiled Exists", func(t *testing.T) {
|
||||
tmpFile, err := os.CreateTemp("", "test*.a")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
@@ -207,3 +207,60 @@ func TestCompile(t *testing.T) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestLibConfig_String(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
config LibConfig
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "Normal name and version",
|
||||
config: LibConfig{
|
||||
Name: "picolibc",
|
||||
Version: "1.0",
|
||||
},
|
||||
expected: "picolibc-1.0",
|
||||
},
|
||||
{
|
||||
name: "Empty name",
|
||||
config: LibConfig{
|
||||
Name: "",
|
||||
Version: "2.5",
|
||||
},
|
||||
expected: "-2.5",
|
||||
},
|
||||
{
|
||||
name: "Empty version",
|
||||
config: LibConfig{
|
||||
Name: "musl",
|
||||
Version: "",
|
||||
},
|
||||
expected: "musl-",
|
||||
},
|
||||
{
|
||||
name: "Both empty",
|
||||
config: LibConfig{
|
||||
Name: "",
|
||||
Version: "",
|
||||
},
|
||||
expected: "-",
|
||||
},
|
||||
{
|
||||
name: "Special characters",
|
||||
config: LibConfig{
|
||||
Name: "glibc++",
|
||||
Version: "v3.2.1",
|
||||
},
|
||||
expected: "glibc++-v3.2.1",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := tt.config.String(); got != tt.expected {
|
||||
t.Errorf("String() = %v, want %v", got, tt.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@@ -2,34 +2,90 @@ package libc
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGetPicolibcConfig(t *testing.T) {
|
||||
func TestGetNewlibESP32Config_LibConfig(t *testing.T) {
|
||||
config := GetNewlibESP32Config()
|
||||
|
||||
// Test basic configuration fields
|
||||
expectedName := "newlib-esp32"
|
||||
if config.Name != expectedName {
|
||||
t.Errorf("Expected Name '%s', got '%s'", expectedName, config.Name)
|
||||
}
|
||||
|
||||
expectedVersion := "esp-4.3.0_20250211-patch3"
|
||||
if config.Version != expectedVersion {
|
||||
t.Errorf("Expected Version '%s', got '%s'", expectedVersion, config.Version)
|
||||
}
|
||||
|
||||
expectedUrl := "https://github.com/goplus/newlib/archive/refs/tags/esp-4.3.0_20250211-patch3.tar.gz"
|
||||
if config.Url != expectedUrl {
|
||||
t.Errorf("Expected Url '%s', got '%s'", expectedUrl, config.Url)
|
||||
}
|
||||
|
||||
expectedArchiveSrcDir := "newlib-esp-4.3.0_20250211-patch3"
|
||||
if config.ResourceSubDir != expectedArchiveSrcDir {
|
||||
t.Errorf("Expected ResourceSubDir '%s', got '%s'", expectedArchiveSrcDir, config.ResourceSubDir)
|
||||
}
|
||||
|
||||
// Test String() method
|
||||
expectedString := "newlib-esp32-esp-4.3.0_20250211-patch3"
|
||||
if config.String() != expectedString {
|
||||
t.Errorf("Expected String() '%s', got '%s'", expectedString, config.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetPicolibcConfig_LibConfig(t *testing.T) {
|
||||
config := GetPicolibcConfig()
|
||||
|
||||
// Test basic configuration fields
|
||||
expectedName := "picolibc"
|
||||
if config.Name != expectedName {
|
||||
t.Errorf("Expected Name '%s', got '%s'", expectedName, config.Name)
|
||||
}
|
||||
|
||||
expectedVersion := "v0.1.0"
|
||||
if config.Version != expectedVersion {
|
||||
t.Errorf("Expected Version '%s', got '%s'", expectedVersion, config.Version)
|
||||
}
|
||||
|
||||
expectedUrl := "https://github.com/goplus/picolibc/archive/refs/heads/main.zip"
|
||||
if config.Url != expectedUrl {
|
||||
t.Errorf("Expected Url '%s', got '%s'", expectedUrl, config.Url)
|
||||
}
|
||||
|
||||
expectedArchiveSrcDir := "picolibc-main"
|
||||
if config.ResourceSubDir != expectedArchiveSrcDir {
|
||||
t.Errorf("Expected ResourceSubDir '%s', got '%s'", expectedArchiveSrcDir, config.ResourceSubDir)
|
||||
}
|
||||
|
||||
// Test String() method
|
||||
expectedString := "picolibc-v0.1.0"
|
||||
if config.String() != expectedString {
|
||||
t.Errorf("Expected String() '%s', got '%s'", expectedString, config.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetPicolibcCompileConfig(t *testing.T) {
|
||||
baseDir := "/test/base"
|
||||
target := "test-target"
|
||||
|
||||
config := GetPicolibcConfig(baseDir, target)
|
||||
|
||||
if config.Name != "picolibc" {
|
||||
t.Errorf("Expected Name 'picolibc', got '%s'", config.Name)
|
||||
}
|
||||
if config.ArchiveSrcDir != "picolibc-main" {
|
||||
t.Errorf("Expected ArchiveSrcDir 'picolibc-main', got '%s'", config.ArchiveSrcDir)
|
||||
}
|
||||
config := GetPicolibcCompileConfig(baseDir, target)
|
||||
|
||||
// Test LibcCFlags
|
||||
if len(config.LibcCFlags) != 2 {
|
||||
t.Errorf("Expected 2 LibcCFlags, got %d", len(config.LibcCFlags))
|
||||
if len(config.ExportCFlags) != 2 {
|
||||
t.Errorf("Expected 2 LibcCFlags, got %d", len(config.ExportCFlags))
|
||||
} else {
|
||||
expected := "-I" + baseDir
|
||||
if config.LibcCFlags[0] != expected {
|
||||
t.Errorf("Expected LibcCFlags[0] to be '%s', got '%s'", expected, config.LibcCFlags[0])
|
||||
if config.ExportCFlags[0] != expected {
|
||||
t.Errorf("Expected LibcCFlags[0] to be '%s', got '%s'", expected, config.ExportCFlags[0])
|
||||
}
|
||||
|
||||
expected = "-isystem" + filepath.Join(baseDir, "newlib", "libc", "include")
|
||||
if config.LibcCFlags[1] != expected {
|
||||
t.Errorf("Expected LibcCFlags[1] to be '%s', got '%s'", expected, config.LibcCFlags[1])
|
||||
if config.ExportCFlags[1] != expected {
|
||||
t.Errorf("Expected LibcCFlags[1] to be '%s', got '%s'", expected, config.ExportCFlags[1])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,22 +169,22 @@ func TestGetPicolibcConfig(t *testing.T) {
|
||||
|
||||
func TestGetPicolibcConfig_EdgeCases(t *testing.T) {
|
||||
t.Run("EmptyBaseDir", func(t *testing.T) {
|
||||
config := GetPicolibcConfig("", "test-target")
|
||||
config := GetPicolibcCompileConfig("", "test-target")
|
||||
|
||||
// Check that paths are constructed correctly even with empty baseDir
|
||||
expected := "-I"
|
||||
if config.LibcCFlags[0] != expected {
|
||||
t.Errorf("Expected LibcCFlags[0] to be '%s', got '%s'", expected, config.LibcCFlags[0])
|
||||
if config.ExportCFlags[0] != expected {
|
||||
t.Errorf("Expected LibcCFlags[0] to be '%s', got '%s'", expected, config.ExportCFlags[0])
|
||||
}
|
||||
|
||||
expected = "-isystem" + filepath.Join("", "newlib", "libc", "include")
|
||||
if config.LibcCFlags[1] != expected {
|
||||
t.Errorf("Expected LibcCFlags[1] to be '%s', got '%s'", expected, config.LibcCFlags[1])
|
||||
if config.ExportCFlags[1] != expected {
|
||||
t.Errorf("Expected LibcCFlags[1] to be '%s', got '%s'", expected, config.ExportCFlags[1])
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("EmptyTarget", func(t *testing.T) {
|
||||
config := GetPicolibcConfig("/test/base", "")
|
||||
config := GetPicolibcCompileConfig("/test/base", "")
|
||||
|
||||
// Check output file name formatting
|
||||
expectedOutput := "libc-.a"
|
||||
@@ -138,23 +194,125 @@ func TestGetPicolibcConfig_EdgeCases(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestPicolibcFileStructure(t *testing.T) {
|
||||
baseDir := "/test/base"
|
||||
target := "test-target"
|
||||
|
||||
config := GetPicolibcCompileConfig(baseDir, target)
|
||||
group := config.Groups[0]
|
||||
|
||||
// Test that all files have .c extension (no assembly files in picolibc config)
|
||||
for _, file := range group.Files {
|
||||
if !strings.HasSuffix(file, ".c") {
|
||||
t.Errorf("File '%s' does not have .c extension", file)
|
||||
}
|
||||
}
|
||||
|
||||
// Test that files are from expected directories
|
||||
stringFiles := 0
|
||||
stdlibFiles := 0
|
||||
tinystdioFiles := 0
|
||||
|
||||
for _, file := range group.Files {
|
||||
if strings.Contains(file, "/string/") {
|
||||
stringFiles++
|
||||
} else if strings.Contains(file, "/stdlib/") {
|
||||
stdlibFiles++
|
||||
} else if strings.Contains(file, "/tinystdio/") {
|
||||
tinystdioFiles++
|
||||
}
|
||||
}
|
||||
|
||||
if stringFiles < 50 {
|
||||
t.Errorf("Expected at least 50 string files, got %d", stringFiles)
|
||||
}
|
||||
if stdlibFiles < 5 {
|
||||
t.Errorf("Expected at least 5 stdlib files, got %d", stdlibFiles)
|
||||
}
|
||||
if tinystdioFiles < 3 {
|
||||
t.Errorf("Expected at least 3 tinystdio files, got %d", tinystdioFiles)
|
||||
}
|
||||
|
||||
// Test that all files have correct base directory
|
||||
for _, file := range group.Files {
|
||||
if !strings.HasPrefix(file, baseDir) {
|
||||
t.Errorf("File '%s' does not have expected base directory '%s'", file, baseDir)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPicolibcCompilerFlags(t *testing.T) {
|
||||
baseDir := "/test/base"
|
||||
target := "test-target"
|
||||
|
||||
config := GetPicolibcCompileConfig(baseDir, target)
|
||||
group := config.Groups[0]
|
||||
|
||||
// Test that required preprocessor definitions are present
|
||||
requiredDefines := []string{
|
||||
"-D_COMPILING_NEWLIB",
|
||||
"-D_HAVE_ALIAS_ATTRIBUTE",
|
||||
"-DTINY_STDIO",
|
||||
"-DPOSIX_IO",
|
||||
"-DFORMAT_DEFAULT_INTEGER",
|
||||
"-D_IEEE_LIBM",
|
||||
"-D_WANT_IO_C99_FORMATS",
|
||||
}
|
||||
|
||||
for _, define := range requiredDefines {
|
||||
found := false
|
||||
for _, flag := range group.CFlags {
|
||||
if flag == define {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
t.Errorf("Required define '%s' not found in CFlags", define)
|
||||
}
|
||||
}
|
||||
|
||||
// Test that required include paths are present
|
||||
requiredIncludes := []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 _, include := range requiredIncludes {
|
||||
found := false
|
||||
for _, flag := range group.CFlags {
|
||||
if flag == include {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
t.Errorf("Required include '%s' not found in CFlags", include)
|
||||
}
|
||||
}
|
||||
|
||||
// Test that nostdlib is present
|
||||
found := false
|
||||
for _, flag := range group.CFlags {
|
||||
if flag == "-nostdlib" {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
t.Error("Required flag '-nostdlib' not found in CFlags")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetNewlibESP32ConfigRISCV(t *testing.T) {
|
||||
baseDir := "/test/base"
|
||||
target := "riscv32-unknown-elf"
|
||||
|
||||
config := getNewlibESP32ConfigRISCV(baseDir, target)
|
||||
|
||||
// Test basic configuration
|
||||
if config.Url != _newlibUrl {
|
||||
t.Errorf("Expected URL '%s', got '%s'", _newlibUrl, config.Url)
|
||||
}
|
||||
if config.Name != "newlib-esp32" {
|
||||
t.Errorf("Expected Name 'newlib-esp32', got '%s'", config.Name)
|
||||
}
|
||||
if config.ArchiveSrcDir != _archiveInternalSrcDir {
|
||||
t.Errorf("Expected ArchiveSrcDir '%s', got '%s'", _archiveInternalSrcDir, config.ArchiveSrcDir)
|
||||
}
|
||||
|
||||
// Test LibcCFlags
|
||||
libcDir := filepath.Join(baseDir, "newlib", "libc")
|
||||
expectedCFlags := []string{
|
||||
@@ -162,12 +320,12 @@ func TestGetNewlibESP32ConfigRISCV(t *testing.T) {
|
||||
"-I" + filepath.Join(baseDir, "newlib"),
|
||||
"-I" + libcDir,
|
||||
}
|
||||
if len(config.LibcCFlags) != len(expectedCFlags) {
|
||||
t.Errorf("Expected %d LibcCFlags, got %d", len(expectedCFlags), len(config.LibcCFlags))
|
||||
if len(config.ExportCFlags) != len(expectedCFlags) {
|
||||
t.Errorf("Expected %d LibcCFlags, got %d", len(expectedCFlags), len(config.ExportCFlags))
|
||||
} else {
|
||||
for i, expected := range expectedCFlags {
|
||||
if config.LibcCFlags[i] != expected {
|
||||
t.Errorf("LibcCFlags[%d] mismatch. Expected '%s', got '%s'", i, expected, config.LibcCFlags[i])
|
||||
if config.ExportCFlags[i] != expected {
|
||||
t.Errorf("ExportCFlags[%d] mismatch. Expected '%s', got '%s'", i, expected, config.ExportCFlags[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -288,17 +446,6 @@ func TestGetNewlibESP32ConfigXtensa(t *testing.T) {
|
||||
|
||||
config := getNewlibESP32ConfigXtensa(baseDir, target)
|
||||
|
||||
// Test basic configuration
|
||||
if config.Url != _newlibUrl {
|
||||
t.Errorf("Expected URL '%s', got '%s'", _newlibUrl, config.Url)
|
||||
}
|
||||
if config.Name != "newlib-esp32" {
|
||||
t.Errorf("Expected Name 'newlib-esp32', got '%s'", config.Name)
|
||||
}
|
||||
if config.ArchiveSrcDir != _archiveInternalSrcDir {
|
||||
t.Errorf("Expected ArchiveSrcDir '%s', got '%s'", _archiveInternalSrcDir, config.ArchiveSrcDir)
|
||||
}
|
||||
|
||||
// Test LibcCFlags
|
||||
libcDir := filepath.Join(baseDir, "newlib", "libc")
|
||||
expectedCFlags := []string{
|
||||
@@ -306,12 +453,12 @@ func TestGetNewlibESP32ConfigXtensa(t *testing.T) {
|
||||
"-I" + filepath.Join(baseDir, "newlib"),
|
||||
"-I" + libcDir,
|
||||
}
|
||||
if len(config.LibcCFlags) != len(expectedCFlags) {
|
||||
t.Errorf("Expected %d LibcCFlags, got %d", len(expectedCFlags), len(config.LibcCFlags))
|
||||
if len(config.ExportCFlags) != len(expectedCFlags) {
|
||||
t.Errorf("Expected %d LibcCFlags, got %d", len(expectedCFlags), len(config.ExportCFlags))
|
||||
} else {
|
||||
for i, expected := range expectedCFlags {
|
||||
if config.LibcCFlags[i] != expected {
|
||||
t.Errorf("LibcCFlags[%d] mismatch. Expected '%s', got '%s'", i, expected, config.LibcCFlags[i])
|
||||
if config.ExportCFlags[i] != expected {
|
||||
t.Errorf("ExportCFlags[%d] mismatch. Expected '%s', got '%s'", i, expected, config.ExportCFlags[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -407,8 +554,8 @@ func TestEdgeCases(t *testing.T) {
|
||||
|
||||
// Check that paths are constructed correctly
|
||||
expected := "-isystem" + filepath.Join(libcDir, "include")
|
||||
if config.LibcCFlags[0] != expected {
|
||||
t.Errorf("Expected LibcCFlags[0] to be '%s', got '%s'", expected, config.LibcCFlags[0])
|
||||
if config.ExportCFlags[0] != expected {
|
||||
t.Errorf("Expected LibcCFlags[0] to be '%s', got '%s'", expected, config.ExportCFlags[0])
|
||||
}
|
||||
})
|
||||
|
||||
@@ -428,8 +575,8 @@ func TestEdgeCases(t *testing.T) {
|
||||
|
||||
// Check that paths are constructed correctly
|
||||
expected := "-I" + filepath.Join(libcDir, "include")
|
||||
if config.LibcCFlags[0] != expected {
|
||||
t.Errorf("Expected LibcCFlags[0] to be '%s', got '%s'", expected, config.LibcCFlags[0])
|
||||
if config.ExportCFlags[0] != expected {
|
||||
t.Errorf("Expected LibcCFlags[0] to be '%s', got '%s'", expected, config.ExportCFlags[0])
|
||||
}
|
||||
})
|
||||
|
||||
|
@@ -21,16 +21,22 @@ var _libcCCFlags = []string{
|
||||
"-ffreestanding",
|
||||
}
|
||||
|
||||
const (
|
||||
_newlibUrl = "https://github.com/goplus/newlib/archive/refs/tags/v0.2.0.tar.gz"
|
||||
_archiveInternalSrcDir = "newlib-0.2.0"
|
||||
)
|
||||
|
||||
// withDefaultCCFlags appends default C compiler flags to the provided flags
|
||||
func withDefaultCCFlags(ccflags []string) []string {
|
||||
return append(ccflags, _libcCCFlags...)
|
||||
}
|
||||
|
||||
func getNewlibESP32ConfigRISCV(baseDir, target string) *compile.CompileConfig {
|
||||
// GetNewlibESP32Config returns the configuration for downloading and building newlib for ESP32
|
||||
func GetNewlibESP32Config() compile.LibConfig {
|
||||
return compile.LibConfig{
|
||||
Url: "https://github.com/goplus/newlib/archive/refs/tags/esp-4.3.0_20250211-patch3.tar.gz",
|
||||
Name: "newlib-esp32",
|
||||
Version: "esp-4.3.0_20250211-patch3",
|
||||
ResourceSubDir: "newlib-esp-4.3.0_20250211-patch3",
|
||||
}
|
||||
}
|
||||
|
||||
func getNewlibESP32ConfigRISCV(baseDir, target string) compile.CompileConfig {
|
||||
libcDir := filepath.Join(baseDir, "newlib", "libc")
|
||||
|
||||
libcIncludeDir := []string{
|
||||
@@ -39,11 +45,8 @@ func getNewlibESP32ConfigRISCV(baseDir, target string) *compile.CompileConfig {
|
||||
"-I" + libcDir,
|
||||
}
|
||||
|
||||
return &compile.CompileConfig{
|
||||
Url: _newlibUrl,
|
||||
Name: "newlib-esp32",
|
||||
LibcCFlags: libcIncludeDir,
|
||||
ArchiveSrcDir: _archiveInternalSrcDir,
|
||||
return compile.CompileConfig{
|
||||
ExportCFlags: libcIncludeDir,
|
||||
Groups: []compile.CompileGroup{
|
||||
{
|
||||
OutputFileName: fmt.Sprintf("libcrt0-%s.a", target),
|
||||
@@ -1092,7 +1095,7 @@ func getNewlibESP32ConfigRISCV(baseDir, target string) *compile.CompileConfig {
|
||||
}
|
||||
}
|
||||
|
||||
func getNewlibESP32ConfigXtensa(baseDir, target string) *compile.CompileConfig {
|
||||
func getNewlibESP32ConfigXtensa(baseDir, target string) compile.CompileConfig {
|
||||
libcDir := filepath.Join(baseDir, "newlib", "libc")
|
||||
|
||||
libcIncludeDir := []string{
|
||||
@@ -1101,11 +1104,8 @@ func getNewlibESP32ConfigXtensa(baseDir, target string) *compile.CompileConfig {
|
||||
"-I" + libcDir,
|
||||
}
|
||||
|
||||
return &compile.CompileConfig{
|
||||
Url: _newlibUrl,
|
||||
Name: "newlib-esp32",
|
||||
ArchiveSrcDir: _archiveInternalSrcDir,
|
||||
LibcCFlags: libcIncludeDir,
|
||||
return compile.CompileConfig{
|
||||
ExportCFlags: libcIncludeDir,
|
||||
Groups: []compile.CompileGroup{
|
||||
{
|
||||
OutputFileName: fmt.Sprintf("libcrt0-%s.a", target),
|
||||
@@ -2075,7 +2075,7 @@ func getNewlibESP32ConfigXtensa(baseDir, target string) *compile.CompileConfig {
|
||||
}
|
||||
|
||||
// getNewlibESP32Config returns configuration for newlib esp32
|
||||
func GetNewlibESP32Config(baseDir, target, mcpu string) *compile.CompileConfig {
|
||||
func GetNewlibESP32CompileConfig(baseDir, target, mcpu string) compile.CompileConfig {
|
||||
if strings.Contains(target, "riscv32") {
|
||||
return getNewlibESP32ConfigRISCV(baseDir, target)
|
||||
}
|
||||
|
@@ -7,16 +7,23 @@ import (
|
||||
"github.com/goplus/llgo/internal/crosscompile/compile"
|
||||
)
|
||||
|
||||
// getPicolibcConfig returns configuration for picolibc
|
||||
func GetPicolibcConfig(baseDir, target string) *compile.CompileConfig {
|
||||
return &compile.CompileConfig{
|
||||
Url: "https://github.com/goplus/picolibc/archive/refs/heads/main.zip",
|
||||
Name: "picolibc",
|
||||
LibcCFlags: []string{
|
||||
// GetPicolibcConfig returns the configuration for downloading and building picolibc
|
||||
func GetPicolibcConfig() compile.LibConfig {
|
||||
return compile.LibConfig{
|
||||
Name: "picolibc",
|
||||
Version: "v0.1.0",
|
||||
Url: "https://github.com/goplus/picolibc/archive/refs/heads/main.zip",
|
||||
ResourceSubDir: "picolibc-main",
|
||||
}
|
||||
}
|
||||
|
||||
// GetPicolibcCompileConfig returns configuration for picolibc
|
||||
func GetPicolibcCompileConfig(baseDir, target string) compile.CompileConfig {
|
||||
return compile.CompileConfig{
|
||||
ExportCFlags: []string{
|
||||
"-I" + baseDir,
|
||||
"-isystem" + filepath.Join(baseDir, "newlib", "libc", "include"),
|
||||
},
|
||||
|
||||
Groups: []compile.CompileGroup{
|
||||
{
|
||||
OutputFileName: fmt.Sprintf("libc-%s.a", target),
|
||||
@@ -158,6 +165,5 @@ func GetPicolibcConfig(baseDir, target string) *compile.CompileConfig {
|
||||
CCFlags: _libcCCFlags,
|
||||
},
|
||||
},
|
||||
ArchiveSrcDir: "picolibc-main",
|
||||
}
|
||||
}
|
||||
|
@@ -100,10 +100,17 @@ func withPlatformSpecifiedFiles(baseDir, target string, files []string) []string
|
||||
return append(files, platformSpecifiedFiles(builtinsDir, target)...)
|
||||
}
|
||||
|
||||
func GetCompilerRTConfig(baseDir, target string) *compile.CompileConfig {
|
||||
return &compile.CompileConfig{
|
||||
Url: "https://github.com/goplus/compiler-rt/archive/refs/tags/v0.1.0.tar.gz",
|
||||
ArchiveSrcDir: "compiler-rt-0.1.0",
|
||||
func GetCompilerRTConfig() compile.LibConfig {
|
||||
return compile.LibConfig{
|
||||
Name: "compiler-rt",
|
||||
Url: "https://github.com/goplus/compiler-rt/archive/refs/tags/xtensa_release_19.1.2.tar.gz",
|
||||
Version: "xtensa_release_19.1.2",
|
||||
ResourceSubDir: "compiler-rt-xtensa_release_19.1.2",
|
||||
}
|
||||
}
|
||||
|
||||
func GetCompilerRTCompileConfig(baseDir, target string) compile.CompileConfig {
|
||||
return compile.CompileConfig{
|
||||
Groups: []compile.CompileGroup{
|
||||
{
|
||||
OutputFileName: fmt.Sprintf("libclang_builtins-%s.a", target),
|
||||
@@ -277,7 +284,8 @@ func GetCompilerRTConfig(baseDir, target string) *compile.CompileConfig {
|
||||
"-Werror=return-stack-address",
|
||||
"-Werror=sizeof-array-decay",
|
||||
"-Werror=format-insufficient-args",
|
||||
"-Wformat -std=c11",
|
||||
"-Wformat",
|
||||
"-std=c11",
|
||||
"-fno-builtin",
|
||||
"-fvisibility=hidden",
|
||||
"-fomit-frame-pointer",
|
||||
|
@@ -5,6 +5,37 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGetCompilerRTConfig_LibConfig(t *testing.T) {
|
||||
config := GetCompilerRTConfig()
|
||||
|
||||
// Test basic configuration fields
|
||||
expectedName := "compiler-rt"
|
||||
if config.Name != expectedName {
|
||||
t.Errorf("Expected Name '%s', got '%s'", expectedName, config.Name)
|
||||
}
|
||||
|
||||
expectedVersion := "xtensa_release_19.1.2"
|
||||
if config.Version != expectedVersion {
|
||||
t.Errorf("Expected Version '%s', got '%s'", expectedVersion, config.Version)
|
||||
}
|
||||
|
||||
expectedUrl := "https://github.com/goplus/compiler-rt/archive/refs/tags/xtensa_release_19.1.2.tar.gz"
|
||||
if config.Url != expectedUrl {
|
||||
t.Errorf("Expected Url '%s', got '%s'", expectedUrl, config.Url)
|
||||
}
|
||||
|
||||
expectedArchiveSrcDir := "compiler-rt-xtensa_release_19.1.2"
|
||||
if config.ResourceSubDir != expectedArchiveSrcDir {
|
||||
t.Errorf("Expected ResourceSubDir '%s', got '%s'", expectedArchiveSrcDir, config.ResourceSubDir)
|
||||
}
|
||||
|
||||
// Test String() method
|
||||
expectedString := "compiler-rt-xtensa_release_19.1.2"
|
||||
if config.String() != expectedString {
|
||||
t.Errorf("Expected String() '%s', got '%s'", expectedString, config.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestPlatformSpecifiedFiles(t *testing.T) {
|
||||
tests := []struct {
|
||||
target string
|
||||
@@ -60,7 +91,7 @@ func TestGetCompilerRTConfig(t *testing.T) {
|
||||
baseDir := "/test/base"
|
||||
target := "riscv32-unknown-elf"
|
||||
|
||||
config := GetCompilerRTConfig(baseDir, target)
|
||||
config := GetCompilerRTCompileConfig(baseDir, target)
|
||||
|
||||
// Test groups configuration
|
||||
if len(config.Groups) != 1 {
|
||||
@@ -101,15 +132,8 @@ func TestGetCompilerRTConfig_DifferentTargets(t *testing.T) {
|
||||
baseDir := "/test/base"
|
||||
for _, target := range targets {
|
||||
t.Run(target, func(t *testing.T) {
|
||||
config := GetCompilerRTConfig(baseDir, target)
|
||||
config := GetCompilerRTCompileConfig(baseDir, target)
|
||||
|
||||
// Basic validation
|
||||
if config.Url == "" {
|
||||
t.Error("URL should not be empty")
|
||||
}
|
||||
if config.ArchiveSrcDir == "" {
|
||||
t.Error("ArchiveSrcDir should not be empty")
|
||||
}
|
||||
if len(config.Groups) == 0 {
|
||||
t.Error("Should have at least one group")
|
||||
}
|
||||
|
@@ -15,6 +15,7 @@ import (
|
||||
"github.com/goplus/llgo/internal/flash"
|
||||
"github.com/goplus/llgo/internal/targets"
|
||||
"github.com/goplus/llgo/internal/xtool/llvm"
|
||||
envllvm "github.com/goplus/llgo/xtool/env/llvm"
|
||||
)
|
||||
|
||||
type Export struct {
|
||||
@@ -48,8 +49,8 @@ var (
|
||||
)
|
||||
|
||||
var (
|
||||
espClangBaseUrl = "https://github.com/goplus/espressif-llvm-project-prebuilt/releases/download/19.1.2_20250820"
|
||||
espClangVersion = "19.1.2_20250820"
|
||||
espClangBaseUrl = "https://github.com/goplus/espressif-llvm-project-prebuilt/releases/download/19.1.2_20250905-3"
|
||||
espClangVersion = "19.1.2_20250905-3"
|
||||
)
|
||||
|
||||
// cacheRoot can be overridden for testing
|
||||
@@ -108,7 +109,7 @@ func getESPClangRoot(forceEspClang bool) (clangRoot string, err error) {
|
||||
llgoRoot := env.LLGoROOT()
|
||||
|
||||
// First check if clang exists in LLGoROOT
|
||||
espClangRoot := filepath.Join(llgoRoot, "crosscompile", "clang")
|
||||
espClangRoot := filepath.Join(llgoRoot, envllvm.CrosscompileClangPath)
|
||||
if _, err = os.Stat(espClangRoot); err == nil {
|
||||
clangRoot = espClangRoot
|
||||
return
|
||||
@@ -167,20 +168,18 @@ func getESPClangPlatform(goos, goarch string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// ldFlagsFromFileName extracts the library name from a filename for use in linker flags
|
||||
// For example, "libmath.a" becomes "math" for use with "-lmath"
|
||||
func ldFlagsFromFileName(fileName string) string {
|
||||
return strings.TrimPrefix(strings.TrimSuffix(fileName, ".a"), "lib")
|
||||
}
|
||||
|
||||
func getOrCompileWithConfig(
|
||||
compileConfig *compile.CompileConfig,
|
||||
// compileWithConfig compiles libraries according to the provided configuration
|
||||
// and returns the necessary linker flags for linking against the compiled libraries
|
||||
func compileWithConfig(
|
||||
compileConfig compile.CompileConfig,
|
||||
outputDir string, options compile.CompileOptions,
|
||||
) (ldflags []string, err error) {
|
||||
if err = checkDownloadAndExtractLib(
|
||||
compileConfig.Url, outputDir,
|
||||
compileConfig.ArchiveSrcDir,
|
||||
); err != nil {
|
||||
return
|
||||
}
|
||||
ldflags = append(ldflags, "-nostdlib", "-L"+outputDir)
|
||||
|
||||
for _, group := range compileConfig.Groups {
|
||||
@@ -586,16 +585,16 @@ func UseTarget(targetName string) (export Export, err error) {
|
||||
var libcIncludeDir []string
|
||||
|
||||
if config.Libc != "" {
|
||||
var outputDir string
|
||||
var libcLDFlags []string
|
||||
var compileConfig *compile.CompileConfig
|
||||
var compileConfig compile.CompileConfig
|
||||
baseDir := filepath.Join(cacheRoot(), "crosscompile")
|
||||
outputDir := filepath.Join(baseDir, config.Libc)
|
||||
|
||||
compileConfig, err = getLibcCompileConfigByName(baseDir, config.Libc, config.LLVMTarget, config.CPU)
|
||||
outputDir, compileConfig, err = getLibcCompileConfigByName(baseDir, config.Libc, config.LLVMTarget, config.CPU)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
libcLDFlags, err = getOrCompileWithConfig(compileConfig, outputDir, compile.CompileOptions{
|
||||
libcLDFlags, err = compileWithConfig(compileConfig, outputDir, compile.CompileOptions{
|
||||
CC: export.CC,
|
||||
Linker: export.Linker,
|
||||
CCFLAGS: ccflags,
|
||||
@@ -604,24 +603,24 @@ func UseTarget(targetName string) (export Export, err error) {
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
cflags = append(cflags, compileConfig.LibcCFlags...)
|
||||
cflags = append(cflags, compileConfig.ExportCFlags...)
|
||||
ldflags = append(ldflags, libcLDFlags...)
|
||||
|
||||
libcIncludeDir = compileConfig.LibcCFlags
|
||||
libcIncludeDir = compileConfig.ExportCFlags
|
||||
export.Libc = config.Libc
|
||||
}
|
||||
|
||||
if config.RTLib != "" {
|
||||
var outputDir string
|
||||
var rtLibLDFlags []string
|
||||
var compileConfig *compile.CompileConfig
|
||||
var compileConfig compile.CompileConfig
|
||||
baseDir := filepath.Join(cacheRoot(), "crosscompile")
|
||||
outputDir := filepath.Join(baseDir, config.RTLib)
|
||||
|
||||
compileConfig, err = getRTCompileConfigByName(baseDir, config.RTLib, config.LLVMTarget)
|
||||
outputDir, compileConfig, err = getRTCompileConfigByName(baseDir, config.RTLib, config.LLVMTarget)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
rtLibLDFlags, err = getOrCompileWithConfig(compileConfig, outputDir, compile.CompileOptions{
|
||||
rtLibLDFlags, err = compileWithConfig(compileConfig, outputDir, compile.CompileOptions{
|
||||
CC: export.CC,
|
||||
Linker: export.Linker,
|
||||
CCFLAGS: ccflags,
|
||||
|
@@ -37,10 +37,10 @@ func TestUseCrossCompileSDK(t *testing.T) {
|
||||
name: "Same Platform",
|
||||
goos: runtime.GOOS,
|
||||
goarch: runtime.GOARCH,
|
||||
expectSDK: true, // Changed: now we expect flags even for same platform
|
||||
expectCCFlags: true, // Changed: CCFLAGS will contain sysroot
|
||||
expectCFlags: false, // Changed: CFLAGS will not contain include paths
|
||||
expectLDFlags: false, // Changed: LDFLAGS will not contain library paths
|
||||
expectSDK: true, // We expect flags even for same platform
|
||||
expectCCFlags: true, // CCFLAGS will contain sysroot
|
||||
expectCFlags: false, // CFLAGS will not contain include paths
|
||||
expectLDFlags: false, // LDFLAGS will not contain library paths
|
||||
},
|
||||
{
|
||||
name: "WASM Target",
|
||||
|
@@ -605,7 +605,7 @@ func TestESPClangDownloadWhenNotExists(t *testing.T) {
|
||||
}
|
||||
|
||||
server := createTestServer(t, map[string]string{
|
||||
"clang-esp-19.1.2_20250820-linux.tar.xz": string(archiveContent),
|
||||
fmt.Sprintf("clang-esp-%s-linux.tar.xz", espClangVersion): string(archiveContent),
|
||||
})
|
||||
defer server.Close()
|
||||
|
||||
|
@@ -9,34 +9,70 @@ import (
|
||||
"github.com/goplus/llgo/internal/crosscompile/compile/rtlib"
|
||||
)
|
||||
|
||||
// GetCompileConfigByName retrieves libc compilation configuration by name
|
||||
// Returns compilation file lists and corresponding cflags
|
||||
func getLibcCompileConfigByName(baseDir, libcName, target, mcpu string) (*compile.CompileConfig, error) {
|
||||
// for testing, in testing env, we use fake path, it will cause downloading failure
|
||||
var needSkipDownload = false
|
||||
|
||||
// getLibcCompileConfigByName retrieves libc compilation configuration by name
|
||||
// Returns the actual libc output dir, compilation config and err
|
||||
func getLibcCompileConfigByName(baseDir, libcName, target, mcpu string) (outputDir string, cfg compile.CompileConfig, err error) {
|
||||
if libcName == "" {
|
||||
return nil, fmt.Errorf("libc name cannot be empty")
|
||||
err = fmt.Errorf("libc name cannot be empty")
|
||||
return
|
||||
}
|
||||
libcDir := filepath.Join(baseDir, libcName)
|
||||
var libcDir string
|
||||
var config compile.LibConfig
|
||||
var compileConfig compile.CompileConfig
|
||||
|
||||
switch libcName {
|
||||
case "picolibc":
|
||||
return libc.GetPicolibcConfig(libcDir, target), nil
|
||||
config = libc.GetPicolibcConfig()
|
||||
libcDir = filepath.Join(baseDir, config.String())
|
||||
compileConfig = libc.GetPicolibcCompileConfig(libcDir, target)
|
||||
case "newlib-esp32":
|
||||
return libc.GetNewlibESP32Config(libcDir, target, mcpu), nil
|
||||
config = libc.GetNewlibESP32Config()
|
||||
libcDir = filepath.Join(baseDir, config.String())
|
||||
compileConfig = libc.GetNewlibESP32CompileConfig(libcDir, target, mcpu)
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported libc: %s", libcName)
|
||||
err = fmt.Errorf("unsupported libc: %s", libcName)
|
||||
return
|
||||
}
|
||||
if needSkipDownload {
|
||||
return libcDir, compileConfig, err
|
||||
}
|
||||
|
||||
if err = checkDownloadAndExtractLib(config.Url, libcDir, config.ResourceSubDir); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return libcDir, compileConfig, nil
|
||||
}
|
||||
|
||||
func getRTCompileConfigByName(baseDir, rtName, target string) (*compile.CompileConfig, error) {
|
||||
// getRTCompileConfigByName retrieves runtime library compilation configuration by name
|
||||
// Returns the actual libc output dir, compilation config and err
|
||||
func getRTCompileConfigByName(baseDir, rtName, target string) (outputDir string, cfg compile.CompileConfig, err error) {
|
||||
if rtName == "" {
|
||||
return nil, fmt.Errorf("rt name cannot be empty")
|
||||
err = fmt.Errorf("rt name cannot be empty")
|
||||
return
|
||||
}
|
||||
rtDir := filepath.Join(baseDir, rtName)
|
||||
var rtDir string
|
||||
var config compile.LibConfig
|
||||
var compileConfig compile.CompileConfig
|
||||
|
||||
switch rtName {
|
||||
case "compiler-rt":
|
||||
return rtlib.GetCompilerRTConfig(rtDir, target), nil
|
||||
config = rtlib.GetCompilerRTConfig()
|
||||
rtDir = filepath.Join(baseDir, config.String())
|
||||
compileConfig = rtlib.GetCompilerRTCompileConfig(rtDir, target)
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported rt: %s", rtName)
|
||||
err = fmt.Errorf("unsupported rt: %s", rtName)
|
||||
}
|
||||
if needSkipDownload {
|
||||
return rtDir, compileConfig, err
|
||||
}
|
||||
|
||||
if err = checkDownloadAndExtractLib(config.Url, rtDir, config.ResourceSubDir); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return rtDir, compileConfig, nil
|
||||
}
|
||||
|
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -34,7 +34,7 @@ func VArg() *types.Var {
|
||||
return types.NewParam(0, nil, NameValist, types.NewSlice(tyAny))
|
||||
}
|
||||
|
||||
func hasNameValist(sig *types.Signature) bool {
|
||||
func HasNameValist(sig *types.Signature) bool {
|
||||
if sig.Variadic() {
|
||||
if params := sig.Params(); params.At(params.Len()-1).Name() == NameValist {
|
||||
return true
|
||||
@@ -241,7 +241,7 @@ func newParams(fn Type, prog Program) (params []Type, hasVArg bool) {
|
||||
sig := fn.raw.Type.(*types.Signature)
|
||||
in := sig.Params()
|
||||
if n := in.Len(); n > 0 {
|
||||
if hasVArg = hasNameValist(sig); hasVArg {
|
||||
if hasVArg = HasNameValist(sig); hasVArg {
|
||||
n--
|
||||
}
|
||||
params = make([]Type, n)
|
||||
|
@@ -458,7 +458,7 @@ func (p Program) toLLVMTypes(t *types.Tuple, n int) (ret []llvm.Type) {
|
||||
func (p Program) toLLVMFunc(sig *types.Signature) llvm.Type {
|
||||
tParams := sig.Params()
|
||||
n := tParams.Len()
|
||||
hasVArg := hasNameValist(sig)
|
||||
hasVArg := HasNameValist(sig)
|
||||
if hasVArg {
|
||||
n--
|
||||
}
|
||||
|
@@ -5,23 +5,6 @@ ENTRY(_start)
|
||||
SECTIONS
|
||||
{
|
||||
. = SEGMENT_START("iram_seg", 0);
|
||||
.vectors :
|
||||
{
|
||||
_vector_table = ABSOLUTE(.);
|
||||
KEEP(*(.WindowVectors.text));
|
||||
KEEP(*(.Level2InterruptVector.text));
|
||||
KEEP(*(.Level3InterruptVector.text));
|
||||
KEEP(*(.Level4InterruptVector.text));
|
||||
KEEP(*(.Level5InterruptVector.text));
|
||||
KEEP(*(.DebugExceptionVector.text));
|
||||
KEEP(*(.NMIExceptionVector.text));
|
||||
KEEP(*(.KernelExceptionVector.text));
|
||||
KEEP(*(.UserExceptionVector.text));
|
||||
KEEP(*(.DoubleExceptionVector.text));
|
||||
KEEP(*(.ResetVector.text));
|
||||
*(.*Vector.literal)
|
||||
. = ALIGN (16);
|
||||
} > iram_seg
|
||||
|
||||
text :
|
||||
{
|
||||
|
15
xtool/env/llvm/llvm.go
vendored
15
xtool/env/llvm/llvm.go
vendored
@@ -22,6 +22,7 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/goplus/llgo/internal/env"
|
||||
"github.com/goplus/llgo/xtool/clang"
|
||||
"github.com/goplus/llgo/xtool/llvm/install_name_tool"
|
||||
"github.com/goplus/llgo/xtool/llvm/llvmlink"
|
||||
@@ -30,6 +31,13 @@ import (
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
const (
|
||||
// CrosscompileClangPath is the relative path from LLGO_ROOT to the clang installation
|
||||
CrosscompileClangPath = "crosscompile/clang"
|
||||
)
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// defaultLLVMConfigBin returns the default path to the llvm-config binary. It
|
||||
// checks the LLVM_CONFIG environment variable first, then searches in PATH. If
|
||||
// not found, it returns [ldLLVMConfigBin] as a last resort.
|
||||
@@ -42,6 +50,13 @@ func defaultLLVMConfigBin() string {
|
||||
if bin != "" {
|
||||
return bin
|
||||
}
|
||||
|
||||
llgoRoot := env.LLGoROOT()
|
||||
// Check LLGO_ROOT/crosscompile/clang for llvm-config
|
||||
crossLLVMConfigBin := filepath.Join(llgoRoot, CrosscompileClangPath, "bin", "llvm-config")
|
||||
if _, err := os.Stat(crossLLVMConfigBin); err == nil {
|
||||
return crossLLVMConfigBin
|
||||
}
|
||||
return ldLLVMConfigBin
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user