Does sbt-native-packager generate shared library?

Hello everyone,
I’d like to know if sbt-native-packager can generate native shared library (.h, .lib, .dll for Windows) in order to use them in C++ project. If yes, could you give me some advice to do so ?
Thanks

I don’t know the definitive answer but as far as I know the purpose of sbt-native-packager is to generate executables to run an application. That’s still very different from generating a native library.

It sounds like you might want to look into Scala Native.

It might be able to do so via the graal aotc stuff, but I seriously doubt it. Scala native also seems to not be the answer yet. I’d guess your best bet would be something like avian vm(avian is not maintained anymore)

edit: it looks like graal native image is what you need: GraalVM

You might be able to do what you want with some fancy configuration of Sbt-native-packager, but I don’t know for sure. It may be up to you to write an SBT plugin (or mill plugin) that builds your code with native-image the way you want. Good luck!

My first instinct would be to re-examine the necessity of the integration. This doesn’t sound like a comfortable thing to do.

I write in C++ now and then, more in the past than now, despite Scala now being my most-used language. But this kind of integration isn’t something I’ve ever been interested in. My C++ programs explicitly manage lots of things: memory, threads, file handles, hardware resources, etc… Even if I could “integrate” Scala, it would add a big automatically-managed hairball.

Instead, I’ve primarily taken two strategies. When the functionality I need is sizable, and depends on the large Scala (and perhaps Java) library ecosystem, I instead write a server. I’ve used both direct connection to sockets and a web server, favoring the latter because it takes care of more stuff for me (e.g. using requests-scala). I pass data in JSON, for which rapidjson works fine for me on the C++ side, and on the Scala side I mostly use my own but uPickle/uJson for ease of use or jsoniter-scala for speed are good choices too (not sure the latter is available for Scala 3). Of course the latency is not great with this approach, but if the task is so complex that I really need the whole Scala/Java stack, the latency probably isn’t that bad compared to the operation itself. (And if I need it somewhat faster, I can use binary data transfer over sockets, which generally beats web servers in both latency and throughput.)

On the other hand, when the functionality I need is modest, then I simply don’t use Scala. Rust is a lovely and sufficiently mature language, fully capable of tackling quite complex problems. A post detailing all the relative advantages and drawbacks is beyond the scope of what I want to type right now, but the bottom line is that when left to my own devices I generally gravitate towards Scala. But Rust is fast as blazes, especially if you put a tiny bit of care into it, it’s safer than anything, and it has a solid C FFI which makes C++ interop pretty straightforward (with a little messing around with libraries if you’re using threading). So if you have a small- to medium-sized project in Scala, you might just port it to Rust.

(Aside: I write a lot of high-performance Scala code, but my not-very-serious attempts in Rust routinely beat my Scala code by a factor of 2 while being safer, and taking only a little longer to write. However, the maximum complexity I can handle in Scala is considerably higher than in Rust, so I generally default to Scala unless I know for certain that that possible factor of 2 will be really important, AND the complexity is within my capacity.)

Maybe someday I’ll reach for scala-native or GraalVM’s native packager. But so far, despite having need of a fair bit of C++ iterop, I haven’t really been tempted. The set of use cases for which I think it’s clearly the right solution is very narrow. Maybe you have one of those use cases. But maybe not.

3 Likes