# Rake and Rant

**URL:** <https://rubytalk.org/t/rake-and-rant/39828>\
**Category:** ruby-talk\
**Created:** [11 August 2007 18:35 UTC](https://rubytalk.org/t/rake-and-rant/39828 "2007-08-11T18:35:05Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![barcaroller](https://avatars.discourse-cdn.com/v4/letter/b/5f9b8f/32.png) [@barcaroller](https://rubytalk.org/u/barcaroller)\
**Post date:** [11 August 2007 18:35 UTC](https://rubytalk.org/t/rake-and-rant/39828/1 "2007-08-11T18:35:05Z")

</div>

I was wondering whether anybody has had any experience with both these Ruby  
build tools. If so, which one would be more suitable for large projects  
that contain both C++ and Java source code?

---

<div class="post-metadata">

**Author:** ![David\_Karapetyan](https://avatars.discourse-cdn.com/v4/letter/d/bcef8e/32.png) [@David\_Karapetyan](https://rubytalk.org/u/David_Karapetyan)\
**Post date:** [11 August 2007 23:42 UTC](https://rubytalk.org/t/rake-and-rant/39828/2 "2007-08-11T23:42:36Z")

</div>

Rant is a superset of Rake in that it has everything Rake has and more, so  
if you are looking for a build tool that uses Ruby as its underlying  
language then you should go with Rant. You can use only a subset of it and  
pretend it is Rake if you want.

> **···**
>
> On 8/11/07, barcaroller \<barcaroller@music.net\> wrote:
> 
> > I was wondering whether anybody has had any experience with both these  
> > Ruby  
> > build tools. If so, which one would be more suitable for large projects  
> > that contain both C++ and Java source code?

---

<div class="post-metadata">

**Author:** ![Jeremy\_Hinegardner](https://avatars.discourse-cdn.com/v4/letter/j/65b543/32.png) [@Jeremy\_Hinegardner](https://rubytalk.org/u/Jeremy_Hinegardner)\
**Post date:** [12 August 2007 04:17 UTC](https://rubytalk.org/t/rake-and-rant/39828/3 "2007-08-12T04:17:43Z")

</div>

Yes, Rake is perfectly useful in large non-ruby projects as a build  
tool. According to  
([http://railsenvy.com/2007/6/11/ruby-on-rails-rake-tutorial\](http://railsenvy.com/2007/6/11/ruby-on-rails-rake-tutorial%5C)) Jim  
actually created Rake to deal with a Java project. And that link is a  
good tutorial too.

Jim has a few tutorials on using Rake with C :

&nbsp;&nbsp;- [http://onestepback.org/index.cgi/Tech/Rake/Tutorial/RakeTutorialIntroduction.rdoc](http://onestepback.org/index.cgi/Tech/Rake/Tutorial/RakeTutorialIntroduction.rdoc)  
&nbsp;&nbsp;- [http://onestepback.org/index.cgi/Tech/Rake/Tutorial/RakeTutorialAnotherCExample.red](http://onestepback.org/index.cgi/Tech/Rake/Tutorial/RakeTutorialAnotherCExample.red)

enjoy,

-jeremy

> **···**
>
> On Sun, Aug 12, 2007 at 03:35:05AM +0900, barcaroller wrote:
> 
> > I was wondering whether anybody has had any experience with both these Ruby  
> > build tools. If so, which one would be more suitable for large projects  
> > that contain both C++ and Java source code?
> 
> # --
> 
> Jeremy Hinegardner jeremy@hinegardner.org

---

<div class="post-metadata">

**Author:** ![Alex\_Young](https://avatars.discourse-cdn.com/v4/letter/a/ee7513/32.png) [@Alex\_Young](https://rubytalk.org/u/Alex_Young)\
**Post date:** [12 August 2007 08:19 UTC](https://rubytalk.org/t/rake-and-rant/39828/4 "2007-08-12T08:19:14Z")

</div>

barcaroller wrote:

> I was wondering whether anybody has had any experience with both these Ruby build tools. If so, which one would be more suitable for large projects that contain both C++ and Java source code?

I've used Rake on a few C/C++ projects myself - if you want to see an example of a fairly complex C project using Rake, check out the Rubinius source.

> **···**
>
> --  
> Alex

---

<div class="post-metadata">

**Author:** ![Brad\_Phelan](https://avatars.discourse-cdn.com/v4/letter/b/9fc348/32.png) [@Brad\_Phelan](https://rubytalk.org/u/Brad_Phelan)\
**Post date:** [12 August 2007 11:40 UTC](https://rubytalk.org/t/rake-and-rant/39828/5 "2007-08-12T11:40:03Z")

</div>

Alex Young wrote:

> barcaroller wrote:
> 
> > I was wondering whether anybody has had any experience with both these Ruby build tools. If so, which one would be more suitable for large projects that contain both C++ and Java source code?
> 
> I've used Rake on a few C/C++ projects myself - if you want to see an example of a fairly complex C project using Rake, check out the Rubinius source.

I don't think that Rake currently has the concept of a scanner for automatically discovering dependencies such as in header file  
hierarchies. SCons for example has this built in. What is the  
best way of going about auto generating dependencies within  
Rake for C/C++ projects?

I would prefer to use Rake than SCons for C/C++

Brad

---

<div class="post-metadata">

**Author:** ![Jim\_Weirich1](https://avatars.discourse-cdn.com/v4/letter/j/73ab20/32.png) [@Jim\_Weirich1](https://rubytalk.org/u/Jim_Weirich1)\
**Post date:** [16 August 2007 02:10 UTC](https://rubytalk.org/t/rake-and-rant/39828/6 "2007-08-16T02:10:31Z")

</div>

david karapetyan wrote:

> Rant is a superset of Rake in that it has everything Rake has and more,

Although that may have once been true, it is certainly no longer the  
case. Neither Rant nor Rake are supersets of the other, for both have  
evolved beyond the early Rake functionality upon which Rant was based.  
(Also note that the rake/rant comparison on the rant project page is  
quite dated).

-- Jim Weirich

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Alex\_Young](https://avatars.discourse-cdn.com/v4/letter/a/ee7513/32.png) [@Alex\_Young](https://rubytalk.org/u/Alex_Young)\
**Post date:** [12 August 2007 13:25 UTC](https://rubytalk.org/t/rake-and-rant/39828/7 "2007-08-12T13:25:46Z")

</div>

Brad Phelan wrote:

> Alex Young wrote:
> 
> > barcaroller wrote:
> > 
> > > I was wondering whether anybody has had any experience with both these Ruby build tools. If so, which one would be more suitable for large projects that contain both C++ and Java source code?
> > 
> > I've used Rake on a few C/C++ projects myself - if you want to see an example of a fairly complex C project using Rake, check out the Rubinius source.
> 
> I don't think that Rake currently has the concept of a scanner for automatically discovering dependencies such as in header file  
> hierarchies. SCons for example has this built in. What is the  
> best way of going about auto generating dependencies within  
> Rake for C/C++ projects?

The same as for make - shell out to the compiler, then parse the result. gcc -MM is what I'm familiar with, I presume other compilers have similar switches. Rant does have this built in, but I'm not familiar with it (although having just researched it a little, I think I will make the effort now 🙂 )

> **···**
>
> --  
> Alex

---

<div class="post-metadata">

**Author:** ![David\_Karapetyan](https://avatars.discourse-cdn.com/v4/letter/d/bcef8e/32.png) [@David\_Karapetyan](https://rubytalk.org/u/David_Karapetyan)\
**Post date:** [16 August 2007 04:47 UTC](https://rubytalk.org/t/rake-and-rant/39828/8 "2007-08-16T04:47:40Z")

</div>

my mistake.

> **···**
>
> On 8/15/07, Jim Weirich \<jim@weirichhouse.org\> wrote:
> 
> > david karapetyan wrote:  
> > \> Rant is a superset of Rake in that it has everything Rake has and more,
> > 
> > Although that may have once been true, it is certainly no longer the  
> > case. Neither Rant nor Rake are supersets of the other, for both have  
> > evolved beyond the early Rake functionality upon which Rant was based.  
> > (Also note that the rake/rant comparison on the rant project page is  
> > quite dated).
> > 
> > -- Jim Weirich  
> > --  
> > Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Brad\_Phelan](https://avatars.discourse-cdn.com/v4/letter/b/9fc348/32.png) [@Brad\_Phelan](https://rubytalk.org/u/Brad_Phelan)\
**Post date:** [12 August 2007 13:45 UTC](https://rubytalk.org/t/rake-and-rant/39828/9 "2007-08-12T13:45:09Z")

</div>

> The same as for make - shell out to the compiler, then parse the result. gcc -MM is what I'm familiar with, I presume other compilers have similar switches. Rant does have this built in, but I'm not familiar with it (although having just researched it a little, I think I will make the effort now 🙂 )

I found

&nbsp;&nbsp;require 'rake/loaders/makefile'

&nbsp;&nbsp;&nbsp;file ".depends.mf" =\> [SRC\_LIST] do |t|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sh "makedepend -f- -- #{CFLAGS} -- #{t.prerequisites} \> #{t.name}"  
&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;import ".depends.mf"

at

[http://docs.rubyrake.org/read/chapter/4](http://docs.rubyrake.org/read/chapter/4)

Still a native Ruby solution would be nicer.

Brad

---

<div class="post-metadata">

**Author:** ![Simon\_Krahnke](https://avatars.discourse-cdn.com/v4/letter/s/b782af/32.png) [@Simon\_Krahnke](https://rubytalk.org/u/Simon_Krahnke)\
**Post date:** [15 August 2007 18:05 UTC](https://rubytalk.org/t/rake-and-rant/39828/10 "2007-08-15T18:05:03Z")

</div>

\* Brad Phelan \<bradphelan@xtargets.com\> (2007-08-12) schrieb:

> Still a native Ruby solution would be nicer.

Why, is you C compiler a Ruby solution?

mfg, simon .... l

---

<div class="post-metadata">

**Author:** ![Jim\_Weirich1](https://avatars.discourse-cdn.com/v4/letter/j/73ab20/32.png) [@Jim\_Weirich1](https://rubytalk.org/u/Jim_Weirich1)\
**Post date:** [16 August 2007 02:24 UTC](https://rubytalk.org/t/rake-and-rant/39828/11 "2007-08-16T02:24:04Z")

</div>

Brad Phelan wrote:

> Still a native Ruby solution would be nicer.

If someone wanted to contribute a dependency scanner for their favorite  
language to the Rake project, I would be willing to consider it for  
inclusion.

A C/C++ scanner shouldn't be that hard to write. Its just that I've not  
working in a C/C++ project since starting Rake, so I've never had the  
need to write one.

> **···**
>
> --  
> -- Jim Weirich  
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Brad\_Phelan1](https://avatars.discourse-cdn.com/v4/letter/b/f6c823/32.png) [@Brad\_Phelan1](https://rubytalk.org/u/Brad_Phelan1)\
**Post date:** [16 August 2007 09:54 UTC](https://rubytalk.org/t/rake-and-rant/39828/12 "2007-08-16T09:54:58Z")

</div>

Jim Weirich wrote:

> Brad Phelan wrote:
> 
> > Still a native Ruby solution would be nicer.
> 
> If someone wanted to contribute a dependency scanner for their favorite language to the Rake project, I would be willing to consider it for inclusion.
> 
> A C/C++ scanner shouldn't be that hard to write. Its just that I've not working in a C/C++ project since starting Rake, so I've never had the need to write one.
> 
> --  
> -- Jim Weirich

With regards to the RANT project [http://rubyforge.org/projects/make/](http://rubyforge.org/projects/make/)  
where I nicked the scanner this should do the job.

> **···**
>
> ===========================================
> 
> module Rake  
> &nbsp;&nbsp;&nbsp;&nbsp;module C  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;module Include  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def Include.depends(file)  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;File.open file do |f|  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;txt = f.read  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;parse\_includes txt  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end
> 
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Searches for all `#include' statements in the C/C++ source  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# from the string +src+.  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Returns two arguments:  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 1. A list of all standard library includes (e.g. #include \<stdio.h\>).  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 2. A list of all local includes (e.g. #include "stdio.h").  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def Include.parse\_includes(src)  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if src.respond\_to? :to\_str  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;src = src.to\_str  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raise ArgumentError, "src has to be a string"  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s\_includes =   
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;l\_includes =   
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;in\_block\_comment = false  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prev\_line = nil  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;src.each { |line|  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;line.chomp!  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if block\_start\_i = line.index("/\*")  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;c\_start\_i = line.index("//")  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if !c\_start\_i || block\_start\_i \< c\_start\_i  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if block\_end\_i = line.index("\*/")  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if block\_end\_i \> block\_start\_i  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;line[block\_start\_i..block\_end\_i+1] = ""  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if prev\_line  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;line = prev\_line \<\< line  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prev\_line = nil  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if line =~ /\\$/  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prev\_line = line.chomp[0...line.length-1]  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if in\_block\_comment  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;in\_block\_comment = false if line =~ %r|\*/|  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;next  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case line  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;when /\s\*#\s\*include\s+"([^"]+)"/  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;l\_includes \<\< $1  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;when /\s\*#\s\*include\s+\<([^\>]+)\>/  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s\_includes \<\< $1  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;when %r|(?!//)[^/]\*/\*|  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;in\_block\_comment = true  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[s\_includes, l\_includes]  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;end  
> end
> 
> # RAKE Rule figures out the dependencies for the C file
> 
> rule( /\.o$/ =\>
> 
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proc do |task\_name|  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a =   
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;name = task\_name.sub(/\.[^.]+$/, '.c')  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s\_includes, l\_includes = Rake::C::Include.depends(name)  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a \<\< name  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a \<\< l\_includes  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end
> 
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;) do |t|  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sh "cc #{t.source} -c -o #{t.name}"  
> end
> 
> The scanner is not recursive yet but should be simple  
> to implement but I have to run ......
> 
> Regards
> 
> --  
> Brad Phelan  
> [http://xtargets.com](http://xtargets.com)

---

<div class="post-metadata">

**Author:** ![Brad\_Phelan1](https://avatars.discourse-cdn.com/v4/letter/b/f6c823/32.png) [@Brad\_Phelan1](https://rubytalk.org/u/Brad_Phelan1)\
**Post date:** [16 August 2007 09:59 UTC](https://rubytalk.org/t/rake-and-rant/39828/13 "2007-08-16T09:59:58Z")

</div>

Brad Phelan wrote:

> Jim Weirich wrote:
> 
> > Brad Phelan wrote:
> > 
> > > Still a native Ruby solution would be nicer.
> > 
> > If someone wanted to contribute a dependency scanner for their favorite language to the Rake project, I would be willing to consider it for inclusion.
> > 
> > A C/C++ scanner shouldn't be that hard to write. Its just that I've not working in a C/C++ project since starting Rake, so I've never had the need to write one.
> > 
> > --  
> > -- Jim Weirich
> 
> With regards to the RANT project [http://rubyforge.org/projects/make/](http://rubyforge.org/projects/make/)  
> where I nicked the scanner this should do the job.
> 
> ===========================================
> 
> module Rake  
> &nbsp;&nbsp;&nbsp;module C  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;module Include  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def Include.depends(file)  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;File.open file do |f|  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;txt = f.read  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;parse\_includes txt  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end
> 
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Searches for all `#include' statements in the C/C++ source  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# from the string +src+.  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Returns two arguments:  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 1. A list of all standard library includes (e.g. #include \<stdio.h\>).  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 2. A list of all local includes (e.g. #include "stdio.h").  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def Include.parse\_includes(src)  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if src.respond\_to? :to\_str  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;src = src.to\_str  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raise ArgumentError, "src has to be a string"  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s\_includes =   
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;l\_includes =   
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;in\_block\_comment = false  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prev\_line = nil  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;src.each { |line|  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;line.chomp!  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if block\_start\_i = line.index("/\*")  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;c\_start\_i = line.index("//")  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if !c\_start\_i || block\_start\_i \< c\_start\_i  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if block\_end\_i = line.index("\*/")  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if block\_end\_i \> block\_start\_i  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;line[block\_start\_i..block\_end\_i+1] = ""  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if prev\_line  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;line = prev\_line \<\< line  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prev\_line = nil  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if line =~ /\\$/  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prev\_line = line.chomp[0...line.length-1]  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if in\_block\_comment  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;in\_block\_comment = false if line =~ %r|\*/|  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;next  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case line  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;when /\s\*#\s\*include\s+"([^"]+)"/  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;l\_includes \<\< $1  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;when /\s\*#\s\*include\s+\<([^\>]+)\>/  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s\_includes \<\< $1  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;when %r|(?!//)[^/]\*/\*|  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;in\_block\_comment = true  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[s\_includes, l\_includes]  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;end  
> end
> 
> # RAKE Rule figures out the dependencies for the C file
> 
> rule( /\.o$/ =\>
> 
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proc do |task\_name|  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a =   
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;name = task\_name.sub(/\.[^.]+$/, '.c')  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s\_includes, l\_includes = Rake::C::Include.depends(name)  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a \<\< name  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a \<\< l\_includes  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end
> 
> &nbsp;&nbsp;&nbsp;&nbsp;) do |t|  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sh "cc #{t.source} -c -o #{t.name}"  
> end
> 
> The scanner is not recursive yet but should be simple  
> to implement but I have to run ......
> 
> Regards
> 
> --  
> Brad Phelan  
> [http://xtargets.com](http://xtargets.com)

My simple test rake file was

> **···**
>
> ++++++++++++++++++++++++++++++++++++++
> 
> require 'cscanner'
> 
> task :default =\> 'main.out'
> 
> file 'main.out' =\> ['main.o'] do |t|  
> &nbsp;&nbsp;&nbsp;sh "cc -o #{t.name} #{t.prerequisites.join(' ')}"  
> end
> 
> +++
> 
> and the C/H file was
> 
> +++  
> #include \<stdio.h\>  
> #include \<stdlib.h\>  
> #include "main.h"  
> int main ( int argc, char \* argv ){  
> &nbsp;&nbsp;&nbsp;&nbsp;printf("Hello world");  
> &nbsp;&nbsp;&nbsp;&nbsp;return 0;  
> }
> 
> ++
> 
> #ifndef \_MAIN\_  
> #define \_MAIN\_  
> typedef struct {  
> &nbsp;&nbsp;&nbsp;&nbsp;int a;  
> &nbsp;&nbsp;&nbsp;&nbsp;int b;  
> } Foo;  
> #endif
> 
> and it seemed to work ok
