Yesterday I stayed up until 4:30 AM while trying to fix Amarok to works on Windows and when I got it to build it was so late I was too tired to test it. So I fired it this morning and this is the result (click for larger images):

I have tested and it plays MP3, WMA, APE and whatever Magnatune streams on. Built with Visual C++ 2008.

Update Two more screenshots added and in case you were wondering, yes, Plasma works!

Yesterday I fixed the Phonon DirectShow 9 backend for Windows. Now audio and video are available to KDE applications on Windows, which means Amarok 2-trunk works! Currently, it can only play .WMA files (I think I have to install the .ax files for the MP3, MIDI, WAV, etc codecs in the KDE bin or libs directory, I’ll try and fix that next week). In the meanwhile, you need patch #6 if you want to build Amarok on Windows and hear something. Please note I’ve only tried to build it with MSVC2005, not MinGW, not MSVC2008 yet.

This afternoon I started to add Visual C++ 2008 support to the emerge tool to build KDE 4 on Windows. After a few changes, I tried to build Qt 4.4.0 but it failed.

“Why, oh why?” I wondered. I had previously built Qt 4.4.0 using VC++2008.

Turns out on this computer I had installed the Visual C++ 2008 Feature Pack, which adds some nice stuff (if the Office 2007 look tastes nice to you) but also breaks some stuff (mostly MFC but also some math functions).

Fortunately, it’s easy to fix the issue: just do not #include <xmath> and everything will work fine. As the same codebase has to work with many other compilers, I cannot just get rid of that line of code: I need to #if-case it for VC++2008 with Feature Pack.

Unfortunately, there is no easy way to check for “VC++2008 with Feature Pack”. Sure, you can check for VC++2008 by checking _MSC_VER >= 1500. Easy. Unluckily, the only way to check for the Feature Pack is to check _MFC_VER (check you have MFC 9.0.30411 instead of 9.0.21022), which is only defined if you #include <afxver_ .h>. Of course that file #includes many other files, which means some ugly, confusing problem is waiting to happen.

How dumb can you be, Microsoft? Why aren’t you changing _MSC_VER, too, and make my life easier?

Apache Log4CXX is a logging framework for C++ patterned after Apache log4j. It also happens to be quite difficult to build on Windows if you are using Microsoft Windows SDK 1.0 (AKA Microsoft Platform SDK 6.0). If you are building software for Windows Vista or Windows Server 2008, or using Visual C++ 2008, you are using Windows SDK 1.0.

The reason Log4CXX 0.10.0 is hard to compile with Windows SDK 1.0 is a bug in APR 1.2.12 (the latest version available as of this writing) and a bug in Windows SDK 1.0 itself (a preprocessor redefinition due to including twice a header file). Here comes the recipe in case you want to build the stuff yourself:

  1. Download APR 1.2.12 and extract it. Rename to apr.
  2. Download APR Util 1.2.12 and extract it. Rename to apr-util.
  3. Download Log4CXX 0.10.0 and extract it
  4. Download GNU Sed and install it
  5. Open cmd.exe and run %PROGRAMFILES%Microsoft Visual Studio 9.0VCvcvarsall.bat
  6. Apply the apr-1.2.12-win32.patch patch to fix bug 40398 in APR 1.2.12 (this step is not needed if you are using APR 1.2.13)
  7. Apply the log4cxx-0.10.0-vc90-support.patch patch
  8. Enter directory apache-log4cxx-0.10.0
  9. Execute configure.bat
  10. Execute configure-aprutil.bat
  11. Open the log4cxx.dsw solution When asked to convert the solution to VC++9, click Yes to All.
  12. Right click on Solution log4cxx and select Build solution

I’m at València, Spain for Guademy 2008.

Guademy is a combined Gnome + KDE conference, hence the name (Guadec + aKademy), where developers of both desktops (actually every free desktop developer is invited) try to improve collaboration. IMHO it should be renamed to “Freedesktop.org Conferences” because that’s what it actually is.

I’ve seen some frienly faces I knew from other FLOSS events (Aleix Pol, Rodrigo Moya, Carlos Garnacho, Will Stephenson) and I’ve met people I had only read so far (Jos Poortvliet, Holger Freyther). There are some people that were not under my radar, too (Richard Hughes, Vincent Untz).

Yesterday we had talk about QtWebkit by Holger. He tried to show us how good Qt integration with Webkitwas. But he failed. Miserably. It’s not good. It’s AMAZING. Thanks to QtWebkit, he was able to wrote a browser with tabs, cookie management, bookmarks and plugin support in 7800 (seventy eight hundred) lines of code. In five days. The only thing missing was SSL certificate management. Awesome. I provided live translation to Spanish, for non-English speaks.

In the afternoon we had a couple of talks about FreeDesktop.org by Rodrigo, Will and Vicent. In the end, I think the problem with FreeDesktop.org is Gnome and KDE are just suggesting, instead of strongly demanding, their developers to work together.

After that, Aleix talked about KDevelop 4 and demoed it. I have to say I’m gratefully surprised by its progess. Last time I tested it (like 5 months ago), it was totally useless. Currently it works and it works reasonable well. I may start using it soon.

