Gradle: อะไรคือความแตกต่างระหว่าง classpath และ compile dependencies?


92

เมื่อเพิ่มการอ้างอิงลงในโครงการของฉันฉันไม่แน่ใจว่าควรให้คำนำหน้าอะไรเช่น"classpath"หรือ"compile".

ตัวอย่างเช่นการอ้างอิงของฉันด้านล่างควรรวบรวมเวลาหรือคลาสพา ธ หรือไม่

นอกจากนี้สิ่งนี้ควรอยู่ในแอปพลิเคชัน build.gradle ของฉันหรือในbuild.gradle เฉพาะของโมดูล

build.gradle ปัจจุบัน (ที่ระดับแอปพลิเคชัน):

apply plugin: 'java'

repositories {
    mavenCentral()
}

dependencies {
    compile 'org.hibernate:hibernate-core:5.0.5.Final'
    compile 'mysql:mysql-connector-java:5.1.38'
} 

1
ฉันไม่แน่ใจว่าฉันเข้าใจ classpathไม่ใช่ขอบเขตการอ้างอิงที่ถูกต้อง
Tunaki

บางทีฉันอาจจะสับสนอะไรคือขอบเขตการพึ่งพาที่ถูกต้อง?
java123999

ดูเอกสารนี้: docs.gradle.org/current/userguide/…
Tunaki

สิ่งหนึ่งที่ฉันสังเกตเห็นคือการcompileOnlyอ้างอิงไปที่project.configurations.compileClasspathแต่ไม่เป็นไปproject.configurations.compileตามที่กล่าวไว้ที่นี่github.com/iboyko/gradle-plugins/issues/5
Vytenis Bivainis

คำตอบ:


47

ฉันจะเดาว่าคุณกำลังอ้างอิงcompileและclasspathอยู่ในdependencies {}บล็อก ถ้าเป็นเช่นนั้นผู้ที่มีการพึ่งพาการตั้งค่า

การกำหนดค่าเป็นเพียงชุดการอ้างอิงที่มีชื่อ

การcompileกำหนดค่าถูกสร้างขึ้นโดยปลั๊กอิน Java การclasspathกำหนดค่ามักจะเห็นได้ในbuildSrc {}บล็อกที่เราต้องประกาศการอ้างอิงสำหรับ build.gradle ตัวมันเอง (สำหรับปลั๊กอิน)


ขอบคุณสำหรับ build.gradle หลักของฉันฉันไม่ควรใช้ classpath?
java123999

@ java123999 ไม่เว้นแต่คุณจะใช้ปลั๊กอินที่เขียนเอง
Eric Wendelin

@EricWendelin คุณพูดว่า "ภายในการอ้างอิง {} บล็อก" คุณหมายถึง "ภายในบล็อก {dependencies {}} buildscript" ตรงไหน (ฉันไม่แน่ใจแค่ถาม)
Paulo Merson

2
dependencies {}บล็อกสามารถประกาศทั้งภายในbuildscript {}และภายนอกของมัน เมื่ออยู่ภายในคุณใช้การclasspathกำหนดค่าสำหรับการอ้างอิงที่จำเป็นในการคอมไพล์สคริปต์การสร้างเอง
Eric Wendelin

55

หากbuildscriptตัวเองต้องการบางสิ่งบางอย่างที่จะวิ่งใช้classpath

หากโครงการของคุณต้องการบางสิ่งบางอย่างที่จะวิ่งใช้คอมไพล์

buildscript{}บล็อกสำหรับ build.gradle ตัวเอง

สำหรับการสร้างหลายโปรเจ็กต์ไฟล์บิลด์ระดับบนสุดมีไว้สำหรับโปรเจ็กต์รูทไฟล์บิลด์เฉพาะสำหรับโปรเจ็กต์ย่อย (โมดูล)

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

อย่าวางการอ้างอิงแอปพลิเคชันของคุณในไฟล์บิลด์ระดับบนสุดซึ่งจะอยู่ในไฟล์ build.gradle ของแต่ละโมดูล


เพื่อยืนยัน: นั่นหมายความว่า proandroiddev.com/… ควรใช้ a compileไม่ใช่classpathหรือ?
WillC

1
แต่ทำไมไม่วางการอ้างอิงของแอปพลิเคชันไว้ในไฟล์ระดับบนสุดหากโครงการมีเพียงโมดูลเดียวเช่นแอปพลิเคชัน Android ทั่วไป
Harsha

18

ถ้าฉันเข้าใจถูกต้องแสดงว่าคุณกำลังสับสนProject.dependenciesบล็อกสคริปต์กับProject.buildscript.dependenciesบล็อกสคริปต์ (เช่นเดียวกับที่ฉันทำเมื่อฉันถึงคำถามนี้)

