scala ant

La velocidad de la tarea de scala''s ant fsc



(1)

Espero que esto te ayude a:

primer caso (fsc ant task)

Cuando inicia ant, carga una nueva JVM en la que se carga scala-compiler.jar . El archivo está cargado debido a la línea <taskdef resource="scala/tools/ant/antlib.xml" classpath="${scala-library.jar}:${scala-compiler.jar}" /> no debido a la parte classpath

segundo caso (ant comienza una línea de comando)

Como se indica, esto se limita a proyectos simples con pocos archivos. Longitud máxima de la línea de comando: windows xp -> 8191, linux / osx -> valor del kernel (generalmente> 100000) Por cierto, está generando dos JVM aquí (uno para ant, otro para fsc). Quizás sea más rápido en tus pruebas ya que usa cachés.

solución propuesta

En maven está el objetivo scala:cc (compilación continua) que mantiene el compilador en la memoria y escanea continuamente los archivos en busca de modificaciones. Si no quieres cambiar tu constructor a maven, quizás puedas escribir una nueva tarea ant que haga lo mismo (fscc: un compilador continuo scala rápido)

Tengo un archivo ant que utilizo para compilar mi proyecto scala. Estoy usando fsc, que funciona de maravilla para evitar los 2 ~ 3 segundos que mi núcleo 2 necesita para simplemente cargar el compilador.
Mi problema es: la tarea ant fsc incurre en la misma penalización de 2 a 3 segundos, según mi conocimiento. Es bastante molesto, porque hay fsc específicamente por esta razón. Es aún más molesto ya que es realmente el tiempo de inicio y no el tiempo de procesamiento, por lo que tengo que esperar 3 segundos en la tarea fsc, incluso cuando no hay nada que volver a compilar. Cada vez, se vuelve agravante.

Mi investigación parece mostrar que la mayor parte del tiempo se dedica a leer scala-compiler.jar. De hecho, tiene sentido que las tareas scalac y fsc necesiten, ya que ejecutan el compilador directamente. Además, eliminar scala-compiler.jar de la ruta de clase de los resultados de la tarea ant, por supuesto, en la tarea falla por falta de dependencia.
Hablando lógicamente, la tarea fsc solo se conecta a la recopilación dæmon, supongo, por lo que no debería necesitar esa dependencia, pero supongo que se trata de cómo se implementa (la tarea fsc se hereda de la tarea de scala). Tal vez vendrá en una próxima versión.

La solución que estoy viendo en este momento es reescribir mi tarea fsc como una tarea de aplicación e invocar fsc manualmente. No tendré la demora entonces. Es una pena tener que rehacer manualmente el trabajo para el que se escribieron específicamente las tareas incluidas con scala.

¿Alguien tiene experiencia con este problema? ¿Hay algo malo en mi análisis? ¿Y puede sugerir una solución mejor que la que planeo implementar?

Como referencia, este es el aspecto de mi tarea (sí, compila un proyecto de 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>

Editar : Aquí es cómo se ve la tarea con aplicar. Parece funcionar. Sin embargo, es bastante insatisfactorio, por lo que la pregunta sigue siendo válida.

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

Vuelva a editar : lo anterior funciona, pero me parece que tiene una limitación bastante grave. Cuando el número de archivos crece, la tarea anterior está limitada por el número de argumentos y / o la longitud de la línea de comando. En Linux o Mac OS con un buen shell, puede ir bastante lejos sin chocar con este muro, pero en Windows solo es necesario un par de docenas de archivos para evitar que funcione lo anterior. Agregar una opción para especificar archivos como rutas de acceso relativas en lugar de absolutas da un poco de aliento, pero no mucho. La división de archivos en varios comandos de acuerdo con las dependencias no es una opción realista, ya que es una tarea bastante pesada y debe actualizarse cada vez que cambia la estructura del archivo. Entonces, mientras que para los proyectos pequeños, lo anterior resolverá principalmente el problema, no ayudará para ningún proyecto de un tamaño respetable ...