Pro Yearly is on sale from $80 to $50! »

Static vs. Dynamic Linking

Static vs. Dynamic Linking

Since iOS 8, dynamic linking is also available on Apple’s mobile platform. Before the release, we had only static libraries and frameworks as options to include third-party dependencies in applications. The new opportunities offer some advantages, but have also minor drawbacks inherent. This talk should give some overview of what’s possible, help on problem discovery and points out where to pay attention.

Ca018f2258eadef2d02f5dcea5c25b88?s=128

Marius Rackwitz

February 06, 2015
Tweet

Transcript

  1. STATIC VS. Dynamic LINKING DOTSWIFT 2015, MARIUS RACKWITZ, @MRACKWITZ 1

  2. LIBRARIES VS. FRAMEWORKS 2

  3. ❓ 3

  4. PERSPECTIVE CLARIFICATION 4

  5. ARCHITECTURAL PERSPECTIVE: Hollywood PRINCIPLE 5

  6. DON'T CALL us, WE'LL CALL you! 6

  7. 7

  8. TOOLING PERSPECTIVE: DIFFERENT BUILD PRODUCTS 8

  9. A STATIC LIBRARY (AKA STATIC ARCHIVE) … is a collection

    of .o files with a table of contents that lists the global symbols in the .o files. — the man page of ld 9
  10. 10

  11. BUILDING A STATIC LIBRARY $ xcodebuild -target BananaLib … MACH_O_TYPE=staticlib

    # Pseudo (⾠) Code of what happens under the hood: PRODUCT_PATHS='' for ARCH in $ARCHS do OBJECT_FILES='' for FILE in $SRC_FILES do FILE_BASENAME=$(basename $FILE) OBJECT_FILE="$OBJECT_FILE_DIR_normal/$ARCH/$FILE_BASENAME.o" clang … -c $FILE -o $OBJECT_FILE OBJECT_FILES="$OUTPUT_FILES $OBJECT_FILE" end PRODUCT_PATH="$OBJECT_FILE_DIR_normal/$ARCH/$PRODUCT_NAME.a" ranlib $PRODUCT_PATH - $OBJECT_FILES PRODUCT_PATHS="$PRODUCT_PATHS $PRODUCT_PATH" end lipo -create $PRODUCT_PATHS -output $CONFIGURATION_BUILD_DIR/$PRODUCT_NAME.a 11
  12. STATIC LIBS ON LINK TIME ld will only pull .o

    files out of a static library if needed to resolve some symbol reference. — the man page of ld 12
  13. 13

  14. 14

  15. FRAMEWORK 15

  16. STATIC FRAMEWORK $ xcodebuild -target BananaFramework … MACH_O_TYPE=staticlib … #

    Build the static library mkdir $PRODUCT_NAME.framework mv $PRODUCT_NAME.a $PRODUCT_NAME.framework/$PRODUCT_NAME 16
  17. ⾠ CLASSES OF STATIC FRAMEWORKS ARE PART OF THE MAIN

    BUNDLE 17
  18. A DYNAMIC LIBRARY (AKA DYLIB OR FRAMEWORK) … is a

    final linked image. — the man page of ld 18
  19. 19

  20. DYNAMIC LIBRARY $ xcodebuild -target BananaLib … MACH_O_TYPE=mh_dylib PRODUCT_PATHS='' for

    ARCH in $ARCHS do … # Build $OBJECT_FILES PRODUCT_PATH="$OBJECT_FILE_DIR_normal/$ARCH/$PRODUCT_NAME.dylib" ld $OBJECT_FILES -o $PRODUCT_PATH -framework Foundation … PRODUCT_PATHS="$PRODUCT_PATHS $PRODUCT_PATH" end lipo -create $PRODUCT_PATHS -output $CONFIGURATION_BUILD_DIR/$PRODUCT_NAME.dylib 20
  21. DYNAMIC FRAMEWORK $ xcodebuild -target BananaFramework … MACH_O_TYPE=mh_dylib … #

    Build the dylib mkdir $PRODUCT_NAME.framework mv $PRODUCT_NAME.dylib $PRODUCT_NAME.framework/$PRODUCT_NAME 21
  22. DYLIBS ON LINK TIME Exported symbols from the dynamic library

    are used to resolve references. — the man page of ld 22
  23. 23

  24. 24

  25. 25

  26. 26

  27. 27

  28. 28

  29. 29

  30. 30

  31. DYLIBS ON LINK TIME The generated final linked image will

    have encoded that it depends on that dynamic library. — the man page of ld 31
  32. MACH-O FILE FORMAT BASIC STRUCTURE SOURCE: OS X ABI MACH-O

    FILE FORMAT REFERENCE 32
  33. $ otool -l BananaKit.framework/BananaKit BananaKit.framework/BananaKit: … Load command 3 cmd

    LC_ID_DYLIB cmdsize 96 name @rpath/BananaKit.framework/BananaKit (offset 24) time stamp 1 Thu Jan 1 01:00:01 1970 current version 1.0.0 compatibility version 1.0.0 … Load command 9 cmd LC_LOAD_DYLIB cmdsize 56 name @rpath/libswiftCore.dylib (offset 24) time stamp 2 Wed Dec 31 16:00:02 1969 current version 0.0.0 compatibility version 0.0.0 … Load command 22 cmd LC_RPATH cmdsize 40 path @executable_path/Frameworks (offset 12) Load command 23 cmd LC_RPATH cmdsize 40 path @loader_path/Frameworks (offset 12) … 33
  34. MACH-O LOAD COMMANDS ▸ LC_LOAD_DYLIB (OTHER_LD_FLAGS -l/-framework) ▸ LC_ID_DYLIB LD_DYLIB_INSTALL_NAME

    ▸ LC_RPATH LD_RUNPATH_SEARCH_PATHS 34
  35. @rpath? ▸ Should be used as prefix in LC_ID_DYLIB /

    LC_LOAD_DYLIB ▸ Searched by dyld at runtime. 35
  36. WRAP UP 36

  37. ADVANTAGES OF DYNAMIC FRAMEWORKS ▸ Easier to distribute & integrate

    if compiled ▸ Encoded Dependencies ▸ Two-Level Namespacing ▸ Reduces file size if used for app & extensions ▸ Separate resources in distinct bundles 37
  38. ADVANTAGES OF DYNAMIC FRAMEWORKS ▸ Easier to distribute & integrate

    if compiled ▸ Encoded Dependencies ▸ Two-Level Namespacing ▸ Reduces file size if used for app & extensions ▸ Separate resources in distinct bundles 38
  39. DISADVANTAGES OF DYNAMIC LINKING ▸ Limits dead-code stripping ▸ Increases

    load times 39
  40. RESTRICTIONS ▸ Dynamic Frameworks are needed for @IBDesignable. ▸ Dynamic

    Linking is needed for Swift. 40
  41. WHEN ALTERING BUILD SETTINGS ACROSS TARGETS CLEAN WON'T DO THE

    JOB! 41
  42. GOLDEN RULE #1 WHEN ALTERING BUILD SETTINGS ACROSS TARGETS NUKE

    DERIVEDDATA ! 42
  43. GOLDEN RULE #1 WHEN ALTERING BUILD SETTINGS ACROSS TARGETS Always

    NUKE DERIVEDDATA ! 43
  44. THANKS FOR YOUR ATTENTION! @MRACKWITZ MR@REALM.IO 44

  45. for question in questions { question.ask()! } 45