When we build an app using --lib
there is no linking with the host (as far as I know).
I was just wanting to ask why is it this way? Would it make sense for the linkers to link the prebuilt host if it was available?
Related question.. if I have an app and I build it using roc build --lib app.roc
, can a host built with e.g. rust load that dynamic library and provide implementations for externs like roc_alloc
, roc_rx_someEffect
etc?
Lib generates a shared library that can be loaded dynamically at runtime
Used in glue this way for example
Would probably be how a game would load a mod written in roc
When using --lib
you explicitly don't want to link the platform. just generate a shared lib for the platform to use.
can a host built with e.g. rust load that dynamic library and provide implementations for externs like
roc_alloc
,roc_rx_someEffect
etc?
So yeah, 100%
Thank you
This said, linkers don't tend to like when a shared library calls into a host app like that. It can be made to work, but often linker cleanup hid symbols you need. That is part of the reason for effect interpreters and passing in explicit allocators. It fixes those linking issues
Ohk, that is the piece I'm missing
Until we get those up and working, any platform that wants to produce a nice standalone dylib (for e.g. a game engine) will probably need an additional linking step.
Ohk -- I still think it make senses to enable a linking step in roc for --lib
, even if we have passed in allocators and effect interpreters.
What if I'm wanting a dylib for a game engine and it expects a particular interface.
I will still need to link a "host" which provides the glue between these two interfaces.
Without any linking provided by roc, this use case limits the usability for end users. They now have to have a toolchain like zig
installed to do this extra linking step. They can't just run roc build
and get a thing that fits in the end application.
I'm not sure I follow. Any game could be made to open a roc shared library and run it. So I don't think there needs to be an extra set here.
Luke Boswell said:
What if I'm wanting a dylib for a game engine and it expects a particular interface.
I will still need to link a "host" which provides the glue between these two interfaces.
Ah yeah, that case specifically is different. You would need a shim of some sort
But I don't think it needs extra linking. I see it as 2 common cases:
--lib
. Then loads and uses the plugins. Nothing extra needed--lib
no extra link step required. But you do have to build the shim lib.Of course, the shim lib and roc lib could be compiled into a single shared library if really wanted.
Yeah this shim library is what I'm thinking of. My thoughts were if roc could link for a lib just like an exe than the experience for end users could be as simple as roc build
and they have a thing that's gtg for the (non-roc compatible) game engine.
is there an argument for eg a --link-platform
flag that could be used in conjunction with --lib
to effectively solve the "I want to use roc to build a library for X". --lib
as it exists today has limited usefullness to an end user because 1) a roc app is not allowed to provide no platform and 2) no other existing projects that consume a shared library uses roc's types. Doesn't it make sense that the platform is the "shim" in the case roc is compiled into a shared library? In many cases these "shims" will be pretty large.
Using roc build
to compile statically linked executable is a pretty well solved problem. The other use cases are less well supported.
I think one of the next logical steps to let roc integrate with the existing ecosystem is to provide a good story for building shared libraries.
The tooling for building shared libraries is complex for Roc's apparent target audience (myself included). Can roc provide a better experience? Let the platform devs assume the complexity for some of the larger ecosystems where roc could be embedded. Then users just need to write their roc "app" and they get a high level, performant integration with a dead simple interface.
I don't think it even needs a flag
Should be part of the platform header
Cause a platform knows how it wants roc to compile
You are 100% right
Shared lib, static lib, or full app
Brendan Hansknecht said:
Should be part of the platform header
This isn't how we do things rn.
What do we need to add to enable this kind of thing?
I've been looking at the build pipeline, and this could be a good change to make
Like maybe some kind of data structure that could specify default build arguments?
I've got some ideas, I moght sketch something up
Yeah, just some extra fields in the header. They could specify both the roc expected output as well as the location where the host compilation objects will be located. Then when roc bundles (or local path builds), it can follow that path to grab the expected objects.
No need for all of the output files to be shoved on the platform folder. They can just live in zig out or rust target dir
I didn't get around to writing up my idea in much detail.
Basically, I was thinking the cli has all this functionality to build an app using different options/flags etc. The platform can provide some kind of data structure which instructs the cli what to do for the default build.
Indeed, to clean-up the cli build pipeline I think it would help to have some kind of intermediate representation of the build instruction anyway. Take the cli flags and produce a similar kind of data structure which is then used to roc run
, roc build
, roc dev
etc. I.e. do we expect a prebuilt host, where is it, or maybe we are just producing a standalone object instead; do we need to link, using which linker, etc...
Last updated: Jul 06 2025 at 12:14 UTC