2010-09-27 4 views
3

FSC перекомпилирует мои файлы .scala каждый раз, даже если нет необходимости - я могу скомпилировать его дважды, не редактируя ничего между попытками, и он перекомпилирует их! Например, у меня есть 2 файлаFSC перекомпилирует каждый раз

Hello.scala

class Hello{ 
    print("hello") 
} 

И 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) 

Когда я спрашиваю муравей скомпилировать проект с нуля, я вижу следующий вывод:

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 Я ничего не редактировал, и снова проконсультируйся с коммиком:

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 

Как вы можете видеть, fsc действует умным в случае Hello.scala (без перекомпиляции) и действует немым в случае Tokens.scala. Я полагаю, что проблема как-то связана с наследованием, но это все.

Итак, что не так?

+2

FSC будет скомпилировать все, кроме случаев, когда вы передадите флажки, говорящие ему, чтобы сделать транзитивный анализ зависимостей. Как вы настроили задачу компиляции Scala в Ant? –

ответ

4

Мне не нравится много сообщений, написанных другими, но я думаю, что этот вопрос заслуживает более полного ответа на то, что было строго задано.

Итак, прежде всего, fsc перекомпилирует все по умолчанию, период. Это ant, а не fsc, что оставляет Hello.scala вне, поскольку имя файла совпадает с именем класса. Он не оставляет Tokens.scala, потому что нет класса под названием Tokens, скомпилированного - так что, в отсутствие Tokens.class, он перекомпилировал Tokens.scala.

Это не то, что связано с Scala. Scala отличается в одном фундаментальном аспекте от Java тем, что из-за технических ограничений на JVM изменение в trait требует перекомпиляции каждого класса, объекта или экземпляра, который его использует.

Теперь можно исправить задачу ant, чтобы сделать более умную вещь, начиная с Scala 2.8. Я беру эту информацию от blogtrader.net от Caoyuan, плагина Scala для славы Netbeans.Вы определяете задачу 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.

5

Tokens.scala перекомпилирован, потому что нет файла класса, соответствующего его базовому имени. То есть, он не создает файл Tokens.class. При определении того, следует ли компилировать исходный файл, fsc ищет файл класса с тем же самым базовым именем, и если файл класса не существует или время изменения в исходном файле больше, чем в файле класса, исходный файл будет перестроен , Если вы можете, я предлагаю вам заглянуть в Simple Build Tool, его режим непрерывной компиляции точно отслеживает сопоставление файлов source-> classfile и не будет перекомпилировать Tokens.scala

Для дополнительного смеха подумайте о том, что может сделать компилятор, если у вас есть другой исходный файл, в котором есть class Tokens.

Хотя scala позволяет произвольным публичным классам/объектам в любом исходном файле, все еще существует довольно много инструментов, предполагающих, что вы будете несколько следовать за соглашением java и по крайней мере иметь один класс/объект в файле с тем же именем, что и исходное имя файла.

+0

ahaha, это было «бинго» за 1 секунду, но я пропустил столько времени, чтобы точно написать свой ответ, чтобы вы были первыми). Также соглашение Java не подходит, когда у вас есть закрытые классы. – Jeriho

Смежные вопросы