Recently it appeared to me that, with D, I could finally solve a long standing problem, that is write a good advanced installer.
What appealed to me were the following features:
- Statically linked. Produce an EXE with no dependency! (Save for win32 that is, fair enough!)
- Elegant syntax on par with C# and Java
- Compile time executable code, making it easy to include “resource” files (zip and include file to install inside the installer)
- Finally with a nice IDE and GUI library (almost as good as a slim WinForm)
- Can directly call into C (I plan to call into the MsiXXX function) at no cost!
So I started to try to use it.
Ho boy, just having 1 program, using 1 custom library to compile was quite an odyssey! Hopefully, this blog entry could save future language explorer!
First thing first, you’ll need to download and installer the D SDK (the compiler, linker, runtime library, etc. The whole shebang!) That can be found there:
Unzip the latest version of DMD somewhere, you are done! Now that was easy.
And if you heard about DM / DMC, don’t worry about it. It was for D1, just ignore it.
Well, arguably you can go with the command line. The compiler flags and linker flags are simple enough. Yet I’m too spoiled by VS, I need my IDE!
In fact, on the D2 page, following the Editor link on the left (in Tools), I found 3 which were attractive: D-IDE, Entice and Visual D.
D-IDE is cool because it’s C# but that’s about it (it’s still basic and buggy, sadly).
Entice is a GUI designer. It was exciting at first, but I deleted it in the end because it is used for DFL or DWT which both requires to overwrite the base runtime library (aka Phobos). Which I don’t quite feel like doing yet.
And, finally, Visual D, a plug in for Visual Studio. Create D projects in Visual Studio, yoohoo! Download and install it now.
3. My First Program
You can create a new module with Visual D (new D project), press F5, and voila, hello D world!
Now I wanted to create a GUI Hello world!
I had a look at DFL and DWT. DFL looks lighter / smaller and good enough for my need. Yet they both required Tango, which seem to be a popular D BCL (aka Phobos) replacement. Well that ended it for me. Tango might be popular but I’m not going to replace my BCL when I can’t even compile a(n advanced) program yet (you’ll see my library trouble next).
Finally, I found DGui. Looking like WinForm. Depending just on Phobos (the BCL).
I downloaded, unzipped, copied a sample (in the sample directory) into my “hello.d” file and tried to compile.
Now the problems started…
First error would be:
Error 1 Error: module all is in file 'dgui\all.d' which cannot be read C:\Dev\DTest\DTest1\hello.d 3
This is due to the
import statement at the top:
3.a. File and Hierarchy Structure
D has 2 ‘code unit’ if I may call it that way. Module and package. It’s a bit like classes and packages in Java. A module is everything in one file. I’m not yet sure if the module should be named after the file it’s in, but that, at least, seems to be the convention.
The package is a folder of source code.
When I wrote “
import dgui.all”, the compiler looked for the module “
all” (i.e. the file “
all.d”) in the package (i.e.
I need to specify the search path for those modules / packages for this to work. Go to project properties => Configuration => DMD and add the path to the source of the library.
Press F5, now we get an other error! (i.e. we progressed!…)
3.b. Declaration File
So, what’s going on? And why does it look for a ‘.d’ file (a source file! I want to use the library, not recompile it!)
Here is what happens, the compiler needs some declaration to describe the function that is going to be called. They could be defined inline in the program (if calling into Win32 from D for example, much like DllImport in C#), but more generally, you will look at declaration file defined by the library. There are 2 options there:
- Unlike C, where the developer should maintain and synchronise a definition (header / .h) and an implementation (.c /.cpp) file, D can use a single implementation file for both purpose. Hence, it will look in the original D source file.
- If there is a need to protect some intellectual property, the developer can an generate an ‘interface file’ when compiling (ordinary D file with the ‘.di’ extension and only declaration inside) and deploy these instead of the source code.
Much like C, C++ and other native environment, compiling D is a 2 stage program. First compiling the source files into object files (.o) and then linking all those files into various target (library (.lib or .dll), executable (.exe)).
But it’s all done on the key stroke of F5, hence a catch all usage meaning of compile for both compiling (making object files) and linking (creating the final output).
When I ‘compile’ now, I get those kind of errors:
Error 1 Error 42: Symbol Undefined _D4dgui4form4Form13startPositionMFNdE4dgui4core5enums17FormStartPositionZv C:\Dev\DTest\DTest1\
Error 2 Error 42: Symbol Undefined _D4dgui7control7Control4sizeMFNdS4dgui4core8geometry4SizeZv C:\Dev\DTest\DTest1\
Error 3 Error 42: Symbol Undefined _D4dgui6button6Button6__ctorMFZC4dgui6button6Button C:\Dev\DTest\DTest1\
And so on.
Symbol alien_looking_name’ generally mean a linker problem. It just happened that Visual D created a “buildlog.html” as well as a “$(project).build.cmd” file in the output folder. So you can see what command it ran to compile and the link the program.
Now I guess I need to include dgui.lib in my project. So go to project properties => linker and set the libraries and search path.
Now it still doesn’t compile and give me this warning:
Warning 1 Warning 2: File Not Found dgui.lib C:\Dev\DTest\DTest1\
I can see in the cmd file or build log that it build with the following command:
set PATH=C:\D\dmd2\windows\bin;C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\\bin;%PATH%
Now I can see in D Linker’s documentation that
DMD_LIB is not used, it is
LIB that is used. I guess it’s a little bug with Visual D (maybe it was made for D1?) at any rate, I solved it by setting the whole path to the
F5… build succeeded!
4. Bonus, Compile DGui
Well, one could add all the file of DGui in Visual D I guess. But DGui comes with a “dgui_build_rel.bat”, I should use it, don’t you think?
Well, all I had to do was to add the path to dmd.exe (i.e. C:\D\dmd2\windows\bin\) to the
PATH environment variable.
As found in System Property => Advance System Settings => Advanced => Environment Variables…
Now I can just click on the bat file and… DGui build successfully, that was easy!
That’s it, I showed how to install D, install a library and compile a program using it!