Rake - How to use separate source and build folders

Hello Rubyists,

I am new to rake and attempting to use it to build a small C++ project. I made some changes to one of the example rake files from rake.rubyforge.org and I want to have a separate source and build folder named 'src' and 'build'. I use the FileList to specify my cpp files, then I modify that list with the 'ext' and 'sub' methods. I would expect this to work, however I get this:

"Don't know how to build task 'build/CGfxOpenGL.o'" which points to this line: "Rake::Task['link'].invoke" in the build task.

If I change these 2 lines:

exts = SRC.ext('o')
OBJ = exts.sub("#{SRC_DIR}", "#{BUILD_DIR}")

to just

OBJ = SRC.ext('o')

it WORKS FINE except all my object files are in my src folder WHICH I DON'T WANT.

How can I remedy this? I thought that since the 'build/CGfxOpenGL.o' does not exist that the rule '.o' would execute which is what does the compile.

many many thanks!

-Barry

require 'rake/clean'

SRC_DIR = 'src'
BUILD_DIR = 'build'

SRC = FileList["#{SRC_DIR}/*.cpp"]
exts = SRC.ext('o')
OBJ = exts.sub("#{SRC_DIR}", "#{BUILD_DIR}")

task :echo do
   puts "Usage:\n"
   puts " clean\n"
   puts " build\n"
end

# clean
CLEAN.include("#{BUILD_DIR}/*.o")

task :default => ["echo"]

task :init do
   FileUtils.mkdir "#{BUILD_DIR}" if !FileTest.exists?("#{BUILD_DIR}")
end

# compile
rule '.o' => '.cpp' do |t|
   sh "g++ -Wall -Weffc++ -O2 -c -o #{t.name} #{t.source}"
end

# link
file "link" => OBJ do
   puts "myobject: #{OBJ}\n";
   sh "g++ -Wall -L/usr/local/lib -lglut -lGL -lGLU -o #{BUILD_DIR}/Balance #{OBJ}"
end

# build it!
task :build => [:init] do
   Rake::Task['link'].invoke
end

# File dependencies go here ...
file 'CGfxOpenGL.o' => ['CGfxOpenGL.cpp',
                         'CGfxOpenGL.h']

file 'winmain.o' => ['winmain.cpp']

Well, I stole this from Jim Weirich's blog so if it does not work, blame him :wink:

You want to modify your "rule '.o' => ..." line so that it maps to a
lambda function ...

def find_source( objfile )
  SRC.find { |s| File.basename(s, '.cpp') == File.basename(objfile, '.o') }
end

rule '.o' => lambda {|objfile| find_source(objfile)} do |t|
  sh "g++ -Wall -Weffc++ -O2 -c -o #{t.name} #{t.source}"
end

Jim's full writeup can be found here
http://jimweirich.umlcoop.net/index.cgi/Tech/Rake/Tutorial

The only thing to watch out for with this rule is that all your source
code files must be uniquely named. All directory information is
stripped off by the call to File.basename in the find_source method.

Blessings,
TwP

···

On 10/10/06, Barry Andrews <titanandrews@none.com> wrote:

Hello Rubyists,

I am new to rake and attempting to use it to build a small C++ project.
I made some changes to one of the example rake files from
rake.rubyforge.org and I want to have a separate source and build folder
named 'src' and 'build'. I use the FileList to specify my cpp files,
then I modify that list with the 'ext' and 'sub' methods. I would expect
this to work, however I get this:

"Don't know how to build task 'build/CGfxOpenGL.o'" which points to this
line: "Rake::Task['link'].invoke" in the build task.

If I change these 2 lines:

exts = SRC.ext('o')
OBJ = exts.sub("#{SRC_DIR}", "#{BUILD_DIR}")

to just

OBJ = SRC.ext('o')

it WORKS FINE except all my object files are in my src folder WHICH I
DON'T WANT.

How can I remedy this? I thought that since the 'build/CGfxOpenGL.o'
does not exist that the rule '.o' would execute which is what does the
compile.

many many thanks!