如何在android gradle构建文件中为从maven Central提取的库指定injars
Posted
技术标签:
【中文标题】如何在android gradle构建文件中为从maven Central提取的库指定injars【英文标题】:how to specify injars for proguard within android gradle build files for libraries that are pulled from maven central 【发布时间】:2013-08-29 22:30:16 【问题描述】:有没有办法将从 maven Central 中提取的库作为 proguard 的 injars 传递?我希望他们被混淆。上下文:remove unused classes with proguard for android
【问题讨论】:
您找到解决方案了吗? 【参考方案1】:我从未使用过 Maven,而我正在使用 Gradle,但无论是构建系统,我相信同样适用。而且我不认为你想要什么是可能的......
-injars
关键字特定于 ProGuard 配置文件,它是构建工具读取的文本文件。
我看到的唯一方法是,如果您构建某种脚本,它将为您服务。也就是说,读取所有 Maven 依赖项,创建适当的 ProGuard 配置文件,指定所有必需的 -injars 并将其传递给构建过程。不确定这对 Maven 是否可行。
使用 Gradle 应该不会太难。使用 Gradle,您可以轻松传递多个 ProGuard 配置文件,您只需在 build.gradle
文件中创建一个方法以从依赖项中获取所有 .jar 文件位置,并创建一个临时文本文件,然后将其传递到 ProGuard 配置中。
我假设同样的过程也适用于 Maven,但同样,我从未使用过它。
【讨论】:
【参考方案2】:编辑:我现在看到 Gradle 专门提出的问题。我的回答是针对 Ant,但它可能会给你一些想法。
完整的解决方案包括以下步骤:
-
创建自定义 build.xml
复制并修改“混淆”目标以使用 injars
使用 Maven 放置它们的目录中的 injars
自动化 Maven 以将 jar 放入目录中。 这就是我迷路的地方。 gradle/maven 经验不足。
详细步骤:
1。自定义 build.xml
在build.xml中,放入“custom”,如下:
<!-- version-tag: custom -->
<import file="$sdk.dir/tools/ant/build.xml" />
在此位之前,插入以下代码,或将其放入单独的文件 (general-build.xml) 并将其导入 build.xml。
2。目标
插入以下内容:
<!-- Obfuscate target
This is only active in release builds when proguard.config is defined
in default.properties.
To replace Proguard with a different obfuscation engine:
Override the following targets in your build.xml, before the call to <setup>
-release-obfuscation-check
Check whether obfuscation should happen, and put the result in a property.
-debug-obfuscation-check
Obfuscation should not happen. Set the same property to false.
-obfuscate
check if the property set in -debug/release-obfuscation-check is set to true.
If true:
Perform obfuscation
Set property out.dex.input.absolute.dir to be the output of the obfuscation
-->
<target name="-obfuscate">
<if condition="$proguard.enabled">
<then>
<property name="obfuscate.absolute.dir" location="$out.absolute.dir/proguard" />
<property name="preobfuscate.jar.file" value="$obfuscate.absolute.dir/original.jar" />
<property name="obfuscated.jar.file" value="$obfuscate.absolute.dir/obfuscated.jar" />
<!-- input for dex will be proguard's output -->
<property name="out.dex.input.absolute.dir" value="$obfuscated.jar.file" />
<!-- Add Proguard Tasks -->
<property name="proguard.jar" location="$android.tools.dir/proguard/lib/proguard.jar" />
<taskdef name="proguard" classname="proguard.ant.ProGuardTask" classpath="$proguard.jar" />
<!-- Set the android classpath Path object into a single property. It'll be
all the jar files separated by a platform path-separator.
Each path must be quoted if it contains spaces.
-->
<pathconvert property="project.target.classpath.value" refid="project.target.class.path">
<firstmatchmapper>
<regexpmapper from='^([^ ]*)( .*)$$' to='"\1\2"'/>
<identitymapper/>
</firstmatchmapper>
</pathconvert>
<!-- Build a path object with all the jar files that must be obfuscated.
This include the project compiled source code and any 3rd party jar
files. -->
<path id="project.all.classes.path">
<pathelement location="$preobfuscate.jar.file" />
<path refid="project.all.jars.path" />
</path>
<!-- Set the project jar files Path object into a single property. It'll be
all the jar files separated by a platform path-separator.
Each path must be quoted if it contains spaces.
-->
<pathconvert property="project.all.classes.value" refid="project.all.classes.path">
<firstmatchmapper>
<regexpmapper from='^([^ ]*)( .*)$$' to='"\1\2"'/>
<identitymapper/>
</firstmatchmapper>
</pathconvert>
<!-- Turn the path property $proguard.config from an A:B:C property
into a series of includes: -include A -include B -include C
suitable for processing by the ProGuard task. Note - this does
not include the leading '-include "' or the closing '"'; those
are added under the <proguard> call below.
-->
<path id="proguard.configpath">
<pathelement path="$proguard.config"/>
</path>
<pathconvert pathsep='" -include "' property="proguard.configcmd" refid="proguard.configpath"/>
<!-- INSERT SOME MAVEN STORAGE DIR BELOW -->
<echo level="info">PROJECT.ALL.CLASSES.VALUE === $project.all.classes.value</echo>
<echo level="info">PROJECT.TARGET.CLASSPATH.VALUE === $project.target.classpath.value</echo>
<property name="project.all.classes.value2" value="$project.all.classes.value:/some-maven-dir"/>
<echo level="info">PROJECT.ALL.CLASSES.VALUE2 === $project.all.classes.value2</echo>
<mkdir dir="$obfuscate.absolute.dir" />
<delete file="$preobfuscate.jar.file"/>
<delete file="$obfuscated.jar.file"/>
<jar basedir="$out.classes.absolute.dir"
destfile="$preobfuscate.jar.file" />
<proguard>
-include "$proguard.configcmd"
-include "$out.absolute.dir/proguard.txt"
-injars $project.all.classes.value2
-outjars "$obfuscated.jar.file"
-libraryjars $project.target.classpath.value(!META-INF/MANIFEST.MF,!META-INF/NOTICE.txt,!META-INF/LICENSE.txt)
-dump "$obfuscate.absolute.dir/dump.txt"
-printseeds "$obfuscate.absolute.dir/seeds.txt"
-printusage "$obfuscate.absolute.dir/usage.txt"
-printmapping "$obfuscate.absolute.dir/mapping.txt"
-printconfiguration "$obfuscate.absolute.dir/used_config.txt"
</proguard>
</then>
</if>
</target>
另一种方法是仅在 jar 中临时复制(相同的技术用于不是 Android 库项目的常规 Java 项目依赖项):
<property name="lib.javalib1.project.dir" location="$basedir/../../some-maven-dir" />
<target name="-pre-build">
<subant buildpath="$lib.javalib1.project.dir" target="package" failonerror="true" />
<copy todir="$basedir/libs" failonerror="true" verbose="true">
<fileset dir="$lib.javalib1.project.dir/bin">
<filename name="general-api.jar"/>
</fileset>
</copy>
</target>
<target name="-post-package">
<delete verbose="true">
<fileset dir="$basedir/libs" includes="general-api.jar" />
</delete>
</target>
但是它会一个一个地编译jar并复制它们,所以对于已经有jar的Maven来说,这是一个劣势。
3。 Maven 目录
“/some-maven-dir”是存放jar的目录。
4。 Maven 自动化
在这里我无能为力,但我对第一部分提出了建议。也许有人可以继续这样做。
【讨论】:
以上是关于如何在android gradle构建文件中为从maven Central提取的库指定injars的主要内容,如果未能解决你的问题,请参考以下文章
构建 Gradle 时出现问题(无法创建任务 ':path_provider_android:generateDebugUnitTestConfig')。在颤振中为 android
如何在 build.gradle 中为不同的 productFlavors 定义 android:label
如何在intelliJ IDEA中为我现有的Kotlin项目生成build.gradle文件