Gradle: Sự khác biệt giữa classpath và các phụ thuộc biên dịch là gì?


92

Khi thêm các phần phụ thuộc vào dự án của mình, tôi không bao giờ chắc chắn mình nên đặt tiền tố nào cho chúng, ví dụ: "classpath"hoặc"compile".

Ví dụ: các phần phụ thuộc của tôi bên dưới là thời gian biên dịch hay đường dẫn classpath?

Ngoài ra, điều này nên nằm trong ứng dụng build.gradle của tôi hay trong build.gradle mô-đun cụ thể?

Build.gradle hiện tại (ở cấp ứng dụng):

apply plugin: 'java'

repositories {
    mavenCentral()
}

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

1
Tôi không chắc là tôi hiểu. classpathkhông phải là một phạm vi phụ thuộc hợp lệ.
Tunaki

Có lẽ tôi đang bối rối, phạm vi phụ thuộc hợp lệ là gì?
java123999

Hãy xem tài liệu này: docs.gradle.org/current/userguide/…
Tunaki

Một điều tôi nhận thấy là compileOnlyphụ thuộc vào project.configurations.compileClasspathnhưng không project.configurations.compile, như đã đề cập ở đây github.com/iboyko/gradle-plugins/issues/5
Vytenis Bivainis

Câu trả lời:


47

Tôi sẽ đoán rằng bạn đang tham khảo compileclasspathtrong dependencies {}khối. Nếu đúng như vậy, đó là các Cấu hình phụ thuộc .

Cấu hình chỉ đơn giản là một tập hợp các phụ thuộc được đặt tên.

Các compilecấu hình được tạo ra bởi các plugin Java. Các classpathcấu hình thường thấy trong các buildSrc {}khối nơi người ta cần phải khai báo phụ thuộc cho build.gradle, bản thân (đối với plug-in, có lẽ).


Cảm ơn, vì vậy đối với build.gradle chính của tôi, tôi không cần phải sử dụng classpath?
java123999

@ java123999 Không, trừ khi bạn sử dụng plugin tùy chỉnh bằng văn bản
Eric Wendelin

@EricWendelin Nơi bạn nói "trong khối {} phụ thuộc" có nghĩa là "trong khối {phụ thuộc {}} buildcript"? (Tôi không chắc, chỉ hỏi thôi.)
Paulo Merson

2
Một dependencies {}khối có thể được khai báo cả bên trong buildscript {}và bên ngoài của nó. Khi ở bên trong, bạn sử dụng classpathcấu hình cho các phụ thuộc cần thiết để biên dịch chính tập lệnh xây dựng.
Eric Wendelin

55

Nếu bản thân buildcript cần thứ gì đó để chạy, hãy sử dụng classpath .

Nếu dự án của bạn cần thứ gì đó để chạy, hãy sử dụng biên dịch .

Các buildscript{}khối là cho build.gradle riêng của mình.

Để xây dựng nhiều dự án, tệp xây dựng cấp cao nhất dành cho dự án gốc, tệp xây dựng cụ thể dành cho dự án con (mô-đun).

Tệp xây dựng cấp cao nhất nơi bạn có thể thêm các tùy chọn cấu hình chung cho tất cả các dự án con / mô-đun.

Không đặt các phụ thuộc ứng dụng của bạn trong tệp xây dựng cấp cao nhất, chúng thuộc về tệp build.gradle mô-đun riêng lẻ


Để xác nhận: điều đó có nghĩa là proandroiddev.com/… nên sử dụng a compilechứ không phải a classpath?
WillC

1
Nhưng tại sao không đặt các phần phụ thuộc của ứng dụng vào chính tệp cấp cao nhất nếu dự án chỉ có một mô-đun, như các ứng dụng android thông thường?
Harsha

18

Nếu tôi hiểu đúng, bạn đang nhầm lẫn giữa Project.dependencieskhối tập lệnh với Project.buildscript.dependencieskhối tập lệnh (giống như tôi đã làm khi tôi đến câu hỏi này).

