7

有没有办法将从 maven Central 提取的库作为 proguard 的 injars 传递?我希望他们被混淆。上下文:使用 proguard for Android 删除未使用的类

4

2 回答 2

0

编辑:我现在看到了 Gradle 专门提出的问题。我的答案是针对 Ant,但它可能会给你一些想法。

完整的解决方案包括以下步骤:

  1. 创建自定义 build.xml
  2. 复制并修改“混淆”目标以使用 injars
  3. 使用 Maven 放置它们的目录中的 injars
  4. 自动化 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自动化

我在这里帮不上忙,但我对第一部分提出了建议。也许有人可以继续这样做。

于 2013-09-04T19:59:31.060 回答
0

我从未使用过 Maven,而我正在使用 Gradle,但无论是构建系统,我相信同样的事情适用。而且我不认为你想要的是可能的......

-injars关键字特定于 ProGuard 配置文件,它是构建工具读取的文本文件。

我看到的唯一方法是,如果您构建某种适合您的脚本。也就是说,读取所有 Maven 依赖项,创建适当的 ProGuard 配置文件,指定所有必需的 -injars 并将其传递给构建过程。不确定这对 Maven 有多可行。

Gradle 应该不会太难。使用 Gradle,您可以轻松传递多个 ProGuard 配置文件,您只需在build.gradle文件中创建一个方法来从依赖项中获取所有 .jar 文件位置,然后创建一个临时文本文件,然后将其传递到 ProGuard 配置中。

我会假设相同的过程适用于 Maven,但同样,我从未使用过它。

于 2013-08-27T17:19:38.857 回答