Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add macOS support and CI workflow #5

Merged
merged 11 commits into from
Aug 14, 2024
30 changes: 30 additions & 0 deletions .github/workflows/run_examples.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Run examples

on: [push, pull_request]

env:
CGO_ENABLED: 0

jobs:
run:
strategy:
matrix:
os: [ubuntu-latest, macos-latest]

runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@v4
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: '1.22.x'
- name: Install libffi
if: runner.os == 'macOS'
run: |
brew update
brew install libffi
- name: Run example
run: go run examples/simple/cos/main_unix.go
env:
DYLD_FALLBACK_LIBRARY_PATH: $DYLD_FALLBACK_LIBRARY_PATH:/opt/homebrew/opt/libffi/lib
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ You can use [purego](https://github.com/ebitengine/purego) to call C code withou

## Requirements
### OS/Architecture
- darwin/amd64
- darwin/arm64
- freebsd/amd64
- freebsd/arm64
- linux/amd64
Expand Down Expand Up @@ -42,6 +44,16 @@ Note: Use this `-gcflags="github.com/ebitengine/purego/internal/fakecgo=-std"` b
#### Windows
You need a `libffi-8.dll` next to the executable/root folder of your project or inside C:\Windows\System32. If you don't want to build libffi from source, you can find this dll for example inside the [Windows embeddable package](https://www.python.org/downloads/windows/) of Python.

#### macOS
You can use [Homebrew](https://brew.sh/) to install libffi:
```sh
brew install libffi
```
Note: If dlopen can't find the libffi.8.dylib file, you can try setting this environment variable:
```sh
export DYLD_FALLBACK_LIBRARY_PATH=$DYLD_FALLBACK_LIBRARY_PATH:/opt/homebrew/opt/libffi/lib
```

## Examples
In this example we use the puts function inside the standard C library to print "Hello World!" to the console:

Expand Down
2 changes: 1 addition & 1 deletion abi.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//go:build ((freebsd || linux) && arm64) || (windows && (amd64 || arm64))
//go:build ((freebsd || linux || darwin) && arm64) || (windows && (amd64 || arm64))

package ffi

Expand Down
2 changes: 1 addition & 1 deletion abi_amd64.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//go:build freebsd || linux
//go:build freebsd || linux || darwin

package ffi

Expand Down
4 changes: 3 additions & 1 deletion examples/simple/cos/main_unix.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//go:build (freebsd || linux) && (amd64 || arm64)
//go:build (freebsd || linux || darwin) && (amd64 || arm64)

package main

Expand All @@ -18,6 +18,8 @@ func main() {
filename = "libm.so.6"
case "freebsd":
filename = "libm.so.5"
case "darwin":
filename = "libm.dylib"
}

// open the shared library
Expand Down
2 changes: 1 addition & 1 deletion ffi.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//go:build (freebsd || linux || windows) && (amd64 || arm64)
//go:build (freebsd || linux || windows || darwin) && (amd64 || arm64)

package ffi

Expand Down
31 changes: 31 additions & 0 deletions ffi_darwin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//go:build darwin && (amd64 || arm64)

package ffi

import (
"github.com/ebitengine/purego"
)

func init() {
const filename = "libffi.8.dylib"

libffi, err := purego.Dlopen(filename, purego.RTLD_LAZY)
if err != nil {
panic(err)
}

prepCif, err = purego.Dlsym(libffi, "ffi_prep_cif")
if err != nil {
panic(err)
}

prepCifVar, err = purego.Dlsym(libffi, "ffi_prep_cif_var")
if err != nil {
panic(err)
}

call, err = purego.Dlsym(libffi, "ffi_call")
if err != nil {
panic(err)
}
}
2 changes: 1 addition & 1 deletion types.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//go:build (freebsd || linux || windows) && (amd64 || arm64)
//go:build (freebsd || linux || windows || darwin) && (amd64 || arm64)

package ffi

Expand Down