Tùy chọn javac để biên dịch tất cả các tệp java trong một thư mục đã cho đệ quy


127

Tôi đang sử dụng trình biên dịch javac để biên dịch các tệp java trong dự án của tôi. Các tập tin được phân phối trên nhiều gói như thế này: com.vistas.util, com.vistas.converter, com.vistas.LineHelper,com.current.mdcontect .

Mỗi gói này có một số tệp java. Tôi đang sử dụng javac như thế này:

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

(trong một dòng)

Thay vì đưa ra quá nhiều đường dẫn, làm thế nào tôi có thể yêu cầu trình biên dịch biên dịch đệ quy tất cả các tệp java từ thư mục com com?


2
Bạn thực sự nên xem qua các công cụ như Ant hoặc Maven.
Laurent Pireyn

Bài đăng SO này có thể hữu ích stackoverflow.com/questions/864630/ từ
Gopi

Câu trả lời:


220

Tôi cũng sẽ đề xuất sử dụng một số loại công cụ xây dựng ( Ant hoặc Maven , Ant đã được đề xuất và dễ bắt đầu hơn) hoặc một IDE xử lý việc biên dịch (Eclipse sử dụng biên dịch gia tăng với chiến lược đối chiếu và thậm chí bạn không phải quan tâm để nhấn bất kỳ nút "Biên dịch" ).

Sử dụng Javac

Nếu bạn cần thử một cái gì đó cho một dự án lớn hơn và không có bất kỳ công cụ xây dựng phù hợp nào gần đó, bạn luôn có thể sử dụng một mẹo nhỏ javaccung cấp: tên lớp để biên dịch có thể được chỉ định trong một tệp. Bạn chỉ cần chuyển tên của tệp javacvới @tiền tố.

Nếu bạn có thể tạo một danh sách tất cả các *.javatệp trong dự án của mình, thật dễ dàng:

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

:: Windows
> dir /s /B *.java > sources.txt
> javac @sources.txt
  • Ưu điểm là một giải pháp nhanh chóng và dễ dàng.
  • Hạn chế là bạn phải tạo lại sources.txttệp mỗi khi bạn tạo nguồn mới hoặc đổi tên một tệp hiện có, đây là một nhiệm vụ dễ quên (do đó dễ bị lỗi) và nhiệm vụ mệt mỏi.

Sử dụng công cụ xây dựng

Về lâu dài, tốt hơn là sử dụng một công cụ được thiết kế để xây dựng phần mềm.

Sử dụng kiến

Nếu bạn tạo một build.xmltệp đơn giản mô tả cách xây dựng phần mềm:

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

bạn có thể biên dịch toàn bộ phần mềm bằng cách chạy lệnh sau:

$ ant
  • Ưu điểm là bạn đang sử dụng một công cụ xây dựng tiêu chuẩn dễ dàng mở rộng.
  • Hạn chế là bạn phải tải xuống, thiết lập và tìm hiểu một công cụ bổ sung. Lưu ý rằng hầu hết các IDE (như NetBeans và Eclipse) cung cấp hỗ trợ tuyệt vời cho việc viết các tệp xây dựng để bạn không phải tải xuống bất cứ thứ gì trong trường hợp này.

Sử dụng Maven

Maven không phải là tầm thường để thiết lập và làm việc cùng, nhưng học nó sẽ trả tiền rất tốt. Đây là một hướng dẫn tuyệt vời để bắt đầu một dự án trong vòng 5 phút .

  • Ưu điểm chính của nó (đối với tôi) là nó cũng xử lý các phụ thuộc, vì vậy bạn sẽ không cần tải xuống bất kỳ tệp Jar nào nữa và quản lý chúng bằng tay và tôi thấy nó hữu ích hơn cho việc xây dựng, đóng gói và thử nghiệm các dự án lớn hơn.
  • Hạn chế là nó có đường cong học tập dốc và nếu các plugin Maven muốn khắc phục lỗi :-) Một điều nữa là khá nhiều công cụ cũng hoạt động với kho lưu trữ của Maven (như Sbt cho Scala, Ivy cho Ant, Graddle cho Groovy) .

Sử dụng IDE

Bây giờ những gì có thể tăng năng suất phát triển của bạn. Có một vài lựa chọn thay thế nguồn mở (như EclipseNetBeans , tôi thích cái trước) và thậm chí cả cái thương mại (như IntelliJ ) khá phổ biến và mạnh mẽ.

Họ có thể quản lý việc xây dựng dự án trong nền để bạn không phải đối phó với tất cả các công cụ dòng lệnh. Tuy nhiên, nó luôn có ích nếu bạn biết những gì thực sự xảy ra trong nền để bạn có thể tìm ra các lỗi thỉnh thoảng nhưClassNotFoundException .

Thêm một lưu ý

Đối với các dự án lớn hơn, luôn luôn nên sử dụng IDE công cụ xây dựng. Cái trước giúp tăng năng suất của bạn, trong khi cái sau cho phép sử dụng các IDE khác nhau với dự án (ví dụ, Maven có thể tạo các mô tả dự án Eclipse bằng một mvn eclipse:eclipselệnh đơn giản ). Hơn nữa, có một dự án có thể được kiểm tra / xây dựng bằng một dòng lệnh đơn giản để dễ dàng giới thiệu với các đồng nghiệp mới và vào một máy chủ tích hợp liên tục chẳng hạn. Miếng bánh :-)