After so much talk, we were quite tired and hungry and went to Los Bestias (“The Rudes”) for dinner. It’s not the typical Spanish restaurant, it’s a “funny restaurant”: the bartender threw (literally) salted peanuts all over the our table, they brought us urinaries with beer and sangria, etc. It was quite funny, IMO.

There are two more days of Guademy, I’ll post more tomorrow.

I’m moving a large software package from Visual C++ 2003 to Visual C++ 2008. It depends on 3 years old versions of a lot of third party packages: ICE 3.0.1, ACE 5.4.3, Boost 1.33.1, Qt 4.1, etc.

Those libraries have underwent so many changes that updating the whole software to Visual C++ 2008 and the newest versions of the 3rd party libraries would be a too difficult task to be accomplished in a reasonable amount of time, therefore I’ve decided I’m going to stick to old libraries as much as possible, while moving to Visual C++ 9.0. The next step would be to move to newer versions of the 3rd party libraries or even to remove most of those dependencies and make the software depend only on Qt.

For starters, stock Boost 1.33.1 did not build with VC++ 9.0 but after some digging and tweaking, it works. Here is how:

  1. Download Boost 1.33.1 and uncompress it. It does not support VC++ 9.0.
  2. Apply patch to support VC++ 9.0
  3. Open cmd.exe and run %PROGRAMFILES%\Microsoft Visual Studio 9.0\VC\vcvarsall.bat
  4. boost_1_33_1\tools\build\jam_src and run build.bat
  5. Go to directory boost_1_33_1 and run tools\build\jam_src\bin.nt\x86\bjam.exe -sTOOLS=vc-9_0
  6. Run tools\build\jam_src\bin.nt\x86\bjam.exe -sTOOLS=vc-9_0 install to install to c:\boost

I have started a new open source project: The Digest Software Project. It’s a small project where I develop two tiny libraries, libdigest and libpam-digestfile.

libdigest is a C library which generates RFC2617-compliant digests, used by Apache and others.

libpam-digestfile is a Pluggable Authentication Module which lets you use an arbitrarily-named text file similar in structure to /etc/passwd to authenticate users but using digested passwords (see RFC 2617 for more information about the digest algorithm).

Both libraries are stable and in production.

Did you know the code the compiler generates to handle C++ exceptions is not written in stone? I did not.

Did you know there are two preponderant styles to do that, DWARF(2) and SJLJ? I did not

When most of the unit tests in ZeroC ICE failed after building it with MinGW, I suspected something was wrong. It turned out the stable MinGW version provides gcc/g++ 3.4.5, which implements exceptions using the SJLJ style but has not implemented propagatation of user exceptions across libraries. That was the reason why unit tests were failing.

I have already built third party dependencies (OpenSSL, Bzip2, Expat and BerkeleyDB) with a gcc/g++ 4.2.1 which produces SJLJ code and is able to propagate user exceptions. ICE is now building on the side (some warnings and info messages are shown, let’s see what happens as some of them are not my fault).

I am creating Debian packages for a SNMP library in C++ which unfortunately does not properly set soname or versioning information in the makefile. It is unacceptable to ship a library in those conditions under Debian guidelines.

If you are a C programmer you don’t need to worry as binary-compatibility is usually not an issue in C as it lacks polymorphism.

If you are a C++ programmer and you don’t know what an ABI is and why binary compatibility matters, you must first read and understand what an API, an ABI and name mangling are.

Even if you already knew about ABI and name mangling, you probably don’t know about binary compatibility in shared objects (libraries). Don’t worry: ABI-compatibility is non-obvius and most C++ programmers don’t know a word about that.

The idea is quite simple: if you uncarefully change the API of your library you have also changed the ABI of your library and, most probably, due to name-mangling and virtual tables (needed to support polymorphism), the new version of the library is ABI-incompatible with the older version.

There are two kind of changes you can make: extend the API/ABI but leave it compatible with former versions, or extend the API/ABI and break binary-compatibility. There is very good information about what changes render your library binary-compatible and which don’t in the KDE wiki and in the Qt FAQ.

Once ABI compatibility is clear, the next question arises: how does my library state its binary compatibiliy? There are essentially two mechanisms for that: the Sun Solaris-specific mechanism (which is great, by the way) and sonames (used by most other Unices and Linux). There is plenty of information about sonames at the libtool manual and the Debian Libraries Packaging Guide and a good example at LinuxQuestions. For more information about the Solaris mechanism, read carefully the DSO howto by Ulrich Drepper (page 35, section 3.3: “ABI Versioning”).

Two important things you have to remember:

  • If your library version is the same as your soname version, you have not understood a thing of what I said above
  • If your library is stable, follow these guidelines.

In case you really want to keep ABI-compatibility for whatever reason (you are developing a very spreaded C++ library and the user might have a newer/older version already installed, you don’t want to update versions unless totally necessary, etc), take a look at the opaque pointer technique (AKA D-Pointer) invented by Trolltech.