Jim said:
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.
With regards to the RANT project
http://rubyforge.org/projects/make/
where I nicked the scanner this should do the job.
===========================================
module Rake
module C
module Include
def Include.depends(file)
File.open file do |f|
txt = f.read
parse_includes txt
end
end
# Searches for all `#include' statements in the C/C++ source
# from the string +src+.
#
# Returns two arguments:
# 1. A list of all standard library includes (e.g. #include
<stdio.h>).
# 2. A list of all local includes (e.g. #include "stdio.h").
def Include.parse_includes(src)
if src.respond_to? :to_str
src = src.to_str
else
raise ArgumentError, "src has to be a string"
end
s_includes = []
l_includes = []
in_block_comment = false
prev_line = nil
src.each { |line|
line.chomp!
if block_start_i = line.index("/*")
c_start_i = line.index("//")
if !c_start_i || block_start_i < c_start_i
if block_end_i = line.index("*/")
if block_end_i > block_start_i
line[block_start_i..block_end_i+1] = ""
end
end
end
end
if prev_line
line = prev_line << line
prev_line = nil
end
if line =~ /\\$/
prev_line = line.chomp[0...line.length-1]
end
if in_block_comment
in_block_comment = false if line =~ %r|\*/|
next
end
case line
when /\s*#\s*include\s+"([^"]+)"/
l_includes << $1
when /\s*#\s*include\s+<([^>]+)>/
s_includes << $1
when %r|(?!//)[^/]*/\*|
in_block_comment = true
end
}
[s_includes, l_includes]
end
end
end
end
# RAKE Rule figures out the dependencies for the C file
rule( /\.o$/ =>
proc do |task_name|
a = []
name = task_name.sub(/\.[^.]+$/, '.c')
s_includes, l_includes = Rake::C::Include.depends(name)
a << name
a << l_includes
a
end
) do |t|
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