Ciaran McCreesh’s Blag

July 24, 2008

Paludis 0.28.1 Released

Filed under: Uncategorized — Tags: , — Ciaran McCreesh @ 1:26 pm

Paludis 0.28.1 has been released:

  • Work around compiler issues that eventually lead to unpack dying when it shouldn’t on certain EAPIs on certain systems (ticket:622).

July 22, 2008

GNU ‘make’ Target Specific Variables are Dumb

Filed under: Uncategorized — Tags: , , — Ciaran McCreesh @ 7:41 pm

Let’s say we have a Makefile using some target-specific variables:

$ cat Makefile
foo = global
b : foo = for-b

all : d
        @cat d

a :
        @echo a:$(foo) > a

b : a
        @{ cat a ; echo b:$(foo) ; } > b

c : a
        @{ cat a ; echo c:$(foo) ; } > c

d : b c
        @cat b c > d

Then we can get different results depending upon how we make the ‘all’ target:

$ rm a b c d ; make
a:for-b
b:for-b
a:for-b
c:global
$ rm a b c d ; make a b c d all
a:global
b:for-b
a:global
c:global

This is considered a feature:

There is one more special feature of target-specific variables: when you define a target-specific variable that variable value is also in effect for all prerequisites of this target, and all their prerequisites, etc. (unless those prerequisites override that variable with their own target-specific variable value).

In practice, it’s a pain in the ass. Using Quagmire, you’re supposed to be able to do this:

noinst_SHARED_LIBRARIES = libone.so libtwo.so libthree.so

libone.so_SOURCES = one.c
libone.so : LDFLAGS = -Wl,-soname,libone.so
libone.so_LIBS = libthree.so

libtwo.so_SOURCES = two.c
libtwo.so : LDFLAGS = -Wl,-soname,libtwo.so
libtwo.so_LIBS = libthree.so

libthree.so_SOURCES = three.c

Which leads to some rather bizarre behaviour:

$ make clean all &>/dev/null ; scanelf -S libthree.so
 TYPE   SONAME FILE
ET_DYN libone.so libthree.so 

$ make clean libone.so &>/dev/null ; scanelf -S libthree.so
 TYPE   SONAME FILE
ET_DYN libone.so libthree.so 

$ make clean libtwo.so &>/dev/null ; scanelf -S libthree.so
 TYPE   SONAME FILE
ET_DYN libtwo.so libthree.so 

$ make clean libthree.so &>/dev/null ; scanelf -S libthree.so
 TYPE   SONAME FILE
ET_DYN  libthree.so

I can think of a few not very nice ways of getting around this. Hopefully someone will come up with something better…

July 16, 2008

Hot Fresh Shiny Config Files

Filed under: Uncategorized — Tags: , , , , , , , , — Ciaran McCreesh @ 7:31 pm

I’ve moved my configuration files repository from Subversion to Git, since I’m sick of trying to decide whether my laptop or desktop should hold the ‘master’ copy. For the lulz, I shall also push to GitHub at irregular intervals, so you shall no longer need to pester me to upload newer versions of my bashrc / vimrc / whatever to webspace somewhere. Instead, you can just:

git clone git://github.com/ciaranm/dotfiles-ciaranm.git

Or browse them online.

We’ll see whether this lasts…

Git and Subversion information in the Bash Prompt

Filed under: Uncategorized — Tags: , , , , — Ciaran McCreesh @ 10:10 am

Here’s my variation on the “Git and Subversion status in the bash prompt” thing:

