7 votes

comment spécifier les injares pour proguard dans les fichiers de construction Android gradle pour les bibliothèques qui sont tirées de maven central

Existe-t-il un moyen de passer les bibliothèques tirées de maven central comme des injares pour proguard ? Je veux qu'elles soient obfusquées. Contexte : supprimer les classes inutilisées avec proguard pour Android

0voto

Ricardo Amaral Points 4362

Je n'ai jamais utilisé Maven et j'utilise Gradle, mais quel que soit le système de construction, la même chose s'applique je crois. Et je ne pense pas que ce que vous voulez soit possible...

El -injars Le mot-clé est spécifique au fichier de configuration ProGuard, qui est un fichier texte lu par les outils de construction.

Le seul moyen que je vois est que si vous construisez une sorte de script qui le fera pour vous. C'est-à-dire, lire toutes les dépendances Maven, créer le fichier de configuration ProGuard approprié spécifiant toutes les -injars requises et le passer au processus de construction. Pas sûr que ce soit faisable avec Maven.

Cela ne devrait pas être trop difficile avec Gradle. Avec Gradle, vous pouvez facilement passer plusieurs fichiers de configuration ProGuard et vous pourriez simplement créer une méthode dans la section build.gradle pour obtenir tous les emplacements des fichiers .jar des dépendances et créer un fichier texte temporaire que vous passerez ensuite dans la configuration de ProGuard.

Je suppose que le même processus fonctionnerait avec Maven, mais là encore, je ne l'ai jamais utilisé.

0voto

pjv Points 4527

EDIT : Je vois maintenant que la question demandait spécifiquement Gradle. Ma réponse est pour Ant, mais elle pourrait vous donner des idées.

Une solution complète implique les étapes suivantes :

  1. Créer un build.xml personnalisé
  2. Copiez et modifiez la cible "obfuscate" pour utiliser les injars.
  3. Utiliser les injars d'un répertoire où Maven les place
  4. Automatiser Maven pour mettre les jars dans un répertoire. Et c'est là que je suis perdu. Pas assez d'expérience avec gradle/maven.

Les étapes en détail :

1. Fichier build.xml personnalisé

Dans le build.xml, mettez "custom", comme tel :

<!-- version-tag: custom -->
<import file="${sdk.dir}/tools/ant/build.xml" />

Avant cette partie, insérez le code ci-dessous, ou mettez-le dans un fichier séparé (general-build.xml) et importez-le dans build.xml.

2. Cible

Insérez ce qui suit :

<!-- 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> 

Une autre façon de procéder est de copier dans les jars uniquement de façon temporaire (la même technique est utilisée pour les dépendances de projets Java ordinaires qui ne sont pas des projets de bibliothèques Android) :

<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>

Mais il compile les jars un par un et les copie, donc pour Maven, où les jars sont déjà disponibles, c'est un inconvénient.

3. Répertoire Maven

"/some-maven-dir" est un répertoire où sont stockés les jars.

4. Automatisation de Maven

Je ne peux pas aider ici, mais j'ai fait une suggestion pour la première partie. Peut-être que quelqu'un peut continuer avec ça.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X