Skip to content

Commit

Permalink
Use macos arm runner, update base interface to 0.0.24, LLVM 17(!) fix…
Browse files Browse the repository at this point in the history
…es (#270)

* Try out M1 runners
* Update base version to 0.0.24
* Base LLVM 17 for discovery, use local bindgen for libclang generation
* Regenerate libclang bindings and adjust imports
* Handle anonymous types correctly according to LLVM 17
* Handle structs with unnamed fields by excluding them entirely
* Don't check formatting of generated sources
  • Loading branch information
keynmol authored Jan 31, 2024
1 parent 6b270bb commit 0611009
Show file tree
Hide file tree
Showing 25 changed files with 4,509 additions and 4,331 deletions.
84 changes: 25 additions & 59 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@ env:
JAVA_OPTS: "-Xmx4G"
JVM_OPTS: "-Xmx4G"
SBT_OPTS: "-Xmx4G"
LLVM_VERSION: 14
LLVM_VERSION: 17

jobs:
macos_build:
name: MacOS
name: MacOS (${{ matrix.OS }})
strategy:
fail-fast: true
runs-on: macos-12
env:
LLVM_VERSION: 14
matrix:
OS: ["macos-12", "macos-14"]
runs-on: ${{ matrix.OS }}
steps:
- uses: actions/checkout@v3
with:
Expand All @@ -31,6 +31,11 @@ jobs:
java-version: '17'
cache: 'sbt'

- name: Install SBT
run: |
curl -Lo sbt https://raw.githubusercontent.com/sbt/sbt/1.9.x/sbt && \
chmod +x sbt
- name: Install LLVM
run: brew install llvm@$LLVM_VERSION

Expand All @@ -41,61 +46,23 @@ jobs:

- name: Sets env vars for LLVM
run: |
echo "LLVM_BIN=/usr/local/opt/llvm@$LLVM_VERSION/bin" >> $GITHUB_ENV
if [ $(arch) == "arm64" ]; then
echo "LLVM_BIN=/opt/homebrew/opt/llvm@$LLVM_VERSION/bin" >> $GITHUB_ENV
else
echo "LLVM_BIN=/usr/local/opt/llvm@$LLVM_VERSION/bin" >> $GITHUB_ENV
fi
- name: CI and build the binary
run: sbt ci buildPlatformBinary
run: ./sbt ci buildPlatformBinary

- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
path: bin/sn-bindgen-*
name: macos-intel-binaries
name: ${{ matrix.os }}-binaries
if-no-files-found: error

macos_arm_build:
name: MacOS (Arm64)
strategy:
fail-fast: true
runs-on: macos-aarch64
if: startsWith(github.ref, 'refs/tags/v')
continue-on-error: true
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0

- uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '17'
cache: 'sbt'

- name: Install LLVM
run: brew install llvm@$LLVM_VERSION

- name: Install SBT
run: brew install sbt

- name: Sets env vars for release
if: startsWith(github.ref, 'refs/tags/v') || (github.ref == 'refs/heads/main')
run: |
echo "SCALANATIVE_MODE=release-fast" >> $GITHUB_ENV
- name: Sets env vars for LLVM
run: |
echo "LLVM_BIN=/opt/homebrew/opt/llvm@$LLVM_VERSION/bin" >> $GITHUB_ENV
- name: CI and build the binary
run: sbt ci buildPlatformBinary

- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
path: bin/sn-bindgen-*
name: macos-arm-binaries
if-no-files-found: error

linux_build:
name: Linux
runs-on: ubuntu-20.04
Expand Down Expand Up @@ -166,7 +133,7 @@ jobs:
runs-on: windows-2019
env:
LLVM_BIN: 'C:\Program Files\LLVM\bin'
LLVM_VERSION: "14.0.6"
LLVM_VERSION: "17.0.6"
steps:
# This step is important to make sure scalafmt
# checks don't fail
Expand Down Expand Up @@ -232,13 +199,12 @@ jobs:

release:
if: ${{ always() }}
needs: [linux_build, linux_arm64_build, windows_build, macos_build, macos_arm_build]
needs: [linux_build, linux_arm64_build, windows_build, macos_build]
name: Release
runs-on: ubuntu-20.04
env:
BINARIES: binaries/
LLVM_BIN: /usr/lib/llvm-14/bin
LLVM_VERSION: 14
LLVM_BIN: /usr/lib/llvm-17/bin
steps:
- uses: actions/checkout@v3
with:
Expand Down Expand Up @@ -270,14 +236,11 @@ jobs:
./cs resolve com.indoorvivants:bindgen-interface_3:$(cat version)
./cs resolve com.indoorvivants:bindgen-interface_2.12:$(cat version)
./cs fetch com.indoorvivants:bindgen_native0.4_3:$(cat version) --classifier osx-x86_64 --artifact-type jar
# ./cs fetch com.indoorvivants:bindgen_native0.4_3:$(cat version) --classifier osx-aarch64 --artifact-type jar
./cs fetch com.indoorvivants:bindgen_native0.4_3:$(cat version) --classifier osx-aarch64 --artifact-type jar
./cs fetch com.indoorvivants:bindgen_native0.4_3:$(cat version) --classifier linux-x86_64 --artifact-type jar
./cs fetch com.indoorvivants:bindgen_native0.4_3:$(cat version) --classifier linux-aarch64 --artifact-type jar
./cs fetch com.indoorvivants:bindgen_native0.4_3:$(cat version) --classifier windows-x86_64 --artifact-type jar
- name: Setup Unix-like
run: ./build/setup_unix.sh

- name: Publish
if: startsWith(github.ref, 'refs/tags/v') || (github.ref == 'refs/heads/main')
run: |
Expand All @@ -288,6 +251,9 @@ jobs:
SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }}
SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }}

