ตัวเลือก javac เพื่อรวบรวมไฟล์ java ทั้งหมดภายใต้ไดเร็กทอรีที่กำหนดแบบวนซ้ำ


127

ฉันใช้คอมไพเลอร์ javac เพื่อรวบรวมไฟล์ java ในโครงการของฉัน com.vistas.utilไฟล์จะถูกกระจายไปทั่วหลายแพ็กเกจเช่นนี้: com.vistas.converter, com.vistas.LineHelper, com.current.mdcontect,

แต่ละแพ็คเกจเหล่านี้มีไฟล์ java หลายไฟล์ ฉันใช้ javac แบบนี้:

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

(ในบรรทัดเดียว)

แทนที่จะให้พา ธ มากมายฉันจะขอให้คอมไพเลอร์รวบรวมไฟล์ java ทั้งหมดแบบวนซ้ำจากไดเร็กทอรี com หลักได้อย่างไร


2
คุณควรดูเครื่องมือเช่น Ant หรือ Maven
Laurent Pireyn

โพสต์นี้อาจเป็นประโยชน์stackoverflow.com/questions/864630/…
Gopi

คำตอบ:


220

ฉันขอแนะนำให้ใช้เครื่องมือสร้างบางประเภท ( AntหรือMaven Ant ได้รับการแนะนำแล้วและเริ่มต้นได้ง่ายกว่า) หรือ IDE ที่จัดการการคอมไพล์ (Eclipse ใช้การคอมไพล์ที่เพิ่มขึ้นพร้อมกับกลยุทธ์การกระทบยอดและคุณไม่จำเป็นต้อง โปรดกดปุ่ม"คอมไพล์" )

ใช้ Javac

หากคุณต้องการทดลองใช้งานสำหรับโปรเจ็กต์ขนาดใหญ่และไม่มีเครื่องมือสร้างที่เหมาะสมอยู่ใกล้ ๆ คุณสามารถใช้เคล็ดลับเล็ก ๆ น้อย ๆ ที่javacนำเสนอได้ตลอดเวลา: ชื่อคลาสที่จะคอมไพล์สามารถระบุในไฟล์ได้ คุณต้องส่งชื่อไฟล์ไปให้javacพร้อมกับ@คำนำหน้า

หากคุณสามารถสร้างรายการ*.javaไฟล์ทั้งหมดในโปรเจ็กต์ของคุณได้ง่ายๆ:

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

:: Windows
> dir /s /B *.java > sources.txt
> javac @sources.txt
  • ข้อดีคือเป็นวิธีแก้ปัญหาที่ง่ายและรวดเร็ว
  • ข้อเสียเปรียบคือคุณต้องสร้างsources.txtไฟล์ใหม่ทุกครั้งที่สร้างซอร์สใหม่หรือเปลี่ยนชื่อไฟล์ที่มีอยู่ซึ่งง่ายต่อการลืม (จึงเกิดข้อผิดพลาดได้ง่าย) และงานที่น่าเบื่อ

ใช้เครื่องมือสร้าง

ในระยะยาวควรใช้เครื่องมือที่ออกแบบมาเพื่อสร้างซอฟต์แวร์ในระยะยาว

ใช้ Ant

หากคุณสร้างbuild.xmlไฟล์ง่ายๆที่อธิบายวิธีการสร้างซอฟต์แวร์:

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

คุณสามารถคอมไพล์ซอฟต์แวร์ทั้งหมดโดยเรียกใช้คำสั่งต่อไปนี้:

$ ant
  • ข้อดีคือคุณใช้เครื่องมือสร้างมาตรฐานที่ง่ายต่อการขยาย
  • ข้อเสียคือคุณต้องดาวน์โหลดตั้งค่าและเรียนรู้เครื่องมือเพิ่มเติม โปรดทราบว่า IDE ส่วนใหญ่ (เช่น NetBeans และ Eclipse) ให้การสนับสนุนที่ดีเยี่ยมสำหรับการเขียนไฟล์บิลด์ดังนั้นคุณจึงไม่ต้องดาวน์โหลดอะไรในกรณีนี้

ใช้ Maven

