Having difficulty setting up Gradle multiproject b

2019-01-31 10:39发布

问题:

I'm trying to craft a Gradle multiproject build for a situation in which my project layout is already dictated to me. I have something like this:

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

My settings.gradle looks like this:

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

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

When I run Gradle in the build folder like this:

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

I get:

: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

i.e. it doesn't find the projects I'm trying to build. Is what I'm trying to do possible with Gradle's multiproject support? Or am I barking up the wrong tree?

回答1:

A couple of pointers:

  • Gradle strictly separates the logical project hierarchy (the way Gradle organizes your build into a logical hierarchy of projects) from the physical directory layout. Just about any mapping is possible. (One exception that comes to mind is that you can't have two projects sharing the same project directory.)
  • To implement a custom directory layout, you'll have to set projectDir for all projects, not just the root project. You should use relative paths, e.g. rootProject.projectDir = new File(settingsDir, "../foo") and project(":sub1").projectDir = new File(rootDir, "bar"). Here, settingsDir refers to the directory containing settings.gradle, and rootDir is a shorthand for rootProject.projectDir.
  • To configure projects generically, you can recursively walk (root)Project.children. Note that settings.gradle and build.gradle use different types to represent a project - ProjectDescriptor and Project, respectively.
  • Gradle has to be invoked from the directory containing settings.gradle, or a subdirectory thereof. From a usability perspective, it is therefore best to put settings.gradle into the root of the directory hierarchy.

For more information, see Settings in the Gradle Build Language Reference, and the Multi-Project Builds chapter in the Gradle User Guide.



回答2:

For completeness, the settings.gradle that solved my specific example above is as follows:

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'

Clearly this doesn't scale to large numbers of subprojects and it could be done significantly better using the hints provided by Peter above.



标签: gradle