ฉันจะพยายามตอบสิ่งนี้ด้วยสิ่งที่ฉันพบ

ฉันคิดว่าคุณน่าจะคุ้นเคยกับProject.dependenciesบล็อกสคริปต์แล้ว ในบล็อกนี้เราประกาศการอ้างอิงที่จำเป็นโดยซอร์สโค้ดของเรา มีหลายวิธีในการประกาศการพึ่งพาที่เราต้องการสำหรับโครงการ ดูGradle Tutorial: ประเภทพึ่งพา ฉันจะพูดถึงเฉพาะส่วนที่เกี่ยวข้องกับปัญหานี้มากที่สุด:

compile 'org.hibernate:hibernate-core:5.0.5.Final'เป็นการประกาศการพึ่งพาโมดูล คอนฟิกูเรชันคอมไพล์ (ซึ่งตอนนี้เลิกใช้แล้วโดยการกำหนดคอนฟิกการนำไปใช้งาน) เป็นเพียงคีย์เวิร์ดสำหรับImplementation only dependencies.มันไม่ใช่คีย์เวิร์ดที่อธิบายประเภทของการอ้างอิง (ตามประเภทที่นี่ฉันกำลังติดตามสามประเภทที่กำหนดไว้ในบทช่วยสอนนั่นคือโมดูล ไฟล์และโครงการ)

ในGradle Tutorial: Organizing Build Logic มีข้อความว่า:

หากบิลด์สคริปต์ของคุณจำเป็นต้องใช้ไลบรารีภายนอกคุณสามารถเพิ่มลงในคลาสพา ธ ของสคริปต์ในตัวสคริปต์บิลด์ คุณทำได้โดยใช้เมธอด buildscript () ผ่านการปิดซึ่งประกาศคลาสพา ธ build script

นี่เป็นวิธีเดียวกับที่คุณประกาศตัวอย่างเช่นคลาสพา ธ คอมไพล์ Java คุณสามารถใช้ประเภทการอ้างอิงใด ๆ ที่อธิบายไว้ในประเภทการอ้างอิงยกเว้นการอ้างอิงโครงการ

เมื่อประกาศคลาสพา ธ build script แล้วคุณสามารถใช้คลาสในบิลด์สคริปต์ของคุณได้เหมือนกับคลาสอื่น ๆ บนคลาสพา ธ

ฉันหวังว่าทุกอย่างจะชัดเจนสำหรับคุณตอนนี้

ด้วยความclasspath "com.android.tools.build:gradle:${Versions.android_gradle_plugin}"ที่เรากำลังตั้งclasspathด้วยวิธีcom.android.tools.build:gradle:${Versions.android_gradle_plugin}ซึ่งเป็นพึ่งพาโมดูลที่ถูกใช้โดยสร้างสคริปต์ตัวเองมากกว่าแหล่งที่มาในโครงการของคุณ

ในทางตรงกันข้ามกับcompile 'org.hibernate:hibernate-core:5.0.5.Final'ที่เรากำลังประกาศพึ่งพาโมดูลที่จำเป็นสำหรับโครงการของคุณกับรวบรวมการกำหนดค่า

TL; DR: ตัวclasspath, compileและimplementationเป็นคำหลักทั้งหมดที่สามารถนำมาใช้กับการอ้างอิงภายใต้สถานการณ์ที่แตกต่างกัน ก่อนหน้านี้ใช้เมื่อคุณต้องการส่งผ่านไปยังสคริปต์บิลด์ในการพึ่งพาและหลังเป็นหนึ่งในการกำหนดค่าที่คุณอาจต้องการประกาศ


1
คำตอบที่ดี. ฉันต้องเพิ่มว่าไม่เพียง แต่เราต้องจ้องไปที่คำหลักด้วยตัวเองตามที่อธิบายไว้ข้างต้นอย่างดี แต่นอกจากนี้เรายังต้องคำนึงถึงสิ่งประดิษฐ์ที่ถูกร้องขอเนื่องจากคำหลักเพียงอย่างเดียวไม่ได้กำหนดบริบททั้งหมด ตัวอย่างเช่น'org.projectlombok:lombok:1.18.4'ไม่มีการclasspathเชื่อมโยงเนื่องจากเป็น jar ที่จำเป็นเฉพาะในช่วงjavacเวลาคอมไพล์แต่ไม่จำเป็นสำหรับjavaรันไทม์ ดังนั้นการใช้งานที่ถูกต้องคือการทำงานร่วมกันของคีย์เวิร์ดที่กำหนดและส่วน ซึ่งหมายความว่าเราต้องการความรู้เบื้องต้น
eigenfield
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.