javac opcja rekurencyjnej kompilacji wszystkich plików java w danym katalogu

127

Używam kompilatora javac do kompilowania plików Java w moim projekcie. Pliki te są rozłożone na kilka pakietów tak: com.vistas.util, com.vistas.converter, com.vistas.LineHelper, com.current.mdcontect.

Każdy z tych pakietów zawiera kilka plików java. Używam javaca w ten sposób:

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

(w jednej linii)

Zamiast podawać tak wiele ścieżek, jak mogę poprosić kompilator o rekursywną kompilację wszystkich plików java z nadrzędnego katalogu com?

user496934
źródło
2
Naprawdę powinieneś rzucić okiem na narzędzia takie jak Ant czy Maven.
Laurent Pireyn,
Ten post SO może być przydatny stackoverflow.com/questions/864630/ ...
Gopi,

Odpowiedzi:

220

Sugerowałbym również użycie jakiegoś narzędzia do budowania ( Ant lub Maven , Ant jest już sugerowane i jest łatwiejsze do rozpoczęcia) lub IDE, które obsługuje kompilację (Eclipse używa kompilacji przyrostowej ze strategią uzgadniania, a ty nawet nie musisz pamiętaj o naciśnięciu dowolnego „Kompiluj” ).

Korzystanie z Javac

Jeśli chcesz wypróbować coś dla większego projektu i nie masz w pobliżu żadnych odpowiednich narzędzi do kompilacji, zawsze możesz użyć małej sztuczki, która javacoferuje: nazwy klas do kompilacji można określić w pliku. Po prostu musisz przekazać nazwę pliku do javacz @przedrostkiem.

Jeśli możesz utworzyć listę wszystkich *.javaplików w projekcie, jest to łatwe:

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

:: Windows
> dir /s /B *.java > sources.txt
> javac @sources.txt
  • Zaletą jest to, że jest to szybkie i łatwe rozwiązanie.
  • Wadą jest to, że musisz ponownie sources.txtgenerować plik za każdym razem, gdy tworzysz nowe źródło lub zmieniasz nazwę istniejącego pliku, co jest łatwe do zapomnienia (a więc podatne na błędy) i męczące zadanie.

Korzystanie z narzędzia do budowania

Na dłuższą metę lepiej jest używać narzędzia, które zostało zaprojektowane do tworzenia oprogramowania.

Korzystanie z Ant

Jeśli utworzysz prosty build.xmlplik, który opisuje, jak zbudować oprogramowanie:

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

możesz skompilować całe oprogramowanie, uruchamiając następujące polecenie:

$ ant
  • Zaletą jest to, że używasz standardowego narzędzia do budowania, które można łatwo rozszerzyć.
  • Wadą jest to, że musisz pobrać, skonfigurować i nauczyć się dodatkowego narzędzia. Zauważ, że większość IDE (takich jak NetBeans i Eclipse) oferuje świetne wsparcie dla pisania plików kompilacji, więc nie musisz niczego pobierać w tym przypadku.

Korzystanie z Maven

Konfiguracja i praca z Maven nie są takie trywialne, ale nauka tego się opłaca. Oto świetny samouczek, aby rozpocząć projekt w ciągu 5 minut .

  • Jego główną zaletą (dla mnie) jest to, że obsługuje również zależności, więc nie będziesz musiał pobierać więcej plików Jar i zarządzać nimi ręcznie, a uznałem, że jest to bardziej przydatne do budowania, pakowania i testowania większych projektów.
  • Wadą jest to, że ma stromą krzywą uczenia się, a jeśli wtyczki Maven lubią tłumić błędy :-) Inną rzeczą jest to, że całkiem sporo narzędzi działa również z repozytoriami Maven (jak Sbt for Scala, Ivy for Ant, Graddle for Groovy) .

Korzystanie z IDE

Teraz to, co może zwiększyć produktywność rozwoju. Jest kilka alternatyw open source (jak Eclipse i NetBeans , wolę tę pierwszą), a nawet komercyjne (jak IntelliJ ), które są dość popularne i potężne.

Mogą zarządzać budowaniem projektu w tle, więc nie musisz zajmować się wszystkimi sprawami wiersza poleceń. Jednak zawsze przydaje się, jeśli wiesz, co faktycznie dzieje się w tle, dzięki czemu możesz znaleźć sporadyczne błędy, takie jak plik ClassNotFoundException.

Jedna dodatkowa uwaga

W przypadku większych projektów zawsze zaleca się korzystanie ze środowiska IDE i narzędzia do kompilacji. Pierwsza z nich zwiększa produktywność, podczas gdy druga umożliwia korzystanie z różnych IDE w projekcie (np. Maven może generować deskryptory projektów Eclipse za pomocą prostego mvn eclipse:eclipsepolecenia). Co więcej, posiadanie projektu, który można przetestować / zbudować za pomocą polecenia w jednym wierszu, jest łatwe do wprowadzenia dla nowych kolegów i na przykład do serwera ciągłej integracji. Bułka z masłem :-)

