Gradle: в чем разница между путями к классам и зависимостями компиляции?

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'
} 
java123999
источник
1
Я не уверен, что понимаю. classpathне является допустимой областью зависимости.
Тунаки
Возможно, я запутался, каковы допустимые области зависимости?
java123999
Взгляните на этот документ: docs.gradle.org/current/userguide/…
Тунаки
Одна вещь, которую я заметил, это то, что compileOnlyзависимости идут, project.configurations.compileClasspathно не в project.configurations.compile, как упоминалось здесь github.com/iboyko/gradle-plugins/issues/5
Витенис Биваинис

Ответы:

47

Я собираюсь предположить, что вы ссылаетесь compileи находитесь classpathвнутри dependencies {}блока. Если это так, то это Конфигурации зависимостей .

Конфигурация - это просто именованный набор зависимостей.

compileКонфигурация создается с помощью плагина Java. classpathКонфигурации обычно рассматриваются в buildSrc {}блоке , где нужно , чтобы объявить зависимости для build.gradle, сам (для плагин, возможно).

Эрик Венделин
источник
Спасибо, поэтому для моего основного build.gradle мне не нужно использовать путь к классам?
java123999
@ java123999 Нет, если вы не используете специально написанные плагины
Эрик Венделин
@EricWendelin Где вы говорите "внутри блока зависимостей {}", вы имеете в виду "внутри блока buildscript {dependencies {}}"? (Я не уверен, просто спрашиваю.)
Пауло Мерсон
2
dependencies {}Блок может быть объявлен как внутри , так buildscript {}и вне его. Находясь внутри, вы используете classpathконфигурацию зависимостей, необходимую для компиляции самого скрипта сборки.
Эрик Венделин
55

Если самому buildscript нужно что-то запустить, используйте classpath .

Если вашему проекту нужно что-то запустить, используйте компиляцию .

buildscript{}Блок для самого build.gradle.

При построении нескольких проектов файл сборки верхнего уровня предназначен для корневого проекта, а конкретный файл сборки - для подпроекта (модуля).

Файл сборки верхнего уровня, в который вы можете добавить параметры конфигурации, общие для всех подпроектов / модулей.

Не помещайте зависимости вашего приложения в файл сборки верхнего уровня, они принадлежат отдельным файлам build.gradle модуля

д ...
источник
Для подтверждения: означает ли это, что proandroiddev.com/… должен использовать a, compileа не a classpath?
WillC
1
Но почему бы не разместить зависимости приложения в самом файле верхнего уровня, если в проекте есть только один модуль, как в типичных приложениях Android?
Харша,
18

Если я правильно понимаю, вы путаете Project.dependenciesблок сценария с блоком Project.buildscript.dependenciesсценария (как и я, когда дошел до этого вопроса).

Я постараюсь ответить на это тем, что нашел.

Думаю, вы уже должны быть знакомы с Project.dependenciesблоком скрипта. В этом блоке мы объявляем зависимости, которые требуются для нашего исходного кода. Есть несколько способов объявить зависимость, которая нам нужна для проекта. См. Учебное пособие по Gradle: Типы зависимостей . Я упомяну только ту часть, которая наиболее актуальна для этой проблемы:

compile 'org.hibernate:hibernate-core:5.0.5.Final'это объявление зависимости модуля. Конфигурация компиляции (которая теперь устарела конфигурацией реализации.) - это просто ключевое слово для него. Implementation only dependencies.Это не ключевое слово, описывающее, какой тип зависимости это (здесь по типу я следую за тремя типами, определенными в учебнике, то есть модулем, файл и проект.)

В Gradle Tutorial: Organizing Build Logic говорится:

Если вашему сценарию сборки необходимо использовать внешние библиотеки, вы можете добавить их в путь к классам сценария в самом сценарии сборки. Вы делаете это с помощью метода buildscript (), передавая закрытие, которое объявляет путь к классам скрипта сборки.

Таким же образом вы объявляете, например, путь к классам компиляции Java. Вы можете использовать любой из типов зависимостей, описанных в разделе Типы зависимостей, кроме зависимостей проекта.

Объявив путь к классам скрипта сборки, вы можете использовать классы в своем скрипте сборки, как и любые другие классы в пути к классам.

Я надеюсь, что теперь вам все стало ясно.

Здесь 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'мы объявляем зависимость модуля, необходимую для вашего проекта, с конфигурацией компиляции .

ТЛ; Dr: classpath, compileи implementationвсе ключевые слова , которые могут быть использованы против зависимостей при различных обстоятельствах. Первый используется, когда вы хотите передать зависимость сценарию сборки, а второй - это одна из конфигураций, которые вы, возможно, захотите объявить.

Тэн Пао Ю
источник
1
Хороший ответ. Я должен добавить, что мы не только должны смотреть на сами ключевые слова, как это красиво объяснено выше, но, кроме того, мы также должны учитывать запрашиваемый артефакт, потому что одни ключевые слова не определяют полный контекст. Например, у 'org.projectlombok:lombok:1.18.4'него нет classpathассоциации, потому что это jar, который нужен только во время компиляции, javacно не нужен во javaвремя выполнения. Следовательно, правильное использование - это взаимодействие определенных ключевых слов и артефакта. Значит, нужны априорные знания.
eigenfield