Maven ไม่ใช่เรื่องเล็กน้อยในการตั้งค่าและทำงานด้วย แต่การเรียนรู้นั้นคุ้มค่า นี่คือการสอนที่ดีในการเริ่มต้นโครงการได้ภายใน 5 นาที

  • ข้อได้เปรียบหลัก (สำหรับฉัน) คือมันจัดการการอ้างอิงด้วยดังนั้นคุณไม่จำเป็นต้องดาวน์โหลดไฟล์ Jar อีกต่อไปและจัดการด้วยมือและฉันพบว่ามันมีประโยชน์มากกว่าสำหรับการสร้างบรรจุภัณฑ์และการทดสอบโครงการขนาดใหญ่
  • ข้อเสียเปรียบคือมันมีเส้นโค้งการเรียนรู้ที่สูงชันและหากปลั๊กอิน Maven ต้องการระงับข้อผิดพลาด :-) อีกสิ่งหนึ่งคือเครื่องมือจำนวนมากยังทำงานกับที่เก็บ Maven (เช่นSbtสำหรับ Scala, Ivy for Ant, Graddleสำหรับ Groovy) .

ใช้ IDE

ตอนนี้สิ่งที่สามารถเพิ่มประสิทธิภาพการพัฒนาของคุณ มีทางเลือกโอเพ่นซอร์สอยู่สองสามทาง (เช่นEclipseและNetBeansฉันชอบแบบเดิม) และแม้แต่ทางเลือกในเชิงพาณิชย์ (เช่นIntelliJ ) ซึ่งค่อนข้างเป็นที่นิยมและมีประสิทธิภาพ

พวกเขาสามารถจัดการการสร้างโครงการในพื้นหลังดังนั้นคุณจึงไม่ต้องจัดการกับสิ่งต่างๆในบรรทัดคำสั่งทั้งหมด อย่างไรก็ตามมันจะมีประโยชน์เสมอหากคุณรู้ว่าเกิดอะไรขึ้นในเบื้องหลังเพื่อให้คุณสามารถค้นหาข้อผิดพลาดในบางครั้งเช่นไฟล์ClassNotFoundException.

หมายเหตุเพิ่มเติม

สำหรับโครงการขนาดใหญ่ขอแนะนำให้ใช้ IDE และเครื่องมือสร้างเสมอ อดีตช่วยเพิ่มประสิทธิภาพการทำงานของคุณในขณะที่อย่างหลังทำให้สามารถใช้ IDE ที่แตกต่างกันกับโปรเจ็กต์ได้ (เช่น Maven สามารถสร้างตัวอธิบายโปรเจ็กต์ Eclipse ด้วยmvn eclipse:eclipseคำสั่งง่ายๆ) ยิ่งไปกว่านั้นการมีโครงการที่สามารถทดสอบ / สร้างด้วยคำสั่งบรรทัดเดียวนั้นง่ายต่อการแนะนำเพื่อนร่วมงานใหม่และในเซิร์ฟเวอร์การรวมแบบต่อเนื่อง ชิ้นเค้ก :-)


4
เมื่อใช้javacควรระบุไดเร็กทอรีเอาต์พุตจะดีกว่า find -name "*.java" > sources.txt && javac -d bin @sources.txt. มิฉะนั้นไฟล์ * .class จะถูกบันทึกลงในไดเร็กทอรีที่แหล่งที่มา
Maksim Dmitriev

1
จริงที่สุด. แม้ว่าในความคิดของฉันถ้ามีคนเพิ่งเริ่มเล่นด้วยjavacแนวคิดของCLASSPATHวิธีการรันโค้ดjavaวิธีจัดการกับแพ็คเกจซึ่งควรเป็นโฟลเดอร์รูทสำหรับการเรียกใช้ ฯลฯ มักจะไม่ชัดเจน ดังนั้นฉันจึงละเว้น dir เอาท์พุท ยังไงก็ขอบคุณสำหรับคำแนะนำ!
rlegendi

6
สำหรับผู้ใช้ mac ที่เจอสิ่งนี้findคำสั่งคือ: find . -name "*.java" > sources.txt(สังเกต.)
MrDuk

@MrDuk การเพิ่ม "." คืออะไร ทำ? ใช้สำหรับค้นหาภายในไดเร็กทอรีปัจจุบันหรือไม่
Brady Sheehan

@BradySheehan มันจะเริ่มค้นหาจากเส้นทางที่กำหนด "" หมายถึงเริ่มจากพจนานุกรมปัจจุบัน โปรดทราบว่าคุณต้องระบุเส้นทางสำหรับการค้นหา (ใน OS X)
คริส

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

โหดมาก แต่ทำงานเหมือนนรก (ใช้กับโปรแกรมขนาดเล็กเท่านั้นไม่มีประสิทธิภาพอย่างแน่นอน)