- name: Setup Unix-like
run: ./build/setup_unix.sh

- name: Build site
run: sbt buildWebsite

Expand Down
3 changes: 3 additions & 0 deletions .scalafmt.conf
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,6 @@ fileOverride {
runner.dialect = scala212source3
}
}

project.excludePaths = ["glob:**/modules/libclang/src/main/scala/generated/**/*.scala"]

15 changes: 7 additions & 8 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ lazy val libclang = project
scalaDir = ((Compile / sourceDirectory).value / "scala" / "generated"),
cDir = (Compile / resourceDirectory).value / "scala-native" / "generated"
),
bindgenBinary := (LocalProject("bindgen") / Compile / nativeLink).value,
bindgenBindings := {
val detected =
llvmFolder(nativeConfig.value.clang.toAbsolutePath()).llvmInclude
Expand All @@ -255,12 +256,10 @@ lazy val libclang = project
case head :: tl =>
val include = new File(head)
Seq(
Binding
.builder(include / "clang-c" / "Index.h", "libclang")
Binding(include / "clang-c" / "Index.h", "libclang")
.withClangFlags(List(s"-I$head"))
.addCImport("clang-c/Index.h")
.withMultiFile(true)
.build
)
case immutable.Nil =>
sLog.value.error(
Expand Down Expand Up @@ -637,18 +636,18 @@ def collectBindings(headersPath: File) = {
val multiFileFlag = "--multi-file"
val isMultiFile = contents.contains(multiFileFlag)

Binding
.builder(header, pkg.getOrElse(s"lib_test_$name"))
Binding(header, pkg.getOrElse(s"lib_test_$name"))
.addCImport(s"$name.h")
.withBindgenArguments(contents.filterNot(_ == multiFileFlag))
.withMultiFile(isMultiFile)
.build
}
}

def llvmFolder(clangPath: java.nio.file.Path): LLVMInfo = {
import Platform.OS.*

val LLVM_MAJOR_VERSION = "17"

Platform.os match {
case MacOS =>
val detected =
Expand All @@ -662,9 +661,9 @@ def llvmFolder(clangPath: java.nio.file.Path): LLVMInfo = {
val speculative =
if (detected.isEmpty)
List(
Paths.get("/usr/local/opt/llvm@14"),
Paths.get(s"/usr/local/opt/llvm@$LLVM_MAJOR_VERSION"),
Paths.get("/usr/local/opt/llvm"),
Paths.get("/opt/homebrew/opt/llvm@14"),
Paths.get(s"/opt/homebrew/opt/llvm@$LLVM_MAJOR_VERSION"),
Paths.get("/opt/homebrew/opt/llvm")
)
else Nil
Expand Down
12 changes: 2 additions & 10 deletions modules/bindgen/src/main/scala/DefTag.scala
Original file line number Diff line number Diff line change
@@ -1,16 +1,8 @@
package bindgen

import bindgen.CType.Parameter
import scala.collection.mutable
import scala.collection.mutable.ListBuffer
import scala.scalanative.unsafe.Tag
import scala.scalanative.unsigned.ULong
import Def.*
import CType.*
enum DefTag:
case Union, Alias, Struct, Function, Enum

object DefTag:
import DefTag.*
def all = Set(Union, Alias, Struct, Function, Enum)

enum DefTag:
case Union, Alias, Struct, Function, Enum
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package bindgen

import libclang.all.*
import libclang.fluent.*
import libclang.*, fluent.*
import scalanative.unsafe.*
import scala.util.boundary, boundary.break, boundary.Label

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package bindgen

import libclang.all.*
import libclang.fluent.*
import libclang.*, fluent.*
import scalanative.unsafe.*
import scalanative.unsigned.*

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package bindgen

import libclang.all.*
import libclang.fluent.*
import libclang.*, fluent.*
import scalanative.unsafe.*
import scalanative.unsigned.*
import scala.util.boundary, boundary.break, boundary.Label
Expand Down Expand Up @@ -43,7 +42,7 @@ object ClangTranslationUnit:
allClangFlags.size,
null,
0.toUInt,
CXTranslationUnit_Flags.CXTranslationUnit_None
CXTranslationUnit_Flags.CXTranslationUnit_None.uint
)

boundary:
Expand Down
14 changes: 6 additions & 8 deletions modules/bindgen/src/main/scala/analysis/ClangVisitor.scala
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
package bindgen

import _root_.libclang.structs.*
import _root_.libclang.enumerations.*
import _root_.libclang.aliases.*
import _root_.libclang.functions.*
import _root_.libclang.fluent.*

import scalanative.unsafe.*
import libclang.*, fluent.*

object ClangVisitor:
val visitor =
Expand Down Expand Up @@ -103,7 +98,8 @@ object ClangVisitor:

if cursor.kind == CXCursorKind.CXCursor_UnionDecl then
val name = clang_getCursorSpelling(cursor).string
if name != "" then
val isAnonymous = clang_Cursor_isAnonymous(cursor).toInt != 0
if name != "" && !isAnonymous then
val en = visitStruct(cursor, name)
val union = Def.Union(
fields = en.fields.map { case (n, f) =>
Expand All @@ -119,7 +115,9 @@ object ClangVisitor:

if cursor.kind == CXCursorKind.CXCursor_StructDecl then
val name = cursor.spelling
if name != "" then
val isAnonymous = clang_Cursor_isAnonymous(cursor).toInt != 0
trace(s"Cursor: [${cursor.spelling}], ${isAnonymous}")
if name != "" && !isAnonymous then
val en = visitStruct(cursor, name)
binding.add(en, location)
end if
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
package bindgen

import _root_.libclang.structs.*
import _root_.libclang.enumerations.*
import _root_.libclang.aliases.*
import _root_.libclang.functions.*
import _root_.libclang.fluent.*
import java.io.FileWriter
import java.nio.file.Files
import scala.collection.mutable
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
package bindgen

import _root_.libclang.structs.*
import _root_.libclang.enumerations.*
import _root_.libclang.aliases.*
import _root_.libclang.functions.*
import _root_.libclang.fluent.*

import java.io.FileWriter
import java.nio.file.Files
import scala.collection.mutable
Expand Down
9 changes: 3 additions & 6 deletions modules/bindgen/src/main/scala/analysis/constructType.scala
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
package bindgen

import libclang.functions.*
import libclang.enumerations.*
import libclang.fluent.*

import scala.collection.mutable
import scala.scalanative.unsafe.*
import scala.scalanative.unsigned.*
import scala.util.control.NoStackTrace

import scalanative.libc.*
import libclang.structs.CXType
import libclang.*, fluent.*

def constructType(typ: CXType)(using
Zone,
Expand All @@ -35,9 +31,10 @@ def constructType(typ: CXType)(using
case CXType_Record =>
val decl = clang_getTypeDeclaration(typ)
val name = clang_getCursorSpelling(decl).string
val isAnonymous = clang_Cursor_isAnonymous(decl).toInt != 0

CType.Reference(
if name.isEmpty then Name.Unnamed
if name.isEmpty || isAnonymous then Name.Unnamed
else Name.Model(name, extractMetadata(decl))
)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
package bindgen

import libclang.structs.CXCursor
import libclang.*, fluent.*
import scala.scalanative.unsafe.*
import libclang.functions.*
import libclang.fluent.*
import libclang.aliases.CXFile

def extractMetadata(cursor: CXCursor)(using Zone) =
val file = stackalloc[CXFile]()
Expand Down
8 changes: 1 addition & 7 deletions modules/bindgen/src/main/scala/analysis/visitEnum.scala
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
package bindgen

import _root_.libclang.structs.*
import _root_.libclang.enumerations.*
import _root_.libclang.aliases.*
import _root_.libclang.functions.*
import _root_.libclang.fluent.*

import scala.scalanative.unsafe.*
import scala.scalanative.unsigned.*
import scalanative.libc.*
import scala.collection.mutable

import libclang.*
import libclang.*, fluent.*

def visitEnum(rootCursor: CXCursor, isTypeDef: Boolean)(using
Zone,
Expand Down
Loading

0 comments on commit 0611009

Please sign in to comment.