An example Rakefile which compiles a source tree in SRC_DIR and outputs all objects to a build tree in OBJ_DIR.

The OBJ_DIR can depend on arguments passed to rake, e.g.:

$ rake build

gcc -c "src/foo/bar.c" -o "build/x86-gnuabi-Release/foo/bar.o"
gcc -c "src/printf.c" -o "build/x86-gnuabi-Release/printf.o"
mkdir -p dist/x86-gnuabi-Release
gcc -o "dist/x86-gnuabi-Release/raketest.exe" build/x86-gnuabi-Release/foo/bar.o build/x86-gnuabi-Release/printf.o




$ rake CONFIG=Test build

gcc -c "src/foo/bar.c" -o "build/x86-gnuabi-Test/foo/bar.o"
gcc -c "src/printf.c" -o "build/x86-gnuabi-Test/printf.o"
mkdir -p dist/x86-gnuabi-Test
gcc -o "dist/x86-gnuabi-Test/raketest.exe" build/x86-gnuabi-Test/foo/bar.o build/x86-gnuabi-Test/printf.o
# Rakefile for output directory mapping example
#
require 'rake/clean'

## Tasks
Dir['tasks/*.rake'].each { |f| import f }

##### Config ######
PROJ = "raketest"
CONFIG = ENV["CONFIG"] || "Release"

## Arch-ABI-Configuration
ARCH = "x86"
ABI = "abi"
AAC = [ARCH, ABI, CONFIG].join('-')

##### Tools #####
CC = "gcc"

##### Inputs ######
SRC_DIR = "src"
OBJ_DIR = File.join("build", AAC)
DIST_DIR = File.join("dist", AAC)

DIST_EXE = File.join(DIST_DIR, PROJ).ext('exe')


C_SRCS = FileList["#{SRC_DIR}/*\*/\*.c"]

##### Outputs ######

# Map sources to objects
C\_OBJS = C\_SRCS.map { |f|
  f.sub(/^#{SRC\_DIR}/, OBJ\_DIR).ext('.o')
}

##### Targets ######
CLEAN.include C_OBJS
CLEAN.include DIST_DIR

directory OBJ_DIR
directory DIST_DIR

# Create output dirs for each include dir
C_OBJS.each do |f|
  directory f.pathmap('%d')
end

task :default => :build

desc "Build"
task :build => DIST_EXE

task :info do
  p C_SRCS
  p C_OBJS
  p DIST_EXE
end

##### Rules ######

## CC
rule '.o' => [
    proc { |tn| tn.sub(/#{OBJ\_DIR}/, SRC\_DIR).ext('.c') },
    '%d'
  ] do |t|
  sh %Q{#{CC} -c "#{t.source}" -o "#{t.name}"}
end

## LD
rule '.exe' => [*C_OBJS, '%d'] do |t|
  sh %Q{#{CC} -o "#{t.name}" #{C_OBJS}}
end
 

Notes

  • The example above does not handle object filepaths with spaces. See RakeForMakeUsers.