4
Khi sử dụng javac, tốt hơn là chỉ định một thư mục đầu ra. find -name "*.java" > sources.txt && javac -d bin @sources.txt. Mặt khác, các tệp *. Class được lưu vào thư mục chứa các nguồn.
Maksim Dmitriev

1
Hoàn toàn đúng. Mặc dù theo ý kiến ​​của tôi, nếu ai đó mới bắt đầu chơi javac, khái niệm về CLASSPATHcách chạy mã java, cách xử lý các gói, nên là thư mục gốc để chạy, v.v. thường không rõ ràng. Vì vậy, tôi đã bỏ qua thư mục đầu ra. Dù sao, cảm ơn cho lời đề nghị!
rlegendi

6
Đối với người dùng mac gặp phải điều này, findlệnh là: find . -name "*.java" > sources.txt(lưu ý .)
MrDuk

@MrDuk Việc thêm "." làm gì Có phải để tìm kiếm trong thư mục hiện tại?
Brady Sheehan

@BradySheehan nó sẽ bắt đầu tìm kiếm từ đường dẫn đã cho. "." có nghĩa là bắt đầu từ từ điển hiện tại. Lưu ý rằng bạn phải chỉ định đường dẫn tìm (trong OS X)
Kris

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

Kinda tàn bạo, nhưng hoạt động như địa ngục. (Chỉ sử dụng trên các chương trình nhỏ, nó hoàn toàn không hiệu quả)


1
Nếu bạn sử dụng cân nhắc này find ... -print0xargs -0 ...thay vào đó để không phá vỡ khoảng trắng trong tên tệp
sapht

29

Nếu vỏ của bạn hỗ trợ nó, một cái gì đó như thế này sẽ làm việc?

javac com/**/*.java 

Nếu shell của bạn không hỗ trợ **, thì có lẽ

javac com/*/*/*.java

hoạt động (đối với tất cả các gói có 3 thành phần - thích ứng nhiều hơn hoặc ít hơn).


Tôi đã cố gắng sử dụng điều này trong dấu nhắc lệnh trên windows 10. Ai đó có thể xác nhận nếu nó hoạt động trên windows 10 hoặc nếu tôi làm sai xin vui lòng
Dan

26

Trong trường hợp thông thường khi bạn muốn biên dịch toàn bộ dự án của mình, bạn chỉ cần cung cấp javac với lớp chính của mình và để nó biên dịch tất cả các phụ thuộc cần thiết:

javac -sourcepath . path/to/Main.java


Phương pháp rất đơn giản, không dựa vào các tệp bổ sung
linquize

Đây là cách tốt nhất và đơn giản nhất cho những người không có nhiều thời gian để học Ant (như tôi)
Hamza Abbad

Thật không may là lười biếng. Nếu bạn không chạm vào Main.java, điều mà có lẽ bạn sẽ không chỉ sau khi tạo tệp thứ hai, không có gì khác có trình biên dịch.
Tom Hawtin - tackline

Ở đây cũng không hoạt động tốt. Một số phụ thuộc không được biên dịch lại mặc dù đã được thay đổi. @ TomHawtin-tackline Tôi đã thử chạm vào trước trên chính nhưng không có gì. Có lẽ chạm vào tất cả là bắt buộc. Mặc dù loại vụng về.
mmm

4

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

(Tôi không thích sử dụng xargs vì nó có thể tách chúng ra và chạy javac nhiều lần, mỗi lần có một tập hợp các tệp java, một số tệp có thể nhập các tệp khác không được chỉ định trên cùng một dòng lệnh javac)

Nếu bạn có điểm truy cập App.java, cách của freaker với -sourcepath là tốt nhất. Nó biên dịch mọi tệp java khác mà nó cần, tuân theo các phụ thuộc nhập. ví dụ:

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

Bạn cũng có thể chỉ định một thư mục tệp lớp đích : -d target/.


3

Tôi sẽ khuyên bạn nên học cách sử dụng kiến , rất phù hợp cho nhiệm vụ này và rất dễ nắm bắt và ghi chép tốt.

Bạn sẽ phải xác định một mục tiêu như thế này trong tệp build.xml:

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

2

Tôi chỉ đang sử dụng make với một makefile đơn giản trông như thế này:

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

all : $(classes)

clean :
        rm -f $(classes)

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

Nó biên dịch các nguồn một lần và chỉ biên dịch lại nếu cần thiết.


1

Lệnh javac không tuân theo quy trình biên dịch đệ quy, do đó bạn phải chỉ định từng thư mục khi chạy lệnh hoặc cung cấp tệp văn bản với các thư mục bạn muốn đưa vào:

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

0

Tôi đã sử dụng điều này trong dự án JNI Xcode để xây dựng đệ quy các lớp thử nghiệm của mình:

find ${PROJECT_DIR} -name "*.java" -print | xargs javac -g -classpath ${BUILT_PRODUCTS_DIR} -d ${BUILT_PRODUCTS_DIR}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.