FSC每次都重新编译 [英] FSC recompiles every time

查看:217
本文介绍了FSC每次都重新编译的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

FSC每次都重新编译我的.scala文件,即使没有必要 - 我可以编译它两次,而不需要在尝试之间编辑任何东西,它会重新编译它们!
例如,我有2个文件



Hello.scala

  class Hello {
print(hello)
}

和Tokens.scala:

 抽象类Token(val str:String,val start:Int,val end:Int)
{override def toString = getClass.getSimpleName +(+[+ start + - + end +]+ str +)}
class InputToken(str:String,start: int,end:Int)
extends Token(str,start,end)
类ParsedToken(str:String,start:Int,end:Int,val invisible:Boolean)
extends Token str,start,end)



当我要求ant从头开始编译项目时, / p>

  ant compile 
init:
[mkdir]创建目录:D:\projects\Test\\ \\build\classes
[mkdir]创建目录:D:\projects\Test\build\test\classes

编译:
[fsc] Base目录是`D:\projects\Test`
[fsc]编译源文件:somepackage\Hello.scala,somepackage\Tokens.scala到D:\projects\Test\build\类

BUILD SUCCESSFUL

比我不编辑任何东西,再次编译:

  ant compile 
init:
[mkdir]创建dir:D:\projects \Test\build\classes
[mkdir]创建目录:D:\projects\Test\build\test\classes

编译:
[fsc]基本目录是`D:\projects\Test`
[fsc]将源文件:somepackage\Tokens.scala编译为D:\projects\Test\build\classes

BUILD SUCCESSFUL

正如你所看到的, scala(没有重新编译),并在Tokens.scala的情况下行为蠢。我建议问题是与继承有关,但这是所有。



那么是什么问题?

解决方案

我不喜欢张贴他人写的东西,但我认为这个问题是一个更完整的答案,严格要求。



因此,首先, fsc 默认重新编译所有内容,period。它是 ant ,而不是 fsc ,它留下 Hello.scala out,因为文件名匹配类名。它不会离开 Tokens.scala ,因为没有类 Tokens 编译 - 所以,在没有 Tokens.class ,它重新编译 Tokens.scala



这是与Scala做错了。 Scala与Java的一个基本方面不同之处在于,由于JVM的技术限制, trait 中的更改需要重新编译每个使用它的类,对象或实例化。 / p>

现在,可以修复 ant 任务,从Scala 2.8开始做一个更聪明的事情。我从 blogtrader.net 获取Caoyuan的Netbeans成员的Scala插件的信息。您可以在构建目标上定义Scala任务,如下所示:

 < scalac srcdir =$ {src.dir}
destdir =$ {build.classes.dir}
classpathref =build.classpath
force =yes
addparams = - make:transitive -dependencyfile $ { build.dir} /。scala_dependencies
>
< src path =$ {basedir} / src1/>
<! - include name =compile / ** / *。scala/ - >
<! - exclude name =forget / ** / *。scala/ - >
< / scalac>

它会告诉 ant ant 根本不够聪明,无法确定需要重新编译或不需要重新编译。它还会告诉Scala 构建一个包含编译依赖关系的文件,并使用传递依赖性算法来确定需要重新编译的内容。



您还需要更改init目标以将构建目录包含在构建类路径中,因为Scala将需要重新编译其他类。它应该看起来像这样:

 < path id =build.classpath> 
< pathelement location =$ {scala-library.jar}/>
< pathelement location =$ {scala-compiler.jar}/>
< pathelement location =$ {build.classes.dir}/>
< / path>

详情请参阅Caoyuan的博客。


FSC recompiles my .scala files every time even there is no need - I can compile it twice without editing anything between attempts and it recompiles them! For example, I have 2 files

Hello.scala

class Hello{
  print("hello")
}

And Tokens.scala:

abstract class Token(val str: String, val start: Int, val end: Int)
  {override def toString = getClass.getSimpleName + "(" + "[" + start + "-" + end + "]" + str + ")"}
class InputToken(str: String, start: Int, end: Int)
        extends Token(str, start, end)
 class ParsedToken(str: String, start: Int, end: Int, val invisible: Boolean)
        extends Token(str, start, end)

When I ask ant to compile project from scratch I see following output:

ant compile
init:
    [mkdir] Created dir: D:\projects\Test\build\classes
    [mkdir] Created dir: D:\projects\Test\build\test\classes

compile:
      [fsc] Base directory is `D:\projects\Test`
      [fsc] Compiling source files: somepackage\Hello.scala, somepackage\Tokens.scala to D:\projects\Test\build\classes

BUILD SUCCESSFUL

Than I don't edit anything and ask ant compile again:

ant compile
init:
    [mkdir] Created dir: D:\projects\Test\build\classes
    [mkdir] Created dir: D:\projects\Test\build\test\classes

compile:
      [fsc] Base directory is `D:\projects\Test`
      [fsc] Compiling source files: somepackage\Tokens.scala to D:\projects\Test\build\classes

BUILD SUCCESSFUL

As you can see, fsc acts smart in case of Hello.scala (no recompilation) and acts dumb in case of Tokens.scala. I suggest that the problem is somehow related with inheritance but that is all.

So what is wrong?

解决方案

I don't like much posting stuff written by others, but I think this question merits a more complete answer that what was strictly asked.

So, first of all, fsc recompiles everything by default, period. It is ant, not fsc, which is leaving Hello.scala out, because the file name matches the class name. It is not leaving Tokens.scala out because there is no class called Tokens compiled -- so, in the absence of a Tokens.class, it recompiled Tokens.scala.

That is the wrong thing to do with Scala. Scala differs in one fundamental aspect from Java in that, because of technical limitations on JVM, a change in a trait requires recompilation of every class, object or instantiation that uses it.

Now, one can fix the ant task to do a smarter thing starting with Scala 2.8. I'm taking this information from blogtrader.net by Caoyuan, of Scala plugin for Netbeans fame. You define the Scala task on the build target like below:

<scalac srcdir="${src.dir}"
        destdir="${build.classes.dir}"
        classpathref="build.classpath"
        force="yes"
        addparams="-make:transitive -dependencyfile ${build.dir}/.scala_dependencies"
        >
    <src path="${basedir}/src1"/> 
    <!--include name="compile/**/*.scala"/-->
    <!--exclude name="forget/**/*.scala"/-->
</scalac>

It tells ant to recompile everything, as ant simply isn't smart enough to figure out what needs to be recompiled or not. It also tells Scala to build a file containing compilation dependencies, and use a transitive dependency algorithm to figure out what needs to be recompiled or not.

You also need to change the init target to include the build directory in the build classpath, as Scala will need that to recompile other classes. It should look like this:

<path id="build.classpath">
    <pathelement location="${scala-library.jar}"/>
    <pathelement location="${scala-compiler.jar}"/>
    <pathelement location="${build.classes.dir}"/>
</path>

For more details, please refer to Caoyuan's blog.

这篇关于FSC每次都重新编译的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