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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 16 additions & 71 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -1,76 +1,21 @@
# Test whether we can link to LLVM installed from apt.llvm.org or Homebrew.
---
name: Source checks

name: Test

on: [push, pull_request]
on:
push:
branches: [master]
pull_request:

jobs:
test-macos:
runs-on: macos-latest
strategy:
matrix:
llvm: [14, 15, 16, 17, 18, 19, 20, 21, 22]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.24'
# Optional step when a LLVM version is very new.
- name: Update Homebrew
run: brew update
- name: Install LLVM
run: HOMEBREW_NO_AUTO_UPDATE=1 brew install llvm@${{ matrix.llvm }}
- name: Test LLVM ${{ matrix.llvm }}
run:
go test -v -tags=llvm${{ matrix.llvm }}
test-linux:
runs-on: ubuntu-22.04
strategy:
matrix:
llvm: [14, 15, 16, 17, 18, 19, 20, 21, 22, 23]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.24'
- name: Install LLVM
run: |
suite=llvm-toolchain-jammy-${{ matrix.llvm }}
if [ "${{ matrix.llvm }}" = 23 ]; then
suite=llvm-toolchain-jammy
fi
echo "deb http://apt.llvm.org/jammy/ ${suite} 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 --no-install-recommends llvm-${{ matrix.llvm }}-dev
- name: Test LLVM ${{ matrix.llvm }}
run:
go test -v -tags=llvm${{ matrix.llvm }}
- name: Test default LLVM
if: matrix.llvm == 23
run:
go test -v
test-linux-fedora:
# Fedora uses different paths than other systems, so testing it separately.
format:
runs-on: ubuntu-24.04
strategy:
matrix:
llvm: [19, 20, 21]
container: fedora:43
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install dependencies (default LLVM)
if: matrix.llvm == 21
run: dnf install --assumeyes g++ golang llvm-devel
- name: Install dependencies (older LLVM)
if: matrix.llvm != 21
run: dnf install --assumeyes g++ golang llvm${{ matrix.llvm }}-devel
- name: Test LLVM ${{ matrix.llvm }}
run:
go test -v -tags=llvm${{ matrix.llvm }}
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: '1.25'
- name: Check Go formatting
run: test -z "$(gofmt -l .)"

# Full dynamic and static binding tests require the customized GoALLC LLVM
# payload. Restore those tests by downloading the project's prebuilt payload
# once it is published; do not build LLVM from source in this workflow.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
llvm-*.src.tar.xz
llvm-*/
/llvm
/libLLVMGoALLC.a*
59 changes: 39 additions & 20 deletions README.markdown
Original file line number Diff line number Diff line change
@@ -1,32 +1,51 @@
# Go bindings to system LLVM
# Go bindings for GoALLC LLVM

This library provides bindings to a system-installed LLVM.
This repository contains the LLVM Go bindings used by GoALLC. It intentionally
targets the customized LLVM build maintained by the GoALLC project; a
system-installed LLVM is not supported.

Currently supported:
## LLVM payload

