github.com/goplus/llgo@v0.8.3/README.md (about)

     1  llgo - A Go compiler based on LLVM
     2  =====
     3  
     4  [![Build Status](https://github.com/goplus/llgo/actions/workflows/go.yml/badge.svg)](https://github.com/goplus/llgo/actions/workflows/go.yml)
     5  [![Go Report Card](https://goreportcard.com/badge/github.com/goplus/llgo)](https://goreportcard.com/report/github.com/goplus/llgo)
     6  [![GitHub release](https://img.shields.io/github/v/tag/goplus/llgo.svg?label=release)](https://github.com/goplus/llgo/releases)
     7  [![Coverage Status](https://codecov.io/gh/goplus/llgo/branch/main/graph/badge.svg)](https://codecov.io/gh/goplus/llgo)
     8  [![GoDoc](https://pkg.go.dev/badge/github.com/goplus/llgo.svg)](https://pkg.go.dev/github.com/goplus/llgo)
     9  [![Language](https://img.shields.io/badge/language-Go+-blue.svg)](https://github.com/goplus/gop)
    10  
    11  LLGo is a Go compiler based on LLVM in order to better integrate Go with the C ecosystem including Python. It's a subproject of [the Go+ project](https://github.com/goplus/gop).
    12  
    13  
    14  ## C standard libary support
    15  
    16  ```go
    17  package main
    18  
    19  import "github.com/goplus/llgo/c"
    20  
    21  func main() {
    22  	c.Printf(c.Str("Hello world\n"))
    23  }
    24  ```
    25  
    26  This is a simple example of calling the C `printf` function to print `Hello world`. Here, `c.Str` is not a function for converting a Go string to a C string, but a built-in instruction supported by `llgo` for generating a C string constant.
    27  
    28  The `_demo` directory contains some C standard libary related demos (it start with `_` to prevent the `go` command from compiling it):
    29  
    30  * [hello](_demo/hello/hello.go): call C `printf` to print `Hello world`
    31  * [concat](_demo/concat/concat.go): call C `fprintf` with `stderr`
    32  * [qsort](_demo/qsort/qsort.go): call C function with a callback (eg. `qsort`)
    33  
    34  To run these demos (If you haven't installed `llgo` yet, please refer to [How to install](#how-to-install)):
    35  
    36  ```sh
    37  export LLGOROOT=`pwd`
    38  cd <demo-directory>  # eg. cd _demo/hello
    39  llgo run .
    40  ```
    41  
    42  See [github.com/goplus/llgo/c](https://pkg.go.dev/github.com/goplus/llgo/c) for more detials.
    43  
    44  
    45  ## Python support
    46  
    47  You can import a Python library in LLGo!
    48  
    49  And you can import any Python library into `llgo` through a program called `llpyg` (see [Development tools](#development-tools)). The currently imported libraries include:
    50  
    51  * [sys](https://pkg.go.dev/github.com/goplus/llgo/py/sys)
    52  * [os](https://pkg.go.dev/github.com/goplus/llgo/py/os)
    53  * [math](https://pkg.go.dev/github.com/goplus/llgo/py/math)
    54  * [json](https://pkg.go.dev/github.com/goplus/llgo/py/json)
    55  * [inspect](https://pkg.go.dev/github.com/goplus/llgo/py/inspect)
    56  * [statistics](https://pkg.go.dev/github.com/goplus/llgo/py/statistics)
    57  * [numpy](https://pkg.go.dev/github.com/goplus/llgo/py/numpy)
    58  
    59  Here is an example using the Python `math` library:
    60  
    61  ```go
    62  package main
    63  
    64  import (
    65  	"github.com/goplus/llgo/c"
    66  	"github.com/goplus/llgo/py"
    67  	"github.com/goplus/llgo/py/math"
    68  )
    69  
    70  func main() {
    71  	x := math.Sqrt(py.Float(2))
    72  	c.Printf(c.Str("sqrt(2) = %f\n"), x.Float64())
    73  }
    74  ```
    75  
    76  Here, We call `py.Float(2)` to create a Python number 2, and pass it to Python’s `math.sqrt` to get `x`. Then use `x.Float64()` to convert x to Go's `float64` type, and print the value through the C `printf` function.
    77  
    78  Let's look at a slightly more complex example. For example, we use `numpy` to calculate:
    79  
    80  ```go
    81  package main
    82  
    83  import (
    84  	"github.com/goplus/llgo/c"
    85  	"github.com/goplus/llgo/py"
    86  	"github.com/goplus/llgo/py/numpy"
    87  )
    88  
    89  func main() {
    90  	a := py.List(
    91  		py.List(1.0, 2.0, 3.0),
    92  		py.List(4.0, 5.0, 6.0),
    93  		py.List(7.0, 8.0, 9.0),
    94  	)
    95  	b := py.List(
    96  		py.List(9.0, 8.0, 7.0),
    97  		py.List(6.0, 5.0, 4.0),
    98  		py.List(3.0, 2.0, 1.0),
    99  	)
   100  	x := numpy.Add(a, b)
   101  	c.Printf(c.Str("a+b = %s\n"), x.Str().CStr())
   102  }
   103  ```
   104  
   105  Here we define two 3x3 matrices a and b, add them to get x, and then print the result.
   106  
   107  The `_pydemo` directory contains some python related demos:
   108  
   109  * [callpy](_pydemo/callpy/callpy.go): call Python standard library function `math.sqrt`
   110  * [pi](_pydemo/pi/pi.go): print python constants `math.pi`
   111  * [statistics](_pydemo/statistics/statistics.go): define a python list and call `statistics.mean` to get the mean
   112  * [matrix](_pydemo/matrix/matrix.go): a basic `numpy` demo
   113  
   114  To run these demos, you need to set the `LLGO_LIB_PYTHON` environment variable first.
   115  
   116  If Python is in the search path for `clang` linking, then `LLGO_LIB_PYTHON` only needs to be set to the name of the Python library. For example:
   117  
   118  ```sh
   119  export LLGO_LIB_PYTHON=python3.12
   120  ```
   121  
   122  You can also specify the path to tell `llgo` where the Python library is located:
   123  
   124  ```sh
   125  export LLGO_LIB_PYTHON=/foo/bar/python3.12
   126  ```
   127  
   128  For example, `/opt/homebrew/Frameworks/Python.framework/Versions/3.12/libpython3.12.dylib` is a typical python library location under macOS. So we should set it like this:
   129  
   130  ```sh
   131  export LLGO_LIB_PYTHON=/opt/homebrew/Frameworks/Python.framework/Versions/3.12/python3.12
   132  ```
   133  
   134  Note that the file name must be written in a platform-independent format, using `python3.12` instead of `libpython3.12.dylib`.
   135  
   136  Then you can run the demos:
   137  
   138  ```sh
   139  export LLGOROOT=`pwd`
   140  cd <demo-directory>  # eg. cd _pydemo/callpy
   141  llgo run .
   142  ```
   143  
   144  See [github.com/goplus/llgo/py](https://pkg.go.dev/github.com/goplus/llgo/py) for more detials.
   145  
   146  
   147  ## Other frequently used libraries
   148  
   149  LLGo can easily import any libraries from the C ecosystem. Currently, this import process is still manual, but in the future, it will be automated similar to Python library imports.
   150  
   151  The currently imported libraries include:
   152  
   153  * [llama2.c](https://pkg.go.dev/github.com/goplus/llgo/c/llama2)
   154  * [cjson](https://pkg.go.dev/github.com/goplus/llgo/c/cjson)
   155  * [sqlite](https://pkg.go.dev/github.com/goplus/llgo/c/sqlite)
   156  
   157  Here are some examples related to them:
   158  
   159  * [llama2-c](_demo/llama2-c): inference Llama 2 (It's the first llgo AI example)
   160  * [mkjson](c/cjson/_demo/mkjson/mkjson.go): create a json object and print it
   161  * [sqlitedemo](c/sqlite/_demo/sqlitedemo/demo.go): a basic sqlite demo
   162  
   163  
   164  ## Go syntax support
   165  
   166  The priority of `llgo` feature iteration is:
   167  
   168  * Popular C/Python libraries
   169  * Full Go syntax
   170  * Go standard libraries
   171  * Popular Go packages
   172  
   173  Common Go syntax is already supported. Except for the following, which needs to be improved:
   174  
   175  * interface (Limited support)
   176  * map (Very limited support)
   177  * panic (Limited support)
   178  * recover (Not supported yet)
   179  * defer (Not supported yet)
   180  * gc (Not supported yet)
   181  * chan (Not supported yet)
   182  * goroutine (Not supported yet)
   183  * generics (Not supported yet)
   184  
   185  Here are some examples related to Go syntax:
   186  
   187  * [concat](_demo/concat/concat.go): define a variadic function
   188  * [genints](_demo/genints/genints.go): various forms of closure usage (including C function, recv.method and anonymous function)
   189  
   190  
   191  ## How to install
   192  
   193  Follow these steps to generate the `llgo` command (its usage is the same as the `go` command):
   194  
   195  ### on macOS
   196  
   197  ```sh
   198  brew update  # execute if needed
   199  brew install llvm@17
   200  go install -v ./...
   201  ```
   202  
   203  ### on Linux
   204  
   205  ```sh
   206  echo 'deb http://apt.llvm.org/focal/ llvm-toolchain-focal-17 main' | sudo tee /etc/apt/sources.list.d/llvm.list
   207  wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
   208  sudo apt-get update  # execute if needed
   209  sudo apt-get install --no-install-recommends llvm-17-dev
   210  go install -v ./...
   211  ```
   212  
   213  ### on Windows
   214  
   215  TODO
   216  
   217  
   218  ## Development tools
   219  
   220  * [pydump](chore/_xtool/pydump): It's the first program compiled by `llgo` (NOT `go`) in a production environment. It outputs symbol information (functions, variables, and constants) from a Python library in JSON format, preparing for the generation of corresponding packages in `llgo`.
   221  * [llpyg](chore/llpyg): It is used to automatically convert Python libraries into Go packages that `llgo` can import. It depends on `pydump` to accomplish the task.
   222  * [llgen](chore/llgen): It is used to compile Go packages into LLVM IR files (*.ll).
   223  * [ssadump](chore/ssadump): It is a Go SSA builder and interpreter.
   224  
   225  How do I generate these tools?
   226  
   227  ```sh
   228  go install -v ./...  # compile all tools except pydump
   229  cd chore/_xtool
   230  llgo install ./...   # compile pydump
   231  ```
   232  
   233  ## Key modules
   234  
   235  Below are the key modules for understanding the implementation principles of `llgo`:
   236  
   237  * [llgo/ssa](https://pkg.go.dev/github.com/goplus/llgo/ssa): It generates LLVM IR files (LLVM SSA) using the semantics (interfaces) of Go SSA. Although `LLVM SSA` and `Go SSA` are both IR languages, they work at completely different levels. `LLVM SSA` is closer to machine code, which abstracts different instruction sets. While `Go SSA` is closer to a high-level language. We can think of it as the instruction set of the `Go computer`. `llgo/ssa` is not just limited to the `llgo` compiler. If we view it as the high-level expressive power of `LLVM`, you'll find it very useful. Prior to `llgo/ssa`, you had to operate `LLVM` using machine code semantics. But now, with the advanced SSA form (in the semantics of Go SSA), you can conveniently utilize `LLVM`.
   238  * [llgo/cl](https://pkg.go.dev/github.com/goplus/llgo/cl): It is the core of the llgo compiler. It converts a Go package into LLVM IR files. It depends on `llgo/ssa`.
   239  * [llgo/internal/build](https://pkg.go.dev/github.com/goplus/llgo/internal/build): It strings together the entire compilation process of `llgo`. It depends on `llgo/ssa` and `llgo/cl`.