Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implicit HeaderMaps #3712

Closed
wants to merge 3 commits into from

Commits on Mar 19, 2018

  1. Implicit HeaderMaps

    Request for feedback on an implementation of C++ HeaderMaps in Bazel.
    
    A HeaderMap is a data structure that allows the compiler to lookup included
    headers in constant time.
    
    Traditionally, the compiler has to parse a large string of `iquote` includes,
    and then search these directories for a given header. This is slow for many
    reasons.
    
    The protocol of HeaderMap is implemented within compilers. Please find the
    Lexer implementation in Clang.
    https://clang.llvm.org/doxygen/HeaderMapTypes_8h.html
    https://clang.llvm.org/doxygen/HeaderMap_8cpp_source.html
    
    Use case:
    
    I'm seeing a massive increase in build performance by using this. It cut my
    clean build time in half.
    
    Performance data:
    
    Build time before HeaderMap:
    Target //Pinterest/iOS/App:PinterestDevelopment up-to-date:
    bazel-bin/Pinterest/iOS/App/PinterestDevelopment.ipa
    ____Elapsed time: 373.588s, Critical Path: 18.86s
    
    Build time after header maps on the entire project:
    Target //Pinterest/iOS/App:PinterestDevelopment up-to-date:
    bazel-bin/Pinterest/iOS/App/PinterestDevelopment.ipa
    ____Elapsed time: 188.971s, Critical Path: 17.11s
    
    Additionally, this solves the problem of having namespaced headers which is used
    in CocoaPods all over. Using a namespace makes includes more clear since it is
    easier for the user to distinguish where the header was derived.
    
    Implementation:
    
    At the ObjC level, headermaps are created with a namespace of the given target.
    In `objc_library` it is possible for the user to override the value of the
    namespace via the new attribute, `header_namespace`.
    
    By using 2 headermaps the headersearchs are most efficient: a headermap for the
    current target, and a header map with namespaced includes.
    
    Users can include headers from ObjC targets in the convention of
    `Namespace/Header.h`. Projects that don't use namespacing should see benefits as
    well: includes of the form `Header.h` will be read from the headermap.
    
    `HeaderMapInfo` contains all of the transitive info for dependent header maps,
    and is merged together into a single map. This yields much better performance
    than multiple headermaps.
    
    This is my first PR to the Bazel repo, so any suggestions or feedback is greatly
    appreciated!
    jerrymarino committed Mar 19, 2018
    Configuration menu
    Copy the full SHA
    24946ad View commit details
    Browse the repository at this point in the history
  2. Configuration menu
    Copy the full SHA
    56d7784 View commit details
    Browse the repository at this point in the history
  3. Integrate flatten_virtual_headers

    When flatten virtual headers is set, we add all headers to the
    headermap.
    
    This allows a user to include a Header, "path/to/header" as "header.h"
    
    Together with include_prefix, this allows bazel to support Xcode style
    includes out of the box.
    
    As a followup, we'll want to make this work without headermaps.
    
    + misc cleanups from rebasing
    jerrymarino committed Mar 19, 2018
    Configuration menu
    Copy the full SHA
    91f275a View commit details
    Browse the repository at this point in the history