我的公司目前正在从Ant转向Gradle以获得Java项目,但我仍然坚持使用干净的设置。假设我为一家为客户构建网站的公司工作,这些公司通常使用相同的根库(核心项目),但有一些特定的代码,这些代码放在子项目中。根据客户,我们构建一个新的子项目,这取决于核心项目。客户数量将来会增加。
目前我们有三个项目:
我成功地将整个ant构建转换为核心项目的gradle构建。我的想法是将所有功能和项目结构放在核心,而只是额外用于子项目中实际需要的内容。
以下是我们文件夹结构的简短示例:
-- core
- build.gradle
- settings.gradle
-- repository (our external jars used)
-- Implementation
-- source_code
-- all the core project folders
-- Projects
-- Client A
- build.gradle
- settings.gradle
-- more project specific folders
-- Client B
- build.gradle
- settings.gradle
-- more project specific folders
我经常使用$ rootDir变量。核心的settings.gradle的一小部分看起来像这样:
project(':CoreProjectA').projectDir = new File(rootDir, 'Implementation/Source_code/Core/coreA')
project(':CoreProjectB').projectDir = new File(rootDir, 'Implementation/Source_code/Core/CoreB')
但还有更多。此外,在核心build.gradle中,我将这样称为我们的存储库:
repositories {
//All sub-projects will now refer to the same 'libs' directory
flatDir {
dirs "$rootDir/repository/lib/jaxb"
//many more dirs here
}
}
现在,当我从核心项目进行gradle构建时,这一切都很有效。 我打算将下一段代码放在每个客户的子项目build.gradle中:
apply from: '../../../build.gradle'
当我从Client A文件夹运行gradle构建时,我的rootDir显然已经改变了,现在,我的所有路径都无法在任何地方找到。
有没有办法以干净的方式设置它?所以添加的每个子项目总是可以使用相同的结构?或者我是否必须完全为每个子项目提供build.gradle和settings.gradle?
我知道最后一个选项可以工作,但这是一个很大的开销,对我来说似乎并不好看。
提前致谢!
答案 0 :(得分:1)
看起来您在子项目中有额外的settings.gradle
。这使得Gradle认为子项目是一个独立项目。如果从子项目中删除settings.gradle
,Gradle将在文件系统层次结构中查找它,将在核心项目中找到一个,将创建正确的多模块项目,并且所有路径都应该正常工作。
因此,只需删除额外的settings.gradle
文件,您的构建就可以正常工作。在子项目中使用build.gradle
非常好。
答案 1 :(得分:1)
我最近处理过类似的配置,所以让我解释一下如何构建Gradle基础架构。既然你提到了很多要求,我希望我会错过任何一个要求,你可以将我的方案应用到你的问题中。
我们实际上使用构建系统(如Gradle)来让他们处理任何依赖项(项目,模块,任务)。那么,为什么我们应该在文件系统层次结构中定义依赖性,如果我们可以在Gradle中简单地定义它呢?
我会尽可能避免使用路径(约定优于配置)并尝试坚持使用Gradle项目来构建脚本和依赖项。
此外,如果您在核心float nearMaxValue = BitConverter.ToSingle(BitConverter.GetBytes(BitConverter.ToInt32(BitConverter.GetBytes(float.MaxValue), 0) - 1), 0);
Console.WriteLine("{0:R}: float.MaxValue", float.MaxValue);
Console.WriteLine("{0:R}: previous float", nearMaxValue);
Console.WriteLine("{0:R}: difference", float.MaxValue - nearMaxValue);
中定义依赖项,则应该只调用此gradle文件,即使您只想构建子项目。你的gradle.build
破坏了整个Gradle逻辑。相反,您应该使用apply from: '../../../build.gradle'
之类的东西来构建第一个子项目。
文件系统结构:
gradle :sub1:build
核心core/
build.gradle
settings.gradle
src/
...
sub1/
src/
...
build.gradle [optional]
sub2/
src/
...
build.gradle [optional]
:
settings.gradle
核心include 'sub1'
include 'sub2'
:
build.gradle
文件系统结构:
allprojects {
apply plugin: 'java'
repositories {
// define repos for all projects
}
}
subprojects {
dependencies {
// let subprojects depend on core
compile rootProject
}
}
project(':sub1') {
// define anything you want (e.g. dependencies) just for this subproject
// alternative: use build.gradle in subproject folder
}
Root core/
src/
...
build.gradle [optional]
sub1/
src/
...
build.gradle [optional]
sub2/
src/
...
build.gradle [optional]
build.gradle
settings.gradle
:
settings.gradle
Root'build.gradle'
include 'core'
include 'sub1'
include 'sub2'
这种方法提供了很大的灵活性,因为每个依赖逻辑都由Gradle处理,你永远不必将任何东西复制到另一个位置。只需改变依赖关系就可以了。
答案 2 :(得分:0)
我要感谢Nikita,特别是lukegv的详细答案,但我最终采用了不同的方法。
我不希望有一个主要的gradle构建并在每次有新项目时扩展它。另外,如果他们想为其中一个项目创建构建,我想让同事保持简单和合乎逻辑。
因此,我保留了上面所描述的结构。在根gradle.settings但改变了project(':CoreProjectA').projectDir = new File(rootDir, 'Implementation/Source_code/Core/coreA')
project(':CoreProjectB').projectDir = new File(rootDir, 'Implementation/Source_code/Core/CoreB')
成:
project(':CoreProjectA').projectDir = new File(customRootDir, 'Implementation/Source_code/Core/coreA')
project(':CoreProjectB').projectDir = new File(customRootDir, 'Implementation/Source_code/Core/CoreB')
在每个项目中,我都有一个带有customRootDir的properties.gradle(相对于projects目录)。
这一切都像魅力一样。我可以进入任何项目文件夹并生成构建,同时使用root的build.gradle功能。