我有一个用于编译scala项目的ant文件。我正在使用fsc来创建奇迹,以避免我的核心2需要加载编译器的2~3秒
我的问题是:据我所知,蚂蚁fsc
任务会造成相同的2~3秒的惩罚。这很烦人,因为有这个原因的fsc。它更加烦人,因为它真的是开始时间而不是处理时间,所以即使没有任何重新编译的东西,我也要在fsc任务上等待3秒钟。它每次都会变得更加恶化。
我的调查似乎表明大部分时间花在阅读scala-compiler.jar上。实际上,scalac
和fsc
任务需要这样才有意义,因为它们直接运行编译器。此外,从ant任务的类路径中删除scala-compiler.jar会导致任务因缺少依赖而失败。
从逻辑上讲,fsc
任务只是连接到我想的编译守护程序,所以它不应该需要那个依赖项,但我想它是关于它是如何实现的(fsc任务继承自scala任务)。也许它会出现在下一个版本中。
我现在正在考虑的解决方案是,将我的fsc任务重写为应用任务并手动调用fsc。那时我不会有延迟。很遗憾,必须手动重做scala中包含的任务专门编写的工作。
有没有人有过这个问题的经验?我的分析有什么不对吗?您能否提出比我计划实施的解决方案更好的解决方案?
供参考,这是我的任务看起来的样子(是的,它编译了一个android项目):
<target name="compile-scala" description="Compile scala files">
<taskdef resource="scala/tools/ant/antlib.xml" classpath="${scala-library.jar}:${scala-compiler.jar}" />
<mkdir dir="${out.classes.absolute.dir}" />
<fsc encoding="utf-8" deprecation="on" destdir="${out.classes.absolute.dir}">
<src>
<dirset dir="." includes="src"/>
<dirset dir="." includes="gen"/>
</src>
<classpath>
<pathelement location="${android.jar}" />
<fileset dir="${sdk.dir}/tools/lib" includes="*.jar" />
</classpath>
</fsc>
</target>
修改:以下是适用的任务。它似乎工作。然而,这是非常不满意的,所以问题仍然存在。
<target name="fast-compile-scala"
description="Compile scala files without loading the compiler inside ant">
<mkdir dir="${out.classes.absolute.dir}" />
<apply executable="fsc" failonerror="true" parallel="true">
<arg value="-encoding" />
<arg value="utf-8" />
<arg value="-deprecation" />
<arg value="-dependencyfile" />
<arg value="${out.classes.absolute.dir}/${scala.deps}" />
<arg value="-g:vars" />
<arg value="-d" />
<arg value="${out.classes.absolute.dir}" />
<arg value="-make:transitivenocp" />
<arg value="-classpath" />
<arg value="${android.jar}:${out.classes.absolute.dir}" />
<!-- <arg value="-optimize" /> -->
<!-- <arg value="-verbose" /> -->
<!-- <arg value="-explaintypes" /> -->
<fileset dir="src" includes="**/*.scala" />
<fileset dir="src" includes="**/*.java" />
<fileset dir="gen" includes="**/*.java" />
</apply>
</target>
再次修改: 上述工作,但我发现它有一个非常严重的限制。当文件数量增加时,上述任务受参数数量和/或命令行长度的限制。在具有良好shell的linux或mac OS下,你可以在不打墙的情况下走很远的路,但在Windows下,只需要几十个文件就可以防止上述工作。添加一个选项来指定文件作为相对路径而不是绝对路径会给出一些呼吸,但并不多。根据依赖性在多个命令中拆分文件不是一个现实的选择,因为它是一项非常繁重的任务,需要在文件结构发生变化时进行更新。因此,对于小型项目,上述内容将主要解决问题,对于任何规模可观的项目都无济于事......
答案 0 :(得分:1)
希望这会对你有所帮助:
启动ant时,加载一个全新的JVM,其中加载scala-compiler.jar
。
由于行<taskdef resource="scala/tools/ant/antlib.xml" classpath="${scala-library.jar}:${scala-compiler.jar}" />
而导致jar被加载,而不是因为classpath
部分。
正如您所概述的那样,这仅限于包含少量文件的简单项目。最大命令行长度:windows xp - &gt; 8191,linux / osx - &gt;内核值(通常> 100000) 顺便说一下,你在这里产生两个JVM(一个用于ant,另一个用于fsc)。也许它在你的测试中更快,因为它使用缓存。
在maven中有目标scala:cc
(连续编译),它将编译器保留在内存中以及不断扫描文件以进行修改。如果您不想将构建器更改为maven,也许您可以编写一个执行相同操作的新ant任务(fscc:快速scala连续编译器)