Может ли стандартный Sun javac выполнять инкрементную компиляцию?

Недавно я начал использовать Java-компилятор Eclipse, потому что он значительно быстрее стандартного javac. Мне сказали, что это быстрее, потому что он выполняет инкрементную компиляцию. Но я все еще немного не уверен в этом, так как я не могу найти никакой авторитетной документации об "инкрементной функции" компиляторов eclispse и sun. Правда ли, что компилятор Sun всегда компилирует каждый исходный файл, а компилятор Eclipse компилирует только измененные файлы и те, на которые влияет такое изменение?

Изменить: я не использую функцию автоматического построения Eclipse, но вместо этого я устанавливаю

-Dbuild.compiler=org.eclipse.jdt.core.JDTCompilerAdapter

для моего муравья строит.

4 ответа

Решение

Правда ли, что компилятор Sun всегда компилирует каждый исходный файл, а компилятор Eclipse компилирует только измененные файлы и те, на которые влияет такое изменение?

Я считаю, что вы правы в обоих случаях.

Конечно, вы можете заставить Eclipse перекомпилировать все.

Но другая часть уравнения заключается в том, что инструменты сборки Java, такие как Ant и Maven, способны компилировать только измененные классы и их дерево зависимых классов.

РЕДАКТИРОВАТЬ

В Ant инкрементная компиляция может быть выполнена двумя способами:

  • По умолчанию <javac> задача сравнивает временные метки .java и соответствующий .class файлы, и только говорит компилятору Java перекомпилировать исходные (.java) файлы, которые новее, чем соответствующие им целевые (.class) файлы, или у которых вообще нет целевого файла.

  • <depend> Задача также учитывает зависимости между классами, которые она определяет, читая и анализируя информацию о зависимостях, встроенную в .class файлы. Определив, какой .class файлы устарели, <depend> задача удаляет их, поэтому следующее <javac> задача их перекомпилирует. Однако это не совсем надежно. Например, обширные изменения в исходном коде могут привести к <depend> Задачей может быть анализ устаревших зависимостей. Также определенные виды зависимости (например, от статических констант) не очевидны в .class формат файла.

    Чтобы понять, почему муравей <depend> не является надежным, прочитайте раздел "Ограничения" документации.

Javac компилирует только исходные файлы, которые либо названы в командной строке, либо являются зависимостями и устарели. У Eclipse может быть более детальный способ решить, что это значит.

Повторяя то, что я услышал здесь, и формулируя это для ленивых людей, как я:

Инкрементные сборки можно выполнить с помощью задачи javac в ant, но вы должны использовать задачу зависящего для очистки файлов.class для вашего измененного файла.java И вы не должны оставлять оператор include не заданным в задаче javac. (Указание только пути src в задаче javac и оставление включает в себя неуказанные причины javac перекомпилирует все найденные источники.)

Вот мои задачи и Javac. С помощью стандартного Java-компилятора Oracle компилируются только файлы.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>

Затмение, безусловно, делает это. Также он делает это во время сохранения, если у вас включена эта опция (и это по умолчанию). Похоже, что Sun также не делает этого (это очень легко проверить, просто создайте небольшой проект, где A является основным классом, который использует класс B, но B не использует класс A. Затем измените A и скомпилируйте проект еще раз, посмотреть, если отметка времени для b.class изменился

Так работают многие компиляторы (например, gcc). Вы можете использовать такие инструменты, как ant и make, чтобы компилировать только ту часть проекта, которая изменилась. Также обратите внимание, что эти инструменты не идеальны, иногда Eclipse просто теряет отслеживание изменений, и вам необходимо выполнить полную перестройку.

Другие вопросы по тегам