3

我想做的是javaHome在开始时定义,无论是从环境变量还是从固定字符串作为默认值。然后,稍后,我将使用该字符串。

这是我尝试过的:

javaHome := Some(file("/Library/Java/JavaVirtualMachines/jdk1.7.0_10.jdk/Contents/Home"))

然后

unmanagedJars in Compile <+= (javaHome) { fn => Attributed.blank( fn + "/jre/lib/jfxrt.jar") }

我试图阅读 [reference][1] 但它确实比 Scala 本身更复杂。请帮忙。

我可以通过在构建文件中间有一个固定的字符串来绕过这个,但通常我不喜欢这样。

平台是 OS X、sbt 0.12.1、JDK 7u10、Scala 2.9.2

编辑: 由于我找到了解决方案,我已经删除了错误消息和另外两次(不成功的)尝试,因为它们只会混淆。

4

2 回答 2

5

终于搞定了。问题似乎部分在于理解 sbt 值模型(以及它纯粹过度使用自定义运算符!),部分在于了解 sbt 中使用的类型。

我将相应地编辑问题,但这是我的发现(和解决方案)。

  1. sbt 价值观是预先设定好的。它们不是我无法设置的变量myOwn。这javaHome是 sbt 的一个已知值(或者实际上是一个任务?)。

  2. 话虽如此,我想知道为什么 sbt 不能很好地为我找到合适的 JDK。那好吧。

提示:使用val xxx: Nothing = expression是查找各种事物类型的好工具。不能有一个类型的实例,Nothing因此总是失败,并带有一个很好的错误消息,通知expression.

这是我的javaHome检测代码(来自build.sbt):

//---
// Note: Wouldn't 'sbt' be able to provide us a nice default for this (the following logic
//      would deserve to be automatic, not in a project build script). AK 4-Jan-2013
//
javaHome := {
  var s = System.getenv("JAVA_HOME")
  if (s==null) {
    // tbd. try to detect JDK location on multiple platforms
    //
    // OS X: "/Library/Java/JavaVirtualMachines/jdk1.xxx.jdk/Contents/Home" with greatest id (i.e. "7.0_10")
    //
    s= "/Library/Java/JavaVirtualMachines/jdk1.7.0_10.jdk/Contents/Home"
  }
  //
  val dir = new File(s)
  if (!dir.exists) {
    throw new RuntimeException( "No JDK found - try setting 'JAVA_HOME'." )
  }
  //
  Some(dir)  // 'sbt' 'javaHome' value is ': Option[java.io.File]'
}

这是使用它的片段(稍后在同一个文件中),确保我们可以访问jfxrt.jar(JavaFX 2.x 运行时)。无论如何,Oracle(或 sbt)应该让它在类路径上,所以所有这些都可以幸免。

//---
// JavaFX
//
// Note: We shouldn't even need to say this at all. Part of Java 7 RT (since 7u06) and should come from there (right)
//      The downside is that now this also gets into the 'one-jar' .jar package (where it would not need to be,
//      and takes 15MB of space - of the 17MB package!) AKa 1-Nov-2012
//
unmanagedJars in Compile <+= javaHome map { jh /*: Option[File]*/ =>
  val dir: File = jh.getOrElse(null)    // unSome
  //
  val jfxJar = new File(dir, "/jre/lib/jfxrt.jar")
  if (!jfxJar.exists) {
    throw new RuntimeException( "JavaFX not detected (needs Java runtime 7u06 or later): "+ jfxJar.getPath )  // '.getPath' = full filename
  }
  Attributed.blank(jfxJar)
} 

请注意,sbt 不允许条目中有空行。为了避免这种情况,我//在需要一些空白的地方使用了缩进线。

于 2013-01-04T12:26:13.500 回答
0

<+=确实是用于附加到“集合”设置,我认为字符串连接不支持它。另外,在您的第二次尝试中,您既尝试通过赋值运算符 ( <+=)进行连接,又尝试使用运算符手动连接+,这当然不是您想要的。只需替换<+=<<=,它应该让 sbt 高兴。

unmanagedJars in Compile <<= javaHome map { jh => jh + "/jre/lib/jfxrt.jar" }

更新:原来我误读了你的帖子,完全错了。您使用<+=附加到 unamanagedJar 是正确的,而使用+只是为了创建一个绝对文件路径。对于那个很抱歉。这次我真的尝试用手头的 sbt 修复它,并设法让它编译。不过,我实际上并没有针对实际项目对其进行测试,我会让您尝试并报告它是否按预期工作。

unmanagedJars in Compile <+= javaHome map { jh => Attributed.blank( new File( jh.getOrElse(sys.error("Error, could not get java home")),"jre/lib/jfxrt.jar" ) ) }

不过,这显然不是很好,可能会有一些帮手使它更具可读性。

于 2013-01-02T16:40:32.497 回答