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
127 changes: 127 additions & 0 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,133 @@ jobs:
if: matrix.llvm == 19
run:
go test -v
test-windows:
runs-on: windows-latest
strategy:
fail-fast: false
matrix:
include:
- llvm: 14
version: '14.0.6'
sha256: a46a843b0899d284f2a1c76e15aa9a6f3e939925ed008fd4b3b68c5f2f0c8231
- llvm: 15
version: '15.0.7'
sha256: 8c55ba91a041507bd927c5f82348c36ef3696485afb71c51bbcc35a014d179de
- llvm: 16
version: '16.0.6'
sha256: 8082a28d7ff50e5dfdace530935e3e59c37d11f1f8b52f43b7dc3b2fa130be66
- llvm: 17
version: '17.0.6'
sha256: 773f122cd79a54ecf3cbf1b1aff47543e95b12b4f91278b29c70cade37e3018c
- llvm: 18
version: '18.1.8'
sha256: 7cb37bafd78874e707d0c323f8e16e81503bc76867638ef1c634ee0451fac0be
- llvm: 19
version: '19.1.7'
sha256: d39689f23e1143a710a9120741ac3a1621fc4e2a81a143959bc870c60f9b85d1
- llvm: 20
version: '20.1.8'
sha256: 0944367aff9c3619f98dd0db78a1489018af9a8501b2533d17cc143a9624d853
- llvm: 21
version: '21.1.4'
sha256: f18f364b3aea5e4d09a4ed58d1c34b7220883912662e39935af96fabd603a912
- llvm: 22
version: '22.1.0'
sha256: 00199342f0cedfae60421d5d4ce0f1e217a06d7617611c8541372c47269c7084
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.22'
- name: Set up MSYS2
uses: msys2/setup-msys2@v2
with:
msystem: MINGW64
path-type: inherit
update: true
install: >-
mingw-w64-x86_64-gcc
mingw-w64-x86_64-pkgconf
- name: Install LLVM ${{ matrix.llvm }}
shell: pwsh
run: |
$archiveName = 'llvm-${{ matrix.version }}-windows-gnu.zip'
$archive = Join-Path $env:RUNNER_TEMP $archiveName
$url = "https://github.com/yasuo-ozu/llvm-full/releases/download/v${{ matrix.version }}/$archiveName"
curl.exe --fail --location --retry 3 --output $archive $url
if ($LASTEXITCODE -ne 0) {
throw "failed to download $url"
}

$actualSha256 = (Get-FileHash -Algorithm SHA256 $archive).Hash.ToLowerInvariant()
if ($actualSha256 -ne '${{ matrix.sha256 }}') {
throw "expected SHA-256 ${{ matrix.sha256 }}, got $actualSha256"
}

$prefix = Join-Path $env:RUNNER_TEMP 'llvm-${{ matrix.version }}'
New-Item -ItemType Directory -Force -Path $prefix | Out-Null
7z x $archive "-o$prefix" -y
if ($LASTEXITCODE -ne 0) {
throw "failed to extract $archive"
}
Remove-Item $archive

if (-not (Test-Path (Join-Path $prefix 'bin\llvm-config.exe'))) {
throw "llvm-config.exe is missing from $prefix"
}
"LLVM_PREFIX=$prefix" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
- name: Test LLVM ${{ matrix.llvm }}
shell: msys2 {0}
run: |
set -euo pipefail

llvm_bin="$(cygpath -u "$LLVM_PREFIX")/bin"
export PATH="$llvm_bin:$PATH"
llvm_version="$(llvm-config --version)"
if [[ "$llvm_version" != '${{ matrix.version }}' ]]; then
echo "expected LLVM ${{ matrix.version }}, got $llvm_version" >&2
exit 1
fi

# Supply the installed LLVM's include and library paths through the
# versioned pkg-config name consumed by the Windows binding.
pc_dir="$(cygpath -u "$RUNNER_TEMP")/llvm-pkgconfig"
mkdir -p "$pc_dir"
cflags="$(llvm-config --cflags | tr '\r\n' ' ')"
# The release archives can embed their build machine's zstd import
# library path, and their static LLVM libraries require winpthread.
ldflags="$(llvm-config --ldflags --libs all --system-libs | tr '\r\n' ' ' | sed -E 's#[^[:space:]]*/mingw64/lib/libzstd\.dll\.a#-lzstd#g') -lwinpthread"
printf '%s\n' \
'Name: LLVM ${{ matrix.llvm }}' \
'Description: LLVM ${{ matrix.llvm }} host compiler and linker flags' \
"Version: $llvm_version" \
"Cflags: $cflags" \
"Libs: $ldflags" \
> "$pc_dir/llvm-${{ matrix.llvm }}.pc"

