The DUB package manager for the D programming language doesn’t yet support dynamic library dependencies. How do you roll your own while waiting for this feature to land? Let’s take a look!
Let’s choose GtkD as our example.
Set up your project
Always need to start with a project, right?
$ dub init dynamic-gtk-project $ cd dynamic-gtk-project $ git init $ git add dub.json source $ git commit -m "empty project"
We don’t add any dependencies. Instead, we add gtk-d as a git submodule:
$ git submodule add https://github.com/gtkd-developers/GtkD
Now take the source code from the GtkD HelloWorld demo program and put it in your app.d. Commit it and we’re ready to move on.
Building the dynamic library
Now let’s walk through the steps by hand. We need GtkD built as a dynamic library, but DUB will build it as a static library. We’ll need to fix this:
$ cd GtkD $ sed -i 's/"targetType": "library"/"targetType": "dynamicLibrary"/' dub.json $ dub build gtk-d:gtkd
Wait for the build to finish and you should have a
libgtkd-3.so in your current directory. Let’s copy that somewhere that makes sense:
$ cd .. $ mkdir -p libs $ cp GtkD/libgtk-3.so libs
You can turn this into a script trivially; just put all those commands into a file and add
at the start. Call the file
prebuild.sh and add it to dub.json in
Building your project
You’ve got a GTK+ program, and you’ve got GtkD, but you haven’t told DUB how to build your program. There are three parts:
- Tell dub where to find the GtkD imports you need
- Tell dub where to look for libraries
- Tell dub what libraries you need
All this is done in dub.json:
- To find the imports, add
- To find the libraries, add
- To add the gtk-d library, add
Now you can build your program!
Running your program
Running your program is only a little different from before: add
env LD_LIBRARY_PATH=libs before any command that you’d use to run it.
$ env LD_LIBRARY_PATH=libs dub run $ env LD_LIBRARY_PATH=libs ./myapp
In my case, with Resin Browser, I had both webkit2-d and gtk-d as dependencies. My build times went down from 13 seconds to 2 seconds, and my binary size went from 96MB to 2.5MB.
The larger benefit was the compile time. When it takes over ten seconds to run your application after a one-line change, that feels terrible! I don’t want to experiment like that; I want to batch up my changes. But that means I lose context on problems the compiler shows me.
But when it only takes a couple seconds, it’s not so bad.