Stream: compiler development

Topic: Building using `--lib`


view this post on Zulip Luke Boswell (Jul 08 2024 at 05:43):

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?

view this post on Zulip Brendan Hansknecht (Jul 08 2024 at 05:49):

Lib generates a shared library that can be loaded dynamically at runtime

view this post on Zulip Brendan Hansknecht (Jul 08 2024 at 05:49):

Used in glue this way for example

view this post on Zulip Brendan Hansknecht (Jul 08 2024 at 05:50):

Would probably be how a game would load a mod written in roc

view this post on Zulip Brendan Hansknecht (Jul 08 2024 at 05:50):

When using --lib you explicitly don't want to link the platform. just generate a shared lib for the platform to use.

view this post on Zulip Brendan Hansknecht (Jul 08 2024 at 05:50):

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%

view this post on Zulip Luke Boswell (Jul 08 2024 at 05:52):

Thank you

view this post on Zulip Brendan Hansknecht (Jul 08 2024 at 05:53):

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

view this post on Zulip Luke Boswell (Jul 08 2024 at 05:56):

Ohk, that is the piece I'm missing

view this post on Zulip Luke Boswell (Jul 08 2024 at 05:57):

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.

view this post on Zulip Luke Boswell (Jul 08 2024 at 06:06):

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.

view this post on Zulip Brendan Hansknecht (Jul 08 2024 at 06:22):

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.

view this post on Zulip Brendan Hansknecht (Jul 08 2024 at 06:23):

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

view this post on Zulip Brendan Hansknecht (Jul 08 2024 at 06:25):

But I don't think it needs extra linking. I see it as 2 common cases:

  1. The game/etc is made with the idea of loading roc plugins. So it is the platform and compiles all roc plugins with --lib. Then loads and uses the plugins. Nothing extra needed
  2. Some game/etc knows nothing of roc but can load plugins compiled as shared libraries. Make a shim shared library that's entire job is to load a roc shared library and deal with communication. Roc still uses --lib no extra link step required. But you do have to build the shim lib.

view this post on Zulip Brendan Hansknecht (Jul 08 2024 at 06:26):

Of course, the shim lib and roc lib could be compiled into a single shared library if really wanted.

view this post on Zulip Luke Boswell (Jul 08 2024 at 06:29):

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.

view this post on Zulip Ryan Barth (Jul 08 2024 at 06:30):

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.

view this post on Zulip Ryan Barth (Jul 08 2024 at 06:33):

Using roc build to compile statically linked executable is a pretty well solved problem. The other use cases are less well supported.

view this post on Zulip Ryan Barth (Jul 08 2024 at 06:36):

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.

view this post on Zulip Ryan Barth (Jul 08 2024 at 06:42):

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.

view this post on Zulip Brendan Hansknecht (Jul 08 2024 at 06:49):

I don't think it even needs a flag

view this post on Zulip Brendan Hansknecht (Jul 08 2024 at 06:49):

Should be part of the platform header

view this post on Zulip Brendan Hansknecht (Jul 08 2024 at 06:49):

Cause a platform knows how it wants roc to compile

view this post on Zulip Ryan Barth (Jul 08 2024 at 06:50):

You are 100% right

view this post on Zulip Brendan Hansknecht (Jul 08 2024 at 06:50):

Shared lib, static lib, or full app

view this post on Zulip Luke Boswell (Jul 08 2024 at 06:52):

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?

view this post on Zulip Luke Boswell (Jul 08 2024 at 06:53):

I've been looking at the build pipeline, and this could be a good change to make

view this post on Zulip Luke Boswell (Jul 08 2024 at 06:56):

Like maybe some kind of data structure that could specify default build arguments?

I've got some ideas, I moght sketch something up

view this post on Zulip Brendan Hansknecht (Jul 08 2024 at 15:35):

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.

view this post on Zulip Brendan Hansknecht (Jul 08 2024 at 15:36):

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

view this post on Zulip Luke Boswell (Jul 08 2024 at 23:08):

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