Rant vs. Rake

Since many people (especially Ruby programmers) that know Rake ask for a Rake/Rant comparison, I’ll spend a few paragraphs on this topic.

This comparison is for Rant 0.4.8 and Rake 0.6.2. If not stated otherwise, this document assumes a standard Ruby 1.8/1.9 installation without additional libraries (except for Rant and Rake).

Feature comparison

Generally speaking, Rant has all major features of Rake and more. Especially the following major Rant features aren’t available for Rake:

  • Optional use of MD5 checksums instead of timestamps. To enable it, one import statement at the top of the Rantfile is enough:
      import "md5"
  • Easy and portable tgz/zip file creation on Linux/MacOS X/Windows (and probably most other platforms where ruby runs). No additional libraries necessary!
  • Create a script, tailored to the needs of a project, which can be used instead of an Rant installation => Distribute this script with your project and users and other developers don’t need an Rant installation.

    Try the rant-import command:

      % rant-import --auto make.rb

    rant-import reads the Rantfile in the current directory, determines what code of the Rant distribution (and custom imports) is needed and writes a script that supports all required Rant features and depends only on a standard Ruby (1.8.0 or newer) installation to the file make.rb. Users and other developers don’t need an Rant installation anymore. Instead of typing:

      % rant foo

    they can type:

      % ruby make.rb foo
  • It is possible to split up the build specification into multiple files in different directories. (=> no such thing as "recursive make" necessary).
  • Dependency checking for C/C++ source files (integrated makedepend replacement).
  • The —force-run (-a) option forces the rebuild of a target and all its dependencies. E.g.:
      % rant -a foo

    Let’s say foo depends on foo.o and util.o. Then the above command will cause a rebuild of foo.o, util.o and foo, no matter if Rant considers these files up to date or not.

  • Tasks with command change recognition. Example code:
      import "command"
      var :CFLAGS => "-g -O2" # can be overridden from commandline
      gen Command, "foo", ["foo.o", "util.o"],
          "cc $[CFLAGS] -o $(name) $(prerequisites)"

    The last two lines tell Rant, that the file foo depends on the files foo.o and util.o and that foo can be built by running the command in the last line ("cc …") in a subshell. If at least one of the following three conditions is met, foo will be rebuilt:

    1. foo doesn’t exist.
    2. foo.o or util.o changed since the last build of foo.
    3. The command (most probably CFLAGS) changed since the last build of foo.
  • Dependency checking for C/C++ source files
      import "c/dependencies"
      # save dependencies between source/header files in the file
      # "cdeps"; search for include files in "." and "include" dirs
      gen C::Dependencies, "cdeps"
          :search => [".", "include"]
      # load dependency information when Rant looks at a C file
      gen Action, /\.(c|h)/ do source "cdeps" end

Some other goodies: The make method, the SubFile and AutoClean tasks, special variables and more. Most of this is documented in doc/advanced.rdoc


  • Rake defines many methods (task, file, desc, FileUtils methods, etc.) in the Object class (i.e. accessible from each line of Ruby code) which can get problematic at least if you want to use Rake as a library.

    Rant solves this problem by evaluating Rantfiles in a special context (with instance_eval).

  • Rake uses global variables and class/class instance variables to store state (tasks, etc.). The effect of this is, that you can have only one Rake application per Ruby interpreter (process) at a time.

    Rant stores application state in a class instance. It is possible to instantiate as many "Rant applications" at the same time as needed. On the other hand, there is currently no public and documented interface to do so (but it will come at least with Rant 1.0.0).