Skip to content

Commit

Permalink
external dependencies (#407)
Browse files Browse the repository at this point in the history
  • Loading branch information
MasseGuillaume authored and densh committed Dec 1, 2016
1 parent 2c32244 commit ce4479b
Show file tree
Hide file tree
Showing 10 changed files with 207 additions and 15 deletions.
3 changes: 0 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,6 @@ matrix:
- brew install bdw-gc
- brew link bdw-gc
- brew install jq
cache:
directories:
- $HOME/.ivy2/cache

env:
global:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ final class BinaryDeserializer(_buffer: => ByteBuffer) {
(deps, links, res)
}

final def globals: Set[Global] = header.keySet

final def deserialize(g: Global): Option[(Seq[Dep], Seq[Attr.Link], Defn)] =
header.get(g).map {
case offset =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,16 @@ import scala.util.Try
import System.{lineSeparator => nl}

object ScalaNativePluginInternal {

val nativeLinkerReporter = settingKey[tools.LinkerReporter](
"A reporter that gets notified whenever a linking event happens.")

val nativeOptimizerReporter = settingKey[tools.OptimizerReporter](
"A reporter that gets notified whenever an optimizer event happens.")

val nativeExternalDependencies =
taskKey[Seq[String]]("List all external dependencies.")

private lazy val nativelib: File =
Path.userHome / ".scalanative" / ("nativelib-" + nir.Versions.current)

Expand Down Expand Up @@ -182,7 +186,30 @@ object ScalaNativePluginInternal {
Process(compile, target) ! logger
}

lazy val projectSettings = Seq(
private def externalDependenciesTask[T](compileTask: TaskKey[T]) =
nativeExternalDependencies := ResourceScope { implicit scope =>
import nir.Shows._

val forceCompile = compileTask.value

val classes = classDirectory.value
val progDir = VirtualDirectory.real(classes)
val prog = linker.Path(progDir)

val config =
tools.Config.empty.withPaths(Seq(prog)).withTargetDirectory(progDir)

val (unresolved, _, _) = (linker.Linker(config)).link(prog.globals.toSeq)

unresolved.map(u => sh"$u".toString).sorted
}

lazy val projectSettings =
unscopedSettings ++
inConfig(Compile)(externalDependenciesTask(compile)) ++
inConfig(Test)(externalDependenciesTask(compile in Test))

lazy val unscopedSettings = Seq(
libraryDependencies ++= Seq(
"org.scala-native" %%% "nativelib" % nativeVersion,
"org.scala-native" %%% "javalib" % nativeVersion,
Expand Down Expand Up @@ -212,18 +239,21 @@ object ScalaNativePluginInternal {
},
nativeLinkerReporter := tools.LinkerReporter.empty,
nativeOptimizerReporter := tools.OptimizerReporter.empty,
nativeLink := ResourceScope { implicit in =>
nativeLink := ResourceScope { implicit scope =>
val clangpp = nativeClangPP.value
val clangOpts = nativeClangOptions.value
val clang = nativeClang.value
checkThatClangIsRecentEnough(clang)

val mainClass = (selectMainClass in Compile).value.getOrElse(
throw new MessageOnlyException("No main class detected.")
)
val entry = nir.Global.Top(mainClass.toString + "$")
val classpath = (fullClasspath in Compile).value.map(_.data)
val target = (crossTarget in Compile).value
val appll = target / "out.ll"
val binary = (artifactPath in nativeLink).value
val clang = nativeClang.value
val clangpp = nativeClangPP.value
val clangOpts = nativeClangOptions.value
val entry = nir.Global.Top(mainClass.toString + "$")
val classpath = (fullClasspath in Compile).value.map(_.data)
val target = (crossTarget in Compile).value
val appll = target / "out.ll"
val binary = (artifactPath in nativeLink).value

val linkage = nativeLibraryLinkage.value
val linkerReporter = nativeLinkerReporter.value
val optimizerReporter = nativeOptimizerReporter.value
Expand All @@ -237,8 +267,6 @@ object ScalaNativePluginInternal {
.withTargetDirectory(VirtualDirectory.real(target))
.withInjectMain(!nativeSharedLibrary.value)

checkThatClangIsRecentEnough(clang)

val nirFiles = (Keys.target.value ** "*.nir").get.toSet
val configFile = (streams.value.cacheDirectory / "native-config")
val inputFiles = nirFiles + configFile
Expand Down
5 changes: 5 additions & 0 deletions scripted-tests/run/external-dependencies/build.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
ScalaNativePlugin.projectSettings

scalaVersion := "2.11.8"

Check.setup
79 changes: 79 additions & 0 deletions scripted-tests/run/external-dependencies/project/Check.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import sbt._
import Keys._

import scala.scalanative.sbtplugin.ScalaNativePluginInternal.nativeExternalDependencies

object Check {
lazy val check =
TaskKey[Unit]("check", "make sure we list external dependencies correctly")

val setup = Seq(
check := {
val deps = (nativeExternalDependencies in Compile).value.toSet

// most propably not implemented
val applets = Set(
"@java.applet.Applet",
"@java.applet.Applet::destroy_unit",
"@java.applet.Applet::init",
"@java.applet.Applet::init_unit",
"@java.applet.Applet::start_unit",
"@java.applet.Applet::stop_unit"
)

val awt = Set(
"@java.awt.Component",
"@java.awt.Component::addMouseListener_trait.java.awt.event.MouseListener_unit",
"@java.awt.Component::getHeight_i32",
"@java.awt.Component::getWidth_i32",
"@java.awt.Component::paint_class.java.awt.Graphics_unit",
"@java.awt.Component::repaint_unit",
"@java.awt.Container",
"@java.awt.Container::paint_class.java.awt.Graphics_unit",
"@java.awt.Graphics",
"@java.awt.Graphics::drawRect_i32_i32_i32_i32_unit",
"@java.awt.Graphics::drawString_class.java.lang.String_i32_i32_unit",
"@java.awt.event.MouseEvent",
"@java.awt.event.MouseListener",
"@java.awt.event.MouseListener::mouseClicked_class.java.awt.event.MouseEvent_unit",
"@java.awt.event.MouseListener::mouseEntered_class.java.awt.event.MouseEvent_unit",
"@java.awt.event.MouseListener::mouseExited_class.java.awt.event.MouseEvent_unit",
"@java.awt.event.MouseListener::mousePressed_class.java.awt.event.MouseEvent_unit",
"@java.awt.event.MouseListener::mouseReleased_class.java.awt.event.MouseEvent_unit"
)

assert(((applets ++ awt) -- deps).isEmpty)

// most propably implemented
val rest = Set(
"@java.io.PrintStream",
"@java.io.PrintStream::println_class.java.lang.String_unit",
"@java.lang.Object",
"@java.lang.String",
"@java.lang.StringBuffer",
"@java.lang.StringBuffer::append_class.java.lang.String_class.java.lang.StringBuffer",
"@java.lang.StringBuffer::init",
"@java.lang.StringBuffer::toString_class.java.lang.String",
"@java.lang.System$",
"@java.lang.System$::field.out",
"@scala.LowPriorityImplicits",
"@scala.LowPriorityImplicits::wrapIntArray_class.ssnr.IntArray_class.scala.collection.mutable.WrappedArray",
"@scala.Predef$",
"@scala.Predef$::Set_module.scala.collection.immutable.Set$",
"@scala.collection.GenTraversable",
"@scala.collection.Seq",
"@scala.collection.generic.GenericCompanion",
"@scala.collection.generic.GenericCompanion::apply_trait.scala.collection.Seq_trait.scala.collection.GenTraversable",
"@scala.collection.immutable.Set",
"@scala.collection.immutable.Set$",
"@scala.collection.mutable.WrappedArray",
"@scala.scalanative.runtime.IntArray",
"@scala.scalanative.runtime.IntArray$",
"@scala.scalanative.runtime.IntArray$::alloc_i32_class.ssnr.IntArray",
"@scala.scalanative.runtime.IntArray::update_i32_i32_unit"
)

assert((rest -- deps).isEmpty)
}
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
sbt.version = 0.13.13
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
val pluginVersion = System.getProperty("plugin.version")
if (pluginVersion == null)
throw new RuntimeException(
"""|The system property 'plugin.version' is not defined.
|Specify this property using the scriptedLaunchOpts -D.""".stripMargin)
else addSbtPlugin("org.scala-native" % "sbt-scala-native" % pluginVersion)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import java.awt.event.MouseListener
import java.awt.event.MouseEvent
import java.applet.Applet
import java.awt.Graphics

// We need linking errors, We will never port java.applet._
object AppletTutorial extends Applet with Mouse {
def sc = Set(1)

override def init(): Unit = {
strBuffer = new StringBuffer()
addItem("initializing the apple ")
}

override def start(): Unit = {
addItem("starting the applet ")
}

override def stop(): Unit = {
addItem("stopping the applet ")
}

override def destroy(): Unit = {
addItem("unloading the applet")
}

override def paint(g: Graphics): Unit = {
g.drawRect(0, 0, getWidth() - 1, getHeight() - 1)
g.drawString(strBuffer.toString(), 10, 20)
}
}

trait Mouse extends MouseListener { self: Applet =>
protected var strBuffer: StringBuffer = _

override def init(): Unit = {
addMouseListener(this);
strBuffer = new StringBuffer()
addItem("initializing the apple ")
}

override def start(): Unit = {
addItem("starting the applet ")
}

override def stop(): Unit = {
addItem("stopping the applet ")
}

override def destroy(): Unit = {
addItem("unloading the applet")
}

protected def addItem(word: String): Unit = {
System.out.println(word)
strBuffer.append(word)
repaint()
}

override def mouseEntered(event: MouseEvent): Unit = ()
override def mouseExited(event: MouseEvent): Unit = ()
override def mousePressed(event: MouseEvent): Unit = ()
override def mouseReleased(event: MouseEvent): Unit = ()
override def mouseClicked(event: MouseEvent): Unit =
addItem("mouse clicked! ")
}
1 change: 1 addition & 0 deletions scripted-tests/run/external-dependencies/test
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
> check
5 changes: 5 additions & 0 deletions tools/src/main/scala/scala/scalanative/linker/Path.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ sealed trait Path {

/** Load given global and info about its dependencies. */
def load(name: Global): Option[(Seq[Dep], Seq[Attr.Link], Defn)]

/** Load all globals */
def globals: Set[Global]
}

object Path {
Expand Down Expand Up @@ -43,5 +46,7 @@ object Path {
entries.get(name.top).flatMap { deserializer =>
deserializer.deserialize(name)
}

def globals: Set[Global] = entries.values.flatMap(_.globals).toSet
}
}

0 comments on commit ce4479b

Please sign in to comment.