Your SlideShare is downloading. ×
Advanced iOS Build Mechanics, Sebastien Pouliot
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Advanced iOS Build Mechanics, Sebastien Pouliot

803
views

Published on

Published in: Technology, Business

0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
803
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
0
Comments
0
Likes
2
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Sébastien PouliotSo!ware DeveloperXamarinsebastien@xamarin.comAdvanced iOS build mechanicsImproving performance andreducing executable size
  • 2. Why Should You Care?Quicker BuildsSmaller ApplicationsFaster Applications
  • 3. Prime Directive:Time Everything - Often
  • 4. Best Default Worse147227196How Much Time? Field Service SampleBuild Time (Debug) Deploy TimeBest Default Worse3716141694916Simulator Devices
  • 5. Building for the iOS Simulator.dllC#.exe+ =.appaddinmtouch•Resolve•Package•Embed  mono•Deploy?
  • 6. Simulator vs Emulator• Speed Over Compatibility• Apple Simulator TradeoffsSimpler, less restrictive environment• Xamarin Simulator TradeoffsJust In Time (JIT) compilerMinimize files copying (symlinks)Shared application launcher
  • 7. Simulator : What to Do?bestdefault 72196 Build TimeDeploy Time• BuildAvoid optimizing PNG files• DeployKeep the simulator running
  • 8. Simulator : What to Avoid?bestworse 142276 Build TimeDeploy Time• BuildEnabling the linkerDisabling the shared launcher -­‐-­‐nofastsim• DeployUp to 12 seconds to cold start
  • 9. Simulator : Extra Tips• Prefer Build over Rebuild• Avoid copying filesAccess them from a single locationThe sandbox is not enforced• Use -­‐time  -­‐time to measure your changes
  • 10. -­‐time  -­‐time
  • 11. Building for iOS Devices•Resolve•Global  Op8miza8ons•AOT  Compila8on•Na8ve  Compila8on•Na8ve  Linking•Copy  files•Op8mize  PNG•En8tlements•Code  sign•IPA•Symbols  (DWARF)•Stripping  (symbols)•Stripping  (IL)•Packaging•Deployment.dllC#.exe+ =? .app
  • 12. Building for iOS Devicesaddin mtouch•  Resolve•  Managed  Linking•  AOT  Compila8on•  Na8ve  Compila8on•  Na8ve  Linking•  Symbols  (DWARF)•  Copy  files•  Op8mize  PNG•  Provisioning•  En8tlements•  Code  sign•  IPA•  Stripping•  Registrar•  IL  Removal•  Packaging•  Deploy  apps•  Install  apps.dllC#.exe+ =.app
  • 13. Devices : Build Configurations• Debug : Keep it quick• Release : Focus on performanceLLVM Optimizing CompilerOptimize PNG files• Ad-Hoc / AppStore : No tweaks!
  • 14. Build & Deploy Symbiosis• Deployment time is a function of the app size• Application size versus build time?• Link SDK is default for devices
  • 15. Devices : What to Do?bestdefault 16144916 Build TimeDeploy Time• BuildAvoid optimizing PNG files (debug)• ConsiderLinking all assemblies --linkallDisabling the symbols creation --dsym=false
  • 16. Devices : What to Avoid?bestworse 371416916 Build TimeDeploy Time• FAT binaries (debug)• Disabling the linker --nolink• Disabling strippingSymbols --nosymbolstripIL (release) --nostrip
  • 17. Devices : Extra Tips• Prefer Build over RebuildAOT’ed assemblies (object files) are cached• Avoid deploying large static files (debug)Use UIFileSharingEnabled (Info.plist)• Use -­‐time  -­‐time to measure your changes
  • 18. -­‐time  -­‐time -­‐dsym=false
  • 19. Beyond Build Tips
  • 20. It’s a Matter of Time and SizeDon’t LinkLink SDKLink All 91020212389Build Time Deploy Time48.6 MB11.5 MB10.9 MBField  Service  Sample  Applica8on**  Release  build,  LLVM,  ARMv7
  • 21. 01020304050607080910111213141516Static Analysis Limitations...using  FieldService.Utilities;#if  __iOS__using  MonoTouch.Foundation;  #elif  __ANDROID__using  Android.Runtime;#endifnamespace  FieldService.Data  {        ///  <summary>An  assignment  is  the  "thing"  or  "job"  the  user  is  going...#if  !MOBILE        [Preserve  (AllMembers  =  true)]#endif        public  class  Assignment  {                ...        }
  • 22. 01020304050607080910111213141516Static Analysis Limitations<!-­‐-­‐  add  `-­‐-­‐xml=field.service.xml`  to  your  project  options  -­‐-­‐><linker>        <assembly  fullname="FieldServiceiOS">                <type  fullname="FieldService.Data.Assignment"  />                <type  fullname="FieldService.Data.AssignmentHistory"  />                <type  fullname="FieldService.Data.AssignmentItem"  />                <type  fullname="FieldService.Data.Document"  />                <type  fullname="FieldService.Data.Expense"  />                <type  fullname="FieldService.Data.ExpensePhoto"  />                <type  fullname="FieldService.Data.Preserve"  />                <type  fullname="FieldService.Data.Labor"  />                <type  fullname="FieldService.Data.Photo"  />                <type  fullname="FieldService.Data.Signature"  />                <type  fullname="FieldService.Data.TimeEntry"  />        </assembly></linker>
  • 23. Partially Linking Applications• Link All and skip some assembliesNo source requirede.g. -­‐-­‐linkall  -­‐-­‐linkskip=FieldServiceiOS• Link SDK and use [LinkerSafe] attributeSource code required
  • 24. Objective-C Bindings• Cocos2d’s Jumpy saves 409 KB using[assembly:LinkerSafe]• Less [Export] means faster registration
  • 25. SmartLink• New option [LinkWith  (SmartLink=true)]and -­‐-­‐registrar=static• Helps the native linkerDropBox’s Sync samples drops by 325KB
  • 26. 01020304050607080910111213141516[Export  ("sizeToFit")]void  SizeToFit  ();[Export  ("sizeToFit")][CompilerGenerated]public  virtual  void  SizeToFit  (){        global::MonoTouch.UIKit.UIApplication.EnsureUIThread  ();        if  (IsDirectBinding)  {                Messaging.void_objc_msgSend  (this.Handle,                          Selector.GetHandle  ("sizeToFit"));        }  else  {                Messaging.void_objc_msgSendSuper  (this.SuperHandle,                          Selector.GetHandle  ("sizeToFit"));        }}Automatic Bindings Optimizations[Export  ("sizeToFit")]void  SizeToFit  ();[Export  ("sizeToFit")][CompilerGenerated]public  virtual  void  SizeToFit  (){        global::MonoTouch.UIKit.UIApplication.EnsureUIThread  ();        if  (IsDirectBinding)  {                Messaging.void_objc_msgSend  (this.Handle,                          Selector.GetHandle  ("sizeToFit"));        }  else  {                Messaging.void_objc_msgSendSuper  (this.SuperHandle,                          Selector.GetHandle  ("sizeToFit"));        }}
  • 27. 01020304050607080910111213141516System.Drawing.SizeF  ret;if  (IsDirectBinding)  {        if  (Runtime.Arch  ==  Arch.DEVICE)  {                  Messaging.SizeF_objc_msgSend_stret  (out  ret,  this.Handle,  ...        }  else  {           ret  =  Messaging.SizeF_objc_msgSend  (this.Handle,  ...        }}  else  {        if  (Runtime.Arch  ==  Arch.DEVICE)  {                Messaging.SizeF_objc_msgSendSuper_stret  (out  ret,  ...        }  else  {                ret  =  Messaging.SizeF_objc_msgSendSuper  (this.SuperHandle,  ...        }}return  ret;Automatic Bindings OptimizationsSystem.Drawing.SizeF  ret;if  (IsDirectBinding)  {        if  (Runtime.Arch  ==  Arch.DEVICE)  {                  Messaging.SizeF_objc_msgSend_stret  (out  ret,  this.Handle,  ...        }  else  {           ret  =  Messaging.SizeF_objc_msgSend  (this.Handle,  ...        }}  else  {        if  (Runtime.Arch  ==  Arch.DEVICE)  {                Messaging.SizeF_objc_msgSendSuper_stret  (out  ret,  ...        }  else  {                ret  =  Messaging.SizeF_objc_msgSendSuper  (this.SuperHandle,  ...        }}return  ret;
  • 28. 01020304050607080910111213141516Automatic Bindings Optimizationsobject  __mt_RootViewController_var;[CompilerGenerated]public  virtual  UIViewController  RootViewController  {     [Export  ("rootViewController",  ArgumentSemantic.Retain)]     get  {         global::MonoTouch.UIKit.UIApplication.EnsureUIThread  ();         UIViewController  ret;         if  (IsDirectBinding)  {           ret  =  (UIViewController)  Runtime.GetNSObject  (...  msgSend  ...);           }  else  {           ret  =  (UIViewController)  Runtime.GetNSObject  (...  msgSendSuper  ...);         }         if  (!IsNewRefcountEnabled  ())           __mt_RootViewController_var  =  ret;            return  ret;      }...object  __mt_RootViewController_var;[CompilerGenerated]public  virtual  UIViewController  RootViewController  {     [Export  ("rootViewController",  ArgumentSemantic.Retain)]     get  {         global::MonoTouch.UIKit.UIApplication.EnsureUIThread  ();         UIViewController  ret;         if  (IsDirectBinding)  {           ret  =  (UIViewController)  Runtime.GetNSObject  (...  msgSend  ...);           }  else  {           ret  =  (UIViewController)  Runtime.GetNSObject  (...  msgSendSuper  ...);         }         if  (!IsNewRefcountEnabled  ())           __mt_RootViewController_var  =  ret;            return  ret;      }...object  __mt_RootViewController_var;[CompilerGenerated]public  virtual  UIViewController  RootViewController  {     [Export  ("rootViewController",  ArgumentSemantic.Retain)]     get  {         global::MonoTouch.UIKit.UIApplication.EnsureUIThread  ();         UIViewController  ret;         if  (IsDirectBinding)  {           ret  =  (UIViewController)  Runtime.GetNSObject  (...  msgSend  ...);           }  else  {           ret  =  (UIViewController)  Runtime.GetNSObject  (...  msgSendSuper  ...);         }         if  (!IsNewRefcountEnabled  ())           __mt_RootViewController_var  =  ret;            return  ret;      }...
  • 29. Quicker buildsSmaller appsFaster apps
  • 30. Q&A
  • 31. THANK YOUrelated links @ http://bit.ly/ios-build

×