我目前正在将我们的一个项目从maven转换为Gradle。文件夹结构如下:
gitRoot
settings.gradle
build.gradle
ProjectA
build.gradle
src/main/java
Libraries
SomeLib (git submodule)
ProjectBRoot (git submodule)
settings.gradle
build.gradle
ProjectB
build.gradle
src/main/java
Libraries
FacebookSDK/facebook
build.gradle
src
所以看起来很复杂。但是想法是ProjectB是一个图书馆项目,它应该能够单独构建和打包,这就是为什么它有自己的settings.gradle,据我所知,它似乎工作正常,我有它建设并且它发现facebook就好了。
ProjectB / build.gradle包含此行
compile project(':libraries:facebook-android-sdk:facebook')
ProjectBRoot / settings.gradle包含此行
include ':ProjectB', ':libraries:facebook-android-sdk:facebook'
gitRoot / settings.gradle包含此行
include ':ProjectA', ':Libraries:ProjectBRoot:ProjectB'
ProjectA / build.gradle包含此行
compile project(':Libraries:ProjectBRoot:ProjectB')
当我运行构建时出现此错误
The TaskContainer.add() method has been deprecated and is scheduled to be removed in Gradle 2.0. Please use the create() method instead.
FAILURE: Build failed with an exception.
* Where:
Build file '/gitRoot/Libraries/ProjectBRoot/ProjectB/build.gradle' line: 17
* What went wrong:
A problem occurred evaluating project ':Libraries:ProjectBRoot:ProjectB'.
> Project with path ':libraries:facebook-android-sdk:facebook' could not be found in project ':Libraries:ProjectBRoot:ProjectB'.
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
BUILD FAILED
Total time: 4.652 secs
所以我的猜测是错误的是facebook不在ProjectB的直接子文件夹中......但是在ProjectBRoot中构建时无关紧要。这可能是由于我直接引用ProjectB而不是通过ProjectBRoot / gradle.build引用的面孔,但我尝试了它,但它也没有用。有人可以帮助我,我已经查看了文档,它没有谈论有多个项目有自己的settings.gradle文件,我认为这是让我搞砸的事情。
更新
所以我按照Xav的回答,我现在能够使用命令行构建,但我无法使用android studio导入/构建。我知道问题仍然是facebook项目。我得到的错误是它无法配置ProjectB。
Gradle: A problem occurred configuring project ':ProjectA'.
> Failed to notify project evaluation listener.
> A problem occurred configuring project ':Libraries:ProjectBRoot:ProjectB'.
> Failed to notify project evaluation listener.
> Configuration with name 'default' not found.
错误是由行
引起的 compile project(':facebook-sdk')
在ProjectB / build.gradle中
答案 0 :(得分:94)
settings.gradle必须定义所有模块。它不会加载树中的其他settings.gradle来加载更多模块。
你必须要么
在顶级settings.gradle中为facebook SDK定义模块。是的,它与其他settings.gradle是多余的。
以某种方式发布项目B(以及它的依赖关系,所以在这种情况下是facebook SDK库),某处(例如公司工件库)并从项目A访问它。
虽然#1更好,但它使ProjectB - > Facebook依赖性很棘手,因为路径会有所不同,具体取决于使用的settings.gradle。解决此问题的一种方法是将模块名称/路径从其在磁盘上的实际位置拆分。这是在settings.gradle文件中完成的。
在顶级settings.gradle文件中,执行
include 'facebook-sdk'
project(':facebook-sdk').projectDir = new File('Libraries/ProjectBRoot/Libraries/FacebookSDK/facebook')
在项目B内的setting.gradle文件中,使用不同的相对路径执行相同操作:
include 'facebook-sdk'
project(':facebook-sdk').projectDir = new File('Libraries/FacebookSDK/facebook')
这使得两个项目设置都定义了位于磁盘上相同绝对位置的相同“facebook-sdk”模块。
依赖于此模块的所有项目都应该将依赖项声明为
compile project(':facebook-sdk')
答案 1 :(得分:5)
这不是您正在寻找的答案,但是......
我花了大约4天时间尝试将我复杂的项目结构(实际上与你的实际情况很相似)迁移到gradle中。最后,我放弃了整个子项目的概念(因为在我的情况下,它只是没有用),我选择使用本地maven存储库方法,如本文所述:http://www.flexlabs.org/2013/06/using-local-aar-android-library-packages-in-gradle-builds
因此,在我的具有子项目的图书馆项目中,我基本上为每个项目创建了完整的库项目,然后我使用上面的链接将这些项目发布到maven本地存储库。然后在父项目中,我删除了对子项目的任何引用,在依赖项中,我只引用了已发布的库。然后在我的主项目中,删除了对子项目的所有引用,并引用了我的库的已发布的maven本地版本。
最后,一切都运作良好,但确实需要一些时间来转换所有内容。我有大约6个子项目的图书馆项目,子项目等,现在一切正常。
我不喜欢像Gradle和Maven这样的系统,他们真的希望你改变你的代码/项目结构。因此,如果您要迁移到Gradle而不是从Gradle开始,那么这个过程可能非常令人沮丧。一旦你搞清楚了,下一次就容易了;)
答案 2 :(得分:4)
我只是将这些库的应用程序放在同一级别。您仍然可以基于build.gradle文件构建和打包每个库。我可能会遗漏一些东西,但结构并不像build.gradle文件那样重要。即使它们处于相同的文件夹级别,你仍然可以让projectB依赖于Facebook。
答案 3 :(得分:2)
出现同样的问题,就我而言,我忘了在settings.gradle
中添加项目。在那之后,它工作了
答案 4 :(得分:1)
我终于设法构建项目(没有gradle错误)。来自Xavier的回答非常有帮助。
我花了差不多3天的时间来设置我的项目,我知道我非常接近finsihed,但是在gradle构建过程的最后一步(dexDebug)我有意想不到的顶级异常。
我的项目设置与Stoyan非常相似,但是我有多个android-library项目引用了android-support库。我建议如果你有编译你的顶级根项目的问题(错误说支持android已经添加),你需要将jar移动到单独的android库项目(分解/分离成独立实例)。
实施例
--| ProjectARoot
--| ProjectA (where main/java etc are)
--| build.gradle
--| settings.gradle
--| libraries
--| ProjectBRoot
--| settings.gradle
--| ProjectB
--| libraries
--| android-supports (android lib project)
--| libs
--| android-support-v4.jar
--| android-support-v13.jar
--| build.gradle
--| libA
--| build.gradle (referencing android-supports)'
libA引用android的示例构建脚本支持项目
buildscript {
repositories {
maven { url 'http://repo1.maven.org/maven2' }
}
dependencies {
classpath 'com.android.tools.build:gradle:0.4'
}
}
apply plugin: 'android-library'
dependencies {
compile project(':android-support')
}
android {
compileSdkVersion 17
buildToolsVersion "17.0.0"
defaultConfig {
minSdkVersion 7
targetSdkVersion 17
}
}
// top root settings.gradle
include 'ProjectB', 'android-support', ':ProjectA' (notice Project B is first than android-support and lastly Project A)
project(':android-support').projectDir = new File('libraries/ProjectBRoot/libraries/android-support')
project(':ProjectB').projectDir = new File('libraries/ProjectBRoot/ProjectB')
目前,当我运行gradle build时,我收到此错误
:ProjectA:dexDebug
UNEXPECTED TOP-LEVEL EXCEPTION:
java.lang.IllegalArgumentException: already added: Landroid/support/v4/accessibilityservice/AccessibilityServiceInfoCompat;
at com.android.dx.dex.file.ClassDefsSection.add(ClassDefsSection.java:123)
at com.android.dx.dex.file.DexFile.add(DexFile.java:163)
at com.android.dx.command.dexer.Main.processClass(Main.java:490)
at com.android.dx.command.dexer.Main.processFileBytes(Main.java:459)
at com.android.dx.command.dexer.Main.access$400(Main.java:67)
at com.android.dx.command.dexer.Main$1.processFileBytes(Main.java:398)
at com.android.dx.cf.direct.ClassPathOpener.processArchive(ClassPathOpener.java:245)
at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:131)
at com.android.dx.cf.direct.ClassPathOpener.process(ClassPathOpener.java:109)
at com.android.dx.command.dexer.Main.processOne(Main.java:422)
at com.android.dx.command.dexer.Main.processAllFiles(Main.java:333)
at com.android.dx.command.dexer.Main.run(Main.java:209)
at com.android.dx.command.dexer.Main.main(Main.java:174)
at com.android.dx.command.Main.main(Main.java:91)
1 error; aborting
:ProjectA:dexDebug FAILED