Можно ли стандартное компиляция Sun javac делать?
Недавно я начал использовать java-компилятор Eclipse, потому что он значительно быстрее, чем стандартный javac. Мне сказали, что это быстрее, потому что он выполняет инкрементную компиляцию. Но я все еще немного не уверен в этом, так как я не могу найти никакой авторитетной документации об обоих - eclispse и sun-compilers "инкрементной функции". Верно ли, что компилятор Sun всегда компилирует каждый исходный файл, а компилятор Eclipse компилирует только измененные файлы и те, на которые влияет такое изменение?
Изменить: я не использую функцию автозапуска Eclipse, но вместо этого я устанавливаю
-Dbuild.compiler=org.eclipse.jdt.core.JDTCompilerAdapter
для моей сборки ant.
Ответы
Ответ 1
Верно ли, что компилятор Sun всегда компилирует каждый исходный файл, а компилятор Eclipse компилирует только измененные файлы и те, на которые влияет такое изменение?
Я считаю, что вы верны по обоим пунктам.
Вы можете, конечно, заставить Eclipse перекомпилировать все.
Но другая часть уравнения состоит в том, что Java-инструменты построения, такие как Ant и Maven, способны только компилировать классы, которые изменились, и их дерево зависимых классов.
EDIT
В Ant инкрементная компиляция может быть выполнена двумя способами:
-
По умолчанию задача <javac>
сравнивает отметки времени .java
и соответствующие файлы .class
и сообщает только компилятор Java для перекомпилирования исходных (.java) файлов, которые являются более новыми, чем их соответствующие целевые (.class) файлы, или которые вообще не имеют целевого файла.
-
Задача <depend>
также учитывает зависимости между классами, которые она определяет, считывая и анализируя информацию зависимостей, встроенную в файлах .class
. Определив, какие файлы .class
устарели, задача <depend>
удаляет их, поэтому следующая задача <javac>
будет их перекомпилировать. Однако это не совсем безупречно. Например, обширные изменения исходного кода могут привести к тому, что задача <depend>
может анализировать устаревшие зависимости. Также определенные типы зависимостей (например, от статических констант) не отображаются в формате файла .class
.
Чтобы понять, почему Ant <depend>
не является надежным, прочитайте раздел "Ограничения" документация.
Ответ 2
Javac только компилирует исходные файлы, которые либо именованы в командной строке, либо являются зависимыми, и устарели. У Eclipse может быть более тонкий способ решить, что это значит.
Ответ 3
Eclipse, безусловно, это делает. Также он делает это в режиме экономии времени, если у вас включен этот параметр (и он по умолчанию). Похоже, что солнце тоже этого не делает (это очень легко проверить, просто сделайте небольшой проект, где A - основной класс, который использует класс B, но B не использует класс A. Затем измените A и скомпилируйте проект снова, посмотрите, изменилась ли временная метка для b.class
.
Так много компиляторов работают (например, gcc). Вы можете использовать такие инструменты, как ant, и сделать для компиляции только часть проекта, который изменился. Также обратите внимание, что эти инструменты не идеальны, иногда затмение просто теряет следы изменений, и вам нужно будет полностью перестроить.
Ответ 4
Пересказывая то, что я здесь слышал, и формулирую его для ленивых людей вроде меня:
Вы можете получить инкрементные сборки с помощью задачи javac в ant, но вы должны использовать зависшую задачу для очистки .class файлов для вашего измененного .java И вы не должны оставлять оператор include, не заданный в задаче javac. (Указание только пути src в задаче javac и уходе включает неуказанные причины javac перекомпилировать все найденные источники.)
Вот мои задачи и задачи javac. Со стандартным компилятором Java Java компилируются только файлы .java, которые я модифицирую. Надеюсь, это поможет!
<depend srcdir="JavaSource" destdir="${target.classes}" cache="${dependencies.dir}" closure="yes">
<classpath refid="compiler.classpath" />
<include name="**/*.java"/>
</depend>
<javac destdir="${target.classes}" debug="true" debuglevel="${debug.features}" optimize="${optimize.flag}" fork="yes" deprecation="no" source="1.6" target="1.6" encoding="UTF-8" includeantruntime="no">
<classpath refid="compiler.classpath"/>
<src path="JavaSource"/>
<include name="**/*.java" /> <!-- This enables the incremental build -->
</javac>