Monday, November 09, 2009

Fun with the Debian ARM collection + Building with Scratchbox Part I

There have been a few packages that I simply cannot configure for the ARM platform. These past few weeks I have attempted to build some rather hefty applications that have dozens of dependencies. The way things go, I usually get about three or four dependencies deep when I hit one that just won't 'make' without a pile of errors. Being the non-programmer that I am, I do what anyone else would do. And that is to run the error message through Google and then read through whatever mailing list or forum that I come across. At the end of the day, I usually end up with a pile of compiled and installed libraries - which don't do me any good.

That is, until I found the Debian ARM ports collection. This collection of software includes packages, source code, and patches. Naturally, just taking a compiled binary and dropping it onto the Z2 is not going to work. It's not that easy! And I don't mind building things from source code ... when the source code builds correctly. That's were the source code and patches come into play.

Take for example: gettext. This old GNU utility builds pretty easily on most platforms. But the ARM branch of Debian (and the Zipit Z2 Shell) were built with ulibc. ulibc is a work-alike clone to GNU libc (aka glibc). But there are those little nuances that get under your skin. I found myself beating my head against the wall Saturday afternoon because ulibc doesn't support some sort of program error checking routine. The result is that you cannot build gettext without modifying some code which is well beyond my capabilities. The ulibc folks could probably fix this. But they throw the blame at the glibc folks for supporting a routine which really serves no purpose. While they are busy fighting like a bunch of children (this argument is a couple years old) I still don't have a working gettext!! Surely there are people out there who are smarter than me and who can fix this broken code. There are. And *maybe* they have fixed it. Here is where I go next ...

First, I browsed out to Debians Etch package page for the ARM platform. You can find it here:

After some browsing around (DANGER: the search at the top of the page leads you away from the ARM platform stuff!!) you might find that gettext is available from the "Development" category. Here is the page where the source code was located: Take a look at it now. On this page I can see that gettext has some dependencies which are displayed with a red bullet. While it may be lousy that I have another couple dependencies to install - at least I know I can build them without errors! Time, I have. Development skill - not so much. Assume that we have satisfied all of it's needs (ignoring the libc needs, since Scratchbox provides ulibc for us).

On the right side of the page there are several links for downloading the chunks of code. There is the package itself (some pre-compiled binaries that "might" work, but probably won't). There is the original source code (the tar-ball has the word "orig" in it's title). Most importantly, there is the "patch file" which will always end with "diff.gz". The patch file is what will correct the source code for us so that we can build it properly for our Z2 ARM platform.

If you haven't figured this out yet - it helps to be connected to your Scratchbox development PC in a terminal window, with a browser opened on your regular PC. Then you can copy and paste links directly into scratchbox without weighing it down with whatever else you are running (like the web browser).

So, we would start up Scratchbox and fetch the files we need:

tar -xzf gettext_0.16.1.orig.tar.gz
cd gettext-0.16.1

Now before we start building anything, we need to patch the source code for the Debian ARM platform:

gzip -d gettext_0.16.1-1.diff.gz
patch -p1 < gettext_0.16.1-1.diff

At this point we would run './configure', and then when it was complete we would run 'make' or 'make install'.


But it's not that easy. Gettext *STILL* won't install. Even with the patches. Why is that? Well, because the Debian folks didn't use ulibc. They used the full fledged GNU libc, or glibc. You are still going to get those damned error messages. Grrr! But hey, someone else had to have gotten these errors before. And if you start Googling around you will find what fixes it, which are these two pages:

Here are what the patches entail. Note that these patches were created for version 0.16.1, which was the version I was attempting to build. If I was using the latest and greatest gettext from the folks at GNU, I might have to do some further digging or investigating. As it was, I was able to read the patch snippets and make sense of them. Here are those snippets.