export CC=gcc
export CXX=g++
export CGO_ENABLED=1
PKG_CONFIG_PATH="$(cygpath -m "$pc_dir")"
export PKG_CONFIG_PATH
gcc --version
go test -v -tags=llvm${{ matrix.llvm }}
- name: Test default LLVM
if: matrix.llvm == 19
shell: msys2 {0}
run: |
set -euo pipefail
llvm_bin="$(cygpath -u "$LLVM_PREFIX")/bin"
export PATH="$llvm_bin:$PATH"
export CC=gcc
export CXX=g++
export CGO_ENABLED=1
pc_dir="$(cygpath -u "$RUNNER_TEMP")/llvm-pkgconfig"
PKG_CONFIG_PATH="$(cygpath -m "$pc_dir")"
export PKG_CONFIG_PATH
go test -v
test-linux-fedora:
# Fedora uses different paths than other systems, so testing it separately.
runs-on: ubuntu-24.04
Expand Down
37 changes: 35 additions & 2 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ This library provides bindings to a system-installed LLVM.

Currently supported:

* LLVM 20, 19, 18, 17, 16, 15 and 14 from [apt.llvm.org](http://apt.llvm.org/) on Debian/Ubuntu.
* LLVM 20, 19, 18, 17, 16, 15 and 14 from Homebrew on macOS.
* LLVM 22, 21, 20, 19, 18, 17, 16, 15 and 14 from [apt.llvm.org](http://apt.llvm.org/) on Debian/Ubuntu.
* LLVM 22, 21, 20, 19, 18, 17, 16, 15 and 14 from Homebrew on macOS.
* LLVM 22, 21, 20, 19, 18, 17, 16, 15 and 14 in an MSYS2 MINGW64 environment on Windows (see the setup below).
* 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.

You can select the LLVM version using a build tag, for example `-tags=llvm17`
Expand All @@ -26,6 +27,38 @@ If you have a supported LLVM installation, you should be able to do a simple `go

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.

### Windows (MSYS2 MINGW64)

The Windows bindings expect `pkg-config` metadata named after the selected LLVM
major version, such as `llvm-19`. After installing a MinGW-compatible LLVM,
`mingw-w64-x86_64-gcc`, and `mingw-w64-x86_64-pkgconf` in a MINGW64
environment, generate that file from `llvm-config`:

pc_dir="$PWD/.llvm-pkgconfig"
mkdir -p "$pc_dir"
llvm_version="$(llvm-config --version)"
llvm_major="${llvm_version%%.*}"
case "$llvm_major" in
14|15|16|17|18|19|20|21|22) ;;
*) echo "unsupported LLVM version: $llvm_version" >&2; exit 1 ;;
esac
cflags="$(llvm-config --cflags | tr '\r\n' ' ')"
# Normalize the release build machine's zstd path and link winpthread.
ldflags="$(llvm-config --ldflags --libs all --system-libs | tr '\r\n' ' ' | sed -E 's#[^[:space:]]*/mingw64/lib/libzstd\.dll\.a#-lzstd#g') -lwinpthread"
printf '%s\n' \
"Name: LLVM $llvm_major" \
"Description: LLVM $llvm_major host compiler and linker flags" \
"Version: $llvm_version" \
"Cflags: $cflags" \
"Libs: $ldflags" \
> "$pc_dir/llvm-$llvm_major.pc"
export PKG_CONFIG_PATH="$(cygpath -m "$pc_dir")"
export CC=gcc CXX=g++ CGO_ENABLED=1
go test -tags="llvm$llvm_major"

The Windows CI job in [`.github/workflows/go.yml`](.github/workflows/go.yml)
shows the exact LLVM versions and SHA-256 checksums used by this project.

## License

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.
Expand Down
3 changes: 2 additions & 1 deletion archive_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ package llvm

import (
"bytes"
"fmt"
"os"
"path/filepath"
"strings"
Expand Down Expand Up @@ -74,7 +75,7 @@ func TestWriteArchiveRejectsInvalidMembers(t *testing.T) {
{name: "empty path", members: []ArchiveMember{{}}, want: "archive path is empty"},
{name: "no members", path: path, want: "archive has no members"},
{name: "empty member", path: path, members: []ArchiveMember{{}}, want: "has no file or memory buffer"},
{name: "missing file", path: path, members: []ArchiveMember{NewArchiveMemberFromFile(missing)}, want: missing},
{name: "missing file", path: path, members: []ArchiveMember{NewArchiveMemberFromFile(missing)}, want: fmt.Sprintf("%q", missing)},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down
2 changes: 2 additions & 0 deletions llvm_config_llvm14.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ package llvm
// #cgo linux CPPFLAGS: -I/usr/lib/llvm-14/include -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
// #cgo linux CXXFLAGS: -std=c++14
// #cgo linux LDFLAGS: -L/usr/lib/llvm-14/lib -lLLVM-14
// #cgo windows pkg-config: llvm-14
// #cgo windows CXXFLAGS: -std=c++14
import "C"

type run_build_sh int
2 changes: 2 additions & 0 deletions llvm_config_llvm15.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ package llvm
// #cgo linux CPPFLAGS: -I/usr/lib/llvm-15/include -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
// #cgo linux CXXFLAGS: -std=c++14
// #cgo linux LDFLAGS: -L/usr/lib/llvm-15/lib -lLLVM-15
// #cgo windows pkg-config: llvm-15
// #cgo windows CXXFLAGS: -std=c++14
import "C"

type run_build_sh int
2 changes: 2 additions & 0 deletions llvm_config_llvm16.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ package llvm
// #cgo linux CPPFLAGS: -I/usr/lib/llvm-16/include -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
// #cgo linux CXXFLAGS: -std=c++17
// #cgo linux LDFLAGS: -L/usr/lib/llvm-16/lib -lLLVM-16
// #cgo windows pkg-config: llvm-16
// #cgo windows CXXFLAGS: -std=c++17
import "C"

type run_build_sh int
2 changes: 2 additions & 0 deletions llvm_config_llvm17.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ package llvm
// #cgo linux CPPFLAGS: -I/usr/include/llvm-17 -I/usr/include/llvm-c-17 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
// #cgo linux CXXFLAGS: -std=c++17
// #cgo linux LDFLAGS: -L/usr/lib/llvm-17/lib -lLLVM-17
// #cgo windows pkg-config: llvm-17
// #cgo windows CXXFLAGS: -std=c++17
import "C"

type run_build_sh int
2 changes: 2 additions & 0 deletions llvm_config_llvm18.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ package llvm
// #cgo linux CPPFLAGS: -I/usr/include/llvm-18 -I/usr/include/llvm-c-18 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
// #cgo linux CXXFLAGS: -std=c++17
// #cgo linux LDFLAGS: -L/usr/lib/llvm-18/lib -lLLVM-18
// #cgo windows pkg-config: llvm-18
// #cgo windows CXXFLAGS: -std=c++17
import "C"

type run_build_sh int
2 changes: 2 additions & 0 deletions llvm_config_llvm19.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ package llvm
// #cgo linux CPPFLAGS: -I/usr/include/llvm-19 -I/usr/include/llvm-c-19 -I/usr/lib64/llvm19/include -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
// #cgo linux CXXFLAGS: -std=c++17
// #cgo linux LDFLAGS: -L/usr/lib/llvm-19/lib -L/usr/lib64/llvm19/lib -lLLVM-19
// #cgo windows pkg-config: llvm-19
// #cgo windows CXXFLAGS: -std=c++17
import "C"

type run_build_sh int
2 changes: 2 additions & 0 deletions llvm_config_llvm20.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ package llvm
// #cgo linux CPPFLAGS: -I/usr/include/llvm-20 -I/usr/include/llvm-c-20 -I/usr/lib64/llvm20/include -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
// #cgo linux CXXFLAGS: -std=c++17
// #cgo linux LDFLAGS: -L/usr/lib/llvm-20/lib -L/usr/lib64/llvm20/lib64 -lLLVM-20
// #cgo windows pkg-config: llvm-20
// #cgo windows CXXFLAGS: -std=c++17
import "C"

type run_build_sh int
2 changes: 2 additions & 0 deletions llvm_config_llvm21.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ package llvm
// #cgo linux CPPFLAGS: -I/usr/include/llvm-21 -I/usr/include/llvm-c-21 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
// #cgo linux CXXFLAGS: -std=c++17
// #cgo linux LDFLAGS: -L/usr/lib/llvm-21/lib -lLLVM-21
// #cgo windows pkg-config: llvm-21
// #cgo windows CXXFLAGS: -std=c++17
import "C"

type run_build_sh int
2 changes: 2 additions & 0 deletions llvm_config_llvm22.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ package llvm
// #cgo linux CPPFLAGS: -I/usr/include/llvm-22 -I/usr/include/llvm-c-22 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
// #cgo linux CXXFLAGS: -std=c++17
// #cgo linux LDFLAGS: -L/usr/lib/llvm-22/lib -lLLVM-22
// #cgo windows pkg-config: llvm-22
// #cgo windows CXXFLAGS: -std=c++17
import "C"

type run_build_sh int
10 changes: 0 additions & 10 deletions llvm_config_windows_llvm20.go

This file was deleted.

Loading