1
หากคุณใช้สิ่งนี้ให้พิจารณาfind ... -print0และxargs -0 ...ไม่แบ่งช่องว่างในชื่อไฟล์แทน
sapht

29

ถ้าเชลล์ของคุณรองรับมันจะใช้งานได้ไหม

javac com/**/*.java 

หากเปลือกของคุณไม่รองรับ**อาจเป็นไปได้

javac com/*/*/*.java

ใช้งานได้ (สำหรับแพ็คเกจทั้งหมดที่มี 3 องค์ประกอบ - ปรับให้มากหรือน้อย)


ฉันได้พยายามใช้สิ่งนี้ใน command prompt บน windows 10 ใครบางคนสามารถยืนยันได้ว่ามันทำงานบน windows 10 หรือว่าฉันทำผิดได้โปรด
Dan

26

ในกรณีปกติที่คุณต้องการรวบรวมโปรเจ็กต์ทั้งหมดของคุณคุณสามารถจัดหา javac กับคลาสหลักของคุณและปล่อยให้มันรวบรวมการอ้างอิงที่จำเป็นทั้งหมด:

javac -sourcepath . path/to/Main.java


วิธีที่ง่ายมากไม่ต้องพึ่งพาไฟล์พิเศษ
linquize

นี่คือสิ่งที่ดีที่สุดและง่ายที่สุดสำหรับผู้ที่ไม่มีเวลาเรียนรู้ Ant (เช่นฉัน) มากนัก
Hamza Abbad

มันขี้เกียจน่าเสียดาย หากคุณไม่แตะต้องMain.javaซึ่งคุณอาจจะไม่ทำหลังจากสร้างไฟล์ที่สองของคุณแล้วก็ไม่มีอะไรจะได้รับคอมไพเลอร์
Tom Hawtin - แท

ทำงานได้ไม่ดีที่นี่เช่นกัน การอ้างอิงบางอย่างจะไม่ถูกคอมไพล์ใหม่แม้ว่าจะมีการเปลี่ยนแปลง @ TomHawtin-tackline ฉันลองสัมผัสก่อนหน้านี้บนหลัก แต่ไม่มีอะไรเลย อาจจำเป็นต้องสัมผัสทั้งหมด แบบว่าอึดอัด
mmm

5

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

(ฉันไม่ต้องการใช้ xargs เพราะมันสามารถแบ่งและเรียกใช้ javac ได้หลายครั้งโดยแต่ละไฟล์จะมีไฟล์ java ย่อยซึ่งบางไฟล์อาจนำเข้าไฟล์อื่นที่ไม่ได้ระบุไว้ในบรรทัดคำสั่ง javac เดียวกัน)

หากคุณมีจุดเข้า App.java วิธีของ freaker ที่มี -sourcepath จะดีที่สุด มันรวบรวมไฟล์ java อื่น ๆ ทุกไฟล์ที่ต้องการตามการขึ้นต่อการนำเข้า เช่น:

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

นอกจากนี้คุณยังสามารถระบุ dir -d target/เป้าหมายระดับไฟล์:


3

ฉันอยากจะแนะนำให้คุณเรียนรู้การใช้มดซึ่งเหมาะมากสำหรับงานนี้และเข้าใจง่ายและจัดทำเอกสารได้ดี

คุณจะต้องกำหนดเป้าหมายเช่นนี้ในไฟล์ build.xml:

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

2

ฉันแค่ใช้ make กับ makefile ง่ายๆที่มีลักษณะดังนี้:

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

all : $(classes)

clean :
        rm -f $(classes)

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

รวบรวมแหล่งที่มาทีละรายการและคอมไพล์ใหม่หากจำเป็นเท่านั้น


1

คำสั่ง javac ไม่เป็นไปตามกระบวนการคอมไพล์แบบเรียกซ้ำดังนั้นคุณต้องระบุแต่ละไดเร็กทอรีเมื่อรันคำสั่งหรือระบุไฟล์ข้อความที่มีไดเร็กทอรีที่คุณต้องการรวม:

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

0

ฉันใช้สิ่งนี้ในโครงการ Xcode JNI เพื่อสร้างคลาสทดสอบซ้ำ:

find ${PROJECT_DIR} -name "*.java" -print | xargs javac -g -classpath ${BUILT_PRODUCTS_DIR} -d ${BUILT_PRODUCTS_DIR}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.