Skip to content

Commit

Permalink
Use sbt logger to display linkage error (#406)
Browse files Browse the repository at this point in the history
  • Loading branch information
MasseGuillaume authored and densh committed Nov 26, 2016
1 parent bad85d1 commit e45af1f
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 33 deletions.
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
package scala.scalanative
package sbtplugin

import util._
import sbtcross.CrossPlugin.autoImport._
import ScalaNativePlugin.autoImport._

import sbt._, Keys._, complete.DefaultParsers._
import scala.util.Try
import scalanative.nir
import scalanative.tools
import scalanative.io.VirtualDirectory
import scalanative.sbtplugin.ScalaNativePlugin.autoImport._

import sbt._, Keys._, complete.DefaultParsers._
import xsbti.{Maybe, Reporter, Position, Severity, Problem}
import KeyRanks.DTask

import scala.util.Try

import System.{lineSeparator => nl}

object ScalaNativePluginInternal {
Expand Down Expand Up @@ -62,10 +68,22 @@ object ScalaNativePluginInternal {
}

/** Compiles application nir to llvm ir. */
private def compileNir(config: tools.Config): Seq[nir.Attr.Link] = {
val driver = tools.Driver(config)
val (links, raw) = tools.link(config, driver)
val optimized = tools.optimize(config, driver, raw)
private def compileNir(config: tools.Config,
logger: Logger): Seq[nir.Attr.Link] = {
val driver = tools.Driver(config)
val (unresolved, links, raw) = tools.link(config, driver)

if (!unresolved.isEmpty) {
import nir.Shows._

unresolved.map(u => sh"$u".toString).sorted.foreach { signature =>
logger.error(s"cannot link: $signature")
}

throw new MessageOnlyException("unable to link")
}

val optimized = tools.optimize(config, driver, raw)
tools.codegen(config, optimized)

links
Expand Down Expand Up @@ -234,7 +252,7 @@ object ScalaNativePluginInternal {
unpackNativelib(clang, clangpp, classpath, logger)

if (unpackSuccess) {
val links = compileNir(config).map(_.name)
val links = compileNir(config, logger).map(_.name)
compileLl(clangpp,
target,
appll,
Expand All @@ -249,7 +267,7 @@ object ScalaNativePluginInternal {
}
}

val _ = compileIfChanged(inputFiles)
val result = compileIfChanged(inputFiles)
binary
},
run := {
Expand Down
4 changes: 0 additions & 4 deletions tools/src/main/scala/scala/scalanative/linker/Error.scala

This file was deleted.

19 changes: 3 additions & 16 deletions tools/src/main/scala/scala/scalanative/linker/Linker.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import util.sh
sealed trait Linker {

/** Link the whole world under closed world assumption. */
def link(entries: Seq[Global]): (Seq[Attr.Link], Seq[Defn])
def link(entries: Seq[Global]): (Seq[Global], Seq[Attr.Link], Seq[Defn])
}

object Linker {
Expand All @@ -27,8 +27,7 @@ object Linker {
path.load(global)
}.flatten

private def impl(
entries: Seq[Global]): (Seq[Global], Seq[Attr.Link], Seq[Defn]) = {
def link(entries: Seq[Global]): (Seq[Global], Seq[Attr.Link], Seq[Defn]) = {
val resolved = mutable.Set.empty[Global]
val unresolved = mutable.Set.empty[Global]
val links = mutable.Set.empty[Attr.Link]
Expand Down Expand Up @@ -86,21 +85,9 @@ object Linker {
processConditional
}

(unresolved.toSeq, links.toSeq, defns.sortBy(_.name.toString).toSeq)
}

def link(entries: Seq[Global]): (Seq[Attr.Link], Seq[Defn]) = {
val (unresolved, links, defns) = impl(entries)

config.paths.foreach(_.close)

if (unresolved.nonEmpty) {
println(s"Unresolved dependencies:")
unresolved.map(u => sh" `$u`".toString).sorted.foreach(println(_))
throw new linker.Error("Failed to resolve all dependencies.")
}

(links, defns)
(unresolved.toSeq, links.toSeq, defns.sortBy(_.name.toString).toSeq)
}
}
}
10 changes: 6 additions & 4 deletions tools/src/main/scala/scala/scalanative/tools/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,17 @@ package object tools {
val Path = linker.Path

/** Given the classpath and entry point, link under closed-world assumption. */
def link(config: Config,
driver: Driver): (Seq[nir.Attr.Link], Seq[nir.Defn]) = {
def link(
config: Config,
driver: Driver): (Seq[nir.Global], Seq[nir.Attr.Link], Seq[nir.Defn]) = {
val deps = driver.passes.flatMap(_.depends).distinct
val injects = driver.passes.flatMap(_.injects).distinct
val entry =
nir.Global.Member(config.entry, "main_class.ssnr.ObjectArray_unit")
val (links, defns) = (linker.Linker(config)).link(entry +: deps)
val (unresolved, links, defns) =
(linker.Linker(config)).link(entry +: deps)

(links, defns ++ injects)
(unresolved, links, defns ++ injects)
}

/** Transform high-level closed world to its lower-level counterpart. */
Expand Down

0 comments on commit e45af1f

Please sign in to comment.