опция javac для рекурсивной компиляции всех файлов java в заданном каталоге


127

Я использую компилятор javac для компиляции файлов java в моем проекте. Файлы распределены по несколько пакетов , как это: com.vistas.util, com.vistas.converter, com.vistas.LineHelper, com.current.mdcontect.

В каждом из этих пакетов есть несколько файлов java. Я использую javac вот так:

javac com/vistas/util/*.java com/vistas/converter/*.java
      com.vistas.LineHelper/*.java com/current/mdcontect/*.java

(в одной строке)

Вместо того, чтобы указывать так много путей, как я могу попросить компилятор рекурсивно скомпилировать все java-файлы из родительского каталога com?


2
Вам действительно стоит взглянуть на такие инструменты, как Ant или Maven.
Laurent Pireyn 08

Этот пост SO может быть полезен stackoverflow.com/questions/864630/…
Gopi

Ответы:


220

Я бы также предложил использовать какой-то инструмент сборки ( Ant или Maven , Ant уже предлагается, и с ним проще начать) или IDE, которая обрабатывает компиляцию (Eclipse использует инкрементную компиляцию со стратегией согласования, и вам даже не нужно нажимайте любые кнопки "Compile" ).

Использование Javac

Если вам нужно попробовать что-то для более крупного проекта и у вас нет подходящих инструментов для сборки поблизости, вы всегда можете использовать небольшую уловку, которая javacпредлагает: имена классов для компиляции могут быть указаны в файле. Вам просто нужно передать имя файла javacс @префиксом.

Если вы можете создать список всех *.javaфайлов в своем проекте, это просто:

# Linux / MacOS
$ find -name "*.java" > sources.txt
$ javac @sources.txt

:: Windows
> dir /s /B *.java > sources.txt
> javac @sources.txt
  • Преимущество в том, что это быстрое и простое решение.
  • Недостатком является то, что вам нужно регенерировать sources.txtфайл каждый раз, когда вы создаете новый источник или переименовываете один существующий файл, что легко забыть (а значит, подвержено ошибкам) ​​и утомительно.

Использование инструмента сборки

В конечном итоге лучше использовать инструмент, предназначенный для создания программного обеспечения.

Использование Ant

Если вы создадите простой build.xmlфайл, описывающий, как собрать программное обеспечение:

<project default="compile">
    <target name="compile">
        <mkdir dir="bin"/>
        <javac srcdir="src" destdir="bin"/>
    </target>
</project>

вы можете скомпилировать все программное обеспечение, выполнив следующую команду:

$ ant
  • Преимущество заключается в том, что вы используете стандартный инструмент сборки, который легко расширять.
  • Недостатком является то, что вам придется скачать, настроить и изучить дополнительный инструмент. Обратите внимание, что большинство IDE (таких как NetBeans и Eclipse) предлагают отличную поддержку для записи файлов сборки, поэтому в этом случае вам не нужно ничего загружать.

Использование Maven

Maven не так уж и прост в настройке и работе, но изучение его стоит хорошо. Вот отличное руководство, чтобы начать проект за 5 минут .

  • Его главное преимущество (для меня) заключается в том, что он также обрабатывает зависимости, поэтому вам не нужно больше загружать файлы Jar и управлять ими вручную, и я нашел его более полезным для сборки, упаковки и тестирования более крупных проектов.
  • Недостатком является то, что у него крутая кривая обучения, и если плагины Maven любят подавлять ошибки :-) Другое дело, что довольно много инструментов также работают с репозиториями Maven (например, Sbt для Scala, Ivy для Ant, Graddle для Groovy) ,

Использование IDE

Вот что может повысить продуктивность разработки. Есть несколько альтернатив с открытым исходным кодом (например, Eclipse и NetBeans , я предпочитаю первый) и даже коммерческие (например, IntelliJ ), которые довольно популярны и мощны.

Они могут управлять построением проекта в фоновом режиме, поэтому вам не нужно заниматься всеми вещами командной строки. Тем не менее, это всегда удобно, если вы знаете, что на самом деле происходит в фоновом режиме, чтобы вы могли отслеживать случайные ошибки, такие как ClassNotFoundException.

Еще одно примечание

Для более крупных проектов всегда рекомендуется использовать IDE и инструмент сборки. Первый повышает вашу продуктивность, а второй позволяет использовать с проектом различные IDE (например, Maven может сгенерировать дескрипторы проекта Eclipse с помощью простой mvn eclipse:eclipseкоманды). Более того, имея проект, который можно протестировать / построить с помощью однострочной команды, легко представить новым коллегам, например, на сервере непрерывной интеграции. Кусок пирога :-)


4
При использовании javacлучше указать выходной каталог. find -name "*.java" > sources.txt && javac -d bin @sources.txt, В противном случае файлы * .class сохраняются в каталог, где находятся исходные коды.
Максим Дмитриев

1
Абсолютная правда. Хотя, на мой взгляд, если кто-то только начал экспериментировать javac, концепция того CLASSPATH, как запускать код java, как работать с пакетами, которые должны быть корневой папкой для запуска, и т.д. обычно не ясны. Таким образом, я пропустил выходной каталог. В любом случае спасибо за предложение!
rlegendi

6
Для пользователей Mac, сталкивающихся с этим, findкоманда find . -name "*.java" > sources.txt.
следующая

@MrDuk Что означает добавление "." делать? Это для поиска в текущем каталоге?
Брэди Шиэн

@BradySheehan начнет поиск с заданного пути. "" означает начало с текущего словаря. Обратите внимание, что вы должны указать путь для поиска (в OS X)
Крис

40
find . -name "*.java" -print | xargs javac 

Довольно жестоко, но чертовски работает. (Используйте только в небольших программах, это абсолютно неэффективно)


1
Если вы используете это, подумайте find ... -print0и xargs -0 ...вместо этого не
разбивайте

29

Если ваша оболочка поддерживает это, будет ли что-то подобное работать?

javac com/**/*.java 

