I've been thinking about how to use nim to write system libraries and create tightly integrated applications. There's a couple things that I think need to get done in nim and I'd like to request some comments.
I've also been slowly adding nim support to meson, and lots of this stuff comes out of a desire for good integration there, including with multi-language projects **System libraries** Since most Linux sysadmins are interested in security updates and thus in shared libraries or at least a central location for dependencies, it would be good if nim supported these things. # Shared libraries and interfaces For shared libraries we are almost there, but it's hard to create a shared library for a module that's written in nim and meant to be consumed by nim code. You can exportc everything but then you are limited to c features and (for example) no overloading. Exporting nim identifiers seems fine to me but there should be safeguards (maybe in the "header" files, which I'll get to later) so that you can't accidently use a shared library built with an ABI incompatible version of the compiler (or, for example, a different GC). If we do want to be able to generate nim shared libraries (with the nim ABI of a particular compiler) then we need some way to generate nim files with the prototypes for things exported by those libraries. D has [interface files](https://dlang.org/dmd-linux.html#interface-files) which are generated by the compiler automatically to solve just this problem. It's probably possible to implement this as a nim program that uses the compiler module, and maybe even as a (probably term rewriting) macro. # Finding libraries and interfaces If we generate "system" libraries we then need a way to figure out include paths and link options. D uses pkg-config for this and simply uses Cflags for the dmd/ldc flags and Link for the linker options (including the flag to get dmd/ldc to pass options to the linker. Since nim compiles to C we _may_ want to separate nimflags and cflags, I think the best way to deal with this is to just include --passc and --passl in the pkgconfig file and then let tools extract those parameters if they need to compile the C code separately. an example pc file could be: prefix=/usr exec_prefix=${prefix} includedir=${prefix}/include/nim libdir=${exec_prefix}/lib64 Name: NimPackageExample Description: an example of a nim pc file Version: 1.0.0 Cflags: --path:${includedir}/NimPackageExample Libs: -L${libdir} -lNimPackageExample # Filesystem I've been thinking about where to put files associated with system libraries on the filesystem. I'm not sure what the best locations are but D (on fedora) uses /usr/include/d/ for includes, /usr/lib64 for shared libraries, and /usr/lib64/pkg-config for the pc files. This seems good to me so I propose the following: * /usr/include/nim \-- directory for interface files and nim libraries, structure could be the same as .nimble/pkgs * /usr/lib64 \-- shared libraries go here * /usr/lib{64|32|}/pkgconfig \-- pkgconfig goes here, or wherever the distro usually puts pc files. # Nimble I don't think much is needed in terms of new nimble features, but nimscript modules could be provided to help with pc files and install directories. I know fedora already has someone working on rpm macros to help package nim programs and libraries. **GNOME ideas** While we already have StefanSalewski's gintro project for generating nim source from typelibs, it could be improved (and indeed I'm starting to work on improving it). * It would be great if there was an easy way to tell gintro what nim specific tweaks it needs to make, like gir-to-d's APILayout.txt files or rust-gir's toml config files. the cfg file syntax could be used for this (or maybe even nimscript). * we need to be able to give gintro flags for where to output files, and which libraries to introspect. (working on this now) * IMO gintro should be using gir XML instead of typelib files to generate bindings, this avoids needing to bootstrap the girepository library Next it would be EXTREMELY cool to be able to create new introspectable libraries in nim. I actually think nim is a really good language for this because, somewhat like c, it makes the ABI of your code quite clear. * this could be again done using a program (perhaps nim-g-ir-scanner) that uses the compiler module and essentially implements a new codegen backend, or a new pass for gir files, it may also be possible to use nim's existing --header option to make a header that g-ir-scanner can understand (comments would need to be passed through). This lacks some flexibility since we then couldn't use nim features like custom pragmas, effect tracking, and so on, to influence generation. This happens to create a pretty good story for integration into other languages, you could write a library in nim, and use it in a pretty natural way from: d, rust, python, perl, javascript, C++, (not C yet, strangely), vala, and probably others, all without writing much, if any, binding code. I think gobject introspection even works on windows. Thanks for reading this somewhat long post, It's largely a wishlist but I want to hack on some of this stuff and start a discussion on how to make nim a killer language for people that are currently writing C because of it's binding friendliness and system integration on POSIX. (most new languages fail spectacularly here). **Discuss!**