rlegendi
źródło
4
Podczas używania javaclepiej byłoby określić katalog wyjściowy. find -name "*.java" > sources.txt && javac -d bin @sources.txt. W przeciwnym razie pliki * .class są zapisywane w katalogu, w którym znajdują się źródła.
Maksim Dmitriev
1
Absolutnie prawdziwe. Chociaż moim zdaniem, jeśli ktoś dopiero zaczął się bawić javac, koncepcja CLASSPATH, jak uruchamiać kod java, jak radzić sobie z pakietami, które powinny być głównym folderem do uruchamiania itp. Zwykle nie jest jasna. Pominąłem więc wyjściowy reż. W każdym razie dzięki za sugestię!
rlegendi
6
Dla użytkowników komputerów Mac napotykających to findpolecenie jest: find . -name "*.java" > sources.txt(zwróć uwagę na .)
MrDuk
@MrDuk Co oznacza dodanie znaku „.” robić? Czy służy do wyszukiwania w bieżącym katalogu?
Brady Sheehan
@BradySheehan rozpocznie wyszukiwanie z podanej ścieżki. „.” oznacza rozpoczęcie od bieżącego słownika. Należy pamiętać, że muszą określić ścieżkę do znalezienia (w OS X)
Kris
40
find . -name "*.java" -print | xargs javac 

Trochę brutalne, ale działa jak diabli. (Używaj tylko w małych programach, to absolutnie nie jest wydajne)

Matthieu Riegler
źródło
1
Jeśli korzystasz z tego, rozważ find ... -print0i xargs -0 ...zamiast tego nie przerywaj spacji w nazwach plików
sapht
29

Jeśli twoja powłoka to obsługuje, czy coś takiego zadziała?

javac com/**/*.java 

Jeśli twoja powłoka nie obsługuje **, to może

javac com/*/*/*.java

działa (dla wszystkich pakietów z 3 komponentami - dostosuj dla mniej więcej).

phtrivier
źródło
Próbowałem użyć tego w wierszu poleceń w systemie Windows 10. Czy ktoś może potwierdzić, czy działa w systemie Windows 10, czy też robię to źle, proszę
Dan
26

W zwykłym przypadku, gdy chcesz skompilować cały projekt, możesz po prostu dostarczyć javac z główną klasą i pozwolić mu skompilować wszystkie wymagane zależności:

javac -sourcepath . path/to/Main.java

dziwak
źródło
Bardzo prosta metoda, nie polega na dodatkowych plikach
linquize
To jest najlepsza i najprostsza dla ludzi, którzy nie mają zbyt wiele czasu na naukę Ant (jak ja)
Hamza Abbad
Niestety jest leniwy. Jeśli nie dotkniesz Main.java, czego prawdopodobnie nie zrobiłbyś zaraz po utworzeniu drugiego pliku, nic innego nie zostanie kompilatorem.
Tom Hawtin - linka
Tutaj też nie działa dobrze. Niektóre zależności nie są ponownie kompilowane pomimo zmiany. @ TomHawtin-tackline Próbowałem wcześniej dotknąć na głównej ale nic. Może trzeba dotknąć wszystkiego. Trochę niezręczne.
mmm
5

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

(Wolę nie używać xargs, ponieważ może je podzielić i uruchomić javac wiele razy, każdy z podzbiorem plików java, z których niektóre mogą importować inne, które nie zostały określone w tym samym wierszu poleceń javac)

Jeśli masz punkt wejścia App.java, najlepszy jest sposób na dziwaka z -sourcepath. Kompiluje każdy inny potrzebny plik java, zgodnie z zależnościami importu. na przykład:

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

Można również określić docelową klasy plików Reż -d target/.

Curtis Yallop
źródło
3

Radziłbym ci nauczyć się posługiwać mrówką , która bardzo dobrze nadaje się do tego zadania, jest bardzo łatwa do uchwycenia i dobrze udokumentowana.

Wystarczyłoby zdefiniować taki cel w pliku build.xml:

<target name="compile">
    <javac srcdir="your/source/directory"
           destdir="your/output/directory"
           classpath="xyz.jar" />
</target>
JB Nizet
źródło
2

Po prostu używam make z prostym plikiem makefile, który wygląda następująco:

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

all : $(classes)

clean :
        rm -f $(classes)

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

Kompiluje źródła pojedynczo i rekompiluje tylko wtedy, gdy jest to konieczne.

Edward Doolittle
źródło
1

Polecenie javac nie podlega rekursywnemu procesowi kompilacji, więc musisz albo określić każdy katalog podczas uruchamiania polecenia, albo podać plik tekstowy z katalogami, które chcesz uwzględnić:

javac -classpath "${CLASSPATH}" @java_sources.txt
gvalenncia
źródło
0

Używałem tego w projekcie Xcode JNI do rekurencyjnego tworzenia moich klas testowych:

find ${PROJECT_DIR} -name "*.java" -print | xargs javac -g -classpath ${BUILT_PRODUCTS_DIR} -d ${BUILT_PRODUCTS_DIR}
bishopthom
źródło