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?


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 :-)


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)


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).


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


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/.


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>

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.


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

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}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.