{"id":15570771,"url":"https://github.com/keith/rules_apple_linker","last_synced_at":"2026-04-09T02:00:58.139Z","repository":{"id":39965183,"uuid":"435717267","full_name":"keith/rules_apple_linker","owner":"keith","description":"Bazel rules for overriding ld64 with lld or zld","archived":false,"fork":false,"pushed_at":"2024-12-10T17:38:46.000Z","size":53,"stargazers_count":63,"open_issues_count":6,"forks_count":7,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-01-22T02:54:38.578Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Starlark","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/keith.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-12-07T02:29:26.000Z","updated_at":"2024-12-10T17:38:50.000Z","dependencies_parsed_at":"2024-02-08T19:26:12.085Z","dependency_job_id":"e7745c96-0349-4303-82a6-b65ccf124948","html_url":"https://github.com/keith/rules_apple_linker","commit_stats":null,"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keith%2Frules_apple_linker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keith%2Frules_apple_linker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keith%2Frules_apple_linker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keith%2Frules_apple_linker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/keith","download_url":"https://codeload.github.com/keith/rules_apple_linker/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240367199,"owners_count":19790212,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-02T17:43:53.837Z","updated_at":"2026-04-09T02:00:58.062Z","avatar_url":"https://github.com/keith.png","language":"Starlark","funding_links":[],"categories":[],"sub_categories":[],"readme":"# rules_apple_linker\n\nThis is a set of [bazel][bazel] rules for overriding the default linker\nfor builds targeting Apple platforms.\n\n# Why use a different linker?\n\nThe primary reason to use a different linker is to decrease link times.\nWith large projects you may reach a point where the time it takes to\nlink your binary is a frustrating bottleneck in your iteration cycle. In\nsome cases replacing the default linker can result in a decrease of 85%\nof your link times. For example here are some real world benchmarks (see\n[this issue][issue] for more info on the tests):\n\n![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)\n\n## Linker options\n\nThe default linker for MachO binaries is maintained by Apple and\ngenerally referred to as `ld64` (even though the binary is still `ld`).\nCurrently there are 2 primary alternatives:\n\n### lld\n\n[`lld`][lld] is LLVM's linker. It is a completely separate\nimplementation of a MachO linker, meaning behavior can differ\nsignificantly from `ld64`, but should still be correct. See [the\ndocs][llddocs] for some known differences. `lld`'s MachO support is\nevolving quickly and is being used in production to link Chrome today.\n\n# Usage\n\nBy default `rules_apple_linker` provides a target for `lld`\n(`@rules_apple_linker//:lld`) for you to use. To enable it add the\ntarget to the `deps` of your targets:\n\n```bzl\nobjc_library(\n    name = \"main\",\n    ...\n    deps = [..., \"@rules_apple_linker//:lld\"],\n)\n```\n\nTo make sure you're always using the override, even if you have multiple\napps or test targets that don't all have the same libraries in their\ndependency trees, you can add it directly to the `deps` of your\n[`rules_apple`][rules_apple] packaging target. For example in a custom\nmacro:\n\n```bzl\ndef my_custom_ios_unit_test(**kwargs):\n    deps = kwargs.pop(\"deps\", []) + [\"@rules_apple_linker//:lld\"]\n    ios_unit_test(\n        deps = deps,\n        **kwargs\n    )\n```\n\n## Custom linkopts\n\nUsing bazel's [`--linkopt=`][linkopt] flag you can pass whatever custom\noptions you want to the linker. If you need to customize this more based\non other conditions, you can create your own linker target:\n\n```bzl\nload(\"@rules_apple_linker//:rules.bzl\", \"lld_override\")\n\nlld_override(\n    name = \"lld\"\n    lld_linkopts = select({\n        \"//:release\": [\"-Wl,-icf=all\"], # Using a custom config_setting\n        \"//conditions:default\": [\"-Wl,-icf=none\"],\n    }),\n)\n```\n\nThen you reference your target directly in your `deps` such as\n`//bazel:lld` (or the label for wherever you create the target).\n\nThe rules also allow you to customize if the linker override is enabled,\nand options for either case. For example maybe you want to disable the\ncustom linker for release mode:\n\n```bzl\nload(\"@rules_apple_linker//:rules.bzl\", \"lld_override\")\n\nlld_override(\n    name = \"lld\"\n    lld_linkopts = [...], # Only applies to lld\n    ld64_linkopts = [...], # Only applies to ld64\n    linkopts = [\"-Wl,-fatal_warnings\"], # Applies to both linkers\n    enable = select({\n        \"//:release\": False, # Using a custom config_setting\n        \"//conditions:default\", True,\n    }),\n)\n```\n\n## Custom linkers\n\nIf you'd like to provide your own binary or bazel rule for the linker\nyou want to use, you can pass the `linker` option when creating your own\ntarget:\n\n```bzl\nload(\"@rules_apple_linker//:rules.bzl\", \"lld_override\")\n\nlld_override(\n    name = \"lld\",\n    linker = \"@lld//:my-newer-lld\",\n)\n```\n\nYou can also use the `apple_linker_override` rule directly if you don't\nthe `lld` specific parameters.\n\n```bzl\n\nload(\"@rules_apple_linker//:rules.bzl\", \"apple_linker_override\")\n\napple_linker_override(\n    name = \"linker\",\n    linker = \"//:my-custom-linker\",\n    override_linkopts = [...],\n)\n```\n\n# Installation\n\nSee [the releases][releases] for installation instructions.\n\nNote this repo currently requires bazel 4.x+ and Xcode 13.x+, if you'd\nlike to use this with an older version please [open an issue][newissue]!\n\n[bazel]: https://bazel.build\n[issue]: https://github.com/keith/rules_apple_linker/issues/1\n[linkopt]: https://docs.bazel.build/versions/main/command-line-reference.html#flag--linkopt\n[lld]: https://lld.llvm.org/\n[llddocs]: https://github.com/llvm/llvm-project/blob/main/lld/docs/MachO/ld64-vs-lld.rst\n[newissue]: https://github.com/keith/rules_apple_linker/issues/new\n[releases]: https://github.com/keith/rules_apple_linker/releases\n[rules_apple]: https://github.com/bazelbuild/rules_apple\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkeith%2Frules_apple_linker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkeith%2Frules_apple_linker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkeith%2Frules_apple_linker/lists"}