2011-01-21 14 views
65

Ten przypadek użycia jest prosty. Mam pliki źródłowe, które zostały utworzone za pomocą Eclipse. Istnieje więc głęboka struktura katalogów, w której każda klasa Java może odwoływać się do innej klasy Java w tym samym folderze podrzędnym, rodzimym, rodzimym lub rodzimym.Java: Jak mogę skompilować całą strukturę katalogów kodu?

Jak skompilować tę całość z terminalu za pomocą javac?

+0

Z ciekawości, z jakiego systemu operacyjnego korzystasz - Windows, Linux, Mac itd.? To może pomóc w udzieleniu odpowiedzi na pytanie: –

+0

Używam linuxa. – euphoria83

+1

Nie skompilowałem java z linii poleceń za kilka lat, ale myślę, że jeśli po prostu przekażesz plik zawierający main() do javaca, wyszuka on wszystkie pozostałe pliki, które musi skompilować, ponieważ wszystkie twoje zależności mogą zostać odkryte, zaczynając od pliku zawierającego main(). – Endophage

Odpowiedz

49

Musisz znać wszystkie katalogi lub móc używać symboli wieloznacznych.

javac dir1/*.java dir2/*.java dir3/dir4/*.java dir3/dir5/*.java dir6/*src/*.java 
+1

i wymyśliłem: po prostu wylistuj wszystkie pliki .java po javac, używając ich nazw lub symboli wieloznacznych. – euphoria83

+22

Lub po prostu użyj 'javac $ (find. -name" * .java ")'. –

8

Trzeba by użyć czegoś podobnego Ant to zrobić hierarchicznie:

http://ant.apache.org/manual/Tasks/javac.html

Musisz utworzyć skrypt kompilacji z celem nazywa kompilacji zawierającej następujące:

<javac sourcepath="" srcdir="${src}" 
     destdir="${build}" > 
    <include name="**/*.java"/> 
</javac> 

Następnie możesz skompilować wszystkie pliki, uruchamiając:

ant compile 

Alternatywnie, zaimportuj swój projekt do Eclipse i automatycznie skompiluje wszystkie pliki źródłowe tego projektu.

+0

Niestety, należy to zrobić na serwerze, który nie obsługuje Mrówka. – euphoria83

12

Podjęłbym sugestię Jon i użyłem Ant, ponieważ jest to dość skomplikowane zadanie.

Jeśli jednak chcesz uzyskać wszystko w jednym wierszu terminalu, w systemie Linux możesz użyć polecenia find. Ale nie polecam tego w ogóle, ponieważ nie ma gwarancji, że, powiedzmy, Foo.java zostanie skompilowana po Bar.java, nawet jeśli Foo używa Bar. Przykładem może być:

find . -type f -name "*.java" -exec javac {} \;

przypadku wszystkich klas jeszcze nie zostały skompilowane, jeśli istnieje jeden główny uprząż lub klasy sterownika (w zasadzie jeden zawierający głównego metody), kompilacja, że ​​główną klasą indywidualnie powinien kompilują większość projektu, nawet jeśli znajdują się w różnych folderach, ponieważ Javac będzie starał się jak najlepiej wykorzystać swoje możliwości rozwiązywania problemów z zależnościami.

+1

w oknach można użyć 'find_gnu. -type f -name "* .java" | xargs javac', gdy gnu wersja find.exe zostanie zmieniona na find_gnu.exe. Mam plik gnu find.exe z msysgit. – n611x007

+0

Lub w czystej partii Windows: 'for/f" usebackq "% f in (' 'dir/s/b * .java'') do javac% f' (użyj pojedynczych cudzysłowów w' dir/s/b' ale nie mogę znaleźć sposobu, aby sformatować go poprawnie). – Matthieu

45

Z Bash 4, można po prostu włączyć globstar

shopt -s globstar 

a następnie zrobić

