Wednesday, September 27, 2006

CMake and Autotools

I'm very grateful that somebody (Joe Cooley) contributed Autoconf and Automake files for the PBC library that I maintain. The GNU Autotools are almost essential because many people expect its presence and are used to compiling packages on Unix by typing ./configure followed by make. For the same reason, the Autotools give the project a more mature appearance. And they really do allow painless compilation on many systems.

But there is a dark side to using the GNU build system. The PBC source packages increased by several hundred kilobytes. I notice this extra weight because I often use wireless networks. Additionally, build times are at least twice as slow. On one run, it took 37 seconds to compile PBC, compared to 13 seconds with the original handwritten Makefile. And that's not counting the 13 seconds for ./configure and the 4 seconds for ./setup.

Furthermore, one has to be fluent in m4 and various configuration file formats, and understand how the toolchain works to create and maintain the build system. I was never motivated enough to learn all this, and I haven't changed. Any modifications I make to the Autoconf and Automake files are based on what I see there already, or a brief Google search.

It seems some people were sufficiently dissatisfied with the Autotools that they offered a substantial sum to anyone who wrote a better build tool. The winning project was SCons, which I experimented with last time I needed a build tool with more features than make.

But now a different tool has caught my attention, ever since I read this article. The KDE project ran into trouble with the Autotools, and began searching for alternatives. Like me, they found SCons promising, but after further investigation decided to switch to CMake.

Porting KDE to different platforms is highly nontrivial, so I reasoned that if CMake worked for such a substantial project, odds are good that it would work for my tiny library. I'm following by example I guess, and it certainly isn't the first time. I use git because it works for managing the Linux kernel source, and I use C because it works for countless important parts of the system (including of course the kernel), and for many well-respected programmers across several generations.

While researching CMake I found more arguments for switching: autoconf/automake is insane, glowing reviews of CMake (in the comments section), another endorsement and an interview with a CMake author.

I had a CMakeLists.txt file up and running fairly quickly, as the syntax is quite simple. Running times are much better: CMake took a couple of seconds to generate a Makefile, which in turn only took a second longer than my handwritten one to compile PBC. I was also pleased by the clean and colourful output.

Unfortunately, CMake is not installed on many systems. And it must be relatively untested. How does it compare to the Autotools on less mainstream platforms? And what about the more obscure tasks that the Autotools excel at? For example, is it difficult to get CMake to cross-compile a project?

For now, I'll have to maintain two sets of build configuration files in parallel, but I hope one day CMake will be equally well-known and widespread so I can jettison the autoconf/automake baggage.

Thursday, September 21, 2006

A Tale of Two Hacks

Years ago I wrote rcenter which has long been superseded by the LIRC project. I finally switched to LIRC myself. I wonder if anyone out there is still using rcenter.

It took me a while to figure out that LIRC does not work with OSS drivers unless Stephen Beahm's midi poll patch has been applied. I decided to switch to the ALSA drivers to avoid this issue. But then I had to set some other module options: snd-emu10k1 enable_ir=1 extin="0x3fc3" extout="0x1fff".

I wrote xmmspipe almost simultaneously, and in contrast, this project isn't obsolete yet. In fact, I recently discovered it has been an official Gentoo Linux package for some time when I received a bugfix for it.

It's times like these when I feel warm and fuzzy. I get to experience first-hand some of the touted benefits of free software. Having the source open means thankfully someone else can solve the problem. Even if I managed to fix the bug myself, I probably would've spent hours doing so.

On the other hand, I wouldn't mind if xmmspipe were obsolete and named pipes came with XMMS by default. I'm reminded of a quote from Doug McIlroy:

This is the Unix philosophy. Write programs that do one thing and do it well. Write programs to work together. Write programs to handle text streams, because that is a universal interface.

and one from Rob Pike:

There has been much talk about component architectures, but only one true success: Unix pipes.

Thursday, September 14, 2006

Mental Feats

Michael Curtis (who commented on a previous posting) has written several articles on mental feats involving memory and mathematics.

Coincidently, I too read about the Trachtenberg system (a method for performing mental arithmetic) many years ago.

Reading his site reminded me of a time when I'd relieve boredom during occasions such as high school assemblies by squaring 2-digit numbers in my head using the techniques I had read about.

Today, I'd still use Trachtenberg's method for numbers ending in 5, based on the equation (10 a + 5)^2 = 100 a (a+1) + 25. However I have since found faster methods for other numbers, which I haven't seen described on the web. They only require additions and subtractions, but one has more to memorize.

Let n be the 2-digit number to be squared. Then if n lies in the range:

  1. 0-25: Memorize these answers.
  2. 25-50: Work out how far n is from 50 and how far n is from 25. Then the answer is 100(n - 25) + (50 - n)^2.
  3. 50-75: Compute 100((n-50) + 25) + (n-50)^2. (This is also Trachtenberg's method for squaring fifty-somethings.)
  4. 75-100: Compute 100(100 - 2(100-n)) + (100-n)^2

While I'm at it, I'll record a method for finding square roots (of squares of 2-digit numbers):

  1. Remove the last two digits of the square. Then the first digit of the answer is the largest digit whose square is less than this number.
  2. The last digit of the square tells us what the last digit of the answer could be. If it is 0 or 5, then so is the last digit of the answer and we are done, otherwise:
  3. Let the first digit of the answer is a. Compare the square with the square of 10a+5. If larger, then the last digit of the answer is between 6 and 9, and if smaller, it is between 1 and 4. Luckily, in base 10, the squares of 1 to 4 have distinct last digits. Also the squares of a and (10-a) end in the same digit, so it is now easy to determine the last digit of the answer.

The corresponding algorithm for cube roots is much simpler, because the cube of each digit has a distinct last digit (and similarly with other odd powers).