Cross-platform GUI programming using D and Gtk+

I’ve recently been playing with D and realized it’s an awesome language capable of any task. I’ve also had a few ideas for native applications that i want to realize so i decided to explore the feasibility of building these using D.

Using D presents a little problem though, there is no standard GUI library! Don’t worry there are many third party GUI libraries available, one of these is GTK+ and luckily there are D bindings available to make using this library easy. Well, i say ‘easy’ (in inverted commas) because the installation and usage of these bindings is not very well documented, hence, this post. The actual procedure for installing and using them is actually quite easy once you know what to do, so lets start. I’ve separated the following instructions into Windows and Linux sections.

Microsoft Windows

  1. Download and install the D compiler from http://dlang.org/download.html
  2. Download and install the Bud build tool from http://www.dsource.org/projects/build
  3. Download and install the latest Gtk+ libraries from http://sourceforge.net/projects/gtk-win/files/GTK+ Runtime Environment/.1
  4. Download and extract the latest GtkD bindings from https://github.com/gtkd-developers/GtkD to an accessible place.2
  5. Add the compiler command ‘-I[GtkD-Extract-Path]\src’ to ‘C:\D\dmd2\windows\bin\sc.ini’. This adds the GtkD source directory to the compiler include search path. (Replace [GtkD-Extract-Path] with wherever you extracted the source to).

Once these steps are followed you should now be able to compile a GUI application using D. Try saving the following code into a text file called ‘hello_world.d’.

Then use this compiler command from within a command prompt  bud hello_world.d -clean -exec -full -names  in the same directory as the above code file. You should then see your first D GUI application launch.

Linux (Ubuntu 12.04)

I primarily used Ubuntu 12.04 to get things working but i guess the procedure would be the same apart from maybe the install package format.

  1. Download and install the D compiler from http://dlang.org/download.html
  2. Make sure the GTK+ libraries are installed by executing  sudo apt-get install libgtk2.0-0 libgtk2.0-dev in a terminal. You will be asked for your admin password.
  3. Download and extract the latest GtkD bindings from https://github.com/gtkd-developers/GtkD to an accessible place.
  4. Once extracted, navigate to the new GtkD directory within a terminal and compile the source using the following command make to create the static libraries. Once it’s compiled, install it using make install. This places the static libraries into ‘/usr/local/lib’ and the source code into ‘/usr/local/includes/d’.
  5. Add ‘-I/usr/local/includes/d’ to ‘/etc/dmd.conf’. This adds the GtkD source directory to the compiler include search path.

Once these steps are followed you should now be able to compile a GUI application using D on Linux. Try saving the above test code into a text file called ‘hello_world.d’.

Because there is no available executable for the Bud build tool for Linux and because the Bud source uses deprecated features that throw errors with the new D compiler, i opt to use the standard  rdmd  compiler command to build the test program. Use the following command to do a test build  rdmd -L-ldl hello_world.d . The  -L-ldl  option tells the D linker to link against ‘libdl’. You should then see your first D GUI application launch.

Simple eh? Yeah right! BUT… you now have a cross-platform way of creating GUI applications in D using a very rich GUI library. Very, very cool!

Static libraries

Static libraries are a great way to speed up the compilation times of any application not just GtkD apps. Generally you import headers which define the signatures of types and methods, etc. and then link the static library which provides the implementation of the headers. They are extremely useful to use but there are a few caveats when trying to use them with D and GtkD.

Lets tackle Windows first. By default the Bud build script creates the GtkD static library (GtkD.lib) but does not create the header files. So in order to use this static library on Windows you need to first create the headers. Header files in D are called Interface files.3 Open the Bud build script (..\src\build\gtkD.brf) and add the  -H  compiler option on a new line. This tells the D compiler to emit interface files during compilation. Compile GtkD using Bud like this  bud gtkD.brf  (while in the build directory) and the interface files will be created (in their relevant folders) along with the static library (GtkD.lib) in the build folder. Once the interface files exist they will be read for imports over the regular source files (*.d). To link the static library into your executable and provide your application with the necessary implementations that the headers don’t contain, just add the following pragma4 at the start of your code. Make sure the static library is in the same directory as your program or on the system path so the compiler can find it.

You don’t need to add the *.lib suffix as this is automatically added.

On Linux (very much like Windows) you need to make sure the interface files exist within the source (you may have to recompile again using the  -H  compiler option to emit them.) then you need to use the following pragma’s at the top of your code to define the libraries to link.

You don’t need to add the ‘lib’ prefix or add the *.a suffix as this is added automatically. Also, defining the library linkage of ld like this using a pragma means you can omit the linker option (-L-ldl) when invoking the compiler from the terminal.

Note: If you have problems with the D compiler not being able to find the GtkD libraries make sure the libraries are available in the program directory or on the system path and that you have permissions to read them.

GtkD reference

To see all the available classes and methods from the GtkD libraries see http://gtkd.mikewey.eu/src/gtk/Main.html and click the ‘Package’ tab.

Show 4 footnotes

  1. When distributing a compiled application that relies on these libraries you can embed this installer within your application installer to install them silently. See the command line options here http://sourceforge.net/userapps/mediawiki/alex-sh/index.php?title=Embedding_GTK%2B.
  2. You can compile these bindings into a static library if you so wish, importing this into your program to avoid compiling GtkD over and over. Use the command bud gtkD.brf within the ‘\src\build\’ directory to build.
  3. When an import declaration is processed in a D source file, the compiler searches for the D source file corresponding to the import, and processes that source file to extract the information needed from it. Alternatively, the compiler can instead look for a corresponding D interface file. A D interface file contains only what an import of the module needs, rather than the whole implementation of that module. The advantages of using a D interface file for imports rather than a D source file are: D interface files are often significantly smaller and much faster to process than the corresponding D source file. They can also be used to hide the source code, for example, one can ship a static library along with D interface files rather than the complete source code.
  4. Pragmas can be used in conditional statements, to provide preprocessor functionality, or to provide implementation-defined information to the compiler.

No comments yet.

Submit a Comment

We would love to hear your thoughts. Feel free to submit a comment and join the conversation!

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">