有没有办法将从 maven Central 提取的库作为 proguard 的 injars 传递?我希望他们被混淆。上下文:使用 proguard for Android 删除未使用的类
2 回答
编辑:我现在看到了 Gradle 专门提出的问题。我的答案是针对 Ant,但它可能会给你一些想法。
完整的解决方案包括以下步骤:
- 创建自定义 build.xml
- 复制并修改“混淆”目标以使用 injars
- 使用 Maven 放置它们的目录中的 injars
- 自动化 Maven 以将 jars 放入目录中。这就是我迷路的地方。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自动化
我在这里帮不上忙,但我对第一部分提出了建议。也许有人可以继续这样做。
我从未使用过 Maven,而我正在使用 Gradle,但无论是构建系统,我相信同样的事情适用。而且我不认为你想要的是可能的......
该-injars
关键字特定于 ProGuard 配置文件,它是构建工具读取的文本文件。
我看到的唯一方法是,如果您构建某种适合您的脚本。也就是说,读取所有 Maven 依赖项,创建适当的 ProGuard 配置文件,指定所有必需的 -injars 并将其传递给构建过程。不确定这对 Maven 有多可行。
Gradle 应该不会太难。使用 Gradle,您可以轻松传递多个 ProGuard 配置文件,您只需在build.gradle
文件中创建一个方法来从依赖项中获取所有 .jar 文件位置,然后创建一个临时文本文件,然后将其传递到 ProGuard 配置中。
我会假设相同的过程适用于 Maven,但同样,我从未使用过它。