* LLVM 23, 22, 21, 20, 19, 18, 17, 16, 15 and 14 from [apt.llvm.org](http://apt.llvm.org/) on Debian/Ubuntu.
* LLVM 23, 22, 21, 20, 19, 18, 17, 16, 15 and 14 from Homebrew on macOS.
* Any of the above versions with a manually built LLVM through the `byollvm` build tag. You need to set up `CFLAGS`/`LDFLAGS` etc yourself in this case.
The binding always reads LLVM headers below `${SRCDIR}/llvm`; dynamic linking
also reads the LLVM shared library there:

LLVM 23 is selected by default. You can select another LLVM version using a
build tag, for example `-tags=llvm17` to use LLVM 17. When using a manually
built LLVM 22 or newer, combine the version and custom-build tags, for example
`-tags="byollvm llvm23"`.
llvm/include/llvm-c
llvm/lib

The GoALLC in-tree static LLVM payload is selected explicitly with
`-tags=staticllvm`. Add a version tag when the payload is not LLVM 23, for
example `-tags="staticllvm llvm20"`.
`llvm` is not committed. The caller must create it as a symlink to an LLVM
payload with this layout. GoALLC's `cmd/dist` manages that symlink from its
`-llvm-dir` option, whose default is `$GOROOT/llvm`.

## Usage
## Build tags

If you have a supported LLVM installation, you should be able to do a simple `go get`:
The LLVM API version and link mode are independent, mandatory build-tag axes:

go get tinygo.org/x/go-llvm
* `llvm23` selects the LLVM 23 API. A future LLVM 24 port will add `llvm24`
without changing how the payload path or link mode is selected.
* `dynamicllvm` links `llvm/lib/libLLVM`; it is the GoALLC default.
* `staticllvm` links `${SRCDIR}/libLLVMGoALLC.a`. GoALLC's `cmd/dist`
assembles and caches this build artifact from the selected payload's normal
LLVM component archives with `llvm-config` and `llvm-ar`.

You can use build tags to select a LLVM version. For example, use `-tags=llvm15` to select LLVM 15. Setting a build tag for a LLVM version that is not supported will be ignored.
For example:

## License
go test -tags='llvm23 dynamicllvm' ./...
go test -tags='llvm23 staticllvm' ./...

The static command requires `libLLVMGoALLC.a` to have been assembled first.
The GoALLC toolchain does this automatically for `-llvm-link=static`.

Do not select multiple version tags or multiple link-mode tags in one build.

These LLVM bindings for Go originally come from LLVM, but they have since been [removed](https://discourse.llvm.org/t/rfc-remove-the-go-bindings/65725). Still, they remain under the same license as they were originally, which is the [Apache License 2.0 (with LLVM exceptions)](http://releases.llvm.org/9.0.0/LICENSE.TXT). Check upstream LLVM for detailed copyright information.
## Continuous integration

Automatic pull-request checks currently validate the binding source only. Full
dynamic and static tests require the customized GoALLC LLVM payload and are
validated as part of integration work. Once the project publishes prebuilt LLVM
payloads, CI will download those artifacts and run both link modes without
rebuilding LLVM from source.

## License

This README, the backports\* files, and the Makefile are separate from LLVM but are licensed under the same license.
These bindings originated in LLVM and remain licensed under the Apache License
2.0 with LLVM Exceptions. See `LICENSE.txt`.
2 changes: 1 addition & 1 deletion branch_llvm23.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//go:build llvm23 || (!byollvm && !llvm14 && !llvm15 && !llvm16 && !llvm17 && !llvm18 && !llvm19 && !llvm20 && !llvm21 && !llvm22)
//go:build llvm23

package llvm

Expand Down
13 changes: 0 additions & 13 deletions branch_pre23.go

This file was deleted.

33 changes: 0 additions & 33 deletions gen_llvm_config_static.sh

This file was deleted.

35 changes: 35 additions & 0 deletions goallc_ext.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package llvm

/*
#include "llvm-c/Core.h"
#include <stdlib.h>
*/
import "C"

import (
"errors"
"unsafe"
)

func LLVMPrintModuleToFile(module Module, filename string) error {
filenamestr := C.CString(filename)
defer C.free(unsafe.Pointer(filenamestr))
var errmsg *C.char
if C.LLVMPrintModuleToFile(module.C, filenamestr, &errmsg) != 0 {
err := errors.New(C.GoString(errmsg))
C.LLVMDisposeMessage(errmsg)
return err
}
return nil
}

func LLVMSetValueName2(value Value, name string) {
namestr := C.CString(name)
defer C.free(unsafe.Pointer(namestr))
C.LLVMSetValueName2(value.C, namestr, C.size_t(len(name)))
}

func (c Context) PointerType(addressSpace uint32) (t Type) {
t.C = C.LLVMPointerTypeInContext(c.C, C.unsigned(addressSpace))
return
}
4 changes: 0 additions & 4 deletions llvm/bin/.gitignore

This file was deleted.

4 changes: 0 additions & 4 deletions llvm/include/.gitignore

This file was deleted.

4 changes: 0 additions & 4 deletions llvm/lib/.gitignore

This file was deleted.

4 changes: 0 additions & 4 deletions llvm/share/.gitignore

This file was deleted.

9 changes: 9 additions & 0 deletions llvm_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package llvm

/*
#cgo darwin CPPFLAGS: -I${SRCDIR}/llvm/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
#cgo linux CPPFLAGS: -I${SRCDIR}/llvm/include -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
#cgo darwin CXXFLAGS: -std=c++17
#cgo linux CXXFLAGS: -std=c++17
*/
import "C"
16 changes: 0 additions & 16 deletions llvm_config_llvm14.go

This file was deleted.

16 changes: 0 additions & 16 deletions llvm_config_llvm15.go

This file was deleted.

16 changes: 0 additions & 16 deletions llvm_config_llvm16.go

This file was deleted.

16 changes: 0 additions & 16 deletions llvm_config_llvm17.go

This file was deleted.

16 changes: 0 additions & 16 deletions llvm_config_llvm18.go

This file was deleted.

19 changes: 0 additions & 19 deletions llvm_config_llvm19.go

This file was deleted.

Loading
Loading