Simplify macOS linking by using clang as linker driver - #70
Conversation
The existing macOS linker configuration passed raw ld64 flags that don't work when using clang as the linker driver. This simplifies macOS linking by using clang, which automatically handles SDK detection, system library linking, and architecture flags. Changes: - Use clang instead of ld/ld64.lld on macOS - Change -dylib to -dynamiclib (clang syntax) - Remove manual -syslibroot and -platform_version flags (clang handles these) - Simplify target specs to only pass -Wl,-undefined,dynamic_lookup - Add build.rs to embed LLVM library rpath for runtime linking - Add MacPorts installation instructions to configure script Tested on macOS with MacPorts LLVM 18 and 21 on Apple Silicon (M1).
|
Also, I'm not sure about Homebrew, but with MacPorts I don't have to set LLVM_SYS_211_PREFIX or modify my PATH, as long as I use the sudo port install llvm-21 clang-21 rust cargo
sudo port select --set llvm mp-llvm-21
sudo port select --set clang mp-clang-21Then |
|
Hi Jason, Welcome to the small community of OpenVAF hackers. I did a 'cargo fmt', moved your PR into the verley-macos branch, and set up PR #72. CI passes. I develop on Intel and lack experience with MACs so I have a question: If I build for mac and move the binary to some other mac where the libraries are at some other location that the one baked into the binary (i.e. the one based on the 'llvm-config --libdir' output you collect at compile time) will the binary work if I set the DYLD_LIBRARY_PATH? Best regards, P.S.: Always do a 'cargo machete' followed by 'cargo fmt' before you submit. CI checks these two and fails if they are not flawless. |
|
Thanks for the "cargo" instructions. I'm not familiar with Rust at all. Regarding Macs, macOS is inconsistent in how it handles the DYLD_* variables. For security reasons (SIP), it strips DYLD_LIBRARY_PATH and friends for system binaries and in some launcher contexts, and I’ve seen that break setups that should have worked on paper. In practice, for a user‑installed binary like OpenVAF, DYLD_LIBRARY_PATH or DYLD_FALLBACK_LIBRARY_PATH will generally work as long as LLVM on the second system lives in a non‑system location. But it’s not something I’d rely on long‑term; Apple has changed this behavior before and may do so again. Using rpath is the recommended macOS mechanism for finding non‑system libraries at runtime. The rpath derived from llvm-config --libdir makes the “build and run on the same machine” case work without any environment tweaks, which is the common scenario. For distribution, package managers like Homebrew and MacPorts could use the same approach and ship OpenVAF prelinked against their own LLVM (ngspice is already available via both), but that would require someone to maintain the packaging. In practice, they will sometimes add a package if there is clear demand from users. |
|
Closing, moved to PR #72. |
I ran into linking issues building OpenVAF on macOS (Apple Silicon, MacPorts LLVM 18). The current approach passes raw ld64 flags like
-syslibroot,-platform_version, and-archdirectly, which breaks in some configurations.This PR uses
clangas the linker driver on macOS instead. Clang already handles SDK detection, system library linking, and architecture selection, so the manual flag handling becomes unnecessary.Changes
Linker selection (
linker/src/lib.rs):clangon macOS instead ofld64.lld/ld-dynamiclibinstead of-dylib(clang syntax)Target specs (
target/src/spec/*_apple_darwin.rs):-arch,-platform_version, and-lSystemflags-Wl,-undefined,dynamic_lookupRuntime linking (
openvaf-driver/build.rs):llvm-config --libdirat build time and embed the result as an rpathDYLD_LIBRARY_PATHat runtimeDocumentation (
configure):Testing
openvaf, compiled Verilog-A models to.osdi, loaded them in ngspice