# Building C++ with Rake

**URL:** <https://www.ruby-forum.com/t/building-c-with-rake/105860>\
**Category:** Ruby\
**Created:** [June 3, 2007, 10:21pm UTC](https://www.ruby-forum.com/t/building-c-with-rake/105860 "2007-06-03T22:21:04Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![magnus\_falk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/8797f3/32.png) [@magnus\_falk](https://www.ruby-forum.com/u/magnus_falk)\
**Post date:** [June 3, 2007, 10:21pm UTC](https://www.ruby-forum.com/t/building-c-with-rake/105860/1 "2007-06-03T22:21:04Z")

</div>

I’m familiarizing myself with Rake (and learning a spot of Ruby while  
doing it) by making a build environment for a C++ project I’m doing.  
I’ve run into a few issues though…

First off; here’s the code I have so far:

require ‘rake/clean’

PROJ\_NAME = “testproj”  
BUILD\_DIR = ENV[‘BUILD\_DIR’]  
OBJ\_DIR = File.join(BUILD\_DIR, PROJ\_NAME,  
File.expand\_path(’.’).pathmap("%f"), ‘objects’)  
SRC\_FILES = FileList[‘src/**/_.c_’]  
OBJ\_FILES = FileList[File.join(OBJ\_DIR + '**/\*.o’)]

CLEAN.include(OBJ\_DIR)

directory OBJ\_DIR

def compileTask inclDirs, flags  
includes = inclDirs.collect { |dir| ‘-I’ + dir + ’ ’ }  
compFlags = flags.collect { |flag| flag + ’ ’ }

SRC\_FILES.each do |srcFile|  
objFile = File.join(OBJ\_DIR, srcFile.pathmap("%f").ext(‘o’))

```
file objFile => [srcFile] do
  sh "g++ #{includes} #{compFlags} -c #{srcFile} -o #{objFile}"
end

```

end  
end

def linkTask depLibDirs, depLibs, flags, target  
libDirs = depLibDirs.collect { |dir| ‘-L’ + dir + ’ ’ }  
libs = depLibs.collect { |lib| ‘-l’ + (lib[/lib(.+)./, 1]) + ’ ’ }  
linkFlags = flags.collect { |flag| flag + ’ ’ }

if (File.extname(target) == ‘.so’) then  
linkFlags = linkFlags + [’-shared’ + ’ ‘]  
else  
linkFlags = linkFlags + [’-c’ + ’ ']  
end

targetFile = File.join(BUILD\_DIR, target)

file targetFile =\> OBJ\_FILES do  
objFiles = OBJ\_FILES.collect { |objFile| objFile + ’ ’ }  
sh “g++ #{libDirs} #{libs} #{linkFlags} #{objFiles} -o  
#{targetFile}”  
end  
end

#----This here below I would like to have in a separate file

task :default =\> [:link]

task :compile =\> [OBJ\_DIR] do  
inclDirs = [’/tmp/testdir1’, ‘/tmp/testdir2’]  
flags = [’-g’, ‘-v’]

compileTask(inclDirs, flags)  
end

task :link =\> [:compile] do  
target = ‘libTest.so’  
depLibDirs = [’/usr/lib’]  
depLibs = []  
flags = [’-fpic’]

linkTask(depLibDirs, depLibs, flags, target)  
end

And my issues:

1: The file task thingy doesn’t work as I thought it would, but I’m  
probably using it wrong. I hope it’s evident from the context what I’m  
trying to do though.

2: I have lots of ugly “insert space between the arguments in my  
arrays”. How do I do it in a nicer way?

3: I would like to separate the “defined” tasks from the “regular”  
ones so that the part furthest down is content of each “satellite”  
rakefile which then includes the top part as a kind of library. But  
when I tried doing it by simply putting the top part in a file and  
then putting ‘require “…/…/cppBuildLib.rb”’ at the top of the  
satellite file I got a message that file couldn’t be found (or  
something to that effect).

As I said before, I’m learning Rake and Ruby at the same time, so feel  
free to point out any oddities or other stuff that could/should be  
done differently.

---

<div class="post-metadata">

**Author:** ![magnus\_falk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/8797f3/32.png) [@magnus\_falk](https://www.ruby-forum.com/u/magnus_falk)\
**Post date:** [June 4, 2007, 6:54pm UTC](https://www.ruby-forum.com/t/building-c-with-rake/105860/2 "2007-06-04T18:54:10Z")

</div>

-----BEGIN PGP SIGNED MESSAGE-----  
Hash: SHA1

On Jun 3, 2007, at 23:20 , Magnus F. wrote:

> 2: I have lots of ugly “insert space between the arguments in my  
> arrays”. How do I do it in a nicer way?

Just build your array and then call array.join(’ ') to get a string of  
the array elements separated by a space.

> 3: I would like to separate the “defined” tasks from the “regular”  
> ones so that the part furthest down is content of each “satellite”  
> rakefile which then includes the top part as a kind of library. But  
> when I tried doing it by simply putting the top part in a file and  
> then putting ‘require “…/…/cppBuildLib.rb”’ at the top of the  
> satellite file I got a message that file couldn’t be found (or  
> something to that effect).

Yes, it’s a bit hard to say where ruby thinks that the current directory  
is. But as the string you give to require doesn’t have to be static you  
can just make it an absolute path buy prepending File.dirname( **FILE** )  
(and maybe use File.join to create the path out of its pieces).

Urban

-----BEGIN PGP SIGNATURE-----  
Version: GnuPG v1.4.6 (Darwin)

iD8DBQFGZEMxggNuVCIrEyURAm59AJoDF/dQejNJ4rSGapzJu2OWEdCFnQCfeJxY  
LnIud7fAAIn85LowMZCn5Pw=  
=kXVn  
-----END PGP SIGNATURE-----

---

<div class="post-metadata">

**Author:** ![magnus\_falk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/8797f3/32.png) [@magnus\_falk](https://www.ruby-forum.com/u/magnus_falk)\
**Post date:** [June 5, 2007, 9:42am UTC](https://www.ruby-forum.com/t/building-c-with-rake/105860/3 "2007-06-05T09:42:33Z")

</div>

The Array.join worked beautifully, thanks for the tip.

Also, I seem to have lied about the import issue (I was recreating an  
issue I had earlier before I moved it all into one file). I managed to  
resolve it now and my best guess is that it was appending “.rb” to the  
filename that did it.

Cheers,  
Magnus
