Может ли стандартный Sun javac выполнять инкрементную компиляцию? - PullRequest
23 голосов
/ 07 апреля 2010

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

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

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

для моих сборок муравьев.

Ответы [ 4 ]

15 голосов
/ 07 апреля 2010

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

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

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

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

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

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

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

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

    Чтобы понять, почему Ant <depend> не защищен от ошибок, прочитайте раздел «Ограничения» документации .

3 голосов
/ 04 декабря 2010

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

2 голосов
/ 25 ноября 2013

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

Вы можете получить инкрементную сборку с помощью задачи 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>
2 голосов
/ 07 апреля 2010

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

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

...