ps_scm_f() {
    local s=
    if [[ -d ".svn" ]] ; then
        local r=$(svn info | sed -n -e '/^Revision: \([0-9]*\).*$/s//\1/p' )
        s="(r$r$(svn status | grep -q -v '^?' && echo -n "*" ))"
    else
        local d=$(git rev-parse --git-dir 2>/dev/null ) b= r= a=
        if [[ -n "${d}" ]] ; then
            if [[ -d "${d}/../.dotest" ]] ; then
                if [[ -f "${d}/../.dotest/rebase" ]] ; then
                    r="rebase"
                elif [[ -f "${d}/../.dotest/applying" ]] ; then
                    r="am"
                else
                    r="???"
                fi
                b=$(git symbolic-ref HEAD 2>/dev/null )
            elif [[ -f "${d}/.dotest-merge/interactive" ]] ; then
                r="rebase-i"
                b=$(<${d}/.dotest-merge/head-name)
            elif [[ -d "${d}/../.dotest-merge" ]] ; then
                r="rebase-m"
                b=$(<${d}/.dotest-merge/head-name)
            elif [[ -f "${d}/MERGE_HEAD" ]] ; then
                r="merge"
                b=$(git symbolic-ref HEAD 2>/dev/null )
            elif [[ -f "${d}/BISECT_LOG" ]] ; then
                r="bisect"
                b=$(git symbolic-ref HEAD 2>/dev/null )"???"
            else
                r=""
                b=$(git symbolic-ref HEAD 2>/dev/null )
            fi

            if git status | grep -q '^# Changed but not updated:' ; then
                a="${a}*"
            fi

            if git status | grep -q '^# Changes to be committed:' ; then
                a="${a}+"
            fi

            if git status | grep -q '^# Untracked files:' ; then
                a="${a}?"
            fi

            b=${b#refs/heads/}
            b=${b// }
            [[ -n "${r}${b}${a}" ]] && s="(${r:+${r}:}${b}${a:+ ${a}})"
        fi
    fi
    s="${s}${ACTIVE_COMPILER}"
    s="${s:+${s} }"
    echo -n "$s"
}

This is added to PS1 as normal.

For Subversion, it gives us the revision, and a * if anything’s been modified.

For Git, we get quite a bit more. If we’re in the middle of a merge, interactive rebase or am, we get told so. If we’re in the middle of a bisect, we get question marks, since I’ve not had to bisect anything since I wrote that code and I haven’t implemented anything fancy for it. We also get the branch, and a combination of * for changed but not updated files, + for changed and committed files and ? for untracked files.

It’s generally sufficiently fast to not be annoying, although the initial cd into a large project can take a few seconds. It’s probably possible to drop to a single ‘git status’ call if performance matters, although the kernel does a pretty good job of speeding up subsequent runs.

July 14, 2008

Edimax EW-7728In 802.11n (RaLink rt2860) with Linux 2.6.26

Filed under: Uncategorized — Tags: , , , , — Ciaran McCreesh @ 4:11 pm

Being sick of wireless disconnecting every time it rained, I got my hands upon a cheap Edimax EW-7728In PCI 802.11n card. This uses a RaLink rt2860 (PDF) chip, which has vendor-supplied open source drivers available. Getting it to work with Linux 2.6.26 is slightly non-trivial, however.

First, we need the drivers. At the time of writing, that means 2008_0522_RT2860_Linux_STA_v1.6.1.0.tar.bz2.

Next, we need to fix a couple of things. First, the Makefile is dumb, and tries to install into /tftpboot:

From 82dc3a8737e4f97311f4f4fccd79ea55a319f1ea Mon Sep 17 00:00:00 2001
From: Ciaran McCreesh <ciaran.mccreesh@googlemail.com>
Date: Mon, 14 Jul 2008 16:47:00 +0100
Subject: [PATCH] Get your filthy paws off my /tftpboot

---
 Makefile |    2 --
 1 files changed, 0 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile
index 72bc933..aed3b00 100644
--- a/Makefile
+++ b/Makefile
@@ -80,11 +80,9 @@ LINUX:
 ifneq (,$(findstring 2.4,$(LINUX_SRC)))
        cp -f os/linux/Makefile.4 $(RT28xx_DIR)/os/linux/Makefile
        make -C $(RT28xx_DIR)/os/linux/
-       cp -f $(RT28xx_DIR)/os/linux/rt$(CHIPSET)sta.o /tftpboot
 else
        cp -f os/linux/Makefile.6 $(RT28xx_DIR)/os/linux/Makefile
        make  -C  $(LINUX_SRC) SUBDIRS=$(RT28xx_DIR)/os/linux modules
-       cp -f $(RT28xx_DIR)/os/linux/rt$(CHIPSET)sta.ko /tftpboot
 endif

 clean:
--
1.5.6.2

Next, dev->nd_net should now be dev_net(dev):

From 0878b37a40e2a7f466a74938920ff3751917eec3 Mon Sep 17 00:00:00 2001
From: Ciaran McCreesh <ciaran.mccreesh@googlemail.com>
Date: Mon, 14 Jul 2008 16:48:50 +0100
Subject: [PATCH] dev->nd_net is now dev_net(dev)

---
 os/linux/rt_main_dev.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/os/linux/rt_main_dev.c b/os/linux/rt_main_dev.c
index 24604da..6a3471d 100644
--- a/os/linux/rt_main_dev.c
+++ b/os/linux/rt_main_dev.c
@@ -669,7 +669,7 @@ static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER p

 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
-        device = dev_get_by_name(dev->nd_net, slot_name);
+        device = dev_get_by_name(dev_net(dev), slot_name);
 #else
                device = dev_get_by_name(slot_name);
 #endif
--
1.5.6.2

Finally, the driver is unusably noisy. Unless you want fifty-odd lines of kernel debug informatione every five seconds:

From 19c7a6895333624566775541fbc836e0c9208225 Mon Sep 17 00:00:00 2001
From: Ciaran McCreesh <ciaran.mccreesh@googlemail.com>
Date: Mon, 14 Jul 2008 16:47:43 +0100
Subject: [PATCH] You shut your dirty whore mouth

---
 include/rt_linux.h |    4 ----
 1 files changed, 0 insertions(+), 4 deletions(-)

diff --git a/include/rt_linux.h b/include/rt_linux.h
index dfe4ab5..079d256 100644
--- a/include/rt_linux.h
+++ b/include/rt_linux.h
@@ -325,10 +325,6 @@ extern ULONG    RTDebugLevel;

 #define DBGPRINT_RAW(Level, Fmt)    \
 {                                   \
-    if (Level <= RTDebugLevel)      \
-    {                               \
-        printk Fmt;               \
-    }                               \
 }

 #define DBGPRINT(Level, Fmt)    DBGPRINT_RAW(Level, Fmt)
--
1.5.6.2

There’s no Makefile install target, so you’ll need to sudo cp os/linux/*.ko /lib/modules/`uname -r`/kernel/ then sudo depmod -a before you can sudo modprobe rt2860sta. You’ll also need to sudo mkdir -p /etc/Wireless/RT2860STA/ then cp RT2860STA.dat /etc/Wireless/RT2860STA/, even though we’re not using that file for any configuration.

Gentoo’s init scripts, if you’re using them, try to be overly clever, and won’t be able to bring up the interface. So use something like this as your /etc/init.d/net.ra0:

#!/sbin/runscript

depend() {
    need localmount
    after bootmisc hostname net.lo net.lo0
    use isapnp isdn pcmcia usb wlan
}

start() {
    bash -x -c 'ifconfig ra0 up'
    bash -x -c 'iwconfig ra0 essid giant-space-monkey key "aa:bb:cc:dd:ee:ff:00:11:22:33:44:55:66" freq 2.417G'
    bash -x -c 'dhcpcd ra0'
}

stop() {
    :
}

restart() {
    :
}

And that appears to be sufficient.

July 7, 2008

Paludis 0.28.0 Released

Filed under: Uncategorized — Tags: , — Ciaran McCreesh @ 3:31 pm

Paludis 0.28.0 has been released:

  • Compilers without tr1 memory, type traits and functional support are no longer supported. This means you, gcc-3.
  • Support for the Exherbo distribution.
  • Better detection of SCM versions.
  • Bug fixes: pkg_pretend now behaves correctly with resumes (ticket:604). Better support for Portage config files (ticket:597). Package dep spec parsing no longer has trailing hyphen issues (ticket:590).
  • New Selection + Filter + Generator interface using Environment, replacing the old PackageDatabase Query (ticket:559).
  • importare can now change file ownership to root (ticket:599).

July 4, 2008

Hardware Vendor Hate List

Filed under: Uncategorized — Tags: , , , , — Ciaran McCreesh @ 6:48 pm
  • Logitech. You helpfully claim to be able to provide replacement feet for keyboards free of charge — presumably, breakages are not exactly uncommon. Then you claim not to keep track of whether or not you have any spares for my year-old G15 keyboard, so you can’t give me any. And no, you won’t go and have a look to find out whether you do have any.
  • Whoever makes the push pins found on LGA 775 CPUs. Especially the kind that require so much force to lock that it’s a race between the motherboard and my finger to see which will break first.
  • Abit. You should be ashamed of the F-I90HD motherboard for all sorts of reasons, but today’s gripe is about the heatsink on the integrated graphics chip. I shouldn’t have to install a cooling fan onto the heatsink to stop the screen from going black when the CPU is under load.

June 29, 2008

Bedtime Reading III

Filed under: Uncategorized — Tags: , , — Ciaran McCreesh @ 11:06 pm

June 13, 2008

On-Demand Loading using Smart Pointers

Filed under: Uncategorized — Tags: — Ciaran McCreesh @ 8:50 pm

Previously, I explained how to implement something like the Active Object thread pattern using smart pointers. Next we’ll use the same trick to implement on-demand, lazy construction.

There’s nothing difficult here, once we realise we can reuse the ‘return a different pointer’ trick. We make use of std::tr1::function rather than a raw function pointer so that parameter values can be bound at pointer-construction time. Again, we parameterise on pointer type, not raw type.

template <typename T_>
class DeferredConstructionPtr
{
    private:
        mutable T_ _ptr;
        std::tr1::function<T_ ()> _f;
        mutable bool _done;

    public:
        DeferredConstructionPtr(const std::tr1::function<T_ ()> & f) :
            _ptr(),
            _f(f),
            _done(false)
        {
        }

        DeferredConstructionPtr(const DeferredConstructionPtr & other) :
            _ptr(other._ptr),
            _f(other._f),
            _done(other._done)
        {
        }

        DeferredConstructionPtr &
        operator= (const DeferredConstructionPtr & other)
        {
            if (this != &other)
            {
                _ptr = other._ptr;
                _f = other._f;
                _done = other._done;
            }
            return *this;
        }

        T_ operator-> () const
        {
            if (! _done)
            {
                _ptr = _f();
                _done = true;
            }

            return _ptr;
        }
};

Again, some caveats:

  • Dealing with const is left to the reader.
  • Dealing with thread safety is left to the next article.
  • If the constructor in question can throw exceptions, the exception will be thrown at what could be a rather unobvious place. This may or may not be a problem.

Building but Not Running Tests with Automake

Filed under: Uncategorized — Tags: , , — Ciaran McCreesh @ 9:01 am

If you’re still stuck using autotools because Quagmire can’t yet do everything you need, you might find this little hack handy…

When making an API change that you know will break lots of your unit tests, it would be nice to have a ‘make check-programs-but-don’t-bother-running-them’ target. Automake doesn’t let you do this — to build check_PROGRAMS, you have to run them (and all the tests in SUBDIRS you already fixed) too. This can get annoying if you’re just wanting the compiler to point out the next place you have to change something. But you can cheat…

make check TESTS_ENVIRONMENT=true

One drawback: if you’re using XFAIL_TESTS, they’ll show up as incorrectly passing. If you don’t have many of these, you can disable them and still gain most of the benefits:

make check TESTS_ENVIRONMENT=true XFAIL_TESTS=
Older Posts »

Blog at WordPress.com.