Tuesday, November 20, 2007

LDFLAGS and −−as−needed

Now that I discovered this nice flag I checked a few of my packages. It works nice for the gnome-chemistry-utils application packages. Unfortunately libgcu0 does not benefit from the flag because of libtool bug #347650. However there is an appreciably difference in the dependencies for the plugin and application packages, where the amount of dependencies decreased. For example compare the old

Depends: iceweasel | iceape-browser | xulrunner, libart-2.0-2 (>= 2.3.18),
libatk1.0-0 (>= 1.20.0), libc6 (>= 2.6.1-1), libcairo2 (>= 1.4.0), libgcc1 (>= 1:4.2.1), libgconf2-4 (>= 2.13.5),
libgcu0 (<< 0.9), libgcu0 (>= 0.8), libgl1-mesa-glx | libgl1, libglade2-0 (>= 1:2.6.1), libglib2.0-0 (>= 2.14.0),
libglu1-mesa | libglu1, libgnomecanvas2-0 (>= 2.11.1), libgnomeprint2.2-0 (>= 2.17.0),
libgnomeprintui2.2-0 (>= 2.17.0), libgnomevfs2-0 (>= 1:2.17.90), libgoffice-0-4 (>= 0.4.2),
libgsf-1-114 (>= 1.14.7), libgtk2.0-0 (>= 2.12.0), libgtkglext1, libice6 (>= 1:1.0.0), libnspr4-0d (>= 1.8.0.10),
libopenbabel2, liborbit2 (>= 1:2.14.1), libpango1.0-0 (>= 1.18.3), libsm6, libstdc++6 (>= 4.2.1), libx11-6,
libxml2 (>= 2.6.27), libxmu6, libxt6, zlib1g (>= 1:1.2.3.3.dfsg-1)

and the new Depends field for gcu-plugin:

Depends: libc6 (>= 2.6.1-1), libgcc1 (>= 1:4.2.1), libgcu0 (<< 0.9),
libgcu0 (>= 0.8), libglib2.0-0 (>= 2.14.0), libgnomevfs2-0 (>= 1:2.17.90), libgtk2.0-0 (>= 2.12.0),
libnspr4-0d (>= 1.8.0.10), libstdc++6 (>= 4.2.1), libx11-6, libxml2 (>= 2.6.29), iceweasel | iceape-browser |
xulrunner

As another example bluefish now (the next upload) really only shows the necessary dependencies. Compare the current:

Depends: libart-2.0-2 (>= 2.3.18), libaspell15 (>= 0.60),
libatk1.0-0 (>= 1.20.0), libbonobo2-0 (>= 2.15.0), libbonoboui2-0 (>= 2.15.1), libc6 (>= 2.6.1-1),
libcairo2 (>= 1.4.0), libfontconfig1 (>= 2.4.0), libgconf2-4 (>= 2.13.5), libglib2.0-0 (>= 2.14.0),
libgnome2-0 (>= 2.17.3), libgnomecanvas2-0 (>= 2.11.1), libgnomeui-0 (>= 2.17.1),
libgnomevfs2-0 (>= 1:2.17.90), libgtk2.0-0 (>= 2.12.0), libice6 (>= 1:1.0.0), liborbit2 (>= 1:2.14.1),
libpango1.0-0 (>= 1.18.2), libpcre3 (>= 6.0), libpopt0 (>= 1.10), libsm6, libx11-6, libxcomposite1 (>= 1:0.3-1),
libxcursor1 (>> 1.1.2), libxdamage1 (>= 1:1.1), libxext6, libxfixes3 (>= 1:4.0.1), libxi6, libxinerama1,
libxrandr2 (>= 2:1.2.0), libxrender1

to the “upcoming” Depends field:

Depends: libaspell15 (>= 0.60), libc6 (>= 2.7-1), libglib2.0-0 (>= 2.14.0),
libgnomeui-0 (>= 2.17.1), libgnomevfs2-0 (>= 1:2.17.90), libgtk2.0-0 (>= 2.12.0), libpango1.0-0 (>= 1.18.3),
libpcre3 (>= 6.0)

Nice result. I should check (my) other packages too :) Maybe that's also something for debichems TODO list.

Monday, November 12, 2007

GNU make vs. BSD make - a practical problem experience

I'm currently evaluating Olivier Sessinks jailkit to maintain a small cvsd CHROOT with an included SSH server. The cvsd-buildroot command e.g. doesn't handle the libpam-modules dependency in the CHROOT. So I tried to update the Debian packaging files included in the jailkit source. During this work I found some issues with the build environment - e.g. no DESTDIR support and some other stuff (another user already complained, that there might be problems with the SUID installation part for jk_chrootsh, jk_uchroot and jk_procmailwrapper of the Makefiles).

