Не удалось настроить Gradle сборку мультипроекта для существующего макета хранилища

Я пытаюсь создать сборку Gradle multiproject для ситуации, когда мой проект уже продиктован мне. У меня есть что-то вроде этого:

-->Shared\
---->SharedComponent1\
------>build.gradle
------>src\
...
---->SharedComponent2\
------>build.gradle
...
-->Product1\
---->ProductComponent1\
------>build.gradle
---->ProductComponent2\
------>build.gradle
...
---->build\
------>settings.gradle

Мои настройки .gradle выглядят следующим образом:

rootProject.name = 'Product1'
rootProject.projectDir = new File( "${ProjectsRoot}" )

include 'Shared:SharedComponent1'
include 'Shared:SharedComponent2'
include 'Product1:ProductComponent1'
include 'Product1:ProductComponent2'

Когда я запускаю Gradle в папке сборки следующим образом:

gradle -PProjectsRoot=c:\my\project\root\dir projects

Я получаю:

:projects

------------------------------------------------------------
Root project
------------------------------------------------------------

Root project 'build'
No sub-projects

To see a list of the tasks of a project, run gradle <project-path>:tasks
For example, try running gradle :tasks

BUILD SUCCESSFUL

то есть. он не находит проекты, которые я пытаюсь построить. Является ли то, что я пытаюсь сделать с поддержкой Gradle мультипроекта? Или я лаяю неправильное дерево?

Ответ 1

Несколько указателей:

  • Gradle строго разделяет иерархию логических проектов (способ Gradle организует вашу сборку в логическую иерархию проектов) из макета физического каталога. Возможно любое сопоставление. (Единственное исключение, которое приходит на ум, состоит в том, что у вас не может быть двух проектов, разделяющих один и тот же каталог проекта.)
  • Чтобы реализовать настраиваемый макет каталога, вам нужно установить projectDir для всех проектов, а не только для корневого проекта. Вы должны использовать относительные пути, например. rootProject.projectDir = new File(settingsDir, "../foo") и project(":sub1").projectDir = new File(rootDir, "bar"). Здесь settingsDir ссылается на каталог, содержащий settings.gradle, а rootDir является сокращением для rootProject.projectDir.
  • Чтобы настроить проекты в целом, вы можете рекурсивно пройти (root)Project.children. Обратите внимание, что settings.gradle и build.gradle используют разные типы для представления проекта - ProjectDescriptor и Project, соответственно.
  • Gradle должен быть вызван из каталога, содержащего settings.gradle, или его подкаталога. Поэтому с точки зрения удобства использования лучше всего положить settings.gradle в корень иерархии каталогов.

Для получения дополнительной информации см. Settings в Gradle "Справочник по созданию языка" и глава

Ответ 2

Для полноты, settings.gradle, который решил мой конкретный пример выше, выглядит следующим образом:

rootProject.name = 'Product1'

def projectTreeRootDir = new File( "${ProjectsRoot}" )

// Shared components

def sharedRootDir = new File( projectTreeRootDir, 'Shared' )

include ':SharedComponent1'
project( ':SharedComponent1' ).projectDir = new File( sharedRootDir, 'SharedComponent1' )

include ':SharedComponent2'
project( ':SharedComponent2' ).projectDir = new File( sharedRootDir, 'SharedComponent2' )

// Product components

includeFlat 'ProductComponent1', 'ProductComponent2'

Очевидно, что это не масштабируется для большого количества подпроектов, и это можно сделать значительно лучше, используя подсказки, представленные выше Питером.