如果源没有更改,Proguard 是不是保证提供相同的映射?

Posted

技术标签:

【中文标题】如果源没有更改,Proguard 是不是保证提供相同的映射?【英文标题】:Does Proguard guarantee to provide the same mapping if no source has changed?如果源没有更改,Proguard 是否保证提供相同的映射? 【发布时间】:2012-11-16 19:54:05 【问题描述】:

如果我愿意的话

建立一个项目 清理所有二进制文件 再次构建它(没有源/资源等已更改)。

Proguard 是否保证提供相同的 mapping.txt 文件?

【问题讨论】:

我想它会产生相同的输出(因此使用相同的映射)-除非有一个 RNG 在玩 ;-) 鉴于输入没有变化(包括任何 RNG),那么输出应该是相同的..考虑一个 md5sum 来快速“点头或摇晃”这种断言。然而,由于来源经常变化,这确实不是最有用的问题。 【参考方案1】:

ProGuard 是确定性的:对于相同的输入,它将生成相同的输出。

但是有一个微妙之处:如果操作系统以不同的顺序列出目录中的输入文件(特别是不在归档中的类文件),那么它们可能会以不同的顺序进行处理,并且输出可以是不同。

【讨论】:

ProGuard 手册中哪里写到它是确定性的?我找不到任何相关参考。 @Diego 我是 ProGuard 的开发者;这个你必须相信我,或者你可以看看源代码。 谢谢,@Eric,我忘记了 mapping.txt 的版本,也想知道这个。 @EricLafortune 能否修复此问题,以便 ProGuard 在所有操作系统中完全确定? @EricLafortune 这是否也适用于 Proguard 的代码删除部分?如果“文件顺序”受到最初不会被保护的文件的添加影响,这是否也适用?【参考方案2】:

这可能真的会发生,但我认为 proguard 不能保证这一点。

我在Proguard documentation 中发现了这一点,这将允许您重用您的 mapping.txt 以避免更改映射

-应用映射文件名

指定重用在之前的 ProGuard 混淆运行中打印出的给定名称映射。映射文件中列出的类和类成员接收与其一起指定的名称。未提及的类和类成员将获得新名称。映射可以引用输入类以及库类。此选项可用于增量混淆,即处理现有代码的附加组件或小补丁。如果代码结构发生根本性变化,ProGuard 可能会打印出应用映射导致冲突的警告。您可以通过在两次混淆运行中指定选项 -useuniqueclassmembernames 来降低这种风险。只允许一个映射文件。仅在混淆时适用。

【讨论】:

【参考方案3】:

如果您想要保证,那么您必须使用映射文件作为混淆过程的输入。但是,您必须仔细检查与该映射文件相关的所有冲突警告。如果忽略这一点,在使用反射时可能会出现细微的错误。

【讨论】:

以上是关于如果源没有更改,Proguard 是不是保证提供相同的映射?的主要内容,如果未能解决你的问题,请参考以下文章

加密是否保证完整性?

Android R8(Proguard) 参数名称已更改(我不想更改我的参数名称)

在混淆时我是不是需要在 proguard 规则中“保持” Parcelable

我怎样才能告诉 proguard 假设一个包没有被使用?

ADT R22 - Proguard - 找不到引用的类

proguard 是不是将所有枚举转换为 int 或需要为此配置