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
 

$[Get Code]1

Notes

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