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 Cgo support for NetBSD #268

Draft
wants to merge 33 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
10556e5
CGO support for Netbsd
TotallyGamerJet Aug 16, 2024
5068751
missing build tag
TotallyGamerJet Aug 16, 2024
92769ac
syscallArgs
TotallyGamerJet Aug 16, 2024
000117c
syscall15Args
TotallyGamerJet Aug 16, 2024
b23644e
some more
TotallyGamerJet Aug 16, 2024
68d652c
build tag
TotallyGamerJet Aug 16, 2024
cf0745d
test
TotallyGamerJet Aug 16, 2024
3c3731e
build tag for netbsd
TotallyGamerJet Aug 16, 2024
e87d728
some more stuff needed fixing
TotallyGamerJet Aug 17, 2024
0b92ec5
ignore tests
TotallyGamerJet Aug 17, 2024
68c9fa4
github actions
TotallyGamerJet Aug 18, 2024
4d82012
include go
TotallyGamerJet Aug 18, 2024
f37da23
examples/window: replace deprecated functions (#269)
hajimehoshi Aug 22, 2024
f8c7742
all: remove dependencies on golang.org/x/sys (#271)
hajimehoshi Aug 22, 2024
128551e
Clarify Example section and Dl* windows equivalents (#274)
TotallyGamerJet Aug 25, 2024
5ad9415
purego: mention LoadLibraryEx at Dlopen (#275)
hajimehoshi Aug 25, 2024
c3f4c9c
examples: remove depdencies on golang.org/x/sys/windows (#278)
hajimehoshi Sep 3, 2024
f091b66
all: release v0.9.0-alpha
hajimehoshi Sep 23, 2024
570751c
test
TotallyGamerJet Aug 25, 2024
4b324b2
fix install Go on freebsd
TotallyGamerJet Oct 14, 2024
7ab8812
fix install Go on freebsd
TotallyGamerJet Oct 14, 2024
3b55709
fix install Go
TotallyGamerJet Oct 15, 2024
ec53690
remove Go versions that dl doesn't have downloads for
TotallyGamerJet Oct 15, 2024
49cf092
mkdir
TotallyGamerJet Oct 15, 2024
ae1d516
specify default shell
TotallyGamerJet Oct 15, 2024
6c57d3f
disabled syncing to host VM
TotallyGamerJet Oct 15, 2024
ed60fb8
try installing bash
TotallyGamerJet Oct 15, 2024
c5caadb
prefix pkg_add
TotallyGamerJet Oct 15, 2024
d668211
try bash
TotallyGamerJet Oct 15, 2024
85a72ad
remove some bash references
TotallyGamerJet Oct 15, 2024
7773c24
go plugin not supported on netbsd
TotallyGamerJet Oct 15, 2024
9ddd066
remove echo
TotallyGamerJet Oct 15, 2024
ea999fd
Merge branch 'refs/heads/main' into issue-249_netbsd
TotallyGamerJet Oct 15, 2024
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
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/00-bug.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ body:
- label: macOS
- label: Linux
- label: FreeBSD
- label: NetBSD
- label: Android
- label: iOS
validations:
Expand Down
77 changes: 77 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,83 @@ jobs:
echo "=> go test CGO_ENABLED=1"
env CGO_ENABLED=1 go test -shuffle=on -v -count=10 ./...

if [ -z "$(echo ${{matrix.go}} | grep '^1.1')" ]; then
echo "=> go test race"
go test -race -shuffle=on -v -count=10 ./...
fi
netbsd:
Copy link
Member

@hajimehoshi hajimehoshi Aug 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add to build tests for NetBSD in other platforms (e.g. Can we build a NetBSD binary in FreeBSD?)

            # Check cross-compiling NetBSD binaries.
            env GOOS=netbsd GOARCH=amd64 go build -v ./...
            env GOOS=netbsd GOARCH=arm64 go build -v ./...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if it's possible. We'd need to explicitly enable cgo since it's a cross compile. I'll try once the build in NetBSD is working

strategy:
matrix:
go: ['1.21.13', '1.22.6', '1.23.0']
name: Test with Go ${{ matrix.go }} on NetBSD
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- name: Run in netbsd
uses: vmactions/netbsd-vm@v1
with:
usesh: true
prepare: |
/usr/sbin/pkg_add -v bash
ftp https://go.dev/dl/go${{matrix.go}}.netbsd-amd64.tar.gz
mkdir /usr/local
rm -fr /usr/local/go && tar -C /usr/local -xf go${{matrix.go}}.netbsd-amd64.tar.gz
ln -s /usr/local/go/bin/go /usr/local/bin
run: |
echo "Running tests on $(uname -a) at $PWD"

export PATH=$PATH:/usr/local/go/bin/

# verify Go is available
go version

echo "=> go build"
go build -v ./...
# Compile without optimization to check potential stack overflow.
# The option '-gcflags=all=-N -l' is often used at Visual Studio Code.
# See also https://go.googlesource.com/vscode-go/+/HEAD/docs/debugging.md#launch and the issue hajimehoshi/ebiten#2120.
go build "-gcflags=all=-N -l" -v ./...

# Check cross-compiling Windows binaries.
env GOOS=windows GOARCH=386 go build -v ./...
env GOOS=windows GOARCH=amd64 go build -v ./...
env GOOS=windows GOARCH=arm go build -v ./...
env GOOS=windows GOARCH=arm64 go build -v ./...

# Check cross-compiling macOS binaries.
env GOOS=darwin GOARCH=amd64 go build -v ./...
env GOOS=darwin GOARCH=arm64 go build -v ./...

# Check cross-compiling Linux binaries.
env GOOS=linux GOARCH=amd64 go build -v ./...
env GOOS=linux GOARCH=arm64 go build -v ./...

# Check cross-compiling FreeBSD binaries.
env GOOS=freebsd GOARCH=amd64 go build -gcflags="github.com/ebitengine/purego/internal/fakecgo=-std" -v ./...
env GOOS=freebsd GOARCH=arm64 go build -gcflags="github.com/ebitengine/purego/internal/fakecgo=-std" -v ./...

echo "=> go mod vendor"
mkdir /tmp/vendoring
cd /tmp/vendoring
go mod init foo
echo 'package main' > main.go
echo 'import (' >> main.go
echo ' _ "github.com/ebitengine/purego"' >> main.go
echo ')' >> main.go
echo 'func main() {}' >> main.go
go mod edit -replace github.com/ebitengine/purego=$GITHUB_WORKSPACE
go mod tidy
go mod vendor
go build -v .

# TODO: uncomment once Cgo is not required for NetBSD
# cd $GITHUB_WORKSPACE
# echo "=> go test CGO_ENABLED=0"
# env CGO_ENABLED=0 go test -gcflags="github.com/ebitengine/purego/internal/fakecgo=-std" -shuffle=on -v -count=10 ./...

echo "=> go test CGO_ENABLED=1"
env CGO_ENABLED=1 go test -shuffle=on -v -count=10 ./...

if [ -z "$(echo ${{matrix.go}} | grep '^1.1')" ]; then
echo "=> go test race"
go test -race -shuffle=on -v -count=10 ./...
Expand Down
2 changes: 1 addition & 1 deletion cgo.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors

//go:build cgo && (darwin || freebsd || linux)
//go:build cgo && (darwin || freebsd || netbsd || linux)

package purego

Expand Down
33 changes: 33 additions & 0 deletions dlfcn_netbsd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2024 The Ebitengine Authors

package purego

import "github.com/ebitengine/purego/internal/cgo"

// Source for constants: https://github.com/NetBSD/src/blob/trunk/include/dlfcn.h

const (
intSize = 32 << (^uint(0) >> 63) // 32 or 64
RTLD_DEFAULT = 1<<intSize - 2 // Pseudo-handle for dlsym so search for any loaded symbol
RTLD_LAZY = 0x00000001 // Relocations are performed at an implementation-dependent time.
RTLD_NOW = 0x00000002 // Relocations are performed when the object is loaded.
RTLD_LOCAL = 0x00000000 // All symbols are not made available for relocation processing by other modules.
RTLD_GLOBAL = 0x00000100 // All symbols are available for relocation processing of other modules.
)

func Dlopen(path string, mode int) (uintptr, error) {
return cgo.Dlopen(path, mode)
}

func Dlsym(handle uintptr, name string) (uintptr, error) {
return cgo.Dlsym(handle, name)
}

func Dlclose(handle uintptr) error {
return cgo.Dlclose(handle)
}

func loadSymbol(handle uintptr, name string) (uintptr, error) {
return Dlsym(handle, name)
}
4 changes: 2 additions & 2 deletions dlfcn_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2023 The Ebitengine Authors

//go:build darwin || freebsd || linux
//go:build darwin || freebsd || linux || netbsd

package purego_test

Expand Down Expand Up @@ -54,7 +54,7 @@ func buildSharedLib(compilerEnv, libFile string, sources ...string) error {
}

var args []string
if runtime.GOOS == "freebsd" {
if runtime.GOOS == "freebsd" || runtime.GOOS == "netbsd" {
args = []string{"-shared", "-Wall", "-Werror", "-fPIC", "-o", libFile}
} else {
args = []string{"-shared", "-Wall", "-Werror", "-o", libFile}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just out of curiosity, can't we use -fPIC for other platforms than FreeBSD and NetBSD?

Expand Down
2 changes: 2 additions & 0 deletions examples/libc/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ func getSystemLibrary() string {
return "libc.so.6"
case "freebsd":
return "libc.so.7"
case "netbsd":
return "libc.so"
case "windows":
return "ucrtbase.dll"
default:
Expand Down
2 changes: 1 addition & 1 deletion examples/libc/main_unix.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2023 The Ebitengine Authors

//go:build darwin || freebsd || linux
//go:build darwin || freebsd || linux || netbsd

package main

Expand Down
2 changes: 1 addition & 1 deletion func.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors

//go:build darwin || freebsd || linux || windows
//go:build darwin || freebsd || linux || netbsd || windows

package purego

Expand Down
12 changes: 7 additions & 5 deletions func_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@ func getSystemLibrary() (string, error) {
switch runtime.GOOS {
case "darwin":
return "/usr/lib/libSystem.B.dylib", nil
case "linux":
return "libc.so.6", nil
case "freebsd":
return "libc.so.7", nil
case "linux":
return "libc.so.6", nil
case "netbsd":
return "libc.so", nil
case "windows":
return "ucrtbase.dll", nil
default:
Expand All @@ -43,7 +45,7 @@ func TestRegisterFunc(t *testing.T) {
}

func Test_qsort(t *testing.T) {
if runtime.GOARCH != "arm64" && runtime.GOARCH != "amd64" {
if runtime.GOARCH != "arm64" && runtime.GOARCH != "amd64" || runtime.GOOS == "netbsd" {
t.Skip("Platform doesn't support Floats")
return
}
Expand Down Expand Up @@ -72,7 +74,7 @@ func Test_qsort(t *testing.T) {
}

func TestRegisterFunc_Floats(t *testing.T) {
if runtime.GOARCH != "arm64" && runtime.GOARCH != "amd64" {
if runtime.GOARCH != "arm64" && runtime.GOARCH != "amd64" || runtime.GOOS == "netbsd" {
t.Skip("Platform doesn't support Floats")
return
}
Expand Down Expand Up @@ -111,7 +113,7 @@ func TestRegisterFunc_Floats(t *testing.T) {
}

func TestRegisterLibFunc_Bool(t *testing.T) {
if runtime.GOARCH != "arm64" && runtime.GOARCH != "amd64" {
if runtime.GOARCH != "arm64" && runtime.GOARCH != "amd64" || runtime.GOOS == "netbsd" {
t.Skip("Platform doesn't support callbacks")
return
}
Expand Down
2 changes: 1 addition & 1 deletion go_runtime.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors

//go:build darwin || freebsd || linux || windows
//go:build darwin || freebsd || linux || netbsd || windows

package purego

Expand Down
4 changes: 2 additions & 2 deletions internal/cgo/dlfcn_cgo_unix.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2024 The Ebitengine Authors

//go:build freebsd || linux
//go:build freebsd || linux || netbsd

package cgo

/*
#cgo LDFLAGS: -ldl
#cgo !netbsd LDFLAGS: -ldl

#include <dlfcn.h>
#include <stdlib.h>
Expand Down
4 changes: 2 additions & 2 deletions internal/cgo/syscall_cgo_unix.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors

//go:build freebsd || (linux && !(arm64 || amd64))
//go:build freebsd || (linux && !(arm64 || amd64)) || netbsd

package cgo

// this file is placed inside internal/cgo and not package purego
// because Cgo and assembly files can't be in the same package.

/*
#cgo LDFLAGS: -ldl
#cgo !netbsd LDFLAGS: -ldl

#include <stdint.h>
#include <dlfcn.h>
Expand Down
2 changes: 1 addition & 1 deletion internal/load/load_unix.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2024 The Ebitengine Authors

//go:build darwin || freebsd || linux
//go:build darwin || freebsd || linux || netbsd

package load

Expand Down
2 changes: 1 addition & 1 deletion syscall.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors

//go:build darwin || freebsd || linux || windows
//go:build darwin || freebsd || linux || netbsd || windows

package purego

Expand Down
21 changes: 21 additions & 0 deletions syscall_cgo_netbsd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2024 The Ebitengine Authors

//go:build cgo

package purego

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

var syscall15XABI0 = uintptr(cgo.Syscall15XABI0)

//go:nosplit
func syscall_syscall15X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 uintptr) (r1, r2, err uintptr) {
return cgo.Syscall15X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15)
}

func NewCallback(_ interface{}) uintptr {
panic("purego: NewCallback is not supported on NetBSD")
}