javac **/*.java 
+2

lub użyj zsh z oh-my-zsh :) – DmitrySandalov

2

Jest sposób, aby to zrobić bez używania znaku rury, co jest wygodne, jeśli w celu wykonania tej czynności otwierasz proces z innego języka programowania:

find $JAVA_SRC_DIR -name '*.java' -exec javac -d $OUTPUT_DIR {} + 

Choć jeśli jesteś w bash i/lub nie przeszkadza za pomocą rury, to można zrobić:

find $JAVA_SRC_DIR -name '*.java' | xargs javac -d $OUTPUT_DIR 
31

Jeśli wszystko, co chcesz zrobić, to uruchomić główne klasy (bez kompilacji plików na .java której głównym klasa nie zależy), można wykonać następujące czynności:

cd <root-package-directory> 
javac <complete-path-to-main-class> 

lub

javac -cp <root-package-directory> <complete-path-to-main-class> 

javac byłoby automatycznie rozwiązuje wszystkie zależności i kompiluje wszystkie zależności.

+3

Jest to zdecydowanie najłatwiejsze rozwiązanie robocze. Dlaczego ludzie tego nie lubią? – Alphaaa

+9

Prawdopodobnie dlatego, że jego prostota pomija fakt, że wiele zadań kompilacji biblioteki lub kodu pomocniczego nie będzie miało głównej metody, która będzie łączyła się z wszystkimi wymaganymi zależnościami. To dobra odpowiedź, ale nigdy nie użyłbym jej w żadnej ramowej/publicznej bazie kodów. – Ajax

+2

IMHO, frameworki lub inne publiczne projekty powinny korzystać z pewnego rodzaju zarządzania kompilacją. Ten rodzaj kompilacji ma sens tylko w przypadku małych prywatnych projektów. – svenwltr

9

Po to metoda znalazłem:

1) Zrób listę plików z ścieżek względnych w pliku (powiedzmy FilesList.txt) w następujący sposób (albo oddzielonych spacjami lub linia oddziela):

foo/AccessTestInterface.java 
foo/goo/AccessTestInterfaceImpl.java 

2) Za pomocą polecenia:

javac @FilesList.txt -d classes 

To skompiluje wszystkie pliki i umieścić pliki klas wewnątrz katalogu klas.

Teraz łatwy sposób tworzenia pliku FilesList.txt to: Przejdź do katalogu głównego źródła.

dir *.java /s /b > FilesList.txt 

Ale to zapełni absolutną ścieżkę. Używając edytora tekstowego "Zamień wszystko" ścieżkę do katalogu źródłowego (dołącz \ na końcu) z "" (tj. Pusty ciąg) i Zapisz.

+0

jest to bardziej "natywny" sposób, ponieważ javac obsługuje "wsadowy" plik – lovespring

+0

podejście "dir * .java/s/b> FilesList.txt" nie zadziała, jeśli ścieżka zawiera spacje. javac będzie narzekał na FilesList.txt – aderesh

1

Rozwiązanie Windows: Zakładając, że wszystkie pliki znajdują się w podkatalogu "src", a chcesz je skompilować do "bin".

for /r src %i in (*.java) do javac %i -sourcepath src -d bin 

Jeśli src zawiera plik .java bezpośrednio pod nim, to jest szybsze

javac src\\*.java -d bin 
+1

działa, ale superslow - javac jest wywoływany z jednym plikiem tylko za połączenie, więc jeśli masz ich dużo ... –

7

Istniejąca już odpowiedzi wydają się dotyczyć tylko z siebie * .java same pliki, a nie jak w prosty sposób zrobić to z plikami bibliotek, które mogą być potrzebne do kompilacji.

Ładna sytuacja jednoliniowa rekurencyjnie pobiera wszystkie pliki * .java oraz zawiera *.pliki jar niezbędne do obiektu jest

javac -cp ".:lib/*" -d bin $(find ./src/* | grep .java) 

Tutaj plik bin jest przeznaczenie plików klasowych, lib (i potencjalnie bieżący katalog roboczy) zawierają pliki bibliotek i wszystkie pliki Java w katalogu src i poniżej są skompilowany.