--- gettext-0.16.1/gettext-tools/src/msgfmt.c 2006-11-27 17:02:08.000000000
+++ gettext-0.16.1/gettext-tools/src/msgfmt.c 2007-07-18 20:12:58.000000000
@@ -194,6 +194,7 @@
static void read_catalog_file_msgfmt (char *filename,
catalog_input_format_ty input_syntax);

+void (*error_print_progname) (void) = NULL;

main (int argc, char *argv[])

And ...

--- gettext-0.16.1.orig/gettext-tools/gnulib-lib/error.h 2006-11-27 18:14:50.000000000 +0100
+++ gettext-0.16.1/gettext-tools/gnulib-lib/error.h 2007-06-20 13:29:32.000000000 +0200
@@ -50,7 +50,10 @@ extern void error_at_line (int __status,
/* If NULL, error will flush stdout, then print on stderr the program
name, a colon and a space. Otherwise, error will call this
function without parameters instead. */
-extern DLL_VARIABLE void (*error_print_progname) (void);
+#ifndef __UCLIBC__
+void (*error_print_progname) (void);

/* This variable is incremented each time `error' is called. */
extern DLL_VARIABLE unsigned int error_message_count;

To apply the snippets you can:
1) Create two files, with these snippets and save the files as somefilename.diff. Then run 'patch -p1 < somefilename.diff'.

Now, since I had all ready started building my application and bombed in the middle somewhere, I should clean everything up and start over.

make clean

Ten minutes or so later, you should be done. And if you didn't get any errors. You can now "make install".

That's it! You are one step closer to compiling some giant peice of software. Now, where was I in the list of dependencies when I got stuck trying to solve this? If you get lost or sidetracked, you might never make your way back to where you were when the problems started. For that reason, I often create a running list for myself. If I try to install one program that requires three more, I document them and use simple tab indentation to indicate what is a dependency. Your end result will be a big messy tree that gives you some indication of how many frustrating hours it will take to get this all done. It's also good to document what you have had to do that is "special" to get something to build. If you have to start over later, it might be good to have those notes.

Here is the "tree" as it looked when I was building gettext. An "X" indicated that I completed it. Question marks mean that I think something might be required, even though the Debian pages didn't mention it as a requirement. In other words, there were massive build failures and I had to take a guess at what I was missing. Your notes and abbreviations may vary.

centerim (4.22.5-1~bpo40+1) -
libcurl3-gnutls (>= 7.15.5-1)
libgnutls13 (>= 1.4.0-0)
X zlib1g (>= 1:1.2.1)
libcomerr2 (>= 1.33-3)
libidn11 (>= 0.5.18)
libldap2 - (configured with: CPPFLAGS="-I/usr/local/BerkeleyDB.4.2/include"
LDFLAGS="-L/usr/local/BerkeleyDB.4.2/lib" ./configure,, make depend,, make
X ?? (undocumented requirement) gettext (0.16.1-1)
?? (undocumented requirement) intltool - installaed intltool-0.40.6
X XML::Parser
X ?? expat - installed expat-2.0.1
?? (undocumented requirement) iconv - installed libiconv-1.9.2
X libgnutls13 (>= 1.4.0-0)
X libgpg-error0 (>= 1.4)
X libgcrypt11 (1.2.3-2)
X libgpg-error0 (>= 1.2)
X liblzo1
X libopencdk8 (>= 0.5.8)
X libgcrypt11 (>= 1.2.2)
X libgpg-error0 (>= 1.4)
X zlib1g (>= 1:1.2.1)
X libtasn1-3 (>= 0.3.4)
X zlib1g (>= 1:1.2.1)
X libsasl2-2 (2.1.22.dfsg1-8+etch1) - installed to /usr/local/lib/sasl2
X libdb4.2 (4.2.52+dfsg-2)
X (undocumented requirement) libssl0.9.8 (0.9.8c-4etch9)

1 comment:

  1. I'm learning Scratchbox for my new Nokia N900 and I must say your little explanatory text was very helpful. Thanks :-)