Swift WHOLE_MODULE_OPTIMIZATION 改进了编译时间,但导致 lldb/Xcode 崩溃
Swift WHOLE_MODULE_OPTIMIZATION improves compile time, but causes lldb/Xcode crash
TL;DR
之前
SWIFT_WHOLE_MODULE_OPTIMIZATION = NO
- 调试编译需要10-15分钟
- 发布编译需要 25 分钟以上
po
在 LLDB 中工作正常
之后
SWIFT_WHOLE_MODULE_OPTIMIZATION = YES
- 调试编译需要1-2分钟
- 发布编译大约需要 8 分钟
po
总是 导致 Xcode 崩溃
知道为什么基于此信息的编译时间很糟糕,and/or 为什么 Xcode 可能会崩溃?
迪茨
我正在从事一个大型 100% Swift 项目(Objective-C 中有第 3 方库,但我们所有的代码都是 Swift)。我们的编译时间一直很糟糕,编译调试配置通常需要 10-15 分钟,编译发布配置需要 30 多分钟。
由于可怕的编译时间,这个项目很难处理。我一直在寻找改善这一点的方法,特别是通过构建设置,但几个月来都没有运气。我忽略的一件事是 SWIFT_WHOLE_MODULE_OPTIMIZATION
,特别是因为任何提及它都声称它会增加项目的编译时间。
所以前几天我们启用了 SWIFT_WHOLE_MODULE_OPTIMIZATION
,你瞧,我们的编译时间提高了 10 倍。
问题是,现在每当我们调试项目并尝试使用 po myObject
Xcode 在 lldb 中打印对象时,都会立即崩溃。以下是崩溃日志中的一些信息:
Process: Xcode [5860]
Path: /Applications/Xcode.app/Contents/MacOS/Xcode
Identifier: com.apple.dt.Xcode
Version: 6.4 (7720)
Build Info: IDEFrameworks-7720000000000000~8
App Item ID: 497799835
App External ID: 812725084
Code Type: X86-64 (Native)
Parent Process: ??? [1]
Responsible: Xcode [5860]
Date/Time: 2015-08-05 15:53:08.265 -0600
OS Version: Mac OS X 10.11 (15A235d)
Report Version: 11
Time Awake Since Boot: 13000 seconds
Crashed Thread: 20
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x000000000000008f
Exception Note: EXC_CORPSE_NOTIFY
VM Regions Near 0x8f:
-->
__TEXT 000000010ef62000-000000010ef63000 [ 4K] r-x/rwx SM=COW /Applications/Xcode.app/Contents/MacOS/Xcode
Application Specific Information:
ProductBuildVersion: 6E35b
这是崩溃线程的堆栈跟踪:
Thread 20 Crashed:: <DBGLLDBSessionThread (pid=6402)>
0 com.apple.LLDB.framework 0x0000000116b09ab4 swift::ArchetypeBuilder::resolveArchetype(swift::Type) + 68
1 com.apple.LLDB.framework 0x0000000116b0f808 std::__1::__function::__func<substConcreteTypesForDependentTypes(swift::ArchetypeBuilder&, swift::Type)::$_6, std::__1::allocator<substConcreteTypesForDependentTypes(swift::ArchetypeBuilder&, swift::Type)::$_6>, swift::Type (swift::Type)>::operator()(swift::Type&&) + 152
2 com.apple.LLDB.framework 0x0000000116bc0986 swift::Type::transform(std::__1::function<swift::Type (swift::Type)> const&) const + 54
3 com.apple.LLDB.framework 0x0000000116bc0f2b swift::Type::transform(std::__1::function<swift::Type (swift::Type)> const&) const + 1499
4 com.apple.LLDB.framework 0x0000000116bc0bbb swift::Type::transform(std::__1::function<swift::Type (swift::Type)> const&) const + 619
5 com.apple.LLDB.framework 0x0000000116bc0c0a swift::Type::transform(std::__1::function<swift::Type (swift::Type)> const&) const + 698
6 com.apple.LLDB.framework 0x0000000116b0c8f2 swift::ArchetypeBuilder::substDependentType(swift::Type) + 50
7 com.apple.LLDB.framework 0x0000000116e9554e (anonymous namespace)::LowerType::visitAnyStructType(swift::CanType, swift::StructDecl*) + 270
8 com.apple.LLDB.framework 0x0000000116e92e66 swift::Lowering::TypeConverter::getTypeLoweringForUncachedLoweredType(swift::Lowering::TypeConverter::TypeKey) + 150
9 com.apple.LLDB.framework 0x0000000116e92b39 swift::Lowering::TypeConverter::getTypeLowering(swift::Lowering::AbstractionPattern, swift::Type, unsigned int) + 2361
10 com.apple.LLDB.framework 0x0000000116f8f711 lldb_private::SwiftSILManipulator::emitLValueForVariable(swift::VarDecl*, lldb_private::SwiftExpressionParser::SILVariableInfo&) + 1521
11 com.apple.LLDB.framework 0x00000001172ac7ee (anonymous namespace)::LLDBNameLookup::emitLValueForVariable(swift::VarDecl*, swift::SILBuilder&) + 102
12 com.apple.LLDB.framework 0x0000000116ebb162 swift::Lowering::SILGenFunction::emitInitializationForVarDecl(swift::VarDecl*, swift::Type) + 98
13 com.apple.LLDB.framework 0x0000000116ebbc74 swift::ASTVisitor<(anonymous namespace)::InitializationForPattern, void, void, void, std::__1::unique_ptr<swift::Lowering::Initialization, std::__1::default_delete<swift::Lowering::Initialization> >, void, void>::visit(swift::Pattern*) + 404
14 com.apple.LLDB.framework 0x0000000116ebbc57 swift::ASTVisitor<(anonymous namespace)::InitializationForPattern, void, void, void, std::__1::unique_ptr<swift::Lowering::Initialization, std::__1::default_delete<swift::Lowering::Initialization> >, void, void>::visit(swift::Pattern*) + 375
15 com.apple.LLDB.framework 0x0000000116ebba0d swift::Lowering::SILGenFunction::visitPatternBindingDecl(swift::PatternBindingDecl*) + 45
16 com.apple.LLDB.framework 0x0000000116f0617c swift::Lowering::SILGenFunction::visitBraceStmt(swift::BraceStmt*) + 284
17 com.apple.LLDB.framework 0x0000000116ecd1c0 swift::Lowering::SILGenFunction::emitFunction(swift::FuncDecl*) + 320
18 com.apple.LLDB.framework 0x0000000116ea3966 swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*) + 246
19 com.apple.LLDB.framework 0x0000000116ea3828 swift::Lowering::SILGenModule::visitFuncDecl(swift::FuncDecl*) + 168
20 com.apple.LLDB.framework 0x0000000116ea579b swift::Lowering::SILGenModule::emitSourceFile(swift::SourceFile*, unsigned int) + 427
21 com.apple.LLDB.framework 0x0000000116ea5c22 swift::SILModule::constructSIL(swift::Module*, swift::SILOptions&, swift::SourceFile*, llvm::Optional<unsigned int>, bool, bool) + 386
22 com.apple.LLDB.framework 0x0000000116ea5d42 swift::performSILGeneration(swift::SourceFile&, swift::SILOptions&, llvm::Optional<unsigned int>, bool) + 98
23 com.apple.LLDB.framework 0x00000001172aa617 lldb_private::SwiftExpressionParser::Parse(lldb_private::Stream&, unsigned int, unsigned int, unsigned int) + 10715
24 com.apple.LLDB.framework 0x000000011706b3e8 lldb_private::ClangUserExpression::Parse(lldb_private::Stream&, lldb_private::ExecutionContext&, lldb_private::ExecutionPolicy, bool, unsigned int) + 1064
25 com.apple.LLDB.framework 0x000000011706cdb4 lldb_private::ClangUserExpression::Evaluate(lldb_private::ExecutionContext&, lldb_private::EvaluateExpressionOptions const&, char const*, char const*, lldb_private::SharingPtr<lldb_private::ValueObject>&, lldb_private::Error&, unsigned int, std::__1::shared_ptr<lldb_private::Module>*) + 628
26 com.apple.LLDB.framework 0x00000001171d1696 lldb_private::Target::EvaluateExpression(char const*, lldb_private::StackFrame*, lldb_private::SharingPtr<lldb_private::ValueObject>&, lldb_private::EvaluateExpressionOptions const&) + 376
27 com.apple.LLDB.framework 0x000000011716d75c lldb_private::SwiftLanguageRuntime::GetObjectDescription(lldb_private::Stream&, lldb_private::ValueObject&) + 668
28 com.apple.LLDB.framework 0x00000001170464e6 lldb_private::ValueObject::GetObjectDescription() + 370
29 com.apple.LLDB.framework 0x000000011548e228 lldb::SBValue::GetObjectDescription() + 76
30 com.apple.dt.dbg.DebuggerLLDB 0x00000001153f3c9e -[DBGLLDBDataValue _lldbValueObjectDescription] + 24
31 com.apple.dt.dbg.DebuggerLLDB 0x00000001153f3b7f -[DBGLLDBDataValue lldbDescription] + 29
32 com.apple.dt.dbg.DebuggerLLDB 0x00000001154023dc __87-[DBGLLDBSession printDescriptionOfDataValueToConsole:runAllThreads:completionHandler:]_block_invoke + 182
33 com.apple.dt.dbg.DebuggerLLDB 0x0000000115402e6d -[DBGLLDBSession handleNextActionWithState:withRunPending:] + 424
34 com.apple.dt.dbg.DebuggerLLDB 0x00000001153fdf44 DBGLLDBSessionThread(void*) + 980
35 libsystem_pthread.dylib 0x00007fff8ec12cb3 _pthread_body + 131
36 libsystem_pthread.dylib 0x00007fff8ec12c30 _pthread_start + 168
37 libsystem_pthread.dylib 0x00007fff8ec10419 thread_start + 13
似乎我们可能处于新技术的最前沿,因为我在这个问题上还没有找到太多帮助。我想知道我们是否有某种导致编译时问题的异常配置,或者是否有已知原因导致 lldb 崩溃。在多台不同的机器上都是一样的,El Capitan,Yosemite,Xcode 6.3,Xcode 6.4。感谢您的帮助!
我已经工作并且正在积极从事可能比您的项目更大的项目(50 多个库,数百个自定义 类 和数千个 LoC)。编译需要几秒钟,发布构建(2013 年末 MBP)最多需要 2 分钟,即使对于完整的 Swift 项目也是如此。
我强烈建议您查找其他原因,因为此选项告诉您您的问题出在其他地方,因为它会影响应用程序性能,而不是构建速度。也许您的 .pch 文件中充满了不属于那里的东西或其他东西,它可能会导致这种速度变慢。
另一个有趣的事情是推理的使用。我个人为每个变量声明类型只是因为它更容易为其他人阅读,但还有更多。由于推理可能会变得复杂,它可能会导致编译器花费大量时间来弄清楚您的代码实际做了什么。 Read this example article,尽管它更像是 alpha 问题。但是也许,只是也许,您的代码中也有类似的东西。值得做的是尝试删除所有 swift 代码,编译库,如果它运行良好,那么你就知道问题出在你的 swift 代码中,它可能与此有关。
此外,如果您提供的是什么实际上会减慢您的构建时间(因为您可以看到带有时间戳的整个构建过程,而且很可能一个步骤永远都需要),它可以帮助更准确地查明问题。
希望对您有所帮助!
编辑:Another article 关于这个感兴趣的话题
我设法在我们的项目中解决了这个问题。 (总编译时间 12 分钟)
关键是按照你在user defined
设置中所说的设置SWIFT_WHOLE_MODULE_OPTIMIZATION = YES
但是你还需要做一项改变。您需要在调试中将优化级别设置为 None
否则您将无法调试您的应用程序。
我在这里写了一篇博客post:
https://tech.zalando.com/blog/improving-swift-compilation-times-from-12-to-2-minutes/
TL;DR
之前
SWIFT_WHOLE_MODULE_OPTIMIZATION = NO
- 调试编译需要10-15分钟
- 发布编译需要 25 分钟以上
po
在 LLDB 中工作正常
之后
SWIFT_WHOLE_MODULE_OPTIMIZATION = YES
- 调试编译需要1-2分钟
- 发布编译大约需要 8 分钟
po
总是 导致 Xcode 崩溃
知道为什么基于此信息的编译时间很糟糕,and/or 为什么 Xcode 可能会崩溃?
迪茨
我正在从事一个大型 100% Swift 项目(Objective-C 中有第 3 方库,但我们所有的代码都是 Swift)。我们的编译时间一直很糟糕,编译调试配置通常需要 10-15 分钟,编译发布配置需要 30 多分钟。
由于可怕的编译时间,这个项目很难处理。我一直在寻找改善这一点的方法,特别是通过构建设置,但几个月来都没有运气。我忽略的一件事是 SWIFT_WHOLE_MODULE_OPTIMIZATION
,特别是因为任何提及它都声称它会增加项目的编译时间。
所以前几天我们启用了 SWIFT_WHOLE_MODULE_OPTIMIZATION
,你瞧,我们的编译时间提高了 10 倍。
问题是,现在每当我们调试项目并尝试使用 po myObject
Xcode 在 lldb 中打印对象时,都会立即崩溃。以下是崩溃日志中的一些信息:
Process: Xcode [5860]
Path: /Applications/Xcode.app/Contents/MacOS/Xcode
Identifier: com.apple.dt.Xcode
Version: 6.4 (7720)
Build Info: IDEFrameworks-7720000000000000~8
App Item ID: 497799835
App External ID: 812725084
Code Type: X86-64 (Native)
Parent Process: ??? [1]
Responsible: Xcode [5860]Date/Time: 2015-08-05 15:53:08.265 -0600
OS Version: Mac OS X 10.11 (15A235d)
Report Version: 11Time Awake Since Boot: 13000 seconds
Crashed Thread: 20
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x000000000000008f
Exception Note: EXC_CORPSE_NOTIFYVM Regions Near 0x8f: --> __TEXT 000000010ef62000-000000010ef63000 [ 4K] r-x/rwx SM=COW /Applications/Xcode.app/Contents/MacOS/Xcode
Application Specific Information:
ProductBuildVersion: 6E35b
这是崩溃线程的堆栈跟踪:
Thread 20 Crashed:: <DBGLLDBSessionThread (pid=6402)>
0 com.apple.LLDB.framework 0x0000000116b09ab4 swift::ArchetypeBuilder::resolveArchetype(swift::Type) + 68
1 com.apple.LLDB.framework 0x0000000116b0f808 std::__1::__function::__func<substConcreteTypesForDependentTypes(swift::ArchetypeBuilder&, swift::Type)::$_6, std::__1::allocator<substConcreteTypesForDependentTypes(swift::ArchetypeBuilder&, swift::Type)::$_6>, swift::Type (swift::Type)>::operator()(swift::Type&&) + 152
2 com.apple.LLDB.framework 0x0000000116bc0986 swift::Type::transform(std::__1::function<swift::Type (swift::Type)> const&) const + 54
3 com.apple.LLDB.framework 0x0000000116bc0f2b swift::Type::transform(std::__1::function<swift::Type (swift::Type)> const&) const + 1499
4 com.apple.LLDB.framework 0x0000000116bc0bbb swift::Type::transform(std::__1::function<swift::Type (swift::Type)> const&) const + 619
5 com.apple.LLDB.framework 0x0000000116bc0c0a swift::Type::transform(std::__1::function<swift::Type (swift::Type)> const&) const + 698
6 com.apple.LLDB.framework 0x0000000116b0c8f2 swift::ArchetypeBuilder::substDependentType(swift::Type) + 50
7 com.apple.LLDB.framework 0x0000000116e9554e (anonymous namespace)::LowerType::visitAnyStructType(swift::CanType, swift::StructDecl*) + 270
8 com.apple.LLDB.framework 0x0000000116e92e66 swift::Lowering::TypeConverter::getTypeLoweringForUncachedLoweredType(swift::Lowering::TypeConverter::TypeKey) + 150
9 com.apple.LLDB.framework 0x0000000116e92b39 swift::Lowering::TypeConverter::getTypeLowering(swift::Lowering::AbstractionPattern, swift::Type, unsigned int) + 2361
10 com.apple.LLDB.framework 0x0000000116f8f711 lldb_private::SwiftSILManipulator::emitLValueForVariable(swift::VarDecl*, lldb_private::SwiftExpressionParser::SILVariableInfo&) + 1521
11 com.apple.LLDB.framework 0x00000001172ac7ee (anonymous namespace)::LLDBNameLookup::emitLValueForVariable(swift::VarDecl*, swift::SILBuilder&) + 102
12 com.apple.LLDB.framework 0x0000000116ebb162 swift::Lowering::SILGenFunction::emitInitializationForVarDecl(swift::VarDecl*, swift::Type) + 98
13 com.apple.LLDB.framework 0x0000000116ebbc74 swift::ASTVisitor<(anonymous namespace)::InitializationForPattern, void, void, void, std::__1::unique_ptr<swift::Lowering::Initialization, std::__1::default_delete<swift::Lowering::Initialization> >, void, void>::visit(swift::Pattern*) + 404
14 com.apple.LLDB.framework 0x0000000116ebbc57 swift::ASTVisitor<(anonymous namespace)::InitializationForPattern, void, void, void, std::__1::unique_ptr<swift::Lowering::Initialization, std::__1::default_delete<swift::Lowering::Initialization> >, void, void>::visit(swift::Pattern*) + 375
15 com.apple.LLDB.framework 0x0000000116ebba0d swift::Lowering::SILGenFunction::visitPatternBindingDecl(swift::PatternBindingDecl*) + 45
16 com.apple.LLDB.framework 0x0000000116f0617c swift::Lowering::SILGenFunction::visitBraceStmt(swift::BraceStmt*) + 284
17 com.apple.LLDB.framework 0x0000000116ecd1c0 swift::Lowering::SILGenFunction::emitFunction(swift::FuncDecl*) + 320
18 com.apple.LLDB.framework 0x0000000116ea3966 swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*) + 246
19 com.apple.LLDB.framework 0x0000000116ea3828 swift::Lowering::SILGenModule::visitFuncDecl(swift::FuncDecl*) + 168
20 com.apple.LLDB.framework 0x0000000116ea579b swift::Lowering::SILGenModule::emitSourceFile(swift::SourceFile*, unsigned int) + 427
21 com.apple.LLDB.framework 0x0000000116ea5c22 swift::SILModule::constructSIL(swift::Module*, swift::SILOptions&, swift::SourceFile*, llvm::Optional<unsigned int>, bool, bool) + 386
22 com.apple.LLDB.framework 0x0000000116ea5d42 swift::performSILGeneration(swift::SourceFile&, swift::SILOptions&, llvm::Optional<unsigned int>, bool) + 98
23 com.apple.LLDB.framework 0x00000001172aa617 lldb_private::SwiftExpressionParser::Parse(lldb_private::Stream&, unsigned int, unsigned int, unsigned int) + 10715
24 com.apple.LLDB.framework 0x000000011706b3e8 lldb_private::ClangUserExpression::Parse(lldb_private::Stream&, lldb_private::ExecutionContext&, lldb_private::ExecutionPolicy, bool, unsigned int) + 1064
25 com.apple.LLDB.framework 0x000000011706cdb4 lldb_private::ClangUserExpression::Evaluate(lldb_private::ExecutionContext&, lldb_private::EvaluateExpressionOptions const&, char const*, char const*, lldb_private::SharingPtr<lldb_private::ValueObject>&, lldb_private::Error&, unsigned int, std::__1::shared_ptr<lldb_private::Module>*) + 628
26 com.apple.LLDB.framework 0x00000001171d1696 lldb_private::Target::EvaluateExpression(char const*, lldb_private::StackFrame*, lldb_private::SharingPtr<lldb_private::ValueObject>&, lldb_private::EvaluateExpressionOptions const&) + 376
27 com.apple.LLDB.framework 0x000000011716d75c lldb_private::SwiftLanguageRuntime::GetObjectDescription(lldb_private::Stream&, lldb_private::ValueObject&) + 668
28 com.apple.LLDB.framework 0x00000001170464e6 lldb_private::ValueObject::GetObjectDescription() + 370
29 com.apple.LLDB.framework 0x000000011548e228 lldb::SBValue::GetObjectDescription() + 76
30 com.apple.dt.dbg.DebuggerLLDB 0x00000001153f3c9e -[DBGLLDBDataValue _lldbValueObjectDescription] + 24
31 com.apple.dt.dbg.DebuggerLLDB 0x00000001153f3b7f -[DBGLLDBDataValue lldbDescription] + 29
32 com.apple.dt.dbg.DebuggerLLDB 0x00000001154023dc __87-[DBGLLDBSession printDescriptionOfDataValueToConsole:runAllThreads:completionHandler:]_block_invoke + 182
33 com.apple.dt.dbg.DebuggerLLDB 0x0000000115402e6d -[DBGLLDBSession handleNextActionWithState:withRunPending:] + 424
34 com.apple.dt.dbg.DebuggerLLDB 0x00000001153fdf44 DBGLLDBSessionThread(void*) + 980
35 libsystem_pthread.dylib 0x00007fff8ec12cb3 _pthread_body + 131
36 libsystem_pthread.dylib 0x00007fff8ec12c30 _pthread_start + 168
37 libsystem_pthread.dylib 0x00007fff8ec10419 thread_start + 13
似乎我们可能处于新技术的最前沿,因为我在这个问题上还没有找到太多帮助。我想知道我们是否有某种导致编译时问题的异常配置,或者是否有已知原因导致 lldb 崩溃。在多台不同的机器上都是一样的,El Capitan,Yosemite,Xcode 6.3,Xcode 6.4。感谢您的帮助!
我已经工作并且正在积极从事可能比您的项目更大的项目(50 多个库,数百个自定义 类 和数千个 LoC)。编译需要几秒钟,发布构建(2013 年末 MBP)最多需要 2 分钟,即使对于完整的 Swift 项目也是如此。
我强烈建议您查找其他原因,因为此选项告诉您您的问题出在其他地方,因为它会影响应用程序性能,而不是构建速度。也许您的 .pch 文件中充满了不属于那里的东西或其他东西,它可能会导致这种速度变慢。
另一个有趣的事情是推理的使用。我个人为每个变量声明类型只是因为它更容易为其他人阅读,但还有更多。由于推理可能会变得复杂,它可能会导致编译器花费大量时间来弄清楚您的代码实际做了什么。 Read this example article,尽管它更像是 alpha 问题。但是也许,只是也许,您的代码中也有类似的东西。值得做的是尝试删除所有 swift 代码,编译库,如果它运行良好,那么你就知道问题出在你的 swift 代码中,它可能与此有关。
此外,如果您提供的是什么实际上会减慢您的构建时间(因为您可以看到带有时间戳的整个构建过程,而且很可能一个步骤永远都需要),它可以帮助更准确地查明问题。
希望对您有所帮助!
编辑:Another article 关于这个感兴趣的话题
我设法在我们的项目中解决了这个问题。 (总编译时间 12 分钟)
关键是按照你在user defined
设置中所说的设置SWIFT_WHOLE_MODULE_OPTIMIZATION = YES
但是你还需要做一项改变。您需要在调试中将优化级别设置为 None
否则您将无法调试您的应用程序。
我在这里写了一篇博客post:
https://tech.zalando.com/blog/improving-swift-compilation-times-from-12-to-2-minutes/