Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Exploring Clang Modules

Exploring Clang Modules

Given at try! Swift Tokyo 2018

Samuel E. Giddins

March 01, 2018
Tweet

More Decks by Samuel E. Giddins

Other Decks in Technology

Transcript

  1. Exploring Clang Modules
    Samuel Giddins
    1

    View Slide

  2. @segiddins
    CocoaPods, Bundler, RubyGems
    Mobile Developer Experience @ Square
    Exploring Clang Modules – Samuel Giddins @ try! Swift Tokyo 2018 2

    View Slide

  3. Exploring Clang Modules – Samuel Giddins @ try! Swift Tokyo 2018 3

    View Slide

  4. cool_function.h
    #define AUTHORS_NAME "segiddins"
    extern void printMyName(char *);
    main.c
    #include "cool_function.h"
    int main(int argc, char **argv) {
    printMyName(AUTHORS_NAME);
    }
    Exploring Clang Modules – Samuel Giddins @ try! Swift Tokyo 2018 4

    View Slide

  5. main.c
    extern void printMyName(char *);
    int main(int argc, char **argv) {
    printMyName("segiddins");
    }
    Exploring Clang Modules – Samuel Giddins @ try! Swift Tokyo 2018 5

    View Slide

  6. #include "header.h"
    #define MAGIC_NUMBER 42
    ...
    ...
    ...
    #include "header2.h" // also includes header.h
    preprocessed into:
    static int secretNumber = -1;
    static int secretNumber = 42;
    Exploring Clang Modules – Samuel Giddins @ try! Swift Tokyo 2018 6

    View Slide

  7. // header.h
    #ifndef __HEADER_H
    #define __HEADER_H
    ...
    #endif // #ifndef __HEADER_H
    Exploring Clang Modules – Samuel Giddins @ try! Swift Tokyo 2018 7

    View Slide

  8. #import "header.h"
    Exploring Clang Modules – Samuel Giddins @ try! Swift Tokyo 2018 8

    View Slide

  9. Enter Module Maps
    Exploring Clang Modules – Samuel Giddins @ try! Swift Tokyo 2018 9

    View Slide

  10. Exploring Clang Modules – Samuel Giddins @ try! Swift Tokyo 2018 10

    View Slide

  11. UsefulFramework.modulemap / module.modulemap
    framework module UsefulFramework {
    umbrella header "UsefulFramework.h"
    export *
    module * { export * }
    }
    Exploring Clang Modules – Samuel Giddins @ try! Swift Tokyo 2018 11

    View Slide

  12. UsefulFramework.modulemap
    framework module UsefulFramework {
    umbrella header "UsefulFramework.h"
    export *
    module * { export * }
    }
    Exploring Clang Modules – Samuel Giddins @ try! Swift Tokyo 2018 12

    View Slide

  13. UsefulFramework.modulemap
    framework module UsefulFramework {
    umbrella header "UsefulFramework.h"
    export *
    module * { export * }
    }
    Exploring Clang Modules – Samuel Giddins @ try! Swift Tokyo 2018 13

    View Slide

  14. UsefulFramework.modulemap
    framework module UsefulFramework {
    umbrella header "UsefulFramework.h"
    export *
    module * { export * }
    }
    Exploring Clang Modules – Samuel Giddins @ try! Swift Tokyo 2018 14

    View Slide

  15. UsefulFramework.modulemap
    framework module UsefulFramework {
    umbrella header "UsefulFramework.h"
    export *
    module * { export * }
    }
    Exploring Clang Modules – Samuel Giddins @ try! Swift Tokyo 2018 15

    View Slide

  16. main.swift
    import UsefulFramework
    main.m
    @import UsefulFramework;
    Exploring Clang Modules – Samuel Giddins @ try! Swift Tokyo 2018 16

    View Slide

  17. Module Maps, the hard part
    Exploring Clang Modules – Samuel Giddins @ try! Swift Tokyo 2018 17

    View Slide

  18. Module Maps, the hard part
    Lessons from CocoaPods
    Exploring Clang Modules – Samuel Giddins @ try! Swift Tokyo 2018 18

    View Slide

  19. • Umbrella Directories
    • Explicit Submodules
    • Private Headers
    • Textual Headers
    • ...
    • Automatic Module Map Discovery
    • Relative Paths
    Exploring Clang Modules – Samuel Giddins @ try! Swift Tokyo 2018 19

    View Slide

  20. Umbrella Directories
    framework module UsefulFramework {
    umbrella "HeadersDirectory"
    }
    Exploring Clang Modules – Samuel Giddins @ try! Swift Tokyo 2018 20

    View Slide

  21. Explicit Submodules
    Exploring Clang Modules – Samuel Giddins @ try! Swift Tokyo 2018 21

    View Slide

  22. Explicit Submodules
    framework module UsefulFramework {
    umbrella header "UsefulFramework.h"
    explicit module ForSubclassEyesOnly {
    header "ComplicatedTextField_subclass.h"
    }
    }
    Exploring Clang Modules – Samuel Giddins @ try! Swift Tokyo 2018 22

    View Slide

  23. Private Headers
    framework module UsefulFramework {
    umbrella header "UsefulFramework.h"
    private header "PrivateHashMapImpl.h"
    }
    Exploring Clang Modules – Samuel Giddins @ try! Swift Tokyo 2018 23

    View Slide

  24. Textual Headers
    framework module UsefulFramework {
    umbrella header "UsefulFramework.h"
    textual header "AssertMacros.h"
    }
    Exploring Clang Modules – Samuel Giddins @ try! Swift Tokyo 2018 24

    View Slide

  25. Requires
    framework module UsefulFramework {
    umbrella header "UsefulFramework.h"
    requires objc_arc, blocks, !altivec
    }
    Exploring Clang Modules – Samuel Giddins @ try! Swift Tokyo 2018 25

    View Slide

  26. Conflicts
    framework module UsefulFramework {
    umbrella header "UsefulFramework.h"
    conflict PointlessFramework, "we do something more useful than that framework"
    }
    Exploring Clang Modules – Samuel Giddins @ try! Swift Tokyo 2018 26

    View Slide

  27. Automatic Module Map Discovery
    $ tree include
    include
    !"" baking.h
    !"" cake.h
    !"" cookie.h
    !"" module.modulemap
    Exploring Clang Modules – Samuel Giddins @ try! Swift Tokyo 2018 27

    View Slide

  28. Relative Paths
    Exploring Clang Modules – Samuel Giddins @ try! Swift Tokyo 2018 28

    View Slide

  29. Relative Paths
    framework module UsefulFramework {
    header "UsefulFramework.h"
    }
    Exploring Clang Modules – Samuel Giddins @ try! Swift Tokyo 2018 29

    View Slide

  30. Modules & Swift
    Exploring Clang Modules – Samuel Giddins @ try! Swift Tokyo 2018 30

    View Slide

  31. But my Swift code doesn't have headers...
    Exploring Clang Modules – Samuel Giddins @ try! Swift Tokyo 2018 31

    View Slide

  32. But my Swift code doesn't have headers...
    It does
    !
    Exploring Clang Modules – Samuel Giddins @ try! Swift Tokyo 2018 32

    View Slide

  33. swiftc Understands .swiftmodule Files
    Exploring Clang Modules – Samuel Giddins @ try! Swift Tokyo 2018 33

    View Slide

  34. The Mixed Framework Process
    1. Compile all .swift files
    2. Generate ModuleName-Swift.h in the (empty) .framework
    3. "Extend" existing module map with .Swift submodule
    4. Compile .m files
    Exploring Clang Modules – Samuel Giddins @ try! Swift Tokyo 2018 34

    View Slide

  35. Extended Module Maps
    module ModuleName.Swift {
    header "ModuleName-Swift.h"
    requires objc
    }
    Exploring Clang Modules – Samuel Giddins @ try! Swift Tokyo 2018 35

    View Slide

  36. Same-Module Imports
    Superclass.m
    #import
    Subclass.swift
    // nothing to import!
    Exploring Clang Modules – Samuel Giddins @ try! Swift Tokyo 2018 36

    View Slide

  37. Same-Module Imports
    swiftc Useful.swift
    -module-name UsefulFramework
    -import-underlying-module
    -emit-module
    -emit-objc-header
    -Xcc -fmodule-map-file="UsefulFramework.modulemap"
    Exploring Clang Modules – Samuel Giddins @ try! Swift Tokyo 2018 37

    View Slide

  38. Swift Static Libraries in CocoaPods
    All of the changes needed:
    https://github.com/CocoaPods/CocoaPods/pull/6966
    Exploring Clang Modules – Samuel Giddins @ try! Swift Tokyo 2018 38

    View Slide

  39. Are Modules the Future?
    • Tied to headers
    • Swift module stability
    • Still confusing
    • Better than C
    Exploring Clang Modules – Samuel Giddins @ try! Swift Tokyo 2018 39

    View Slide

  40. Some Resources
    • Clang Docs
    https://clang.llvm.org/docs/Modules.html
    • Clang Source
    https://github.com/llvm-mirror/clang/blob/master/include/clang/
    Basic/Module.h
    • CocoaPods Source
    https://github.com/CocoaPods/CocoaPods/blob/master/lib/
    cocoapods/generator/module_map.rb
    • Trial & Error
    Exploring Clang Modules – Samuel Giddins @ try! Swift Tokyo 2018 40

    View Slide

  41. @segiddins
    Mobile Developer Experience @ Square
    Exploring Clang Modules
    41

    View Slide