Raking up Vala

    I've been watching the Vala project very closely for the past while. The goal is to make a nice high level language built on top of the existing GLib/GObject type system. The advantage is, vala code compiles down to standard C/GLib code, so it maintains the speed and interoperability of C without dealing with the suckiness of GObject copypasta. The issue in paradise? The only build system that remotely supports vala is autotools, which can go die in a fire as far as I'm concerned.

    So, how does one propose we build vala applications if the only build system that has (remote) support is by far the worst one out there? Well, we take a build system that has shown it's flexibility and ease of use time and time again, rake, and we add support to it! And that's exactly what I'm working on right now.

    Yes, it seems somewhat strange to be using a build system written in ruby to build vala applications, but is it any stranger than using one written as m4 macros? In the end, the goal is to have a simple, clean build system that makes modifying and adding tasks to your build as easy as possible, and using rake makes that goal easy to achieve.

    It's important to note that I've only started my vala-rake project, and the rake tasks are barely there, nowhere close to working. But, having a good design goal makes writing stuff like this a lot easier, so I figure I'd post a sample Rakefile (non-functional, this is the ideal outcome however once the work on vala-rake is done):

Vala::Library.new("testlib") do |lib|
  lib.library_name = "testlib"
  lib.src_dir = "testlib"
  lib.classes = [
    "testlib.Person"
  ]
end
 
Vala::Binary("testapp") do |bin|
  bin.bin_name = "testapp"
  bin.src_dir = "testapp"
  bin.classes = [
    "testapp.Application",
    "testapp.Greeter"
  ]
  bin.deps = ["testlib"]
end

    This is a very trivial example, but it shows the important parts of how vala-rake should work. So, let's break stuff down into detail, shall we?

Rake Tasks

    The first thing you'll notice is the two (the only two) rake tasks in the Vala module. One is used to create vala class libraries (hence Vala::Library), and the other is for vala binaries (again, hence Vala::Binary). This already gives us a lot of info on flags we need to pass to valac, and also on the steps we must take after valac finishes its run (since manual calls to GCC are still required in many cases).

library/bin_name

    Another bit of information we need to compile is what the name of the finished binary or .so/vapi pair is. This is more information that is essentially just passed right through to valac itself, since it's only used for the -o and --library flags.

classes

    See, here's where other build systems fail, they allow you to maintain whatever directory structure you want, which means you have to tell it about each and every file and how to compile it. Instead of focusing on files, a build system should encourage a sane directory structure and just focus on your code.

    So, instead of using file paths like "testlib/testlib/Person.vala", we simply assume we have a sane namespace/class.vala directory structure. So, if we had nested namespaces like testlib.errors.HumanError, it'd mad to "testlib/errors/HumanError.vala". This essentially forces the one-class-per-file methodology of Java (a very good methodology really, it encourages proper code organization).

src_dir

    If we're going to allow multiple binaries and libraries to be built from a single Rakefile, we had better have configurable source directories to keep the code seperate. The sample rakefile above has the following project structure:

/
 - Rakefile
 - testlib
 \ - testlib
   | - Human.vala
 - testapp
 \ - testapp
   | - Application.vala
   | - Greeter.vala

deps

    Another thing that we need to handle is dependencies, most of this is just throwing these flags to valac, but we also want to check the dependencies to see if they are related to other Library tasks in the current Rakefile so we can tell valac where to find the interface and header files for them.

Now then

    The above Rakefile should generate the following rake tasks:

rake build:all
rake build:testlib
rake build:testapp
 
rake install:all
rake install:testlib
rake install:testapp

    The tasks are pretty self explanatory, they're essentially make && make install. Since testapp depends on testlib building it should also build testlib as the prerequisite, anything else that's not part of the rakefile is assumed to exist and is linked normally.

    I'm unsure of whether I should handle an autotools-style link-relink cycle that allows you to run applications in-place if they use libraries part of the current build. I have no idea how that's implemented, so maybe one of you fine people will be kind enough to contribute it once I get something in working shape.

    Anyways, keep in mind that vala-rake barely knows hall to call valac, and I've already started refactoring code when I barely have tha valac wrapper written. My goal is to have something remotely usable by the end of the Feb. though, so keep your eyes peeled.

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

gucci

Well , the view of the passage is totally correct ,your details is really reasonable and you guy give us valuable informative post, I totally agree the standpoint of upstairs. I often surfing on this forum when I m free and I find there are so much good information we can learn in this forum! http://www.oneor-more.com/

Post new comment

  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.
  • You can enable syntax highlighting of source code with the following tags: <code>, <blockcode>. Beside the tag style "<foo>" it is also possible to use "[foo]".

More information about formatting options