diff --git a/.github/workflows/doc.yml b/.github/workflows/doc.yml new file mode 100644 index 00000000..6837f0b1 --- /dev/null +++ b/.github/workflows/doc.yml @@ -0,0 +1,68 @@ +name: Docs + +on: + push: + branches: [ "*" ] + pull_request: + branches: [ "*" ] + +jobs: + doc_verify: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Install embedme + run: npm install -g embedme + + - name: Verify README.md embedded code + run: npx embedme --verify README.md + + doc_test: + continue-on-error: true + strategy: + fail-fast: false + matrix: + os: + - macos-latest + - ubuntu-24.04 + runs-on: ${{matrix.os}} + steps: + - uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v4 + with: + go-version: '1.20' + + - name: Install dependencies on macOS + if: startsWith(matrix.os, 'macos') + run: | + set -e + set -x + source doc/_readme/scripts/install_macos.sh + + - name: Install dependencies on Ubuntu + if: startsWith(matrix.os, 'ubuntu') + run: | + set -e + set -x + source doc/_readme/scripts/install_ubuntu.sh + + - name: Install llgo + run: | + set -e + set -x + source doc/_readme/scripts/install_llgo.sh + + - name: Test doc code blocks + run: | + set -e + set -x + source doc/_readme/scripts/run.sh + diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index e1fd0681..46ae1fb0 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -10,6 +10,22 @@ on: branches: [ "*" ] jobs: + fmt: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: '1.20' + + - name: Check formatting + run: | + if [ -n "$(go fmt ./...)" ]; then + echo "Some files are not properly formatted. Please run 'go fmt ./...'" + exit 1 + fi test: strategy: diff --git a/README.md b/README.md index 913adfe2..605f6a72 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,8 @@ You can import a C/C++ standard library in LLGo! Here is a simple example: + + ```go package main @@ -77,6 +79,8 @@ llgo run . LLGo use `go:linkname` to link an extern symbol througth its ABI: + + ```go import _ "unsafe" // for go:linkname @@ -86,6 +90,8 @@ func Sqrt(x float64) float64 You can directly integrate it into [your own code](_demo/linkname/linkname.go): + + ```go package main @@ -101,6 +107,8 @@ func main() { Or put it into a package (see [c/math](c/math/math.go)): + + ```go package main @@ -135,6 +143,8 @@ Note: For third-party libraries (such as pandas and pytorch), you still need to Here is an example: + + ```go package main @@ -152,6 +162,8 @@ func main() { It is equivalent to the following Python code: + + ```py import math @@ -163,6 +175,8 @@ Here, We call `py.Float(2)` to create a Python number 2, and pass it to Python Let's look at a slightly more complex example. For example, we use `numpy` to calculate: + + ```go package main @@ -340,20 +354,24 @@ Follow these steps to generate the `llgo` command (its usage is the same as the ### on macOS + + ```sh brew update -brew install llvm@18 pkg-config bdw-gc openssl +brew install llvm@18 pkg-config bdw-gc openssl cjson brew install python@3.12 # optional go install -v github.com/goplus/llgo/cmd/llgo@latest ``` ### on Linux (Debian/Ubuntu) + + ```sh echo "deb http://apt.llvm.org/$(lsb_release -cs)/ llvm-toolchain-$(lsb_release -cs)-18 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-18-dev clang-18 lld-18 pkg-config libgc-dev libssl-dev zlib1g-dev +sudo apt-get install -y llvm-18-dev clang-18 libclang-18-dev lld-18 pkg-config libgc-dev libssl-dev zlib1g-dev libcjson-dev python3.12-dev sudo apt-get install -y python3.12-dev # optional go install -v github.com/goplus/llgo/cmd/llgo@latest ``` @@ -373,9 +391,12 @@ TODO How do I generate these tools? + + ```sh git clone https://github.com/goplus/llgo.git cd llgo +go install -v ./cmd/... go install -v ./chore/... # compile all tools except pydump cd chore/_xtool llgo install ./... # compile pydump diff --git a/doc/_readme/llgo_call_c/call_c.go b/doc/_readme/llgo_call_c/call_c.go new file mode 100644 index 00000000..b9c1686e --- /dev/null +++ b/doc/_readme/llgo_call_c/call_c.go @@ -0,0 +1,10 @@ +package main + +import _ "unsafe" // for go:linkname + +//go:linkname Sqrt C.sqrt +func Sqrt(x float64) float64 + +func main() { + println("sqrt(2) =", Sqrt(2)) +} diff --git a/doc/_readme/llgo_call_cmath/call_cmath.go b/doc/_readme/llgo_call_cmath/call_cmath.go new file mode 100644 index 00000000..90f7888c --- /dev/null +++ b/doc/_readme/llgo_call_cmath/call_cmath.go @@ -0,0 +1,7 @@ +package main + +import "github.com/goplus/llgo/c/math" + +func main() { + println("sqrt(2) =", math.Sqrt(2)) +} diff --git a/doc/_readme/llgo_call_py/call_math.py b/doc/_readme/llgo_call_py/call_math.py new file mode 100644 index 00000000..80491f6f --- /dev/null +++ b/doc/_readme/llgo_call_py/call_math.py @@ -0,0 +1,4 @@ +import math + +x = math.sqrt(2) +print("sqrt =", x) diff --git a/doc/_readme/llgo_call_py/call_py.go b/doc/_readme/llgo_call_py/call_py.go new file mode 100644 index 00000000..a35c514f --- /dev/null +++ b/doc/_readme/llgo_call_py/call_py.go @@ -0,0 +1,12 @@ +package main + +import ( + "github.com/goplus/llgo/py" + "github.com/goplus/llgo/py/math" + "github.com/goplus/llgo/py/std" +) + +func main() { + x := math.Sqrt(py.Float(2)) // x = sqrt(2) + std.Print(py.Str("sqrt(2) ="), x) // print("sqrt(2) =", x) +} diff --git a/doc/_readme/llgo_py_list/py_list.go b/doc/_readme/llgo_py_list/py_list.go new file mode 100644 index 00000000..e88fa011 --- /dev/null +++ b/doc/_readme/llgo_py_list/py_list.go @@ -0,0 +1,22 @@ +package main + +import ( + "github.com/goplus/llgo/py" + "github.com/goplus/llgo/py/numpy" + "github.com/goplus/llgo/py/std" +) + +func main() { + a := py.List( + py.List(1.0, 2.0, 3.0), + py.List(4.0, 5.0, 6.0), + py.List(7.0, 8.0, 9.0), + ) + b := py.List( + py.List(9.0, 8.0, 7.0), + py.List(6.0, 5.0, 4.0), + py.List(3.0, 2.0, 1.0), + ) + x := numpy.Add(a, b) + std.Print(py.Str("a+b ="), x) +} diff --git a/doc/_readme/llgo_simple/simple.go b/doc/_readme/llgo_simple/simple.go new file mode 100644 index 00000000..63f1b7f5 --- /dev/null +++ b/doc/_readme/llgo_simple/simple.go @@ -0,0 +1,7 @@ +package main + +import "github.com/goplus/llgo/c" + +func main() { + c.Printf(c.Str("Hello world\n")) +} diff --git a/doc/_readme/scripts/install_llgo.sh b/doc/_readme/scripts/install_llgo.sh new file mode 100644 index 00000000..a87d203d --- /dev/null +++ b/doc/_readme/scripts/install_llgo.sh @@ -0,0 +1,8 @@ +# shellcheck disable=all +git clone https://github.com/goplus/llgo.git +cd llgo +go install -v ./cmd/... +go install -v ./chore/... # compile all tools except pydump +cd chore/_xtool +llgo install ./... # compile pydump +go install github.com/goplus/hdq/chore/pysigfetch@v0.8.1 # compile pysigfetch \ No newline at end of file diff --git a/doc/_readme/scripts/install_macos.sh b/doc/_readme/scripts/install_macos.sh new file mode 100644 index 00000000..9892979d --- /dev/null +++ b/doc/_readme/scripts/install_macos.sh @@ -0,0 +1,5 @@ +# shellcheck disable=all +brew update +brew install llvm@18 pkg-config bdw-gc openssl cjson +brew install python@3.12 # optional +go install -v github.com/goplus/llgo/cmd/llgo@latest \ No newline at end of file diff --git a/doc/_readme/scripts/install_ubuntu.sh b/doc/_readme/scripts/install_ubuntu.sh new file mode 100644 index 00000000..069e6170 --- /dev/null +++ b/doc/_readme/scripts/install_ubuntu.sh @@ -0,0 +1,7 @@ +# shellcheck disable=all +echo "deb http://apt.llvm.org/$(lsb_release -cs)/ llvm-toolchain-$(lsb_release -cs)-18 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-18-dev clang-18 libclang-18-dev lld-18 pkg-config libgc-dev libssl-dev zlib1g-dev libcjson-dev python3.12-dev +sudo apt-get install -y python3.12-dev # optional +go install -v github.com/goplus/llgo/cmd/llgo@latest \ No newline at end of file diff --git a/doc/_readme/scripts/run.sh b/doc/_readme/scripts/run.sh new file mode 100644 index 00000000..f54b5257 --- /dev/null +++ b/doc/_readme/scripts/run.sh @@ -0,0 +1,10 @@ +#!/bin/bash +cd ./doc/_readme/ || exit 1 +llgo build -v ./... +pip3 install --user numpy +for dir in ./*/; do + if grep -q "func main()" "$dir"/*.go 2>/dev/null; then + echo "Running examples in $dir" + llgo run "$dir" + fi +done