elliot's blog

Why upgrading to Fedora 13 was a pain in the backside

I resist upgrading my work machine as much as possible, as whenever I do, everything I rely on stops working properly. A few notes on my particular pains this time round as I upgraded to Fedora Core (FC) 13:

  • SELinux is an utter pain. And for some reason it's difficult to turn off in FC 13 as the SELinux graphical config tool isn't installed by default. The package you need is policycoreutils-gui, which will enable you to disable SELinux easily.
    Josh's suggestion is simpler: "edit /etc/selinux/config by hand and set SELINUX= line from enforcing to disabled".
  • The GNOME menus have ceased to be editable by default (there are lots of things there I don't use very often, and don't want clogging up my menus). You need to install alacarte to be able to edit them easily.
  • I like to be able to use sudo, so I uncommented this line in /etc/sudoers:
    %wheel ALL=(ALL) ALL
    and added my user to the wheel group:
    usermod -G wheel -a ell
  • mp3 and other restricted codecs are not available by default. To get these, you can do:
    sudo rpm -ivh http://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-stable.noarch.rpm
    sudo yum install gstreamer-plugins-bad gstreamer-ffmpeg gstreamer-plugins-ugly -y
  • Personally (because I'm set in my ways), I like quodlibet and grip for music (I know how to configure them to suit my taste; and yes, I know they're both pretty old hat). So I tend to install these next. You can also install lame if you want to be able to rip CDs to mp3.
  • I like pidgin better than empathy. Still.
  • I need ruby, ruby-devel and rubygems. At least I don't have to build rubygems any more on modern distros.
  • I need the Java plugin for Firefox:
    sudo yum install java-1.6.0-openjdk-plugin
  • Installed other tools I use quite a bit:
    sudo yum install wget git
  • I've got used to using the gedit plugin which strips trailing space when you save a file:
    mkdir ~/.gnome2/gedit/plugins/
    cd ~/.gnome2/gedit/plugins/
    wget http://users.tkk.fi/~otsaloma/gedit/trailsave.py
    wget http://users.tkk.fi/~otsaloma/gedit/trailsave.gedit-plugin
    It turns up as Save without trailing space in gedit's plugins list.

So what's improved in FC13? Erm...

  • Shotwell is quite a nice photo manager.
  • The system boots slightly faster.
  • The volume settings are more sane, so I don't have to manually keep turning up my speakers between tracks (not sure what the technical term is, but the range from 0 to maximum across the software settings covers a greater range of volumes - if that makes sense).

That's about it. (My main reason for upgrading is so I can more easily build other people's software, rather than for application upgrades.)

There would probably be more if I wasn't so old fashioned about the applications I use...

Album released