So I began to check and “fix” the Makefiles and the configure script and then sent everything to Olivier. I did not only add the DESTDIR variables. I also made use of built-in rules, common variables (also for implicit rules), ... and such stuff to make the Makefiles shorter and easier to maintain. My fault: I tested everything with GNU make. Now Olivier complained, that BSDs make doesn't work anymore. So we began a short hack session to check for the problems.

My first issue: I had to find some BSD make to test it myself. I found it in the freebsd5-buildutils, that contains the freebsd-make command. Then we began to check for incompatibilities and that's the result:

  1. ifdef statements differ in syntax
    • GNU make uses ifdef VAR
    • BSD make uses .ifdef VAR

    solution: We replaced the statement with a construct similar to AM_CONDITIONAL. But we do not use this macro, because it would need to be shipped in aclocal.m4, which is currently not necessary. The code simply sets a variable foo_TRUE to ‘# ‘, if the condition is wrong, or the variable is left empty, if the condition is true:

    if test "x$my_condition" != "xno" ; then
        AC_SUBST([foo_TRUE], [])
    else
        AC_SUBST([foo_TRUE], [# ])
    fi
    FILES = bar
    @foo_TRUE@FILES += foo
  2. prerequisite variables differ in syntax
    • GNU make uses $<, $^, $@, ...
    • BSD make uses ${.IMPSRC}, ${.ALLSRC}, ${.TARGET}, ... (note, that both *SRC variables hold a list of source files)

    Unfortunately both make implementations don't seem to share a variable for the list of prerequisites. So the only solution is to list all prerequisites in the rule again. A variable would be much more comfortable. Maybe one could write a function, that first tests ${.IMPSRC} and falls back to $^. Maybe that's an alternative, but it's IMHO not a very good solution. We've chosen to write down all prerequisites in a rule instead of using a variable. This is a little bit harder to maintain, but it works.

  3. built-in rules are not shared and do not use the same variables
    • GNU make ships built-in rules to build objects from sources and link them; rules consider CPPFLAGS
    • BSD make ships built-in rules to build objects from sources, but there are no rules to link them; rules do not consider CPPFLAGS

    In the case of GNU make, one can simply write:

    myprog: foo.o bar.o

    and GNU make will automatically create foo.o from foo.c (.c.o:, ditto for bar.o) and at least link myprog (.o:). But BSD make will only create the object files. There is no final link-step. So we had to include the rule to link the program in the Makefile.

Finally we got it and it looks good now. I/We learned a lot of new things (I learnd a lot about BSD make) ;), but it took us 1-2 hours to understand and fix the problems.

Here a list of URLs that might give some more information about the programs, their syntax and limitations:

Tuesday, November 6, 2007

Experiences with the “new” fglrx-driver 8.42.3 package

Yesterday I found some minutes to update my kernel. Because I did not have time to compile a 2.6.22 kernel, I simply installed linux-source-k7 (linux-source-2.6-k7). This was a “welcome” occassion to update the ATI/AMD Linux driver for my Radeon X1650 Pro graphics card to their latest version 8.42.3.

As a first step I had to find out, that upgrade from my 8.38.x version did not seem to work properly. I got some error messages regarding the diversions in /usr/lib/fglrx/diversions/. So I purged the fglrx* packages. Then I manually removed the diversions, the (now) empty /usr/lib/fglrx/diversions/ directory and the configuration directory /etc/ati:

$ apt-get remove --purge fglrx-driver fglrx-kernel-src fglrx-control
$ dpkg-divert --remove /usr/llib/libGL.so.1
$ dpkg-divert --remove /usr/llib/libGL.so.1.2
$ rm -rf /usr/lib/fglrx /etc/ati

Then I reinstalled the fglrx* packages, installed the headers linux-headers-2.6-k7 and prepared the flgrx module package with m-a:

$ m-a prepare
$ m-a -l 2.6.22-3-k7 build fglrx

Installing the package and rebooting brought up the system again. glxgears shows around 3000 FPS. However, although everything seems to work properly, I found some log entries and errors, that concern me.

First thing is, that fgl_glxgears refuses to work.

$ fgl_glxgears
Using GLX_SGIX_pbuffer
X Error of failed request:  GLXUnsupportedPrivateRequest
  Major opcode of failed request:  131 (GLX)
  Minor opcode of failed request:  16 (X_GLXVendorPrivate)
  Serial number of failed request:  42
  Current serial number in output stream:  43

Looking into the Xorg.0.log shows me this error:

(EE) fglrx(0): Failed to enable interrupts.

And dmesg shows this:

[fglrx] IRQ_MGR is disabled untill GART_CACHABLE memory will be implemented<6>
[fglrx] Internal AGP support requested, but kernel AGP support active.
[fglrx] Have to use kernel AGP support to avoid conflicts.
[fglrx] AGP detected, AgpState   = 0×1f000217 (hardware caps of chipset)
agpgart: Found an AGP 2.0 compliant device at 0000:00:00.0.
agpgart: Putting AGP V2 device at 0000:00:00.0 into 4x mode
agpgart: Putting AGP V2 device at 0000:01:00.0 into 4x mode
[fglrx] AGP enabled,  AgpCommand = 0×1f000314 (selected caps)
[fglrx:firegl_lock] *ERROR* Process 32648 is using illegal context 0×00000003

This is very similar to everything I read at e.g. phoronix.com. So if you read between the lines: I did not find a solution nor an answer to the shown error message(s) nor the runtime error. So if you know, what's causing this and how it can be solved, please let me know.

At least the good news is: XVideo seems to work again. No juddering video playback. I like that. Now the bad news: It still burdens my CPU (causes a constant usage of 50-70%). I can even observe this effect when the screensaver is running ... and I think, this is NOT the intended design. So I turned off the screensaver for now and simply make the screen go black and lock.

PS: Maybe I will have a look at updating the fglrx manpages (@ATI/AMD: They are still offered for adoption!)

Sunday, November 4, 2007

svn-buildpackage, debian/ only and dpatch-edit-patch

I guess, we (the debichem developers) are not the only people doing some collaborative package maintenance using a SVN-server (just look at svn.debian.org) and svn-buildpackage. To avoid duplication of source code we decided to only keep the Debian packaging files under version control (this also leads to less checkout traffic).

This layout has a problem. You cannot directly create patches, because the SVN of course misses the source code of the package. Fortunately, there is a solution for dpatch users. The dpatch-edit-patch utility provides a switch to handle the above described design: the -b switch. Now all we have to do is, to tell dpatch, where to find the .orig.tar.gz tarball. There is another utility used for this task: dpatch-get-origtargz. This small tool does the following:

  1. check if the tarball can be found in the location given by the DPEP_GETORIGTARGZ environment variable or the conf_getorigtargz option (${HOME}/.dpatch.conf)
  2. try to get the tarball from the Debian archive
  3. try to get the tarball using debian/watch

I don't want to speak about the possibilities 2 and 3. Interesting is the possibility 1. In my case, I have the SVN directories under /usr/local/src/packages/pkg-${PACKAGE} and the tarballs under /usr/local/src/packages/${PACKAGE}. So I tell dpatch the following via ${HOME}/.dpatch.conf:

PACKAGENAME="$(dpkg-parsechangelog | \
        sed -n '/^Source:/{s/^Source:[[:space:]]\+\(.*\)/\1/;p;q}’)”
UPSTREAMVERSION=”$(dpkg-parsechangelog | \
        sed -n ‘/^Version:/{s/^Version:[[:space:]]\+\([0-9]\+:\)\?\([^-]\+\).*/\2/;p;q}’)”

conf_origtargzpath=”/usr/local/src/packages/${PACKAGENAME}”

Now some of you might use different locations of the .orig.tar.gz tarballs. I've created another example dpatch.conf to satisfy such needs. Just adjust the if...else construct to adjust the following ${HOME}/.dpatch.conf for your needs:

PACKAGENAME="$(dpkg-parsechangelog | \
        sed -n '/^Source:/{s/^Source:[[:space:]]\+\(.*\)/\1/;p;q}’)”
UPSTREAMVERSION=”$(dpkg-parsechangelog | \
        sed -n ‘/^Version:/{s/^Version:[[:space:]]\+\([0-9]\+:\)\?\([^-]\+\).*/\2/;p;q}’)”

if [[ `pwd` =~ '^.*/debian-med/trunk/packages/.*$' ]]
then
        conf_origtargzpath=”/usr/local/src/packages/debian-med/trunk/packages/${PACKAGENAME}”
else
        conf_origtargzpath=”/usr/local/src/packages/${PACKAGENAME}”
fi

What about quilt-users? Well, I did not yet use it, so I cannot tell you, what to do here. But I'm sure, there is some way to realize the same behaviour.

Update

The tool svn-do can be used to create quilt patches.