currently, roc behind the scenes calls zig/rustc/clang to compile the platform
this is, on one hand, convenient because i dont need to figure out how to do that myself, but it's also kinda awkward to rely on it just working, and also limiting in a way
what I would imagine is that i could write a platform in a random lang, compile it myself to a .so/.o, that would contain the correct symbols that roc could just link to
and i mean this part wouldn't really be detached from roc, the author will get compile errors on missing symbols so development could happen gradually (we will also provide a guide to do it ofc)
does this make sense or am i missing a piece of the puzzle that would make it more/ too convoluted?
i mean idk if it's too far fetched but i can imagine people making very specific applications with plain (various arch) asm platforms lol
[maybe something like this is planned and i'm just not aware]
This does hit a few important points and plans.
Firstly, platforms should be able to specify the targets they support and their compilation commands. This is definitely planned, but not flexed out. That would remove a lot of the calls to zig and rust and clang.
Fundamentally, as we do this, we want to deprecate the legacy linker on platforms and switch fully to the surgical linker (still needs some updates to support everything). If someone really wanted the equivalent of the legacy linker path, they can do it in their own language's build system. Just have roc output an object file and then link it into the platform build system.
With the idea that everything will be using the surgical linker. Platforms will need to be written such that they depend on the roc app as a shared library. When running roc build, first roc would dump a stub shared library, then it would call the platforms build commands, finally it would surgically link to the platform removing the shared library dependency.
As an extra note, for most developers in the roc ecosystem, the plan is that they would always use prebuilt platforms. So it would just be roc code compiling and then surgically linking.
what I would imagine is that i could write a platform in a random lang, compile it myself to a .so/.o, that would contain the correct symbols that roc could just link to
Since the platform should be building the final executable it is better the other way around with roc compiling to a .o file. Otherwise, there is little chance roc would add all of the linker flags necessary to successfully build the executable. The platform knows it's dependencies, roc does not. This is the path I mentioned above about the legacy linker.
This is also why all of the legacy linker code is such a mess, It guesses at all these dependencies and adds many of them that may or may not be needed.
Brendan Hansknecht said:
platforms should be able to specify the targets they support and their compilation commands. This is definitely planned, but not flexed out. That would remove a lot of the calls to
zigandrustandclang.
just to be even more specific about this, the long-term plan is that roc does not even know about zig, rust, or clang, and certainly never invokes them directly!
the fact that it does today is a stopgap until we have surgical linking working everywhere, at which point we can drop the legacy linker (along with these invocations) altogether
the goal is that roc knows about:
...and that's it
it shouldn't be aware of, let alone coupled to, any other programming language (unless you count the C ABI, but that's just because it's the modern lingua franca to talk to other languages)
One open question this made we think of that we definitely should test: Can I make rust/zig/c/etc link an executable that is full static except for roc? As in it use musl and has no dynamic dependencies except for roc. Then when we surgically link it, can we fully convert it into a static executable.
generally I think compilers give options for fully dynamic or fully static. not for static except for a single dep.
What if a platform wanted to produce a .so that can be shipped to a server and executed there? E.g. something like Cloudflare Workers. In that sort of situation, the .so probably should not contain any of the roc runtime bits or the host code, so that doesn't have to be duplicated across many loaded modules.
Can you explain the goal a bit more more? what would be in the .so if it didn't contain any runtime bits or host code?
like a .so that loaded another .so for the roc standard library?
I’m think apps compiled for iOS do this - they need to statically link certain dependencies, but since Apples system libs are standard those are dynamically linked in
Brendan Hansknecht said:
One open question this made we think of that we definitely should test: Can I make rust/zig/c/etc link an executable that is full static except for roc? As in it use musl and has no dynamic dependencies except for roc. Then when we surgically link it, can we fully convert it into a static executable.
generally I think compilers give options for fully dynamic or fully static. not for static except for a single dep.
I'd like to hope this is possible! Maybe @Jakub Konka knows more specifically?
I think it definitely should be possible, i guess the bigger question is will it be a gigantic hassle that involves jumping through a lot of hoops cause build systems assume either static or dynamic and don't have an easy way to do a very specific mix.
Last updated: Jun 16 2026 at 16:19 UTC