GithubHelp home page GithubHelp logo

thii / rules_apple_linker Goto Github PK

View Code? Open in Web Editor NEW

This project forked from keith/rules_apple_linker

0.0 1.0 0.0 20 KB

Bazel rules for overriding ld64 with lld or zld

License: MIT License

C 0.18% Starlark 99.82%

rules_apple_linker's Introduction

rules_apple_linker

This is a set of bazel rules for overriding the default linker for builds targeting Apple platforms.

Why use a different linker?

The primary reason to use a different linker is to decrease link times. With large projects you may reach a point where the time it takes to link your binary is a frustrating bottleneck in your iteration cycle. In some cases replacing the default linker can result in a decrease of 85% of your link times. For example here are some real world benchmarks (see this issue for more info on the tests):

benchmarks showing that zld is faster than ld64 and lld is faster than both

Linker options

The default linker for MachO binaries is maintained by Apple and generally referred to as ld64 (even though the binary is still ld). Currently there are 2 primary alternatives:

zld

zld is a fork of ld64 that optimizes performance. This means you likely get output that is very similar to what ld64 produces. Unfortunately the base of zld naturally lags behind changes in ld64 because Apple doesn't often push their changes. This means theoretically some features could be a bit behind what you get with Xcode's version.

lld

lld is LLVM's linker. It is a completely separate implementation of a MachO linker, meaning behavior can differ significantly from ld64, but should still be correct. See the docs for some known differences. lld's MachO support is evolving quickly and is being used in production to link Chrome today.

Usage

By default rules_apple_linker provides targets for zld (@rules_apple_linker//:zld) and lld (@rules_apple_linker//:lld) for you to use. To enable them add one of the rules to the deps of your targets:

objc_library(
    name = "main",
    ...
    deps = [..., "@rules_apple_linker//:lld"],
)

To make sure you're always using the override, even if you have multiple apps or test targets that don't all have the same libraries in their dependency trees, you can add it directly to the deps of your rules_apple packaging target. For example in a custom macro:

def my_custom_ios_unit_test(**kwargs):
    deps = kwargs.pop("deps", []) + ["@rules_apple_linker//:zld"]
    ios_unit_test(
        deps = deps,
        **kwargs
    )

Custom linkopts

Using bazel's --linkopt= flag you can pass whatever custom options you want to the linker. If you need to customize this more based on other conditions, you can create your own linker target:

load("@rules_apple_linker//:rules.bzl", "lld_override")

lld_override(
    name = "lld"
    lld_linkopts = select({
        "//:release": ["-Wl,-icf=all"], # Using a custom config_setting
        "//conditions:default": ["-Wl,-icf=none"],
    }),
)

Then you reference your target directly in your deps such as //bazel:lld (or the label for wherever you create the target).

The rules also allow you to customize if the linker override is enabled, and options for either case. For example maybe you want to disable the custom linker for release mode:

load("@rules_apple_linker//:rules.bzl", "lld_override")

lld_override(
    name = "lld"
    lld_linkopts = [...], # Only applies to lld
    ld64_linkopts = [...], # Only applies to ld64
    linkopts = ["-Wl,-fatal_warnings"], # Applies to both linkers
    enable = select({
        "//:release": False, # Using a custom config_setting
        "//conditions:default", True,
    }),
)

Custom linkers

If you'd like to provide your own binary or bazel rule for the linker you want to use, you can pass the linker option when creating your own target:

load("@rules_apple_linker//:rules.bzl", "zld_override")

zld_override(
    name = "zld",
    linker = "@zld//:my-newer-zld",
)

You can also use the apple_linker_override rule directly if you don't want zld or lld specific parameters.

load("@rules_apple_linker//:rules.bzl", "apple_linker_override")

apple_linker_override(
    name = "linker",
    linker = "//:my-custom-linker",
    override_linkopts = [...],
)

Installation

See the releases for installation instructions.

Note this repo currently requires bazel 4.x+ and Xcode 13.x+, if you'd like to use this with an older version please open an issue!

rules_apple_linker's People

Contributors

keith avatar adityadaniel avatar ivan-golub avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.