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

Allow excluding system paths #260

Merged
merged 7 commits into from
Jan 12, 2024
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
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
Loading