Если ваша оболочка не поддерживает **, то возможно

javac com/*/*/*.java

работает (для всех пакетов с 3-мя компонентами - адаптироваться более-менее).


Я попытался использовать это в командной строке в Windows 10. Может кто-нибудь подтвердить, работает ли он в Windows 10 или я делаю это неправильно, пожалуйста
Дэн

26

В обычном случае, когда вы хотите скомпилировать весь свой проект, вы можете просто предоставить javac вашему основному классу и позволить ему скомпилировать все необходимые зависимости:

javac -sourcepath . path/to/Main.java


Очень простой метод, не полагающийся на лишние файлы
linquize

Это лучший и самый простой вариант для людей, у которых мало времени на изучение Ant (как я)
Хамза Аббад

К сожалению, это лениво. Если вы не коснетесь Main.java, чего вы, вероятно, не сделаете сразу после создания второго файла, компилятор не получит ничего другого.
Том Хотин - tackline 01

Здесь тоже не работает. Некоторые зависимости не перекомпилируются, несмотря на изменение. @ TomHawtin-tackline Раньше я пробовал прикоснуться к основному, но ничего. Может быть, нужно все тронуть. Хотя немного неловко.
ммм

5

javac -cp "jar_path/*" $(find . -name '*.java')

(Я предпочитаю не использовать xargs, потому что он может разделять их и запускать javac несколько раз, каждый с подмножеством java-файлов, некоторые из которых могут импортировать другие, не указанные в той же командной строке javac)

Если у вас есть точка входа в App.java, лучше всего подойдет -sourcepath. Он компилирует все остальные файлы Java, которые ему нужны, в соответствии с зависимостями импорта. например:

javac -cp "jar_path/*" -sourcepath src/ src/com/companyname/modulename/App.java

Вы также можете указать класс-файл реж цели: -d target/.


3

Я бы посоветовал вам научиться использовать ant , который очень хорошо подходит для этой задачи, очень прост для понимания и хорошо документирован.

Вам просто нужно определить такую ​​цель в файле build.xml:

<target name="compile">
    <javac srcdir="your/source/directory"
           destdir="your/output/directory"
           classpath="xyz.jar" />
</target>

2

Я просто использую make с простым make-файлом, который выглядит так:

JAVAC = javac -Xlint:unchecked
sources = $(shell find . -type f -name '*.java')
classes = $(sources:.java=.class)

all : $(classes)

clean :
        rm -f $(classes)

%.class : %.java
        $(JAVAC) $<

Он компилирует исходники по одному и перекомпилирует только при необходимости.


1

Команда javac не следует рекурсивному процессу компиляции, поэтому вы должны либо указать каждый каталог при запуске команды, либо предоставить текстовый файл с каталогами, которые вы хотите включить:

javac -classpath "${CLASSPATH}" @java_sources.txt

0

Я использовал это в проекте Xcode JNI для рекурсивного создания моих тестовых классов:

find ${PROJECT_DIR} -name "*.java" -print | xargs javac -g -classpath ${BUILT_PRODUCTS_DIR} -d ${BUILT_PRODUCTS_DIR}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.