jvoegele/gradle-android-plugin — Issue #38: Library projects not handled well
Author: ealden
Created: 2011-12-29 04:21:19+00:00
State: open

Originally reported by matthias@qype.com (26 Jul 2011)
https://code.google.com/p/gradle-android-plugin/issues/detail?id=13

***

On my journey to develop a shared Android library project, I found that while there is some support for building projects with Gradle that depend on Android library projects, it's quite awkward and requires one to straighten out some of its rough edges.

The problem is this:

While we use the Android Ant task to build the APK (which means we get all the benefits like mashing the lib project resources into the app APK), there is no standard Ant task that we can re-use for the rest. The rest is making sure that the lib project's class files and library dependencies also end up being merged into classes.dex (that's before the APK is assembled).

Currently this *somewhat* works, because what you can do is simply declaring a normal Gradle compile dependency (plus transitives) on the lib JAR, so the classes will be added to classes.dex. However, this is awkward for two reasons:

1) even tho you declare a dependency to an artifact from a remote repository, you still need the source code sitting next to your app project, since the APK builder will use a relative path to lookup up the library resource files. This raises the question: why not also use the sources then, too? That's in fact wha the ADT and the Android Ant tasks do, they compile the library project straight into your own app.

2) with a compile dependency on your Gradle classpath, the Eclipse enhancement will break. That's because eclipseClasspath will add the classes (including R.class) from the JAR file to the project's classpath, but since in Eclipse the ADT already create an Eclipse symlink to the lib project's source code, you will end up having the library's R class twice on the classpath, and this will break the dexer. As a workaround, you can add this to your Gradle script:

eclipseClasspath {
whenConfigured { classpath ->
classpath.entries.removeAll { it.endsWith() }
}
}

that makes sure that the Gradle build will see the library classes from the JAR, while Eclipse/ADT will see library classes by linking the source code straight into your app project.

I think we should modify the plugin to work like ADT and Android Ant do, i.e. by not requiring the user to declare a dependency to the library JAR, and instead add the lib's src folder to the compile classpath. Similarly, the lib's own library dependencies must be added, too.