目录
  1. 1. 坑点

打包 iOS 导出 dSYM

像 Bugly 之类的 crash 上报平台都需要上传符号表才能看到具体的堆栈信息,而 iOS 上的符号和调试信息都是在 dSYM 文件中的。
UE 提供了 dSYM 的生成选项,在Project Settings-Platforms-iOS-Build

  • Generate dSYM file for code debugging and profiling:只开启这个会在 Binaries/IOS 下生成 PROJECT_NAME.dSYM 文件
  • Generate dSYM bundle for third party crash tools:依赖上面的选项,如果开启会在 Binaries/IOS 下生成 PROJECT_NAME.dSYM.zip,并且不会再生成PROJECT_NAME.dSYM 文件。

但是,在使用源码版打包 iOS 项目的时候生成的 dSYM 特别大,超过 2G,而同样的工程用 Luncher 引擎打包就只有 100+M,而且 bugly 之类的上传还有大小限制。

经过对比之后发现,大小的差距主要是在 _DWARF_debug_* 这些上(左侧为 Launcher 版,右侧为 DebugGame 源码版):

本来以为是源码版会把所有参与编译的代码都导出到 dSYM 文件中,但是经过翻阅引擎代码发现,其实 TargetRules 中有控制调试信息的选项,就是来控制产生这些 _DWARF_debug_* 的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// TargetRules.cs

/// <summary>
/// Whether to globally disable debug info generation; see DebugInfoHeuristics.cs for per-config and per-platform options.
/// </summary>
[CommandLine("-NoDebugInfo")]
[XmlConfigFile(Category = "BuildConfiguration")]
public bool bDisableDebugInfo = false;

/// <summary>
/// Whether to disable debug info generation for generated files. This improves link times for modules that have a lot of generated glue code.
/// </summary>
[XmlConfigFile(Category = "BuildConfiguration")]
public bool bDisableDebugInfoForGeneratedCode = false;

/// <summary>
/// Whether to disable debug info on PC in development builds (for faster developer iteration, as link times are extremely fast with debug info disabled).
/// </summary>
[XmlConfigFile(Category = "BuildConfiguration")]
public bool bOmitPCDebugInfoInDevelopment = false;

在项目的 Target.cs 中控制这些变量即可,如 bDisableDebugInfo=true,在源码版引擎中也不会生很大的_DWARF_debug 文件了(左侧为 Lunch 版引擎,右侧为 DebugGame 源码版控制bDisableDebugInfo=true):

而且,还发现 UE 在打包 IOS 平台的时候处理有问题,本来以为打 Shipping 生成的 dSYM 会没有调试信息了,但是测试发现还是非常大。

经过分析后发现,在 UE 的构建系统中是通过两个值来控制是否创建调试信息的:

1
2
3
4
5
6
// UEBuildPlatforms.cs

// Create debug info based on the heuristics specified by the user.
GlobalCompileEnvironment.bCreateDebugInfo =
!Target.bDisableDebugInfo && ShouldCreateDebugInfo(Target);
GlobalLinkEnvironment.bCreateDebugInfo = GlobalCompileEnvironment.bCreateDebugInfo;

可以看到是通过 Target.bDisableDebugInfoShouldCreateDebugInfo(Target)两个值来控制的,而 ShouldCreateDebugInfo 函数则是每个平台的有自己的重写实现。

如在 Windows 上:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// UnrealBuildTool/Platform/Windows/UEBuildWindows.cs

/// <summary>
/// Whether this platform should create debug information or not
/// </summary>
/// <param name="Target">The target being built</param>
/// <returns>bool true if debug info should be generated, false if not</returns>
public override bool ShouldCreateDebugInfo(ReadOnlyTargetRules Target)
{
switch (Target.Configuration)
{
case UnrealTargetConfiguration.Development:
case UnrealTargetConfiguration.Shipping:
case UnrealTargetConfiguration.Test:
return !Target.bOmitPCDebugInfoInDevelopment;
case UnrealTargetConfiguration.DebugGame:
case UnrealTargetConfiguration.Debug:
default:
return true;
};
}

但是,在 IOS 和 Mac 上完全没有判断!

1
2
3
4
5
6
// UnrealBuildTool/Platform/IOS/UEBuildIOS.cs

public override bool ShouldCreateDebugInfo(ReadOnlyTargetRules Target)
{
return true;
}

这导致只能自己用 bDisableDebugInfo=true 来控制,太坑爹了。翻了代码才发现 bOmitPCDebugInfoInDevelopment 这个选项只在 PC 上有效:BuildConfigProperties.INT.udn#L85

坑点

根据上面的介绍,可以通过控制 bDisableDebugInfo=true 来生成体积较小的 dSYM,但这样有牵扯出来一个坑的问题:使用远程构建时dSYM 无法通过 UE 的构建系统传回本地。
查了下代码,没有什么比较方便的办法来控制从远程拷贝的文件,目前我使用 pscp 从远程拉取 dSYM 文件回本地。