Skip to content

Commit

Permalink
Allow excluding system paths (#260)
Browse files Browse the repository at this point in the history
Also:
* Remove .all from external path rendering
* Handle package name correctly in forwarders
* Don't write a file if it's empty
  • Loading branch information
keynmol authored Jan 12, 2024
1 parent 9554921 commit e6717f3
Show file tree
Hide file tree
Showing 18 changed files with 140 additions and 63 deletions.
19 changes: 8 additions & 11 deletions modules/bindgen/src/main/scala/Config.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ case class Config(
printFiles: PrintFiles,
exportMode: ExportMode,
outputChannel: OutputChannel,
tempDir: TempPath
tempDir: TempPath,
excludeSystemPaths: List[SystemPath]
)

case class Context(
Expand All @@ -35,19 +36,11 @@ case class Context(
)

object Config:
def withDefaults(
// headerFile: HeaderFile,
// packageName: PackageName,
// lang: Lang,
// outputChannel: OutputChannel
) =
def withDefaults() =
Config(
// packageName = packageName,
// headerFile = headerFile,
linkName = None,
indentSize = defaults.indentSize,
indents = defaults.indents,
// lang = lang,
cImports = Nil,
clangFlags = Nil,
quiet = Quiet.No,
Expand All @@ -59,7 +52,8 @@ object Config:
printFiles = PrintFiles.No,
exportMode = ExportMode.No,
outputChannel = OutputChannel.cli,
tempDir = TempPath(sys.props("java.io.tmpdir"))
tempDir = TempPath(sys.props("java.io.tmpdir")),
excludeSystemPaths = Nil
)
object defaults:
val indentSize = IndentationSize(3)
Expand Down Expand Up @@ -107,6 +101,9 @@ object CImport extends OpaqueString[CImport]
opaque type ClangFlag = String
object ClangFlag extends OpaqueString[ClangFlag]

opaque type SystemPath = String
object SystemPath extends OpaqueString[SystemPath]

opaque type HeaderFile = String
object HeaderFile extends OpaqueString[HeaderFile]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ object InteractiveDriver:
Right(
InteractiveDriver(
config,
ConfiguredEnvironment(clang, SystemHeaderDetector(clang))
ConfiguredEnvironment(
clang,
SystemHeaderDetector(clang, config.excludeSystemPaths)
)
)
)
end InteractiveDriver
20 changes: 16 additions & 4 deletions modules/bindgen/src/main/scala/analysis/SystemHeaderDetector.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,28 @@ import scala.scalanative.unsigned.*
import scalanative.libc.*
import scala.scalanative.runtime.libc
import libclang.fluent.string
import java.nio.file.Path
import java.nio.file.Paths

class SystemHeaderDetector(clangInfo: ClangInfo):
class SystemHeaderDetector(
clangInfo: ClangInfo,
excludeSystemPaths: List[SystemPath]
):
private val mut = collection.mutable.Map.empty[String, Boolean]
private val includes = clangInfo.includePaths.map(Paths.get(_))
private val excludes = excludeSystemPaths.map(_.value).map(Paths.get(_))

def isSystem(filename: String): Boolean =
val path = java.nio.file.Paths.get(filename)

def isChild(ip: Path) = path.startsWith(ip)

val isInExcludedLocation = excludes.exists(isChild)
val isInSystemLocation = includes.exists(isChild)

mut.getOrElseUpdate(
filename,
clangInfo.includePaths.exists { ip =>
path.startsWith(ip)
}
if isInExcludedLocation then false else isInSystemLocation
)
end isSystem
end SystemHeaderDetector
13 changes: 12 additions & 1 deletion modules/bindgen/src/main/scala/cli/arguments.scala
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,16 @@ object CLI:
.withDefault(Nil)
.map(_.map(ClangFlag.apply(_)))

private val excludeSystemPaths = Opts
.options[String](
"exclude-system-path",
help =
"List of paths to mark as non-system (helpful if Clang reports some paths you'd rather not ignore)"
)
.map(_.toList)
.withDefault(Nil)
.map(_.map(SystemPath.apply(_)))

private val clangInclude = Opts
.options[String](
"clang-include",
Expand Down Expand Up @@ -348,7 +358,8 @@ object CLI:
printFiles,
exportMode,
Opts(OutputChannel.cli),
tempDir
tempDir,
excludeSystemPaths
).mapN(Config.apply)

val command = Command(
Expand Down
40 changes: 23 additions & 17 deletions modules/bindgen/src/main/scala/main.scala
Original file line number Diff line number Diff line change
Expand Up @@ -44,28 +44,34 @@ object Generate:
config.config.outputChannel.stdoutLine(lb.result)

case (RenderedOutput.Single(lb), OutputMode.SingleFile(f)) =>
Using.resource(new FileWriter(f.value)) { fw =>
fw.write(lb.result)
}
info(s"Generated ${f.value.toPath.toAbsolutePath()}")
val result = lb.result.trim()
if result.nonEmpty then
Using.resource(new FileWriter(f.value)) { fw =>
fw.write(result)
}
info(s"Generated ${f.value.toPath.toAbsolutePath()}")

if config.config.printFiles == PrintFiles.Yes then
config.config.outputChannel.stdoutLine(
f.value.toPath.toAbsolutePath().toString()
)
if config.config.printFiles == PrintFiles.Yes then
config.config.outputChannel.stdoutLine(
f.value.toPath.toAbsolutePath().toString()
)
end if

case (RenderedOutput.Multi(mp), OutputMode.MultiFile(d)) =>
val path = d.value.toPath()
mp.foreach { (sn, lb) =>
val file = path.resolve(sn.value + ".scala")
Using.resource(new FileWriter(file.toFile)) { fw =>
fw.write(lb.result)
}
info(s"Generated ${file.toAbsolutePath()}")
if config.config.printFiles == PrintFiles.Yes then
config.config.outputChannel.stdoutLine(
file.toAbsolutePath()
)
val result = lb.result.trim()
if result.nonEmpty then
val file = path.resolve(sn.value + ".scala")
Using.resource(new FileWriter(file.toFile)) { fw =>
fw.write(result)
}
info(s"Generated ${file.toAbsolutePath()}")
if config.config.printFiles == PrintFiles.Yes then
config.config.outputChannel.stdoutLine(
file.toAbsolutePath()
)
end if

}
end match
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ enum GeneratedFunction:
end GeneratedFunction

private def externFuncName(s: String)(using c: Context) =
s"__sn_wrap_${c.packageName.value}_" + s
s"__sn_wrap_${c.packageName.value.replace(".", "_")}_" + s

private def scalaForwarderFunction(
bad: Def.Function
Expand Down
2 changes: 1 addition & 1 deletion modules/bindgen/src/main/scala/render/scalaType.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def renderName(name: Name.Model)(using config: Config) =
(nameMatches orElse pathMatches)
.map(_._2.value)
.map { pkgName =>
s"_root_.$pkgName.all.${name.value}"
s"_root_.$pkgName.${name.value}"
}
.getOrElse(name.value)
end renderName
Expand Down
14 changes: 14 additions & 0 deletions modules/interface/src/main/scala/Interface.scala
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ class Binding private (
val externalPaths: Map[String, String] = Defaults.externalPaths,
val externalNames: Map[String, String] = Defaults.externalNames,
val bindgenArguments: List[String] = Defaults.bindgenArguments,
val excludeSystemPaths: List[Path] = Defaults.excludeSystemPaths,
val scalaFile: String,
val cFile: String
) { self =>
Expand All @@ -106,6 +107,7 @@ class Binding private (
externalPaths: Map[String, String] = self.externalPaths,
externalNames: Map[String, String] = self.externalNames,
bindgenArguments: List[String] = self.bindgenArguments,
excludeSystemPaths: List[Path] = self.excludeSystemPaths,
scalaFile: String = self.scalaFile,
cFile: String = self.cFile
) =
Expand All @@ -127,6 +129,7 @@ class Binding private (
externalPaths = externalPaths,
externalNames = externalNames,
bindgenArguments = bindgenArguments,
excludeSystemPaths = excludeSystemPaths,
scalaFile = scalaFile,
cFile = cFile
)
Expand Down Expand Up @@ -185,6 +188,10 @@ class Binding private (
arg("render.external-name", s"$filter=$pkg")
}

excludeSystemPaths.map { case path =>
arg("exclude-system-path", path.toString())
}

sb ++= bindgenArguments

sb.result()
Expand Down Expand Up @@ -260,6 +267,12 @@ object Binding {
def addExternalNames(externals: Map[String, String]) =
copy(b => b.copy(externalNames = b.externalNames ++ externals))

def addExcludedSystemPath(path: Path) =
copy(b => b.copy(excludeSystemPaths = b.excludeSystemPaths :+ path))

def withExcludedSystemPaths(paths: List[Path]) =
copy(b => b.copy(excludeSystemPaths = paths))

def withBindgenArguments(arguments: List[String]) =
copy(_.copy(bindgenArguments = arguments))
def addBindgenArgument(argument: String) =
Expand All @@ -285,6 +298,7 @@ object Binding {
val externalPaths = Map.empty[String, String]
val externalNames = Map.empty[String, String]
val bindgenArguments = List.empty[String]
val excludeSystemPaths = List.empty[Path]
val exportMode = false
}

Expand Down
4 changes: 2 additions & 2 deletions modules/sbt-plugin/src/sbt-test/basic/artifacts/test
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
> run
$ exists target/scala-3.1.1/resource_managed/main/scala-native/libtest.c
-$ exists target/scala-3.1.1/resource_managed/main/scala-native/libtest.c
$ exists target/scala-3.1.1/src_managed/main/libtest.scala
> test
$ exists target/scala-3.1.1/resource_managed/test/scala-native/gentests.c
-$ exists target/scala-3.1.1/resource_managed/test/scala-native/gentests.c
$ exists target/scala-3.1.1/src_managed/test/gentests.scala


Expand Down
32 changes: 23 additions & 9 deletions modules/sbt-plugin/src/sbt-test/basic/binding-mode/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,32 @@ enablePlugins(BindgenPlugin, ScalaNativePlugin, ScalaNativeJUnitPlugin)
import bindgen.interface.Binding
import java.util.concurrent.atomic.AtomicReference

scalaVersion := "3.2.0"
scalaVersion := "3.3.1"

bindgenBindings := {
Seq(
Binding(
headerFile =
Binding
.builder(
baseDirectory.value / "src" / "main" / "resources" / "scala-native" / "header.h",
packageName = "bindings"
)
"bindings"
)
.addCImport("header.h")
.build
)
}

Test / bindgenBindings := {
Seq(
Binding(
headerFile =
Binding
.builder(
baseDirectory.value / "src" / "main" / "resources" / "scala-native" / "header.h",
packageName = "testbindings"
)
"testbindings"
)
.addCImport("header.h")
.addClangFlag(
"-I" + (baseDirectory.value / "src" / "main" / "resources" / "scala-native").toString
)
.build
)
}

Expand All @@ -40,3 +47,10 @@ Test / bindgenMode := {

BindgenMode.Manual(scalaFolder, cFolder)
}

Test / nativeConfig := {
val config = (Test / nativeConfig).value
config.withCompileOptions(
config.compileOptions :+ ("-I" + (baseDirectory.value / "src" / "main" / "resources" / "scala-native").toString)
)
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
addSbtPlugin(
"com.indoorvivants" % "bindgen-sbt-plugin" % sys.props("plugin.version")
)
addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.4.7")
addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.4.16")
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
#include <stdbool.h>

typedef struct {
int i;
} mystruct;

bool hello2(int i, mystruct y);
bool hello(int i, float y);
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,8 @@ bool hello(int i, float y) {
printf("%f", i * y);
return true;
}

bool hello2(int i, mystruct y) {
printf("%d", i * ((int)y.i));
return true;
}
14 changes: 8 additions & 6 deletions modules/sbt-plugin/src/sbt-test/basic/multi-file/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,17 @@ enablePlugins(BindgenPlugin, ScalaNativePlugin, ScalaNativeJUnitPlugin)
import bindgen.interface.Binding
import java.util.concurrent.atomic.AtomicReference

scalaVersion := "3.2.2"
scalaVersion := "3.3.1"

bindgenBindings := {
Seq(
Binding(
headerFile =
Binding
.builder(
baseDirectory.value / "src" / "main" / "resources" / "scala-native" / "header.h",
packageName = "bindings",
multiFile = true
)
"bindings"
)
.withMultiFile(true)
.addCImport("header.h")
.build
)
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
addSbtPlugin(
"com.indoorvivants" % "bindgen-sbt-plugin" % sys.props("plugin.version")
)
addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.4.7")
addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.4.16")
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ bool hello(int i, float y);

typedef float position;

struct Test {
typedef struct {
char x;
};
} Test;

union Bla {
char x;
};

enum X { A, B };

bool hello2(int i, Test y);
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,8 @@ bool hello(int i, float y) {
printf("%f", i * y);
return true;
}

bool hello2(int i, Test y) {
printf("%d", i * ((int)y.x));
return true;
}
Loading

0 comments on commit e6717f3

Please sign in to comment.