Skip to content

Commit

Permalink
Vendor lzld
Browse files Browse the repository at this point in the history
  • Loading branch information
littledivy committed May 6, 2024
1 parent 079cb52 commit bc9a4c6
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 11 deletions.
19 changes: 8 additions & 11 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,19 @@ rustflags = [
"link-arg=/STACK:4194304",
]

[target.x86_64-apple-darwin]
linker = "../lzld/lzld"
rustflags = [
"-C",
"linker-flavor=ld64.lld",
"-C",
"link-args=-L/Users/divy/gh/lzld -llzld_x86_64"
]
# TODO: build lzld for x86_64
# [target.x86_64-apple-darwin]
# linker = "tools/lzld/lzld"
# rustflags = [
# "-C",
# "linker-flavor=ld64.lld",
# ]

[target.aarch64-apple-darwin]
linker = "../lzld/lzld"
linker = "tools/lzld/lzld"
rustflags = [
"-C",
"linker-flavor=ld64.lld",
"-C",
"link-args=-L/Users/divy/gh/lzld -llzld_arm64"
]

[target.'cfg(all())']
Expand Down
3 changes: 3 additions & 0 deletions tools/lzld/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/target

*.o
12 changes: 12 additions & 0 deletions tools/lzld/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
ARCH = $(shell uname -m)

liblzld_${ARCH}.a: lzld.m
cc -c lzld.m -o lzld.o
ar rcs liblzld_${ARCH}.a lzld.o

clean:
rm -f liblzld_${ARCH}.a lzld.o

all: liblzld_${ARCH}.a

.PHONY: clean all
39 changes: 39 additions & 0 deletions tools/lzld/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
A `ld -lazy_framework` for macOS. Designed to build Deno.

## Usage

```toml
[target.aarch64-apple-darwin]
rustflags = [
"-C",
"linker=/path/to/lzld/lzld",
"-C",
"link-args=-L/path/to/lzld -llzld"
]
```

### Usage without `lzld` wrapper

1. `rustc -Z link-native-libraries=no -L/path/to/lzld -llzld`:
Requires nightly but doesn't need a wrapper linker.

2. Manaully source modification: Remove `#[link]` attributes
from all dependencies and link to `liblzld.a`.

## Design

It's pretty simple. Drop in `lzld` as the linker.
It strips out `-framework` arguments and links a
static library (`liblzld.a`) that will lazy load
the framework via `dlopen` when needed.

Rest of the arguments are passed as-is to `lld`.

<!--
Supported frameworks:
- QuartzCore
- CoreFoundation
- TODO
-->


Binary file added tools/lzld/liblzld_arm64.a
Binary file not shown.
26 changes: 26 additions & 0 deletions tools/lzld/lzld
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/bin/bash
set -e

# Find the path to the `lld` binary.
lld=$(which lld)
if [ ! -x "$lld" ]; then
echo "Error: unable to find 'lld' binary" >&2
exit 1
fi

# Filter out `-framework` arguments.
args=()
while [ $# -gt 0 ]; do
case "$1" in
-framework)
shift 2
;;
*)
args+=("$1")
shift
;;
esac
done

# Run `lld` with the filtered arguments.
exec "$lld" "${args[@]}"
25 changes: 25 additions & 0 deletions tools/lzld/lzld.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#import <dlfcn.h>

// -- QuartzCore.framework

extern void *kCAGravityTopLeft = 0;

// -- Metal.framework

void *(*MTLCopyAllDevices_)(void) = 0;

void loadMetalFramework() {
void *handle = dlopen("/System/Library/Frameworks/Metal.framework/Metal", RTLD_LAZY);
if (handle) {
MTLCopyAllDevices_ = dlsym(handle, "MTLCopyAllDevices");
}
}

extern void *MTLCopyAllDevices(void) {
if (MTLCopyAllDevices_ == 0) {
loadMetalFramework();
}

return MTLCopyAllDevices_();
}

0 comments on commit bc9a4c6

Please sign in to comment.