2011-01-21 22 views
65

Il caso d'uso è semplice. Ho ottenuto i file sorgente creati con Eclipse. Quindi, esiste una struttura di directory profonda, in cui qualsiasi classe Java potrebbe fare riferimento a un'altra classe Java nella stessa cartella figlio, fratello o genitore.Java: come posso compilare un'intera struttura di directory del codice?

Come faccio a compilare tutto questo dal terminale usando javac?

+0

Per curiosità, quale sistema operativo utilizzi: Windows, Linux, Mac, ecc.? Questo potrebbe aiutare a rispondere alla domanda –

+0

sto usando linux. – euphoria83

+1

Non ho compilato java sulla riga di comando tra un paio d'anni ma penso che se passi semplicemente il file contenente il main() a javac, cercherà tutti gli altri file di cui ha bisogno per compilare tutte le tue dipendenze essere scoperto a partire dal file contenente main(). – Endophage

risposta

49

Devi conoscere tutte le directory, o essere in grado di utilizzare caratteri jolly ..

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

ho pensato: basta elencare tutti i file .java dopo javac usando i loro nomi o caratteri jolly. – euphoria83

+22

O semplicemente usa 'javac $ (find. -name" * .java ")'. –

8

Dovreste usare qualcosa come Ant per fare questo gerarchicamente:

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

avrete bisogno per creare uno script di build con un obiettivo chiamato compilazione contenente le seguenti:

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

Poi you''ll essere in grado di compilare tutti i file eseguendo:

ant compile 

In alternativa, importa il tuo progetto in Eclipse e compilerà automaticamente tutti i file sorgente per quel progetto.

+0

sfortunatamente, questo deve essere fatto su un server che non supporta formica. – euphoria83

12

Vorrei prendere il suggerimento di Jon e utilizzare Ant, poiché questo è un compito piuttosto complesso.

Tuttavia, se si è certi di ottenere tutto in una riga nel Terminale, su Linux è possibile utilizzare il comando find. Ma non lo consiglio affatto, poiché non è garantito che, ad esempio, Foo.java verrà compilato dopo Bar.java, anche se Foo utilizza Bar. Un esempio potrebbe essere:

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

Se tutte le classi non sono stato ancora compilato, se c'è un cablaggio principale o classe del driver (in pratica quella che contiene il metodo principale), la compilazione di quella classe principale dovrebbe singolarmente compilare la maggior parte del progetto, anche se si trovano in cartelle diverse, poiché Javac proverà a sfruttare al meglio le sue capacità per risolvere i problemi di dipendenza.

+1

su Windows si può usare 'find_gnu. -tipo f -name "* .java" | xargs javac' una volta che la versione gnu di find.exe viene rinominata in find_gnu.exe. Ho ottenuto il mio gnu find.exe da msysgit. – n611x007

+0

Oppure su batch di Windows puro: 'per/f" usebackq "% f in (' 'dir/s/b * .java'') fa javac% f' (usa le virgolette singole in' dir/s/b' ma non riesco a trovare un modo per formattarlo correttamente). – Matthieu

45

Con Bash 4, si può semplicemente abilitare globstar

shopt -s globstar 

e poi fare

javac **/*.java 
+2

o utilizzare zsh con oh-my-zsh :) – DmitrySandalov

2

C'è un modo per farlo senza usare un carattere pipe, che è conveniente se per eseguire questa operazione devi eseguire un processo da un altro linguaggio di programmazione:

Anche se si è in Bash e/o non dispiace usando un tubo, allora si può fare:

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

Se tutto quello che vogliamo fare è eseguire la classe principale (senza compilare i file .java su che la classe principale non dipende), allora si può fare quanto segue:

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

o

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

javac sarebbe risolve automaticamente tutte le dipendenze e compila anche tutte le dipendenze.

+3

Questa è di gran lunga la soluzione di lavoro più semplice. Perché alla gente non piace? – Alphaaa

+9

Probabilmente perché la sua semplicità ignora il fatto che molti lavori di compilazione per la libreria o il codice di supporto non avranno un metodo principale che collega a tutte le dipendenze richieste. È una buona risposta, ma non una che vorrei mai usare in qualsiasi framework/base di codice pubblico. – Ajax

+2

IMHO, framework o altri progetti pubblici dovrebbero utilizzare una sorta di gestione della build. Questo tipo di compilazione ha senso solo su piccoli progetti privati. – svenwltr

9

seguito è il metodo che ho trovato:

1) Fare un elenco di file con i relativi percorsi in un file (ad esempio FilesList.txt) come segue (sia spazio separato o linea separata):

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

2) Utilizzare il comando:

javac @FilesList.txt -d classes 

Questo compilerà tutti i file e mettere i file di classe all'interno di directory classi.

Il modo più semplice per creare FilesList.txt è questo: Passare alla directory radice di origine.

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

Ma questo popolerà il percorso assoluto. Utilizzando un editor di testo "Sostituisci tutto" il percorso fino alla directory di origine (includi \ alla fine) con "" (cioè stringa vuota) e Salva.

+0

questo è il modo più "nativo", in quanto javac supporta un file "batch" – lovespring

+0

"l'approccio dir * .java/s/b> FilesList.txt" non funziona se un percorso contiene spazi. javac si lamenterà di FilesList.txt – aderesh

1

Soluzione Windows: presupponendo tutti i file contenuti nella sottodirectory 'src', e si desidera compilarli in 'bin'.

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

Se src contiene un file .java immediatamente sottostante allora questo è più veloce

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

funziona, ma superslow - javac viene chiamato con un solo file per chiamata, quindi se ne hai molti ... –

7

Il già esistente risposte sembrano riguardare solo se stessi con l'* .java file stessi e non come fare facilmente con i file di libreria che potrebbero essere necessari per la compilazione.

Una situazione a linea singola che ricorsivamente recupera tutti i file * .java e include *.file jar necessari per la costruzione è:

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

Ecco il file bin è la destinazione dei file di classe, lib (e potenzialmente la directory di lavoro corrente) contengono i file di libreria e tutti i file java nella directory src e sotto sono compilato.

Problemi correlati