My title isn't exactly clear so I'll describe my situation before asking the question:
I have a number of libraries (~15), some of which depend on each other and a number of apps (~5) that depend on various subsets of these libraries. The libraries are hosted on an internal maven site. Most of these apps function within the same domain and there's an overlap in functionalities as well as data models used. Sometimes, adding a feature means making changes to a library in the middle of the hierarchy tree, providing support for it upstream (libs towards the root of the dependency tree), and then utilizing the changes upstream (applications as well as libraries that use the changed libraries).
I want to:
Fetch these libraries from Maven when I'm working on application code
Edit and compile these libraries from within my project while I'm working on changes that affect libraries
My current process is a bit tedious:
Checkout the source for the library(ies) and place it beside my application code (workspace/app_code, workspace/lib1_code, workspace/lib2_code, etc.)
I add include ':lib1_code', include ':lib2_code', etc. to my settings.gradle (I have these commented out so I just toggle them on and off as needed)
I replace the
implementation "com.packages:lib1:1.2.3" with implementation project(':lib1_code') (and so on)
I do the same in the dependent libraries too.
As you can see, it's a lot of work and nobody on my team (myself included) likes the process.
I want to be able to just do all of the above with a set of properties like buildLib1UseLocal=true
Questions:
How common is my scenario?
Does gradle have support for something like this?
Is there another build system that does?
Gradle is based on Groovy, so it provides full scripting support. You can just evaluate the property on your own:
dependencies {
if (buildLib1UseLocal) {
implementation project(':lib1_code')
} else {
implementation 'com.packages:lib1:1.2.3'
}
}
Gradle even provides a feature called dependency substitutions. It allows you to define your dependencies in the regular way, but to resolve them from other sources:
dependencies {
implementation 'com.packages:lib1:1.2.3'
}
configurations.all {
resolutionStrategy.dependencySubstitution {
if (buildLib1UseLocal) {
substitute module('com.packages:lib1:1.2.3') with project(':lib1_code') because '<some reason>'
}
}
}
I have a simple question. Is it possible to modify the gradle library build project specific and how?
Following example, I have a library that I use in multiple projects.
Now I want to exclude some files in the library when I build Project_A.
But I want them included when I build Project_B.
I wonder if its possible to add parameters to the dependencies in the build.gradle file of Projekt_A. Something like:
dependencies {
compile project(':explore_layout',
//specify the exclude inside the lib
sourceSets {
main {
java {
exclude '**/uncompilable/**'
}
}
}
)
}
Make two source sets in your library project and then depend on the the according configurations that are added for the source sets. This way you can get only one source set for A but both for B.
I am developing a future open source Android library with Kotlin, and I'd like to count the methods from my own code as well as from dependencies.
Since how Kotlin differs from Java, I assume the tool should take an aar input as a file to get the real methods count, but I only found tools taking apk files as inputs so far.
How can I do it the simplest way?
Thanks for your help!
The dexcount-gradle-plugin works with libraries as well. The resulting #aar file should not differ when using Kotlin instead of Java, since Kotlin just compiles to Java byte code as well. So just use it and you'll get all the information you need for your library.
buildscript {
dependencies {
classpath 'com.getkeepsafe.dexcount:dexcount-gradle-plugin:0.6.4'
}
}
apply plugin: 'com.getkeepsafe.dexcount'
I have seen and used compile, compile files, androidTestCompile etc for importing dependencies in my android project. Today I came across embedded in the gradle of an existing android project. Not sure what this means. Even googling didn't help me on this. Can anyone please help. Below is the line I saw in the build.gradle file.
embedded 'com.eyeverify:EVServiceInterface:2.6.1-release#aar'
The keyword embedded doesn't exist in Gradle syntax. I think in that android project, embedded was a custom configuration defined in a build.gradle file:
configurations {
embedded
}
So you can use:
embedded 'com.eyeverify:EVServiceInterface:2.6.1-release#aar'
I've moved my project to Android Studio a month ago, and I'm glad I did, despite the need to switch to a new (and more powerful) build system (gradle). One thing I'd have known in Eclipse, but I can't figure out how to achieve now, is patching the support library. I know that it does not sound like a good practice, but a couple of code lines are driving me crazy, and the solution would be to simply modify it to solve my problem.
I've tried to modify the code in the sdk's ".\extras\android\m2repository\com\android\support" directory, but that does not seem to affect the code that is really used for compilation.
Any idea about how to achieve this ?
Edit:
I tried to create a module "SupportLibraryV4" in my project, and this is what gradle tells me when I try to build it :
Error Code:
1
Output:
trouble processing "java/android/support/v4/R$anim.class":
Ill-advised or mistaken usage of a core class (java.* or javax.*)
when not building a core library.
This is often due to inadvertently including a core library file
in your application's project, when using an IDE (such as
Eclipse). If you are sure you're not intentionally defining a
core class, then this is the most likely explanation of what's
going on.
However, you might actually be trying to define a class in a core
namespace, the source of which you may have taken, for example,
from a non-Android virtual machine project. This will most
assuredly not work. At a minimum, it jeopardizes the
compatibility of your app with future versions of the platform.
It is also often of questionable legality.
If you really intend to build a core library -- which is only
appropriate as part of creating a full virtual machine
distribution, as opposed to compiling an application -- then use
the "--core-library" option to suppress this error message.
If you go ahead and use "--core-library" but are in fact
building an application, then be forewarned that your application
will still fail to build or run, at some point. Please be
prepared for angry customers who find, for example, that your
application ceases to function once they upgrade their operating
system. You will be to blame for this problem.
If you are legitimately using some code that happens to be in a
core package, then the easiest safe alternative you have is to
repackage that code. That is, move the classes in question into
your own package namespace. This means that they will never be in
conflict with core system classes. JarJar is a tool that may help
you in this endeavor. If you find that you cannot do this, then
that is an indication that the path you are on will ultimately
lead to pain, suffering, grief, and lamentation.
1 error; aborting
impressive !
Android sdk doesn't have all required files for building support library.
You need to checkout additional repositories from https://android.googlesource.com:
platform/frameworks/support
platform/prebuilts/gradle-plugin
platform/prebuilts/maven_repo/android
platform/prebuilts/sdk
platform/prebuilts/tools
Please, keep the directory structure as in android repository.
Now you could change any code in support library. If you need to change support library for api v.4 do it in "platform\frameworks\support\v4". For building patched version of support library use gradle with next command:
platform\frameworks\support\v4\gradle clean jar
Resulted jar could be found in "platform\out\host\gradle\frameworks\support\v4\libs\". Put it to the libs folder of your project and add in build.gradle file.
Updated answer 2016 for Linux and OS X using the bundled gradle wrapper instead of the system's gradle installation:
Checkout the following repositories from https://android.googlesource.com and keep the directory structure:
platform/frameworks/support
platform/prebuilts/gradle-plugin
platform/prebuilts/maven_repo/android
platform/prebuilts/sdk
platform/prebuilts/tools
platform/tools/external/gradle
Modify files in the library:
Change files in platform/frameworks/support/
Build AAR
cd platform/frameworks/support
./gradlew jarRelease
The resulting .aar is in platform/out/host/gradle/frameworks/support/<module>/build/outputs/aar/
Add to project
Create a libs/ folder next to your app's build.gradle
Add libs folder to build.gradle: repositories{ flatDir{ dirs 'libs' } }
Copy the .aar file to libs/
Add aar to your dependencies section in build.gradle, e.g.: dependencies { compile(name:'my_custom_supportlib_module', ext:'aar') }
Module already in project
When you patches a support library module that other modules depend on, you'll have it twice in the build causing errors. This can be avoided by excluding the original dependency.
If you for example patch recyclerview-v7 and add
dependencies {
compile(name:'recyclerview-v7-release', ext:'aar')
}
you have to exclude the dependency like this. Change
compile "com.android.support:design:24.2.1"
to
compile("com.android.support:design:24.2.1") {
exclude group: 'com.android.support', module: 'recyclerview-v7'
}
for all modules that depend on the patched module.
Patch the SupportLib and add it manually as a jar:
Put the SupportLib jar into the libs folder
Right click it and hit 'Add as library'
Ensure that compile files('libs/supportlib.jar') is in your build.gradle file
Do a clean build
Disclaimer: Android Studio: Add jar as library?
Turns out that Ilya Tretyakov's answer only works for parts of the support library that don't have resources because they can't be put into a .jar.
The correct way to build for example the design-support-library is as follows:
checkout these repos from https://android.googlesource.com and keep the file structure:
platform/frameworks/support
platform/prebuilts/gradle-plugin
platform/prebuilts/maven_repo/android
platform/prebuilts/sdk
platform/prebuilts/tools
navigate to platform/frameworks/support/design and edit whatever file you want. Now rebuild everything with gradle clean assembleRelease
you can find the resulting library file support-design-release.aar in platform/out/host/gradle/frameworks/support/support-design/build/outputs/aar
create an app/libs folder in your project and edit the app/build.gradle:
repositories{
flatDir{
dirs 'libs'
}
}
dependencies {
compile(name:'support-design-release.aar', ext:'aar')
}
do a clean rebuild of your project and everything will work as intended