FSC ricompila ogni volta
-
25-09-2019 - |
Domanda
FSC ricompila i miei file .scala ogni volta ancora non v'è alcuna necessità - posso compilarlo due volte senza modificare nulla tra tentativi e li ricompila! Per esempio, io ho 2 file
Hello.scala
class Hello{
print("hello")
}
E 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)
Quando chiedo formica di compilare progetto da zero vedo seguente 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
Che io non modificare nulla e chiedo di nuovo di compilazione ant:
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
Come si può vedere, fsc agisce intelligente in caso di Hello.scala (senza ricompilazione) e agisce muto in caso di Tokens.scala. Suggerisco che il problema è in qualche modo in relazione con l'eredità, ma questo è tutto.
Quindi, ciò che è sbagliato?
Soluzione
non mi piace roba distacco molto scritto da altri, ma credo che questa domanda merita una risposta più completa che ciò che era strettamente chiesto.
Quindi, prima di tutto, fsc
ricompila tutto per default, punto. E 'ant
, non fsc
, che sta lasciando Hello.scala
fuori, perché il nome del file corrisponde al nome della classe. Non sta lasciando Tokens.scala
fuori perché non esiste una categoria denominata Tokens
compilato -. Così, in assenza di un Tokens.class
, è ricompilato Tokens.scala
Questa è la cosa sbagliata da fare con la Scala. differisce Scala in un aspetto fondamentale da Java dal fatto che, a causa delle limitazioni tecniche JVM, un cambiamento in una trait
richiede ricompilazione di ogni classe, oggetto o istanza che l'utilizza.
Ora, si può risolvere il compito ant
di fare una cosa più intelligente a partire da Scala 2.8. Sto prendendo questa informazione da blogtrader.net da Caoyuan, di Scala Plugin per Netbeans fama. Si definisce il compito Scala sul bersaglio costruzione come di seguito:
<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>
Si dice ant
ricompilare tutto, come ant
semplicemente non è abbastanza intelligente per capire che cosa deve essere ricompilato oppure no. Racconta anche Scala per creare un file contenente le dipendenze di compilazione, e utilizzare un algoritmo di dipendenza transitiva di capire cosa deve essere ricompilato oppure no.
È inoltre necessario modificare il target init per includere la directory di costruzione nel classpath accumulo, come avrà bisogno Scala che ricompilare altre classi. Esso dovrebbe essere simile a questo:
<path id="build.classpath">
<pathelement location="${scala-library.jar}"/>
<pathelement location="${scala-compiler.jar}"/>
<pathelement location="${build.classes.dir}"/>
</path>
Per ulteriori informazioni, si prega di fare riferimento al blog di Caoyuan.
Altri suggerimenti
Tokens.scala viene ricompilato perché non c'è un file di classe corrispondente suo nome base. Cioè, non produce un file Tokens.class. Al momento di decidere se un file sorgente deve essere compilato, sguardi FSC per un file di classe con lo stesso nome base e se il file di classe non esiste o la data di modifica del file di origine è successiva a quella del file di classe, il file sorgente verrà ricostruito . Se è possibile, io suggerisco di guardare in semplicità costruttiva strumento , la sua continua modalità di compilazione brani accuratamente source-> classfile mappatura e non sarà ricompilazione Tokens.scala
Per ride troppo, pensare a ciò che il compilatore potrebbe fare se si dispone di un file di origine diversa che ha class Tokens
in esso.
Anche se Scala permette classi pubbliche arbitrarie / oggetti in ogni file sorgente, c'è ancora un bel po 'di utensili che presuppone si un po' seguire la convenzione Java e almeno avere una classe / oggetto nel file con lo stesso nome come la fonte file di nome base.