I've finally released an album: One Million Corners, recorded by me under the name Spill Twins. It's on the Earthrid net label, and available either as a CD or as free mp3 downloads. (I'm going to put lossless versions on bandcamp this week.)

There is an Internet Archive page for the album.

And here's the embedded player from the Bandcamp page:

<a href="http://spilltwins.bandcamp.com/album/one-million-corners">Ant Mansion by Spill Twins</a>

NB the content is Creative Commons by-nc-sa licensed. In the unlikely event anyone fancies remixing it, they're also welcome to the original sound/project files.

Releasing music

I've been writing more music recently, and am really enjoying it. Part of the reason for this was some interest from a local radio DJ, Kevin Busby, who produces Phantom Circuit, a great radio programme with eclectic tastes. Kevin's been a fantastic proponent of my music (he's played a few on his show). Having this external verification that it's not completely terrible has urged me on (though I would carry on without an audience, as I have been doing for the last 20 years).

The second reason was the discovery of LMMS, a free multi-track audio sequencer tool for Linux, which supports (some) VST instruments (I've actually just found a list of VSTs known to work, which I'll explore next week). I've switched entirely to that environment now, and think my music is improving. On top of that, I also bought Music Theory for Dummies. Despite its good reviews, I don't think it's a particularly great book; but it has helped me learn about scales, chords, and chord sequences, which I vaguely understood but never really applied. I feel like understanding form better, and principles of composition, gives me a better feel for what "sounds right", as well as giving me starting points for writing new stuff.

So, to the point, I just finished Umpet Steak Ripple as Spill Twins (my current musical incarnation). Here it is:

<a href="http://spilltwins.bandcamp.com/track/umpet-steak-ripple">Umpet Steak Ripple by Spill Twins</a>

I published it on Bandcamp which was introduced to me by Iain - as an aside, there seem to be a lot of musicians among the people I work with). It's a free download, or you can listen on the site, or embed it elsewhere (like I did above). Bandcamp seems much better suited to releasing music than http://last.fm/, which is what I was using previously: for whatever reason, tracks on last.fm seemed to keep disappearing or turning into limited 30 second previews, even if they were free downloads. Bandcamp allows you to upload proper, lossless recordings (I used a wav file), while making it available in standard formats like mp3; you can also sell stuff through it (not just give it way).

I really like this track. It feels like the kind of music I should be making, and sounds novel when I listen to it: by which I mean, I can't quite fathom it and personally find it interesting to listen to. Although very short (1m 37s), it took ages to put together. Finding just the right notes (I even wrote down the chords) and sounds (I had probably 10 different attempts at the bass sound) and the right tempo etc. took me probably 6 hours. FYI, the voice is sampled from Carnival of Souls (which you can watch in its entirety online); the drum sounds are generated using one of the built-in LMMS instruments which (I think) emulates a Gameboy sound chip.

I've still got a lot to learn about music (just ordered another book about composition; P.S. if anyone knows of a music composition evening class in Birmingham UK, please let me know). But it's currently one of the things I can lose hours to without realising, and which I love doing. So expect more soon. (And I haven't forgotten about my mathis project, either.)

In lieu of a mid-life crisis

I'm 40 this year (not yet, I hasten to add). Yes, I know it's no big deal it's a round number, that's just human preference for powers of 10. Anyway, it does seem like some kind of milestone in my life, for whatever reasons. And as I have a generally introspective mind, and a good dose of self-absorption, and this is my blog, I'm going to write a few notes about it.

Not sure what got me started down this path, but yesterday I dug out a load of old school books, note books, board game designs, roleplaying game campaign books, poetry, short stories - it's all still out there in the garage. But what struck me, rather than "where did all my dreams go? what am I doing with my life?", the usual things accompanying the average mid-life crisis, I found myself thinking "actually, I'm pretty much the same person I was when I was 12; I haven't really changed much; I still believe the same things". I mentioned this to Nicola (my wife) and she said something like "that's one thing you always are: consistent, stable, level-headed". Though she made it sound better than that: I'm paraphrasing.

So, where is my evidence for this. Cue quotations from old school books etc.:

"There is not anybody that I would really like to be, but if I had to be someone else, I think it would be Arthur C. Clarke...I would not like to be him because of the mysteries he has investigated but because of his great output of short stories and books..." (June 22nd 1982; still love science fiction, would love to be a great SF writer, but realise that probably that's not my calling)

"There are three things I would change in the world if I became, as it were, a 'supreme dictator'. 1. Banning of vivisection: all animals should be treated as part of life, and if they are destroyed or harmed we would be affecting our future lives... 2. Freedom of speech: I would give everybody in the world the freedom to speak how they wish... 3. Nuclear war: I would try to stop the production of nuclear weapons." (December 15th c. 1983; basically I was a hippie then and I still am; I think that's quite forward thinking for someone living in a provincial backwater in the early 1980s - probably my mum's influence)

There's really no point going on about achievements since then etc.; you can read my about page to find out what I've done with myself all this time. I don't think I'll ever "do enough" to say I've finished.

More important, though, are things which have meant a lot to me over the past few months. These are the kind of things we're living for:

  • Sledging in the local park with Madeleine (my daughter) on Christmas Eve 2009. This was just the most wonderful day for me: exhilirating, laughing with my daughter, expectations of Christmas the next day, looking forward to warming up in the cafe for lunch. I'll treasure this one for a long time.
  • How Joel (my son) loves to throw himself at me, fling his arms around me, wrestle me, nestle into my neck, calls me "my daddy"; his carefree grin as he ambles around the garden looking for interesting things.
  • Gaming night with Nicola (my wife): it's one time in the week when we sit down together, just the two of us, and get a chance to do nothing but spend time together, chat, have a drink. Sometimes we're both too knackered, but most Sunday nights, that's what we do. Carcassonne and Dominion are our current arenas. It's also great working at home, as we get to see each other a bit more and meet for lunch once a week in the local cafe. Good to be together.
  • Paul (my current manager) having the faith in me to persuade me to work at Intel, when I was at a really low point, virtually no self confidence, no self belief, and practically telling him I couldn't do the job. He was right, and I was wrong. It's taken me a while to build myself up again, but I finally feel like I'm getting into my stride and being useful.
  • Rediscovering my love of SF. I made a concerted effort this year to read more, and have been having a great time doing so. I've read quite a lot of classic SF this year, and have made some good discoveries (Grass by Sherri S. Tepper is my current one, which is really good, and actually brought tears to my eyes). I'm convinced reading fiction, great fiction, makes me a better person.
  • Writing more music and releasing an album. The release will happen in the next few weeks, and it's going to be very small (it's a tiny net label), but I'm really pleased and grateful someone else (Kevin Busby) has enough faith in my music enough to put their name to it.

While digging around, I also found this rather excellent (and very 1980s and corny, obviously around the time of Close Encounters) birthday card from my family; inside it says "HOPE YOUR BIRTHDAY IS OUT OF THIS WORLD!" There's also some of my mum's handwriting: "To Elliot, lots of love Mum, Dad, Dean & Chloë" (she always put the umlaut on Chloe). Finding some of her writing, that made me a bit sad (she died a few years ago of cancer). Here's the picture, anyway:

(Looking at this now, the sentimental part of me suddenly finds this picture quite fitting as a visual metaphor for what it's like to grow up...)

No earth-shattering revelation to come to, no character progression. But perhaps that is my point. What's important is knowing who you are, and doing things which make you (and those around you) feel good.

Using wget to mirror a website

Occasionally you need to mirror a website (or a directory inside one). If you've only got HTTP access, there are tools like httrack which are pretty good (albeit pretty ugly) at doing this. However, as far as I can tell, you can't use httrack on a password-protected website.

curl can probably do this too, and supports authentication, but it wasn't obvious.

So I ended up using wget, as it supports mirroring and credentials. But the issue here is that wget plays nice and respects robots.txt; which can actually prevent you mirroring a site you own. And nothing in the man page explains how to ignore robots.txt.

Eventually, I came up with this incantation, which works for me (access to password-protected site, full mirror, ignoring robots.txt):

wget -e robots=off --wait 1 -x --user=xxx --password=xxx -m -k http://domain.to.mirror/

where:

  • -e robots=off obviously disables robots
  • --wait 1 forces a pause between gets (so the site doesn't get hammered)
  • --user and --password: self-evident
  • -x creates a local directory structure which "mirrors" (see what I did there?) the directory structure on the site you're mirroring
  • -m turns on mirror mode: "turns on recursion and time-stamping, sets infinite recursion depth and keeps FTP directory listings" (from the man page)
  • -k converts links after download so that URLs in the mirrored files reference local files

Don't use it carelessly on someone else's website, as they might get angry...

Zombie Haiku

I noticed this Zombie Haiku book yesterday: http://www.amazon.co.uk/dp/1600610706

Which reminded me of this zombie haiku I wrote when I was about 12 (27 years ago - ouch):

A noxious zombie
eats a mouldy, worm-filled leg
in a rancid cave.

Which isn't very good (though vivid enough for me to remember and obviously ahead of its time); and not strictly haiku (it has no "kireji", or its closest equivalent in English, i.e. "a dignified ending, concluding the verse with a heightened sense of closure" - http://en.wikipedia.org/wiki/Kireji). So I rewrote it while in the bath last night (probably too much information there...):

An ashen zombie
gnaws a muddy, worm-filled leg:
tears run over bones.

Hopefully, this will enable you to see how much I've progressed as an artist.

Update: After having written this, I read this surprisingly relevant blog entry about how we see our artwork when we're young (by way of Rotating Corpse), how our perceptions of it change, and even how art comes to have value.

An unpleasant experience

A few years ago, I wrote a Rails (1.0.0) application for Nicola (my wife), to help her with her PhD research. It ran on her Linux laptop, happily, for those few years.

However, once the new laptop has arrived, I knew I'd have to migrate the application from Linux to Windows; I also wanted to avoid having to update the application for a newer version of Rails. How painful could it be? Fairly.

First I needed an old MySQL server (in case the API has changed), 5.0.15 to be precise. It is practically impossible to find archived downloads on the MySQL website, but I got there eventually.

Next I needed to get an old Ruby (1.8.4) for Windows. Again, virtually impossible to find old versions of Ruby with an installer. When I first did this, there was a Ruby 1.8.4 One-Click Installer for Windows, which seems to have disappeared. I finally tracked it down to some website run off some bloke's back somewhere out East.

Then, I needed Rails 1.0.0. For whatever reason, the Ruby I installed couldn't get Rails off the official gems repository (probably because the gem repo format changed). So I installed rails 1.0.0 on a different machine, created a new Rails project, then froze the 1.0.0 gems into it; then copied the frozen gems over to my app on the new machine. Phew.

Finally, I'd used RedCloth in the app. However, after a couple of attempts, I decided it was easier to rip it out than try to install it on Windows. So I did some surgery.

Add to that the fact that Nicola had forgotten her password (Firefox had been saving it), so I had to manually edit the db to add one; plus no decent text editor on Windows 7; plus MySQL not removing its service properly when I installed the wrong version then uninstalled it (sc delete MySQL removes errant services, by the way); plus Windows 7 making it difficult to get an administrator command prompt; etc. etc..

So overall a frustrating experience, but I did finally get there.

(On top of that, I also migrated several thousand POP-ped emails from Thunderbird 2 on Linux to Thunderbird 3 on Windows: I thought there would be an import wizard which would know what to do, but I saw no sign of it. And moved all her data over and installed OpenOffice. Entertainment all round.)

Once I've got over my trauma, I will provide links to where to find ancient versions of apps and libraries. Perhaps I should be an archaeologist.

Books read 2009, and to read in 2010

Last year I only managed to read 18 books. Pretty poor going. They were:

Microserfs - Douglas Coupland
Magnetism and other stories - F. Scott Fitzgerald
Everything Is Miscellaneous
The Eternal Champion - Michael Moorcock
Phoenix in Obsidian - Michael Moorcock
The Sailor on the Seas of Fate - Michael Moorcock
Dying Inside - Robert Silverberg
Breakthrough - Richard Cowper
Brontomek! - Michael Coney
To Your Scattered Bodies Go - Philip Jose Farmer
Childhood's End - Arthur C. Clarke
400 Billion Stars - Paul J. McAuley
The Road - Cormac McCarthy
Tactics of Conquest - Barry Malzberg
Secret Harmonies - Paul J. McAuley
Inside Intel - Tim Jackson
Imperial Earth - Arthur C. Clarke
A Canticle for Leibowitz - Walter M. Miller Jr.

Of those, The Road was easily the best. I dread to think what a shambles the film will turn it into.

I've also updated my list of important books to include one or two I read last year, and some others I remembered. Plus I created a separate section for my favourite sf books.

This year I'm planning to read some sf classics. Here's the list I'm starting from (as I already have copies of all these):

A Case of Conscience - James Blish
Downward to the Earth - Robert Silverberg
Man Plus - Frederik Pohl
Venus Plus X - Theodore Sturgeon
Davy - Edgar Pangborn
The Space Merchants - Frederik Pohl & C.M. Kornbluth
The Diamond Age - Neal Stephenson
Blood Music - Greg Bear
Stand on Zanzibar - John Brunner
Time Out of Joint - Philip K. Dick
The Embedding - Ian Watson
The Fifth Head of Cerberus - Gene Wolfe
I Am Legend - Richard Matheson
On Wings of Song - Thomas M. Disch
Ringworld - Larry Niven
The Child Garden - Geoff Ryman

Let's see how I get on.

A script for parsing work log files

Attached is my Ruby script for parsing log files I keep at work. I have to complete a weekly report, and this forms the basis of that; as I don't keep regular office hours (I flexi-work around child care), it also helps me keep track of the hours I've worked.

The basic principle of operation is as follows:

  1. I create a file for each working week, called something like week45.log
  2. During the week, I record bits of activity I do (see below); I also note down stuff I plan to do next (again, see below)
  3. At the end of the week, I run parse_work_log <file name> > summary.out on the file to produce a log of what I've done
  4. If anything goes wrong, I tend to edit the work log and regenerate, so I can just keep the log (not the summary)
  5. I cut and paste from the summary.out file into an email I send round

The format of the file is deliberately simple to make it easy to maintain; there are a handful of formatting rules. An example is shown below.

**********
2009-12-21

09:30-12:00    Researching this and that #research
12:00-13:00    -Lunch
13:00-14:00    More research
14:00-18:00    Writing some application #coding

**********
2009-12-22

09:30-10:00    Admin #Admin
10:00-10:15    -Break
10:00-12:00    Found out something rather marvellous #Very important research
12:00-12:45    -Lunch
12:45-18:00    Writing another application #coding

**********
+NEXT Have lots of fun banging my head on a brick wall
+NEXT Reinstall my operating system

Which, when parsed, produces this on stderr:

*************************************

Worked 15.25 hours

And this on stdout:

*************************************
This week:

Admin:

  * Admin

Very important research:

  * Found out something rather marvellous

coding:

  * Writing some application
  * Writing another application

research:

  * Researching this and that

*************************************
Next:

  * Have lots of fun banging my head on a brick wall
  * Reinstall my operating system

Notes on formatting:

  • The asterisks and dates are just there to make it more readable - they're basically ignored
  • An entry is a single line with the format HH:MM-HH:MM <...whitespace...> <text> <#optional tag>\n
  • The time span for an entry is added to the total time, unless the entry text contains -Lunch or -Break
  • # creates a tagged entry which gets included in the report; it appears as a bullet point with the tag as its heading; any entries with the same tag get aggregated under a single heading; tags and entries appear in the order they occur in the file
  • Any line starting with +NEXT gets listed in the Next section at the end; tags don't work on this (could, but don't at the moment)

It is pretty primitive, but it does the job for me.

Installation: there isn't any, really. It works from the command line and needs Ruby. The licence? BSD, I guess.

An introduction (of sorts) to JavaScript desktop application development with Gjs and Clutter

This turned into a pretty long blog entry. To help you decide whether you want to stick it out, it's about:

  • My experience with C development for Moblin
  • JavaScript for desktop applications
  • Gjs, GObject introspection, and GIR repository installation
  • Running JavaScript Clutter applications using gjs
  • Interesting movements in the JavaScript world

Background

I started work at Intel's Open Source Technology Centre 6 weeks ago (just realised I haven't written about that here yet), working on the Moblin SDK. Moblin is a Linux-based platform for mobile devices (netbooks, UMPCs, that sort of thing); my role in the project is working as part of the SDK team - basically trying to help third-party developers outside Intel develop software which runs on Moblin. So far, this has involved learning as much about the Moblin stack and ecosystem as possible, as well as helping organise and add to the content on Moblin-related websites. (It's challenging, exciting work and I'm thoroughly enjoying it so far.)

Currently, software development on Moblin is comparable to generic Linux development: languages like Python, Ruby, C++, Perl, Java, C# (via Mono) etc. are all available. However, if you want to make use of the full range of Moblin libraries (like our stuff for managing media metadata or interacting with social networking sites), and combine them with Clutter (our GUI toolkit), the best approach (at the moment) is to program in C. While many of the Moblin libraries have bindings to other languages (like Python and Perl), C gives you the best, most consistent access to all of them (as they're all written in C). You'll also find Moblin development easier if you're familiar with GNOME and glib, both of which are fairly C-centric.

My background isn't in low-level system programming. I have been learning C since starting at Intel, and have enjoyed it thoroughly, but there are several aspects of it I could live without:

  • Memory management is my main bugbear. I really don't want to have to care about allocating memory for data structures, then cleaning up when I'm finished with them. Learning how to (still learning...) has definitely enhanced my understanding of how programs actually work under the bonnet, but dealing with memory directly is not, in general, fun. I'd rather the runtime dealt with it.
  • autotools (aka the GNU Build System) are not straightforward, especially if you're used to build tools like Ant and Rake (or even Maven). I know they are extremely powerful and flexible, and ubiquitous for open source projects, but I defy anyone to tell me they are simple, easy to learn, or well documented. In fact, the autotools (automake, autoconf) actually wrap other tools (make) which are even more complicated. This is partly a consequence of the job they do (making it possible to compile software across different platforms), but means they are not approachable. See the diagram on the autools Wikipedia page to get an idea of how complicated they are.
  • Pseudo object oriented programming (in C) isn't really as pleasant as full OOP (in a language like Ruby). GObject for C (part of GLib) gives you some of the facilities of full OOP, but (as far as I understand it) it's not possible to encapsulate data with the methods which act upon it. It also seems tremendously complicated. Even with GObject, you are still basically doing imperative programming, so encapsulation relies on namespacing and (kind of) casting objects to the right class before passing them to a function (as classes don't seem to know about their parent class, as such). Having said all this, one smart feature GObject does support is introspection, which makes it possible to automate binding other languages to a C library.

So, with my background, and with the goal of making Moblin development easy and attractive, I am keen to find alternatives to having to program in C all the time. Dynamic, interpreted languages (like Ruby or JavaScript) seem to me to be better suited to exploratory, iterative programming: the kind of programming most people do most of the time. This is a goal shared by the GObject Introspection project:

C is good for graphics, multimedia, and lower level systems work. However, writing complex software is difficult and error-prone without garbage collection. A managed runtime such as JavaScript, Python, Java, Lua, .NET, Scheme etc. makes a lot of sense for non-fast-path application logic such as configuration, layout, dialogs, etc. ... Thus, one of the major goals of the GObject introspection project is to be a convenient bridge between these two worlds, and allow you to choose the right tool for the job, rather than being limited inside one or the other. (from http://live.gnome.org/GObjectIntrospection)

GObject Introspection is already being used in GNOME development, to generate JavaScript bindings for the GNOME libraries: the next version of the GNOME desktop (in GNOME 3), GnomeShell, uses JavaScript extensively (calling Clutter, the Moblin graphics library, incidentally). Gjs is the name of the project producing the bindings, as well as being the home of the JavaScript engine itself (also called gjs, and based on Mozilla's implementation of JavaScript in C, SpiderMonkey).

JavaScript is an interesting language. I've used it in web applications for quite a long time (since about 2000), but never entertained the idea of using it for anything other than client-side web programming. Occasionally I'd come across server-side JavaScript (persevere), JavaScript implementations like Rhino, and even wrote some ASP code in JScript (as Microsoft called it) a few years ago. Frameworks like jQuery and the thorough integration of JavaScript with Rails meant that I've done more of it in recent months, but I never thought of using it as a general purpose language, or one for desktop development.

Looking for an alternative to C, and hearing from my colleagues about JavaScript, made me decide to get a feel for Gjs et al, as well as write something to run on Moblin. I decided to write a JavaScript application which made use of the Moblin graphics library, Clutter. Eventually, I ended up successfully writing a JavaScript implementation of tic-tac-toe, using Clutter for the user interface, and even including some simple animation. As an application, it is a bit scrappy (the code is attached), but as a learning aid, doing the project was very useful. It wasn't an easy journey, but it was an eventually satisfying one.

Using JavaScript for the not-web

I did my development work on a Fedora Core 11 laptop, with an Intel chipset.

I tried a variety of ways to install all the pieces I needed for JavaScript development with Gjs, GObject Introspection, GNOME libraries, and Moblin libraries. Even getting an idea of what all the pieces do is painful, and the documentation is pretty woeful. I ended up doing lots of source code grep-ing and googling.

In the end, it turns out that the following packages are available for Fedora Core:

  • gobject-introspection: This provides tools and APIs for working with GIR XML files and typelib (binary versions of the GIR files): these are two formats for storing introspection data about GObject classes (basically, mapping the API of a C library into language-neutral descriptions of the APIs). The metadata for several common libraries (like GLib) is part of this package.
  • gir-repository: This provides more introspection metadata about other common libraries (like GTK+ and DBus-GLib)
  • gjs: This enables you to use the gobject-introspection data to access C libraries from JavaScript (i.e. it's the JavaScript bindings for GNOME libraries).

Now, unfortunately, the versions in the repositories for Fedora 11 are out of date: generating the Clutter bindings requires gobject-introspection-1.0, which isn't available. Plus, this code is so new that it's changing very rapidly, and you probably need the latest version from the source repository to get stuff to work.

To compile all these bits, you're going to need the basic build tools. On Fedora, that means this lot:

$ sudo yum install git flex bison gnome-common libgnome-devel libffi-devel \
    python-devel libtool automake autoconf make gtk-doc xulrunner-devel

(And maybe others: I lost track. But if you're trying to do this yourself, you'll probably know what to do if something's missing. Anyway, Josh is going to sort some packages out before long, hopefully. If you know a better way, let me know.)

Once you've got those installed, though, you should be able to build everything from source fairly easily.

As we're installing into /usr/local, first thing to do is make sure the compiler/linker can find your custom-compiled packages. In your ~/.bashrc file, add this line:

export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig

This tells the pkg-config tool (used by autotools to locate libraries and headers) where your custom installations are. Then reload your bash settings with:

$ source ~/.bashrc

to make sure they're picked up. Any future bash sessions will use this setting. Now you're ready to build.

gobject-introspection:

$ git clone git://git.gnome.org/gobject-introspection
$ cd gobject-introspection
$ ./autogen.sh --prefix=/usr/local
$ make
$ sudo make install

gir-repository:

$ git clone git://git.gnome.org/gir-repository
$ cd gir-repository
$ ./autogen.sh --prefix=/usr/local
$ make
$ sudo make install

gjs:

$ git clone git://git.gnome.org/gjs
$ cd gjs
$ ./autogen.sh --prefix=/usr/local
$ make
$ sudo make install

You can check gjs is working by doing:

$ /usr/local/bin/gjs
gjs> 1+1
2
gjs>

It's a good idea to add /usr/local/bin to your path, again in ~/.bashrc:

export PATH=$PATH:/usr/local/bin

(and source ~/.bashrc to pick it up if necessary)

To compile Clutter itself, you'll also need these library headers:

$ sudo yum install glib2-devel mesa-libGL-devel libXext-devel \
    libXfixes-devel libXdamage-devel pango-devel cairo-devel

(Again, maybe others too.)

Once you've got those too, you can checkout Clutter using git, and build it with introspection turned on:

$ git clone git://git.clutter-project.org/clutter
$ cd clutter
$ ./autogen.sh --prefix=/usr/local --enable-introspection
$ make
$ sudo make install

The final step is one which doesn't appear to be documented anywhere, but which is utterly vital: without it, gjs can't find any of the introspection metadata, and won't be able to call any of the C libraries through their JavaScript bindings. Add this line to your ~/.bashrc file:

export GI_TYPELIB_PATH=$GI_TYPELIB_PATH:/usr/local/share/gir-1.0/

(Again, use source if necessary.)

Testing gjs with Clutter

To test the install, and make sure the Clutter JavaScript bindings are working, put this code into a file test.js:

const Clutter = imports.gi.Clutter;
Clutter.init (0, null);
let stage = Clutter.Stage.get_default ();
stage.title = "Test";
stage.set_color(new Clutter.Color( {red:150, blue:0, green:0, alpha:255} ));
stage.show ();
Clutter.main ();
stage.destroy ();

Run it from a command line with:

$ gjs test.js

You should see something like this:

If this works, you should be able to run my tic-tac-toe (semi-)implementation, linked at the end of this blog entry. To run it, copy the two files into a directory, remove the .txt suffixes, then get a command line in that directory and run:

$ gjs ox.js

There's no AI (so you'll have to play both sides), but notice the use of a scale animation as each move is written to the board. Also interesting is how you can use anonymous JavaScript functions to define callbacks for signals.

I've not experimented extensively, beyond calling a few bits of the Clutter and Netbook Toolkit APIs. If you want more examples, have a look at the GnomeShell tests and UI code. The mx tests are another source of sample code I used.

Another tip: if you're trying to work out what's available in the JavaScript bindings, there's unfortunately no nice way to do it at the moment. Your only recourse is to grep the XML GIR files, which are located in:

/usr/local/share/gir-1.0/

Reading these is a bit of a chore, and I also found it difficult to figure out what was in the API. For example, if you're trying to use a Clutter constant like CLUTTER_X_AXIS, the GIR file has this entry:

<namespace name="Clutter"
             version="1.0"
             shared-library="libclutter-glx-1.0.so.0"
             c:prefix="Clutter">

... loads of cruft ...

  <enumeration name="RotateAxis"
                  doc="Axis of a rotation."
                  version="0.4"
                  glib:type-name="ClutterRotateAxis"
                  glib:get-type="clutter_rotate_axis_get_type"
                  c:type="ClutterRotateAxis">

    <member name="x_axis"
               value="0"
               c:identifier="CLUTTER_X_AXIS"
               glib:nick="x-axis"/>

  </enumeration>

... loads more cruft ...

</namespace>

So, to reference the CLUTTER_X_AXIS constant, my first thought was look up the member element with a c:identifier corresponding to the constant I want; then use the path from the namespace, through the enumeration name, to the member name, i.e.:

Clutter.RotateAxis.x_axis

But in fact it's:

Clutter.RotateAxis.X_AXIS

(the name attribute, capitalised).

I also found that some methods and classes in the GIR for GLib didn't work (like GLib.printf). I'm sure there's a good reason why, it's just I couldn't work it out.

What's missing?

I spent quite a few hours figuring this stuff out, and stumbled a lot along the way. Partly because I'm not a C programmer, partly because I'm new to GNOME, I'm sure. But I think there are a few things which would have improved my experience:

  • Decent documentation, particularly of the JavaScript APIs generated for C libraries like GLib - at the moment, working out what's going to be available in the JavaScript bindings is very tedious
  • An easy installation process (see above) - largely though because I'm using libraries which are too bleeding edge, just because they're the only ones which worked well
  • An intelligible module system, for modularising code - at the moment my application will only run from the directory where the files are, as I've yet to work out how to get the path to the directory containing the script programmatically; I'm not sure how you'd organise large groups of files spread over lots of directories
  • A decent packaging system with dependency tracking, so that you can distribute JS apps and know they'll work
  • Functions to make developers' lives easier, like a decent REPL (gjs doesn't even have a print function - there is a patch to gjs which will give you that - see here: http://bugzilla-attachments.gnome.org/attachment.cgi?id=135898 - but you'll have to patch manually at the moment to get it)

And finally, it might be worth taking a look at Seed, which is an alternative JavaScript implementation, but one which still understands GObject introspection. Seed is interesting in that it seems to provide more niceties, like a better REPL environment, more documentation, and a fuller standard library (filesystem and environment interfaces in particular).

What's next for JavaScript?

It looks as if the JavaScript world is hotting up at the moment. This is a recent news report on the state of JavaScript:

http://arstechnica.com/web/news/2009/12/commonjs-effort-sets-javascript-...

It mentions the CommonJS standardisation effort, which is attempting to resolve some of the shortcomings of JavaScript as a general purpose language.

Reading through the CommonJS wiki, I was particularly interested in Narwhal, which resolves some of the issues I mentioned in the last section: it includes a package manager, module system, and standard library. It also provides support for different JavaScript engine back-ends: currently this includes a SpiderMonkey adapter. Given that Gjs is broadly based on SpiderMonkey, it seems likely that creating a Gjs back-end for Narwhal wouldn't be too onerous.

One other thing which could potentially be useful in Narwhal is the availability of separate Narwhal environments (called "seas") with their own set of packages. This could help isolate applications from each other in an environment like Moblin, where you want third parties to be able to develop applications without trampling on each other's libraries.

Another tool of interest is jake, a port of Ruby rake to JavaScript, which seems to be optimised to work with Narwhal. This could provide a reasonable alternative to autotools for the simpler build requirements of a JavaScript application (where there's no need for a compile step or library linking).

A combination of Narwhal (packaging/modules), with the power of Gjs binding to pretty much any C library, would make an attractive environment to develop in.

I should also mention node.js, server-side JavaScript primarily designed for building network programs, but which incorporates a CommonJS module system. It's built on Google's V8 JavaScript engine. It's also interesting because it is designed to be highly performant and memory-efficient, and has an interesting event-driven I/O model, like EventMachine or Twisted.

I'm definitely looking forward to seeing what happens next.

Syndicate content