If you're programming in C, C++ or Java, you'll be managing a large number of source files, and using a whole series of commands to build these forward into .o (object) or .class (java class) files, then - in the cases of C and C++ - into executable files.
system has been around for as long as I can remember for C (and Fortran and other) builds. It's very clever, but has some curiosities of syntax and its own definition language - and indeed, in the Java world, Apache Ant
has been around for quite a while to provide an alternative. And indeed Ant and Make are used extensively for a very wide range of other build tasks these days - far beyond just building or preparing for executable files.
is another build system. It's a Ruby application, and you write a rakefile
- the file that describes what depends on what, and how to get from the source to the target of each stage of the process as a piece of Ruby. The rake program, which is written in Ruby, then goes through all the dependencies and builds the code when you run it.
Let's see an example:
file 'shape.o' => ["shape.c", "shape.h"] do
sh "gcc -c -o shape.o shape.c"
and that says "if shape.c or shape.h has changed since shape.o was last produced, run the following shell command". It checks the time and date stamps on the various files to see if the work needs to be done and (the clever bit) it will recursively check on the files shape.c and shape.h first to see if they need to be refreshed first, thus provoking a need for shape.o to be refreshed too even if at first glance it's up to date (i.e. newer than either of its dependencies).
By comparison, the same dependency written in a makefile looks like:
shape.o: shape.c shape.h
gcc -c -o shape.o shape.cpp
There's a complete rakefile example [here]
, and the equivalent makefile [here]
. The application used in the example is from a recent C++ course ... a whole lot of source files, as it's my worked example of how you would split an application over a series of files with separate header and code files for each class. They are ... shape_main.cpp
To run rake, you'll run the rake command at the command line, which runs the ruby program, which in turn pulls in your instructions from the rakefile and does whatever's needed:
munchkin:c5 grahamellis$ rake hereitis
munchkin:c5 grahamellis$ rake hereitis
So the first time I ran it, all the work had to be done ... the second time, everything was up to date and no compiling of my C++ program was necessary.
Further elements of rake allow you to specify general rules for everything of a particular type, and specify things like "all .h files in a directory" which means you can build up sets of rules with lots of file specified very quickly. And because you have ruby there too, you can write loops and other code to generate a whole lot of elements of your build tree in just a few lines. Although the single source-target example above was shorter in a makefile, typically a rakefile as a whole will be much shorter, and easier to follow too if you knoe Ruby.
Rake is extensively used in Rails. Rails is the Ruby based web framework, and there's a whole range of things such as databases to be setup when you start, refreshed when you update your code and start a fresh set of tests, etc ... and rake is used for these tasks. You'll find that all the standard rake files used by rails when you start using it are there for you, but you may need to get in later. And if - as my customers are doing this week - you're using C++ as a production language and Ruby as your company's scripting standard, it's going to be logical for you to choose rake as your build tool. You can find the rake documentation [here]
, and about our Ruby courses [here]
. (written 2011-02-03, updated 2011-02-10)
Associated topics are indexed as below, or enter http://melksh.am/nnnn for individual articlesR119 - Ruby Miscellany 
Good Programming practise - where to initialise variables - (2007-05-09) 
Variable types in Ruby - (2008-03-21) 
Some Ruby lesser used functions - (2008-07-26) 
Ruby mixins, modules, require and include - (2008-11-16) 
MySQL database from Ruby - an example - (2008-11-16) 
How many days to Christmas? - (2011-09-09) 
Loading Ruby classes - where does Ruby look? - (2012-02-24) 
Load path, load and require in Ruby, and a change from 1.8 to 1.9 - (2012-06-24) 
Ruby Documentation through rdoc - (2012-07-07)R115 - Using Ruby with Other Languages 
Running shell (operating system) commands from within Ruby - (2016-05-18)C051 - C and C based languages - C++ - General 
C++, Python, and other training - do we use an IDE - (2009-08-21) 
Learning to program in ... - (2009-11-15) 
All the Cs ... and Java too - (2009-12-13) 
Complete teaching example - C++, inheritance, polymorphism - (2010-01-15) 
Our C and C++ training course are on Open Source platforms - (2010-05-13) 
Further C++ material - view new or old - (2010-07-04) 
Getting your C++ program to run - (2010-11-15) 
Using C and C++ functions in the same program - how to do it - (2010-11-24) 
Extra courses - C and C++ - (2011-01-12) 
C++ - how we teach the language and the concepts behind the language - (2011-04-17) 
C++ Courses - do I get official certification at the end of my Well House course? - (2012-01-20) 
Dwarf Exception Unwind Info - (2012-07-20) 
Flexible public courses - residential or commuting, programming newcomer or experienced, C or C++ - (2014-11-30) 
C++ in 2 days - (2014-12-18)A509 - Web Application Deployment - Java - Ant build tool 
Ant and Make - (2006-04-22) 
Scons - a build system in Python - building hello world - (2016-10-29)
Some other Articles
Returning multiple values from a function call in various languages - a comparisonRuby training - some fresh examples for string handling applicationsA new monopoly on the ferry to Northern IrelandSplitting data reading code from data processing code - RubyRake - a build system using code written in RubyChanging a class later on - RubyPoints West to BelfastJargon bustingDisassembling Python and Java - previously compiled codePython dictionaries - mutable and immutable keys and values