Tôi sẽ cố gắng trả lời điều này với những gì tôi tìm thấy.

Tôi nghĩ bạn đã quen với Project.dependencieskhối script. Trong khối này, chúng tôi khai báo các phần phụ thuộc được yêu cầu bởi mã nguồn của chúng tôi. Có một số cách để khai báo phụ thuộc mà chúng ta cần cho dự án. Xem Hướng dẫn Gradle: Các kiểu phụ thuộc . Tôi sẽ chỉ đề cập đến phần có liên quan nhất đến vấn đề này:

compile 'org.hibernate:hibernate-core:5.0.5.Final'là một khai báo phụ thuộc mô-đun. Cấu hình biên dịch (hiện không được dùng bởi cấu hình triển khai.) Chỉ là một từ khóa cho Implementation only dependencies.Nó không phải là một từ khóa mô tả nó thuộc loại phụ thuộc nào (theo loại ở đây, tôi đang làm theo ba loại được định nghĩa trong hướng dẫn, tức là mô-đun tệp và dự án.)

Trong Hướng dẫn Gradle: Tổ chức Xây dựng Logic, nó nói:

Nếu tập lệnh xây dựng của bạn cần sử dụng các thư viện bên ngoài, bạn có thể thêm chúng vào classpath của tập lệnh trong chính tập lệnh xây dựng. Bạn thực hiện việc này bằng cách sử dụng phương thức buildcript (), truyền vào một bao đóng khai báo classpath tập lệnh xây dựng.

Đây cũng giống như cách bạn khai báo, ví dụ, classpath biên dịch Java. Bạn có thể sử dụng bất kỳ kiểu phụ thuộc nào được mô tả trong Kiểu phụ thuộc, ngoại trừ kiểu phụ thuộc của dự án.

Sau khi khai báo classpath của tập lệnh xây dựng, bạn có thể sử dụng các lớp trong tập lệnh xây dựng của mình như cách bạn sử dụng bất kỳ lớp nào khác trên classpath.

Tôi hy vọng mọi thứ đang trở nên rõ ràng với bạn bây giờ.

Với classpath "com.android.tools.build:gradle:${Versions.android_gradle_plugin}"chúng tôi đang thiết lập classpathphương thức com.android.tools.build:gradle:${Versions.android_gradle_plugin}là một phần phụ thuộc mô-đun được sử dụng bởi chính tập lệnh xây dựng chứ không phải nguồn trong dự án của bạn.

Mặt khác, với việc compile 'org.hibernate:hibernate-core:5.0.5.Final'chúng tôi đang khai báo sự phụ thuộc mô-đun cần thiết cho dự án của bạn với cấu hình biên dịch .

tl; dr: The classpath, compileimplementationlà tất cả các từ khóa có thể được sử dụng để chống lại sự phụ thuộc trong các trường hợp khác nhau. Cái trước được sử dụng khi bạn muốn chuyển một phần phụ thuộc vào tập lệnh xây dựng và cái sau là một trong những cấu hình bạn có thể muốn khai báo.


1
Câu trả lời tốt. Tôi phải nói thêm, rằng chúng ta không chỉ phải nhìn chằm chằm vào bản thân các từ khóa như những gì được giải thích độc đáo ở trên, mà ngoài ra chúng ta cũng phải tính đến yếu tố tạo tác đang được yêu cầu bởi vì chỉ riêng từ khóa không xác định ngữ cảnh hoàn chỉnh. Ví dụ: 'org.projectlombok:lombok:1.18.4'không có classpathliên kết vì nó là một jar chỉ cần thiết trong javacthời gian biên dịch nhưng không cần thiết trong javathời gian chạy. Do đó, cách sử dụng đúng là sự tác động lẫn nhau của các từ khóa đã xác định và cấu tạo. Điều này có nghĩa là, một người cần kiến ​​thức tiên nghiệm.
eigenfield
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.