svn-all-fast-export --identity-map authors.txt --rules pkg-ace.rules svn-pkg-aceHere's the content of the pkg-ace.rules configuration file that was used:
create repository pkg-ace end repository match /trunk/ repository pkg-ace branch master end match match /(branches tags)/([^/]+)/ repository pkg-ace branch \2 end matchThe author mapping file authors.txt being:
markos = Konstantinos Margaritis <email-hidden> mbrudka-guest = Marek Brudka <email-hidden> pgquiles-guest = Pau Garcia i Quiles <email-hidden> tgg = Thomas Girard <email-hidden> tgg-guest = Thomas Girard <email-hidden>The tool sample configuration file merged-branches-tags.rules recommends to post-process tags, which are just a branch in SVN. That's why the configuration file above treats branches as tags. The conversion was indeed fast: less than 1 minute.
svn tags as branches:
Branches are marked with green rectangles, and tags with yellow arrows.
What we have here (expected given our configuration of the tool) are
branches (e.g. 5.4.7-5) corresponding to tags, and tags matching the SVN
tagging commit (e.g. backups/5.4.7-5@224). We'll review and fix this.
merged code that did not appear as such:
Branches that were not merged using svn merge look like they were not
merged at all.
commits with wrong author:
Before being in SVN, the repository was stored in CVS. When it was imported
into SVN, no special attention was given to the commit author. Hence I
got credited for changes I did not write.
obsolete branches:
The tool leaves all branches, including removed ones (with tag on their end)
so that you can decide what to do with them.
missing merges:
The branch 5.4.7-12 was never merged into the trunk!
#!/usr/bin/env ruby # # retag.rb # # Small script to create an annotated tag, specifying commiter as well as # date, and tag comment. # # Based on Scott Chacon "Custom Importer" example. # # Arguments: # $1 -- tag name # $2 -- sha-1 revision to tag # $3 -- committer in the form First Last <email> # $4 -- date to use in the form YYYY/MM/DD_HH:MM:SS def help puts "Usage: retag <tag> <sha1sum> <committer> <date> <comment>" puts "Creates a annotated tag with name <tag> for commit <sha1sum>, using " puts "given <committer>, <date> and <comment>" puts "The output should be piped to git fast-import" end def to_date(datetime) (date, time) = datetime.split('_') (year, month, day) = date.split('/') (hour, minute, second) = time.split(':') return Time.local(year, month, day, hour, minute, second).to_i end def generate_tag(tag, sha1hash, committer, date, message) puts "tag # tag " puts "from # sha1hash " puts "tagger # committer # date +0000" print "data # message.size \n# message " end if ARGV.length != 5 help exit 1 else (tag, sha1sum, committer, date, message) = ARGV generate_tag(tag, sha1sum, committer, to_date(date), message) end
me@mymachine$ echo 6a6d48814d0746fa4c9f6869bd8d5c3bc3af8242 11cf74d4aa996ffed7c07157fe0780ec2224c73e 898ad49b61d4d8d5dc4072351037e2c8ade1ab68 >> .git/info/grafts
#!/bin/sh br="HEAD" TARG_NAME="Raphael Bossek" TARG_EMAIL="hidden" export TARG_NAME TARG_EMAIL filt=' if test "$GIT_COMMIT" = 546db1966133737930350a098057c4d563b1acdf -o \ "$GIT_COMMIT" = 23419dde50662852cfbd2edde9468beb29a9ddcc; then if test -n "$TARG_EMAIL"; then GIT_AUTHOR_EMAIL="$TARG_EMAIL" export GIT_AUTHOR_EMAIL else unset GIT_AUTHOR_EMAIL fi if test -n "$TARG_NAME"; then GIT_AUTHOR_NAME="$TARG_NAME" export GIT_AUTHOR_NAME else unset GIT_AUTHOR_NAME fi fi ' git filter-branch $force --tag-name-filter cat --env-filter "$filt" -- $br(Script edited here; there were much more commits written by Raphael.)
Important
It's important to realize that the whole selected branch history is rewritten, so all objects id will change. You should not do this if you already published your repository.
Hint
Once git filter-branch completes you get a new history, as well as a new original ref to ease comparison. It is highly recommended to check the result of the rewrite before removing original. To shrink the repo after this, git clone the rewritten repo with file:// syntax -- git-filter-branch says it all.
Add graft points where needed.
Clean tags and branches. Using git tag -d, git branch -d and the Ruby script above it was possible to recreate tags. During this I was also able to add missing tags, and remove some SVN errors I did -- like committing in a branch created under tags/.
Remove obsolete branches.
Merge missing pieces. There were just two missing debian/changelog entries. I did this before git filter-branch because I did not find a way to use the tool correctly with multiple heads.
Fix commit author where needed. Using the shell script above Raphael is now correctly credited for his work.
| [1] | http://lists.alioth.debian.org/pipermail/pkg-ace-devel/2011-March/002421.html |
| [2] | available in Debian as svn-all-fast-export |
Curious about these shiny new things i keep hearing about, i set up a test desktop system using using systemd as the init system (yes, that means using systemd-sysv in place of sysvinit -- so i had to remove an essential package for this to work). A system-crippling bug was naturally the result of living on the bleeding edge, but fortunately it was resolved with a trivial patch. In all, i'm pretty happy with some of the things that systemd seems to get right. For example, native supervision of daemon processes, clean process states, elimination of initscript copy-paste-isms, and socket-based service initiation are all obvious, marked improvements over the existing sysvinit legacy cruft. But i'm a bit concerned about other parts. For example, all the above-mentioned features fit really well within a tightly-tuned, well-managed server. But systemd also appears to rely heavily on complex userland systems like dbus and policykit that would be much more at home on a typical desktop machine. I've never seen a well-managed server installation that warranted either policykit or dbus. Also, given the bug i ran into -- when PID 1 aborts due to a silly assertion, your system is well-and-truly horked. Shouldn't a lot more attention to detail be happening? I'd think that a "recover gracefully from failed assertions" approach would be the first thing to target for a would-be PID 1. I'm also concerned about the Linux-centricism of systemd. I understand that features like cgroups and reliance on the spiffiness of inotify are part of the appeal, but i also really don't want to see us stuck with only One Single Kernel as an option. The kFreeBSD folks (and the HURD folks) have done a lot of work to get us close to having some level of choice at this critical layer of infrastructure. It'd be good to see that possibility realized, to help us avoid the creeping monoculture. I worry that systemd's over-reliance on Linux-specific features is heading in the wrong direction. So my question is: why is this all being presented as a package deal? I'd be pretty happy if i could get just the "server-side" features without incurring the dbus/policykit/etc bloat. I already run servers with runit as pid 1 -- they're lean and quite nice, but runit doesn't have systemd's socket-based initiation (or the level of heavyweight backing that systemd seems to have picked up, for that matter). I understand that Lennart is resistant to UNIX's traditional "do one thing; do it well" philosophy. I can understand some of his reasoning, but i think he might be doing his work and his tools a disservice by taking it this far. Wouldn't systemd be better if it was clearer how to take advantage of parts of it without having to subscribe to the entire thing? Of course, i might be missing some nice ways that systemd can be effectively tuned and pared down. But i've read his blog posts about systemd and i haven't seen how to get some of the nice features without the parts i don't want. I'd love to be pointed to some explanations that show me how i'm wrong :)Tags: systemd
i can haz understanding?I m trying to rebuild a package with gcc-4.6 instead of (default) gcc-4.5. Sounds easy, huh?Not today, not with qmake :(Setting CC=gcc-4.6 CXX=g++-4.6 on the command-line does not help. Neither does exporting these in debian/rules. Let s fire up Google, I think I remember qmake tends to prepend EVERYTHING with QMAKE_ Right, official documentation says it s QMAKE_CC and QMAKE_CXX. Setting those on the command-line does not help. debian/rules? Nope!Okay, let s do it the qmake-way, set it in the main .pro file which basically just calls a bunch of other .pro files (one for each component of the project). Guess what? It does not help. You have to set these in each and every .pro file! Rly? Is this what I have a build-system for?</rant>Now, seriously, what s the proper way to override stuff like this in qmake? Any pointers appreciated.
Meike Reichle is a Debian developer since 2008 but has been involved for longer than that, in particular in Debian Women. She s a great speaker and shared her experience in a Debconf talk.
She s also part of the Debian publicity team and managed the live coverage of the last release on identi.ca. Enough introduction, learn more about her by reading the interview. My questions are in bold, the rest is by Meike.
Who are you?
My name is Meike Reichle, I am a studied information scientist and work
as a project manager at Pengutronix, an embedded Linux company probably
best known for their ARM kernel work. I live in Germany, more exactly in
Lower Saxony, but I was originally born and raised in Swabia. Although I
moved here ten years ago I still have a rather strong Swabian cultural
identity. (Among other things I pride myself on having introduced a
number of fellow DDs to the true promise that are real hand-made Sp tzle
2 comments Liked this article? Click here. My blog is Flattr-enabled.
This is the tenth Debian XSF News issue. It is basically meant to be
a follow-up to DXN#9.
xkb-data (a.k.a. xkeyboard-config)
side, as
explained by Sergey Udaltsov.
Protocol:
experimental was a bit overcautious, so upload again unstable.experimental for a while, changes were announced to debian-boot@ unstable.libx11-6; also announced to debian-boot@ experimental.unstable.udebs for generic
drivers for non-Linux architectures. I cleaned them up a bit
(especially on the vesa side, getting rid of libdrm entirely),
got them test-built on a kfreebsd-amd64 box, while Samuel
Thibault was doing the same on a hurd-i386 box. I
raised the topic
on debian-boot@, debian-bsd@, and debian-hurd@, mentioning
the remaining steps.
Drivers (all accepted by ftpmasters after a tiny trip to the NEW queue):
experimental.experimental.experimental.x11-xserver-utils: Julien did everything for DSA-2213 unstable, squeeze-security, lenny-security.experimental.testing (from now on I ll
use testing instead of wheezy so that it s clear it s about
week after week migrations to the testing distribution, rather
than our final plans for the next stable release). After a while,
and thanks to
some hand-holding
from our nice release managers (hi, Adam!), linux-2.6,
libdrm, mesa, xorg-server, and several dozen drivers migrated
to testing. Yay!experimental previously) unstable.unstable and 7.10.1 in experimental (see above) unstable.experimental and supersedes 0.21.4 unstable.unstable.unstable.ati driver unstable.
As already
blogged by Riku,
getting replaced by script is really great!
Until now, I ve had a crontab fetching my supporting-very-big-mails
(up to 100MB or so) mailbox every few minutes, and looking into my
=incoming-buildd/ maildir on a very regular fashion. With some
simple mutt maildir hooks, replying to a Successful log would
trigger extracting the changes file from there, setting some
options, like PGP inline signing, and the mail would be ready to go
back to the buildd. That part was just about being a GPG-signing
monkey, so really not a funny part.
Since we no longer have to worry about this boring and time-consuming
task, I ve switched to a crontab firing up 4 times a day, and I try to
deal with all incoming mails at once. Coupled with the new filters
(e.g. on out-of-date packages on the buildd status page), I started using my time to file
FTBFS bugs again, so that maintainers notice their packages fail to
build without having to wait for a non-happening testing migration.
After 10 days, the following mutt filter in =debian-bts/ lists
69 bugs:
~s "Bug#.*FTBFS" ~P ~d 01/04/2011-
(Subject contains Bug#.*FTBFS, mails from me, starting from 01/04/2011.)
Figuring out whether that s due to another package s bug, an outdated
chroot, a temporary glitch, etc. might take some time; that s why it s
a bit hard to stay on top of things; and when the backlog grows up,
motivation to go through this tedious task can be pretty low,
especially when one sees repeated mistakes. I hope the amount of
(possible) use cases for #620686 will
decrease over time; instead, I d be very happy if maintainers could at
least check what s mentioned in configure.ac/configure.in. Keeping
an eye on its diff between upstream versions should be easy
enough. ;)
This is the ninth Debian XSF News issue. As can be seen below, I m
not yet decided how to present various items. This time, I ll try to
gather all updated packages since the previous issue, grouped by
category, with a single line summary. Lengthy comments come after that
list of updated packages.
experimental.unstable.unstable.experimental.testing if the Linux kernel migrates some day unstable.experimental.unstable.unstable version against experimental s server experimental.experimental.experimental.unstable.unstable wkhtmltopdf failed on several buildds, so I disabled PDF generation, and completed the switch to asciidoc mentioned in DXN#8 unstable.unstable.unstable.experimental only? Because bad regressions happen, on a regular
basis; so it seems quite nice to keep well-tested versions in
unstable for now. Once the X stack has migrated to testing
(which as explained in DXN#7 and
DXN#8 is waiting for the Linux kernel to
migrate), new versions in unstable are welcome, so that one can
tell easily whether bugs with those versions are regressions from
the versions available in testing. In the meanwhile, one can build
packages from the git repositories, using the debian-unstable
branch (which is the default).unstable as
they are released? First of all, our waiting for the kernel means
we have no issues on the 10-day delay front. Second of all, input
bugs are usually fixed very quickly upstream (you can go there and
thank Peter Hutterer in particular). So staying very close to
whatever upstream ships makes some sense.
Alright. If you ever come into the same situation I was in and need a newer kernel (2.6.32 or up, perhaps also 2.6.31) on some system with old iptables package (versions below 1.4.0 I think, 1.3.5 in my case: CentOS5/RHEL5), you might get this helpful error message when using the iprange module in your iptables rules:
iptables: Unknown error 18446744073709551615
Or even more helpful, if you use iptables-restore to load your rules, you will get an error in the line containing the COMMIT statement (iptables-restore: line X failed).
The reason for this is that the netfilter guys have removed an interface to the iprange module in kernel version 2.6.31 or 2.6.32 (see my bug report at #711 of the netfilter bugzilla).
Just posting this so it might hopefully help others if they get into the same situation.
Mandatory warning: What follows is for testing only, and
insecure (root all over the place, giving access to host devices
from the container, etc.).
Problem of the day
mesa needs to be rebuilt against the
library. Doing so on a system running stable doesn t seem too
good: some newer libraries might be needed; and using make
install could make it harder to remember additional bits installed
all over the place ($DESTDIR is our friend but that might mean
more work on the build system side to get everything
detected).squeeze system.apt-get install lxc, read its README.Debian, get the mount
point set up./usr/lib/lxc/templates/lxc-debian template somewhere as
lxc-squeeze, and edit it:
dhcp-client with dhcp3-client.lenny with squeeze.ftp.debian.org.lxc-test directory, and create a container:
./lxc-squeeze -p lxc-test.lxc-start -n
test -f lxc-test/config (the test name passed through -n can
be used to call lxc-stop -n test). Use root/root to get in./etc/apt/sources.list to point to sid instead, and
dist-upgrade (using squeeze to start with means fewer headaches
while bootstrapping, in case sid breaks or gets into some
transition).lxc-stop and lxc-start to make sure the container can be
stopped and restarted at will.udev + LXC =
fail. So let s install it, note that it can t be configured, edit
/var/lib/dpkg/info/udev.postinst, add exit 0 at the top, and
dpkg --configure udev./dev. Using mknod would be
too easy, that s called a container for a reason. So let s edit
the config file (the one passed to lxc-start earlier) to add a
few devices (see below for an example).lxc-stop/lxc-start) the container,
mknod on those devices is now possible.crw-rw---- 1 root video 226, 0 Apr 5 02:34 /dev/dri/card0
crw-rw---- 1 root video 29, 0 Apr 5 02:34 /dev/fb0
crw------- 1 root root 4, 7 Apr 5 02:34 /dev/tty7
crw------- 1 root root 4, 8 Apr 5 02:34 /dev/tty8
Note the major, minor right between owner groups and dates, and edit
the config file accordingly, adding those lines (watch the syntax,
it doesn t like extra whitespaces):
lxc.cgroup.devices.allow = c 226:0 rwm
lxc.cgroup.devices.allow = c 29:0 rwm
lxc.cgroup.devices.allow = c 4:7 rwm
lxc.cgroup.devices.allow = c 4:8 rwm
Once the container restarted, create the devices:
cd /dev
mkdir -p dri
mknod -m 666 dri/card0 c 226 0
mknod -m 666 fb0 c 29 0
mknod -m 666 tty7 c 4 7
mknod -m 666 tty8 c 4 8
Getting serious
apt-get install xorgstartxstrace -f can help diagnose issues. If /dev/dri/card0 shows up
with ENODEV, an old libdrm could even remove that device, so
running mknod is needed again (but not sufficient)startx from the
container again should give better results (that s what happened
here).startx just works , just use ^Z then bg to put it in the
background.awesome)
and mesa-utils, and enjoy!export DISPLAY=:0
awesome &
# this is not a benchmark:
glxgears &
# direct rendering:
glxinfo egrep '(direct renderer)'
which printed here:
direct rendering: Yes
OpenGL renderer string: Gallium 0.4 on ATI RS690
Today I made a couple of small tweaks to my systems. First of all I updated my email handling to allow further restrictions to be applied to incoming mail.
Generally the way I handle incoming mail is to first of all test the recipient, then apply spam checks. To allow mail for a new localpart to be received I'll run this:
cd /srv/example.com/users/valid touch localpartThe result of the file /srv/example.com/users/valid/localpart existing is that mail is accepted for localpart@example.com. As of today that still works - any file beneath users/valid allows the appropriate localpart to receive email. But now a directory indicates an ACL. So I can create:
rm /srv/example.com/users/valid/root mkdir /srv/example.com/users/valid/root/ touch /srv/example.com/users/valid/root/1.2.3.4 touch /srv/example.com/users/valid/root/2.3.4.5Now only the named IP addresses may mail root@example.com. Finally I updated the proxy which is handling incoming access to my websites, so that I actually take advantage of the regular expression support.
'(xen-hosting.net www.xen-hosting.net)':
'rules':
'^/': 'http://kvm-hosting.org/'
,
,
'(xen-hosting.org www.xen-hosting.org)':
'rules':
'^/': 'http://kvm-hosting.org/'
,
,
Using regular expressions meant that I didn't have seperate matches for xen-hosting.org and www.xen-hosting.org. (Obviously I could have combined all four hosts into one regexp, but it looks cleaner this way.)
ObQuote: "Nobody likes a perky goth" - Blood Ties.
This is the eighth Debian XSF News issue. For a change, I m going to
use a numbered list, which should help telling people which item to
look for when pointing to a given URL. Feel free to let me know if
that seems like a nice idea or whether that hurts readability.
Also, it was prepared several days ago already, so I m publishing it
(with the needed bits of polishing it still needed) without mentioning
what happened in the last few days (see you in the next DXN issue!).
XFS) issue as
reported upstream in
FDO#31501
or in Debian as #616578. The
easy fix is to get rid of FontPath in xorg.conf, or to remove
the xfs package. It s deprecated anyway.libxt to find
the
guilty commit
was quite easy. After a quick upload with this commit reverted, a
real fix
was pushed upstream; a new upstream was released, packaged, and
uploaded right after that.upowerd s polling every 30 seconds:
#613745.6.0.1 squeeze point release, leading to cursor
issues with Intel graphics:
#618665.CurrentProblemsInUnstable page on the wiki, which is long
unmaintained (and that s why I m not linking to it). I m not
exactly sure what to do at this point, but I think having a similar
page on http://pkg-xorg.alioth.debian.org/, linked from the
how to report bugs
page would make sense. Common issues as well as their solutions or
workarounds for stable should probably go to the FAQ
instead.wheezy. The 2.6.38 upstream release was
quickly
pushed to unstable,
which is great news, even if it s not really ready yet (since it s
still failing to build on armel and mips).lenny-backports was quickly installed and the website should
look fine.wkhtmltopdf (WebKit-based HTML
to PDF converter), since the table of contents gets pixelated in
the generated PDF documents. We could use a2x to generate
documents through the DocBook way, but that means dealing with
XSL stylesheets as far as I can tell; that looks time-consuming
and a rather low-priority task. But of course, contributions are
welcome.squeeze, I didn t
notice the 1.9 packages were forked right before that, so were
affected too. I fixed it in sid since then (and in git for
experimental). I noticed that when
Ian reported a crash with large
timeouts in xauth calls, which I couldn t reproduce since
untrusted cookies without XSecurity don t trigger this issue. I
reported that upstream as
FDO#35066,
which got marked as a duplicate of (currently restricted)
FDO#27134. My patch
is currently still waiting for a review.experimental, unless 7.10 migrates to testing first, in
which case that update will target unstable..so symlinks
for a while, and I finally gave it a quick look. It seems one is
supposed to put e.g. libI810XvMC.so.1 in
/etc/X11/XvMCConfig to use that library, so the symlinks are
indeed not needed at all, and I removed them.libxt: to unstable, as mentioned above, with a hot fix,
then with a real fix.synaptics input driver: to unstable and experimental,
fixing the FTBFS on GNU/kFreeBSD.xterm: new upstream, to unstable.libdrm: new upstream, to experimental. A few patches to
hide private symbols were sent upstream, but I ve seen no
reactions yet (and that apparently happened in the past already).xorg-server 1.9.5rc1 then 1.9.5, to unstable.xutils-dev to unstable: the
bootstrap issue goes away,
thanks to Steve s report.libxp to unstable, nothing fancy, that s libxp keyboard input driver: mostly documentation update, to
unstable and experimental.mouse input driver: fixes BSD issues, to unstable and
experimental.intel video driver: to experimental, but the
debian-unstable branch can be used to build the driver against
unstable s server.xfixes: protocol to unstable, and library to experimental
(just in case); this brings support for pointer barriers.openchrome video driver: Julien introduced a debugging
package, and got rid of the (old!) via transitional package. He
also performed his first upload as
a Debian Maintainer. Yay!siliconmotion video driver: to unstable.pixman: new upstream release candidate, to experimentalcompiz packages to experimental.
Today we gathered the representatives of different distributions that are present at GNOME.Asia to discuss what GNOME could do to improve its support for distributions that distribute it, especially in matters of long-term support.
It is kind of sad that there weren t any representatives from Canonical nor Red Hat, but the discussion turned out really interesting and we learned a lot about the packaging habits of each other. Furthermore, there were several concrete leads that were explored, which will lead to proposals from the GNOME foundation to all distributions.
Helping with long-term support
The most widespread GNOME version in the LTS releases that happened recently is 2.30, which is used by Debian squeeze, Ubuntu LTS 10.04, RHEL 6, and Solaris 11. It looks like an accident, but on the other hand:
Warning, this post is COMPANY CONFIDENTIAL, do not spread outside of authorized corporate internal communication channels.
Today Nokia will announce that in order to increase investor confidence and foster brand loyalty all Nokia Symbian phones in the world will receive two free Nokia-themed games.
The first game will be Angry Nokias Nokias have discovered that other phones are taking their market share away and now they are very, very angry! Fling cool and shiny Nokia phone and destroy the competition. Complete all free 30 levels and be first to collect all golden Ovi s by gathering MeeGo and Windows Phone 7 logos in the levels!
The other game that is sure to be an instant hit among true Nokia fans will be the Nokia Ninja you are a humble user and sales people are throwing phones at you all kinds of phones. But beware most of those phones are not Nokias! Use your finger to slice trough the competition, rake up combos and achievements! But be careful you do not want to slice trough a Nokia phone! Only trough instant brand recognition you can rake up truly great scores in this game.
Nokia connecting people.
(P.S. Check the date)
In one of the corners of what is now know as Europa, there was a rich,
prosperous and beautiful kingdom known as Trist nia. In the past, not
that long ago, it had been a number of smaller kingdoms and
caliphates, all with their own cultures, religions and ways of life. Wars,
and series of marriages of convenience eventually configured what ended up
being the united kingdom of Trist nia. Throughout the years, some of the
unified cultures grew and flourished, while others struggled to survive in
their ever-shrinking areas of influence.
A required introduction
Sometimes, the minor cultures would suffer due to oppression coming
from the delegates of the King, who would ban any expression of these
cultures, as they were seen as a potential threat to the kingdom's
stability and unity. For example, just a few decades before the main
subject of this tale, the predecessor of the incumbent King took power by
force, after crushing everyone who opposed his uprise during a bloody and
hard civil war. His reign was ruthless and he imposed draconian laws
uppon his people: usage and teaching of the minor languages was banned,
and everyone was forced to use the language of the Centr lia region, in
public or private.
After four decades, the majority of the Tristanian people were sick enough
of the situation to consider standing against their fear of the regime and
demand freedom, but repression prevailed until the old general died. His
place was taken by the King's grandson even if the people had expressed,
just before the Great War, that they had had enough kings and demanded a
ruler they could choose directly. Of course, the new King seemed a lot
nicer than who they had been suffering for ages, so when asked if they
accepted the new situation, an overwhelming majority said yes .
However, there was a region, Verd lia, where the majority said no .
Things were actually more complicated. Verdalians formed a traditional,
proud society, and while the years of oppression had undoubtedly weakened
it, they had managed to preserve their very unique culture, language and
traditions healthy. The Verdal language was really weird to the
ears of Centr lians and even other minor cultures of the Kingdom, and
erudites struggled to find its real origins, not being able to reach
plausible conclusions.
Verdanians, as we already know, were a traditional society, living in a
land of deep and poorly connected valleys. Little they knew or cared about
the complicated matters of Centr lia and other regions. What made them
happy was to take care their sheep and cows, keep a good fire in their
living room and, every now and then, enjoy one of their log cutting
contests. The impositions of the former dictator were too much for them,
and some of them started sabotaging, assaulting and killing some of the
dictator's soldiers, agents and officers. This was a huge risk at the
time; getting caught meant death penalty for sure, and at first, even
people from other regions were in favour of these actions. However, this
popular support greatly diminished when the new King took the throne, as
these minority continued with the killings, while most of the people saw
it was no longer justified.
The Royal Ball
One of the very first measures the young King introduced was to organise
the Royal Ball of Trist nia , a major event through which the people of the
different regions would be able to elect their delegates to the Crown.
Every four years, a Great Ball contest would happen in Centr lia, and the
winners would be able to decide by their own on some of the matters that
affected their region. Verdanians would send a few teams of dancers, each
of which came from different towns or areas. Some Verdanian teams were
happy about the King and the new political situation, but other teams
weren't so much. And some others, while being simple non-violent dancers,
were known to be supporters of the violent minority who kept on harassing,
assaulting and even killing in their struggle for freedom of Verd nia .
The Verdanian groups aligned with the different culture of Verd nia
(including those who were said to support the violent) tended to get a lot
more points in the dancing contest, and a majority of the elected delegates
were appointed by them, making it easier to pass laws and edicts that
favoured protection of their ways, traditions and language.
No matter how hard they tried, the dancing groups closer to Centr lia
kept losing to the majority. After many years of dance contests, these
groups used their closeness to the King's court to pass the Ball Law of
Tristanian, that would ban any dancing group which didn't condemn the assaults
and killings that kept happening in Verd nia. The unsurprising result was
that, with less dancing groups participating in the following Royal Ball, the
Verdanian majority was broken and new delegates, friendly of the
Centralian officers, were elected.
Many people who had been in favour of assaults and killings began to
question this strategy, and this political movement's unity started to
break. In the end, the dancers decided to part ways with the violent; they
wanted to dance in the next ball, and to do so, they wrote a letter to the
King, in which they explicitly expressed their rejection of violent ways,
and their embracing of dancing as the only means to drive their political
agenda. An objective reading of the new Ball Law clearly showed that this
was enough: the text only said the requisite for a dancing group was to
disavow all kinds of violence.
This wasn't really expected in Centr lia, so they started to add new
requirements in an attempt to keep this group from the contest: their
decisive majority in Verd nia was at stake.
The Royal Ball was nearing and registrations for the contest would soon
close. The Centralian government first argued that the dancing group
should reject the violence coming from the Verdanian extremists in
particular. The dancers did it. Then they argued that the dancers were the
same people who had been supporting violence in Verd nia for years, and
obviously their violence rejection statement was a lie. The dancers
struggled to find new dancers who had not been involved in past dances.
But it was not enough. They then claimed that this dance group should be
quarantined for four years, until they could prove they really were
serious about their new non-violent ideas.
The dance group made a plea to the Trist nian Supreme Counsel, a group
of sixteen experts in law of the Kingdom, and argued that all of these
draconian requirements were not part of the law that was being enforced by
the King. Their appeal to the elder counselors was in vain, though. They
ruled this dancing group was as criminal as the violent minority they had
once supported, and should by no means take part in the Royal Ball.
As a last, desperate measure, the dancing group reached an agreement
with other Verdanian dancers to join forces. They would adopt a new name
and new dancing costume colours. Many feared this would only end up in the
ban of the other dancing group.
Unfortunately, the end of this story has not been written yet, but it
will be completed very soon. Only time will tell if things continue being very
sad and unfair in Trist nia, or if the dance contest will once again be
impartial, with legitimate results.
So the other day, I was able to do this in an Ubuntu natty amd64 chroot
for the first time.
# cat > /etc/apt/apt.conf.d/multiarch-me
APT::Architectures "amd64"; "i386"; ;
^D
# cat >> /etc/dpkg/dpkg.cfg
foreign-architecture i386
^D
# apt-get update
# apt-get install flashplugin-installer:i386
Reading package lists... Done
Building dependency tree
Reading state information... Done
[...]
The following NEW packages will be installed:
flashplugin-installer:i386 flashplugin-nonfree:i386 gcc-4.5-base:i386
libatk1.0-0:i386 libavahi-client3:i386 libavahi-common-data:i386
libavahi-common3:i386 libc6:i386 libcairo2:i386 libcomerr2:i386
libcups2:i386 libdatrie1:i386 libdbus-1-3:i386 libdrm2:i386
libegl1-mesa:i386 libexpat1:i386 libfontconfig1:i386 libfreetype6:i386
libgcc1:i386 libgcrypt11:i386 libgdk-pixbuf2.0-0:i386 libgl1-mesa-glx:i386
libglib2.0-0:i386 libgnutls26:i386 libgpg-error0:i386 libgssapi-krb5-2:i386
libgtk2.0-0:i386 libgtk2.0-common libice6:i386 libjasper1:i386
libjpeg62:i386 libk5crypto3:i386 libkeyutils1:i386 libkrb5-3:i386
libkrb5support0:i386 libnspr4:i386 libnspr4-0d:i386 libnss3:i386
libnss3-1d:i386 libpango1.0-0:i386 libpcre3:i386 libpixman-1-0:i386
libpng12-0:i386 libselinux1:i386 libsm6:i386 libsqlite3-0:i386
libstdc++6:i386 libtasn1-3:i386 libthai-data libthai0:i386 libtiff4:i386
libudev0:i386 libuuid1:i386 libx11-6:i386 libx11-data libx11-xcb1:i386
libxau6:i386 libxcb-dri2-0:i386 libxcb-render0:i386 libxcb-shape0:i386
libxcb-shm0:i386 libxcb-xfixes0:i386 libxcb1:i386 libxcomposite1:i386
libxcursor1:i386 libxdamage1:i386 libxdmcp6:i386 libxext6:i386
libxfixes3:i386 libxft2:i386 libxi6:i386 libxinerama1:i386 libxrandr2:i386
libxrender1:i386 libxt6:i386 libxxf86vm1:i386 x11-common zlib1g:i386
0 upgraded, 78 newly installed, 0 to remove and 3 not upgraded.
Need to get 15.1 MB/15.6 MB of archives.
After this operation, 48.9 MB of additional disk space will be used.
Do you want to continue [Y/n]?
It is a truly heady experience, after so many years of talking about the
need to properly support multiarch in Debian and Ubuntu, to see support for
cross-installation of packages come to fruition. If you've talked to me any
time in the past couple of weeks and noticed it's a little hard to get me to
change the subject, well, that's why.
Many who have grown accustomed to Debian and Ubuntu's lack of support for
installing i386 packages on amd64 (or vice versa) may wonder what the fuss
is about. (Whereas others who are well versed in distributions such as Red
Hat and SuSE may laugh and wonder what took us so long...) So maybe a few
words of explanation are in order.
If you've ever installed ia32-libs on an amd64 machine anywhere; if you've
ever noticed a bug where ia32-libs didn't work right because of wrong system
paths, or had to file a request for another library to be added to ia32-libs
because it wasn't included in the set of libraries Debian decided to package
up in this grotesque, all-in-one 32-bit compatibility bundle; if you've ever
decided not to install a 64-bit OS on your perfectly 64-bit-capable hardware
because of concern that you wouldn't be able to run
$random32-bitonly_application; multiarch is for you.
If you've gotten stuck maintaining a lib32foo "biarch" package in Debian
due to popular demand, multiarch is definitely for you. :)
If you've ever cross-compiled software for a different Debian architecture
than the one you were running, multiarch is for you.
If you've ever wanted to run binaries for a different architecture under
emulation, and found it awkward to set up the library dependencies,
multiarch is for you, too.
Because although the .deb world may be a little late to the party, we're
also naturally taking things much
further than anyone's done
with rpm. Multiarch won't just give you the ability to install 32-bit libs
on 64-bit systems; it'll give you the ability to install libs for any known
architecture on any system. And a whole lot of pain just falls out of the
equation in the process. A cross-compiling environment looks the same as a
native-compiling environment. An emulated system looks the same as a native
system. We can start to seriously consider cross-grading systems from one
architecture to another.
And all this is happening now. The groundwork is there in Ubuntu natty.
Wheezy will be the release that brings multiarch to Debian. When dpkg
1.16.0 is uploaded to unstable real soon
now, the
bootstrapping will begin.
I am immensely grateful to everyone who's helped make multiarch a reality -
to Tollef,
Matt and others for seeding the vision;
Aurelien, Matthias and Arthur for their work to
ready the toolchain;
David
and Michael for the apt implementation;
Guillem and Raphael for the dpkg
implementation, and Linaro's support to help make
this possible; and the many other developers who've helped to refine this
design over the years in numerous other BoFs, sessions and mailing list
threads.
I'm excited to find out what the Debian community will do with multiarch now
that it's upon us. Christian, maybe you should start a pool for how long it
will take before all the libraries shipped in ia32-libs have been converted
to multiarch and we can drop ia32-libs from the archive?
The RInside
package makes it pretty simple and straightforward to embed
R, the wonderful statistical
programming environment and language, inside of a C++ application. This uses
both the robust embedding API provided by R itself, and the higher-level
abstractions from our Rcpp package.
A number of examples are shown on this blog both
here and
here
as well as on the RInside page;
and the source package actually contains well over a dozen complete examples which cover
anything from simple examples to parallel use via
MPI for parallel computing.
Beginning users sometimes ask about how to use
RInside inside
larger projects. And as I had meant to experiment with embedding inside of
the powerful Qt framework anyway, I
started to dabble a little. A first result is now in the SVN sources of
RInside.
My starting point was the classic tkdensity demo that comes with
R itself. It is a good point of departure as Tcl/Tk makes it very
portable---in fact it should run on every platform that runs R---and quite
expressive. And having followed some of the GUI experiments around R over
the years, I have also seen various re-implementations using different GUI frameworks. And so I am adding
mine to this body of work:
The problem I addressed first was actual buildability. For the
RInside
examples, Romain and I provide a Makefile that just works by making
calls to R itself to learn about flags
for R,
Rcpp and
RInside such
that all required headers and libraries are found. That is actually
relatively straightforward (and documented in our vignettes) but a little
intimidating at first---which is why a ready-made Makefile is a good thing.
Qt of course uses qmake
and the .pro files to encode / resolve dependencies. So task one
was to map what our Makefile does into its variables. Turns out that wasn't all that
hard:
The double dollar signs and escaping of parentheses are a little tedious, but hey it works and expands the compiler and linker flags such that everything <emjust works="Works">. The code itself is pretty straightforward too. We instantiate the RInside object as well as the main Qt application object. We then instantiate a new object of class## -*- mode: Makefile; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*- ## ## Qt usage example for RInside, inspired by the standard 'density ## sliders' example for other GUI toolkits ## ## Copyright (C) 2011 Dirk Eddelbuettel and Romain Francois TEMPLATE = app HEADERS = qtdensity.h SOURCES = qtdensity.cpp main.cpp QT += svg ## comment this out if you need a different version of R, ## and set set R_HOME accordingly as an environment variable R_HOME = $$system(R RHOME) ## include headers and libraries for R RCPPFLAGS = $$system($$R_HOME/bin/R CMD config --cppflags) RLDFLAGS = $$system($$R_HOME/bin/R CMD config --ldflags) RBLAS = $$system($$R_HOME/bin/R CMD config BLAS_LIBS) RLAPACK = $$system($$R_HOME/bin/R CMD config LAPACK_LIBS) ## if you need to set an rpath to R itself, also uncomment #RRPATH = -Wl,-rpath,$$R_HOME/lib ## include headers and libraries for Rcpp interface classes RCPPINCL = $$system($$R_HOME/bin/Rscript -e \'Rcpp:::CxxFlags\(\)\') RCPPLIBS = $$system($$R_HOME/bin/Rscript -e \'Rcpp:::LdFlags\(\)\') ## for some reason when building with Qt we get this each time ## so we turn unused parameter warnings off RCPPWARNING = -Wno-unused-parameter ## include headers and libraries for RInside embedding classes RINSIDEINCL = $$system($$R_HOME/bin/Rscript -e \'RInside:::CxxFlags\(\)\') RINSIDELIBS = $$system($$R_HOME/bin/Rscript -e \'RInside:::LdFlags\(\)\') ## compiler etc settings used in default make rules QMAKE_CXXFLAGS += $$RCPPWARNING $$RCPPFLAGS $$RCPPINCL $$RINSIDEINCL QMAKE_LFLAGS += $$RLDFLAGS $$RBLAS $$RLAPACK $$RCPPLIBS $$RINSIDELIBS ## addition clean targets QMAKE_CLEAN += qtdensity Makefile
QtDensity that
will launch the main widget; it is given a reference to the
RInside object.
The definition of the main object is pretty simple: a few private variables, and a few functions to interact with the GUI and get values from the radio buttons, slider or input field---as well as functions to update the chart or re-draw the random variables.// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*- // // Qt usage example for RInside, inspired by the standard 'density // sliders' example for other GUI toolkits // // Copyright (C) 2011 Dirk Eddelbuettel and Romain Francois #include <QApplication> #include "qtdensity.h" int main(int argc, char *argv[]) RInside R(argc, argv); // create an embedded R instance QApplication app(argc, argv); QtDensity qtdensity(R); return app.exec();
Lastly, no big magic in the code either (apart from the standard magic provided by RInside). A bit of standard GUI layouting, and then some functions to pick values from the inputs as well as to compute / update the output. One issue is worth mentioning. The screenshot and code show the second version of this little application. I built a first one using a standard portable network graphics (png) file. That was fine, but not crisp as png is a pixel format so I went back and experimented with scalable vector graphics (svg) instead. One can create svg output with R in a number of ways, one of which is the cairoDevice package by Michael Lawrence (who also wrote RGtk2 and good chunks of Ggobi). Now, it turns out that Qt displays the so-called SVG tiny standard whereas R creates a fuller SVG format. Some discussion with Michael reveals that one can modify the svg file suitably (which is what the function// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*- // // Qt usage example for RInside, inspired by the standard 'density // sliders' example for other GUI toolkits // // Copyright (C) 2011 Dirk Eddelbuettel and Romain Francois #ifndef QTDENSITY_H #define QTDENSITY_H #include <RInside.h> #include <QMainWindow> #include <QHBoxLayout> #include <QSlider> #include <QSpinBox> #include <QLabel> #include <QTemporaryFile> #include <QSvgWidget> class QtDensity : public QMainWindow Q_OBJECT public: QtDensity(RInside & R); private slots: void getBandwidth(int bw); void getKernel(int kernel); void getRandomDataCmd(QString txt); void runRandomDataCmd(void); private: void setupDisplay(void); // standard GUI boilderplate of arranging things void plot(void); // run a density plot in R and update the void filterFile(void); // modify the richer SVG produced by R QSvgWidget *m_svg; // the SVG device RInside & m_R; // reference to the R instance passed to constructor QString m_tempfile; // name of file used by R for plots QString m_svgfile; // another temp file, this time from Qt int m_bw, m_kernel; // parameters used to estimate the density QString m_cmd; // random draw command string ; #endif
filterFile below does) and it all works. Well:
almost. There is a bug (and Michael thinks it is the SVG rendering) in which
the density estimate does not get clipped to the plotting region.
What the little application does is actually somewhat neat for the few lines. One key features is that the generated data can be specified directly by an R expression which allows for mixtures (as shown, and as is the default). With that it easy to see how many points are needed in the second hump to make the estimate multi-modal, and how much of a distance between both centers is needed and so on. Obviously, the effect of the chosen kernel and bandwidth can also be visualized. And with the chart the being a support vector graphics display, we can resize and scale at will and it still looks crisp. The code (for both the simpler png variant and the svg version shown here) is in the SVN repository for RInside and will be in the next release. Special thanks to Michael Lawrence for patiently working through some svg woes with me over a few emails.// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*- // // Qt usage example for RInside, inspired by the standard 'density // sliders' example for other GUI toolkits -- this time with SVG // // Copyright (C) 2011 Dirk Eddelbuettel and Romain Francois #include <QtGui> #include "qtdensity.h" QtDensity::QtDensity(RInside & R) : m_R(R) m_bw = 100; // initial bandwidth, will be scaled by 100 so 1.0 m_kernel = 0; // initial kernel: gaussian m_cmd = "c(rnorm(100,0,1), rnorm(50,5,1))"; // simple mixture m_R["bw"] = m_bw; // pass bandwidth to R, and have R compute a temp.file name m_tempfile = QString::fromStdString(Rcpp::as<std::string>(m_R.parseEval("tfile <- tempfile()"))); m_svgfile = QString::fromStdString(Rcpp::as<std::string>(m_R.parseEval("sfile <- tempfile()"))); m_R.parseEvalQ("library(cairoDevice)"); setupDisplay(); void QtDensity::setupDisplay(void) QWidget *window = new QWidget; window->setWindowTitle("Qt and RInside demo: density estimation"); QSpinBox *spinBox = new QSpinBox; QSlider *slider = new QSlider(Qt::Horizontal); spinBox->setRange(5, 200); slider->setRange(5, 200); QObject::connect(spinBox, SIGNAL(valueChanged(int)), slider, SLOT(setValue(int))); QObject::connect(slider, SIGNAL(valueChanged(int)), spinBox, SLOT(setValue(int))); spinBox->setValue(m_bw); QObject::connect(spinBox, SIGNAL(valueChanged(int)), this, SLOT(getBandwidth(int))); QLabel *cmdLabel = new QLabel("R command for random data creation"); QLineEdit *cmdEntry = new QLineEdit(m_cmd); QObject::connect(cmdEntry, SIGNAL(textEdited(QString)), this, SLOT(getRandomDataCmd(QString))); QObject::connect(cmdEntry, SIGNAL(editingFinished()), this, SLOT(runRandomDataCmd())); QGroupBox *kernelRadioBox = new QGroupBox("Density Estimation kernel"); QRadioButton *radio1 = new QRadioButton("&Gaussian"); QRadioButton *radio2 = new QRadioButton("&Epanechnikov"); QRadioButton *radio3 = new QRadioButton("&Rectangular"); QRadioButton *radio4 = new QRadioButton("&Triangular"); QRadioButton *radio5 = new QRadioButton("&Cosine"); radio1->setChecked(true); QVBoxLayout *vbox = new QVBoxLayout; vbox->addWidget(radio1); vbox->addWidget(radio2); vbox->addWidget(radio3); vbox->addWidget(radio4); vbox->addWidget(radio5); kernelRadioBox->setMinimumSize(260,140); kernelRadioBox->setMaximumSize(260,140); kernelRadioBox->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); kernelRadioBox->setLayout(vbox); QButtonGroup *kernelGroup = new QButtonGroup; kernelGroup->addButton(radio1, 0); kernelGroup->addButton(radio2, 1); kernelGroup->addButton(radio3, 2); kernelGroup->addButton(radio4, 3); kernelGroup->addButton(radio5, 4); QObject::connect(kernelGroup, SIGNAL(buttonClicked(int)), this, SLOT(getKernel(int))); m_svg = new QSvgWidget(); runRandomDataCmd(); // also calls plot() QGroupBox *estimationBox = new QGroupBox("Density estimation bandwidth (scaled by 100)"); QHBoxLayout *spinners = new QHBoxLayout; spinners->addWidget(spinBox); spinners->addWidget(slider); QVBoxLayout *topright = new QVBoxLayout; topright->addLayout(spinners); topright->addWidget(cmdLabel); topright->addWidget(cmdEntry); estimationBox->setMinimumSize(360,140); estimationBox->setMaximumSize(360,140); estimationBox->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); estimationBox->setLayout(topright); QHBoxLayout *upperlayout = new QHBoxLayout; upperlayout->addWidget(kernelRadioBox); upperlayout->addWidget(estimationBox); QHBoxLayout *svglayout = new QHBoxLayout; svglayout->addWidget(m_svg); QVBoxLayout *outer = new QVBoxLayout; outer->addLayout(upperlayout); outer->addLayout(svglayout); window->setLayout(outer); window->show(); void QtDensity::plot(void) const char *kernelstrings[] = "gaussian", "epanechnikov", "rectangular", "triangular", "cosine" ; m_R["bw"] = m_bw; m_R["kernel"] = kernelstrings[m_kernel]; // that passes the string to R std::string cmd1 = "Cairo(width=6,height=6,pointsize=10,surface='svg',filename=tfile); " "plot(density(y, bw=bw/100, kernel=kernel), xlim=range(y)+c(-2,2), main=\"Kernel: "; std::string cmd2 = "\"); points(y, rep(0, length(y)), pch=16, col=rgb(0,0,0,1/4)); dev.off()"; std::string cmd = cmd1 + kernelstrings[m_kernel] + cmd2; // stick the selected kernel in the middle m_R.parseEvalQ(cmd); filterFile(); // we need to simplify the svg file for display by Qt m_svg->load(m_svgfile); void QtDensity::getBandwidth(int bw) if (bw != m_bw) m_bw = bw; plot(); void QtDensity::getKernel(int kernel) if (kernel != m_kernel) m_kernel = kernel; plot(); void QtDensity::getRandomDataCmd(QString txt) m_cmd = txt; void QtDensity::runRandomDataCmd(void) std::string cmd = "y <- " + m_cmd.toStdString(); m_R.parseEvalQ(cmd); plot(); // after each random draw, update plot with estimate void QtDensity::filterFile() // cairoDevice creates richer SVG than Qt can display // but per Michaele Lawrence, a simple trick is to s/symbol/g/ which we do here QFile infile(m_tempfile); infile.open(QFile::ReadOnly); QFile outfile(m_svgfile); outfile.open(QFile::WriteOnly QFile::Truncate); QTextStream in(&infile); QTextStream out(&outfile); QRegExp rx1("<symbol"); QRegExp rx2("</symbol"); while (!in.atEnd()) QString line = in.readLine(); line.replace(rx1, "<g"); // so '<symbol' becomes '<g ...' line.replace(rx2, "</g");// and '</symbol becomes '</g' out << line << "\n"; infile.close(); outfile.close();
Update: Some typos fixed.
Update 2: Two URLs corrected.
Next.