Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ignore proguard configuration of an external library

So, I want to add an external library to my project. The library itself is quite small, around 300 methods. But it is configured to be very liberal with it's proguard configuration. I ran a simple test with/without the library and with/without proguard on a barebones project and this is what I came up with

Proguard    Lib     Method Count
N           N       15631
Y           N       6370
N           Y       15945
Y           Y       15573

As you can see, with proguard enabled, the count is ~6000. But the moment I add the lib, count shoots up to ~15000 despite the library itself being only ~300 methods.

So my question is, how do I ignore the proguard configuration of this particular library?

UPDATE:

It is not possible with android gradle plugin now. I found android bug which doesn't have priority at all. Please avoid answers with mentioning "it is not possible" and keep question opened until a workaround or an official decision is possible. Otherwise, you will collect half of bounty without adding value. Thanks!

like image 539
iTwenty Avatar asked Dec 10 '15 14:12

iTwenty


People also ask

What is ProGuard obfuscation?

ProGuard is a command-line tool that reduces app size by shrinking bytecode and obfuscates the names of classes, fields and methods. It's an ideal fit for developers working with Java or Kotlin who are primarily interested in an Android optimizer.

Where is ProGuard configuration file?

By default, this file is located at the root of the module (next to the build. gradle file).

Is ProGuard enabled by default?

When you create a new module using Android Studio, the IDE creates a proguard-rules.pro file in the root directory of that module. By default, this file does not apply any rules. So, include your own ProGuard rules here, such as your custom keep rules.


1 Answers

In this specific case you have a few options:

  • extract the classes.jar file from the aar and include it as normal jar dependency in your project (will not work when the aar includes resources)
  • change the aar and remove the consumer proguard rules from it
  • use DexGuard which allows you to filter out unwanted consumer rules
  • do a bit of gradle hacking, see below

Add the following to your build.gradle:

afterEvaluate {
  // All proguard tasks shall depend on our filter task
  def proguardTasks = tasks.findAll { task ->
    task.name.startsWith('transformClassesAndResourcesWithProguardFor') }
  proguardTasks.each { task -> task.dependsOn filterConsumerRules }
}

// Let's define our custom task that filters some unwanted
// consumer proguard rules
task(filterConsumerRules) << {
  // Collect all consumer rules first
  FileTree allConsumerRules = fileTree(dir: 'build/intermediates/exploded-aar',
                                       include: '**/proguard.txt')

  // Now filter the ones we want to exclude:
  // Change it to fit your needs, replace library with
  // the name of the aar you want to filter.
  FileTree excludeRules = allConsumerRules.matching {
    include '**/library/**'
  }

  // Print some info and delete the file, so ProGuard
  // does not pick it up. We could also just rename it.
  excludeRules.each { File file ->
    println 'Deleting ProGuard consumer rule ' + file
    file.delete()
  }
}

When using DexGuard (7.2.02+), you can add the following snippet to your build.gradle:

dexguard {
  // Replace library with the name of the aar you want to filter
  // The ** at the end will include every other rule.
  consumerRuleFilter '!**/library/**,**'
}

Mind that the logic is inverted to the ProGuard example above, the consumerRuleFilter will only include consumer rules that match the pattern.

like image 76
T. Neidhart Avatar answered Sep 18 '22 05:09

T. Neidhart