Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/keith/rules_apple_linker
Bazel rules for overriding ld64 with lld or zld
https://github.com/keith/rules_apple_linker
Last synced: 3 days ago
JSON representation
Bazel rules for overriding ld64 with lld or zld
- Host: GitHub
- URL: https://github.com/keith/rules_apple_linker
- Owner: keith
- License: mit
- Created: 2021-12-07T02:29:26.000Z (almost 3 years ago)
- Default Branch: main
- Last Pushed: 2024-10-21T22:21:43.000Z (22 days ago)
- Last Synced: 2024-10-22T11:56:56.878Z (22 days ago)
- Language: Starlark
- Size: 54.7 KB
- Stars: 61
- Watchers: 5
- Forks: 7
- Open Issues: 6
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# rules_apple_linker
This is a set of [bazel][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][issue] for more info on the tests):![benchmarks showing that zld is faster than ld64 and lld is faster than both](https://user-images.githubusercontent.com/283886/149881398-33aa618b-392b-44e1-95d4-7258d17a4ab6.png)
## 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:### lld
[`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][llddocs] 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 a target for `lld`
(`@rules_apple_linker//:lld`) for you to use. To enable it add the
target to the `deps` of your targets:```bzl
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`][rules_apple] packaging target. For example in a custom
macro:```bzl
def my_custom_ios_unit_test(**kwargs):
deps = kwargs.pop("deps", []) + ["@rules_apple_linker//:lld"]
ios_unit_test(
deps = deps,
**kwargs
)
```## Custom linkopts
Using bazel's [`--linkopt=`][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:```bzl
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:```bzl
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:```bzl
load("@rules_apple_linker//:rules.bzl", "lld_override")lld_override(
name = "lld",
linker = "@lld//:my-newer-lld",
)
```You can also use the `apple_linker_override` rule directly if you don't
the `lld` specific parameters.```bzl
load("@rules_apple_linker//:rules.bzl", "apple_linker_override")
apple_linker_override(
name = "linker",
linker = "//:my-custom-linker",
override_linkopts = [...],
)
```# Installation
See [the releases][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][newissue]![bazel]: https://bazel.build
[issue]: https://github.com/keith/rules_apple_linker/issues/1
[linkopt]: https://docs.bazel.build/versions/main/command-line-reference.html#flag--linkopt
[lld]: https://lld.llvm.org/
[llddocs]: https://github.com/llvm/llvm-project/blob/main/lld/docs/MachO/ld64-vs-lld.rst
[newissue]: https://github.com/keith/rules_apple_linker/issues/new
[releases]: https://github.com/keith/rules_apple_linker/releases
[rules_apple]: https://github.com/bazelbuild/rules_apple