Feature/unified rpath darwin#741
Conversation
| # limitations under the License. | ||
| # | ||
|
|
||
| include_guard(GLOBAL) |
There was a problem hiding this comment.
can you explain this? it's new for me
There was a problem hiding this comment.
It's a modern CMake command introduced in 3.10 that works like #pragma once in C++. I used include_guard(GLOBAL) to prevent the script from being processed multiple times if it's included in different parts of the build tree. It’s a bit cleaner than the old if(NOT DEFINED) guard pattern
| get_filename_component(lib_basename "${lib_path}" NAME) | ||
|
|
||
| add_custom_command(TARGET ${TARGET_NAME} POST_BUILD | ||
| COMMAND "${Patchelf_EXECUTABLE}" --set-rpath "$ORIGIN" "${lib_path}" |
There was a problem hiding this comment.
does this work like this?
COMMAND ${Patchelf_EXECUTABLE} --set-rpath [=["\$$ORIGIN"]=] ${PROJECT_OUTPUT_DIR}/${rustc_lib_name}There was a problem hiding this comment.
Yeah I know that looks wild Tbh I spent a good amout of time figuring out with the linker because both CMake and the shell kept trying to eat dollar sign in $ORIGIN.
I stumbled upon this bracket argument thing it’s basically a raw string that tells CMake to don't remove the $ sign It’s def a bit heavy handed so if there’s a more standard way MetaCall usually handles escaping let me know and I’ll update it
| @@ -1,3 +1,3 @@ | |||
| parallel-compiler = true | |||
| [build] | |||
| rustflags = ["-C", "link-args=-Wl,-rpath=$ORIGIN"] | |||
There was a problem hiding this comment.
should this file be added to .gitignore?
|
@heyitsmohdd one more question, for testing this we should enable rust in the macos ci, right? |
|
I'm running the CI but this will test Linux only, we have to enable it on macos too. |
|
Once it's tested I will merge it. |
|
@heyitsmohdd the whole linux ci is failing... |
I’ve implemented a unified RPath patching module (PatchRPath.cmake) to handle binary portability across both Darwin and Linux. This replaces the legacy, platform-specific hacks and the hard dependency on patchelf for macOS builds.
Key Changes:
Unified API: Created a metacall_patch_rpath function that automatically switches between install_name_tool (Darwin) and patchelf (Linux).
Darwin Linker Fixes: Updated the Rust loader build to use -Wl,-undefined,dynamic_lookup on macOS. This allows the compiler to ignore undefined MetaCall core symbols at build time, which are resolved at runtime when the plugin is loaded.
Dynamic Cargo Configuration: Introduced a .cargo/config.in template. CMake now generates the correct .cargo/config based on the host OS, ensuring Linux-specific flags like $ORIGIN don't break the Mac linker.
Build Order & Dependency Logic: Fixed a race condition where patching was attempted before the library was finished. The patching target now correctly waits for the Cargo build to complete and specifically includes the loader's own .dylib in the patch list.
How I tested it
I’ve verified this on Apple Silicon (M-series) with the following results:
Compilation: The Rust loader and MetaCall CLI now build to 100% success without manual environment tweaks.
Header Verification: Used otool -l to confirm that @loader_path is correctly embedded in the Mach-O load commands.
Runtime Check: The metacallcli initializes successfully. While it currently shows missing plugin errors (due to .so vs .dylib mapping), the core linking issues are fully resolved.