# Problem with rake and dependencies

**URL:** <https://www.ruby-forum.com/t/problem-with-rake-and-dependencies/149588>\
**Category:** Ruby\
**Created:** [September 26, 2008, 3:42pm UTC](https://www.ruby-forum.com/t/problem-with-rake-and-dependencies/149588 "2008-09-26T15:42:30Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![rake\_newb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/2bfe46/32.png) [@rake\_newb](https://www.ruby-forum.com/u/rake_newb)\
**Post date:** [September 26, 2008, 3:42pm UTC](https://www.ruby-forum.com/t/problem-with-rake-and-dependencies/149588/1 "2008-09-26T15:42:30Z")

</div>

Hello:

I am new to rake, and I am stuck on a problem with incremental building.  
My rakefile does what I would like, for the most part. If I touch a .c  
file, the rakefile functions properly and only builds the necessary  
files. However, if I touch the corresponding .h file, my rakefile  
assumes everything is up-to-date. I am pretty certain that I am not  
importing/loading my dependency files correctly. Please help.

I am using a dependency generation feature that is part of the DSP  
compiler we are using. The output from the preprocessor creates files  
with a .pp extension, formatted like so:

C:/dir/obj/lcd.obj: C:\dir\lcd.c  
C:/dir/obj/lcd.obj: C:\dir\lcd.h  
C:/dir/obj/lcd.obj: C:\dir\lcdpanel.h  
C:/dir/obj/lcd.obj: C:/CCStudio\_v3.3/C6000/cgtools/include/string.h  
C:/dir/obj/lcd.obj: C:/CCStudio\_v3.3/C6000/cgtools/include/linkage.h

I decided to copy those files to a file with a .mf extension because I  
was hoping that the makefile loader would handle things correctly.

Below is my rakefile. Notice that I am attempting to import the  
dependency files within my :build\_depend task. Unfortunately, I have no  
idea what import does, and therefore I have no idea if my dependencies  
are getting extracted in a way that rake understands.

###############################################################################  
###############################################################################  
###############################################################################  
###############################################################################  
require ‘dsp\_build\_defs’

## The following require’s are actually found in my dsp\_build\_defs.rb

file  
require ‘rake/clean’  
require ‘rake/loaders/makefile’  
require 'fileutils

include DspRakeFileConstants

###############################################################################

# Create the list of source files, etc.

###############################################################################  
#SRC\_FILES = FileList["#{DSP\_PROJ\_ROOT}/**/\*.#{C\_EXT}"]  
SRC\_FILES = FileList["#{DSP\_PROJ\_ROOT}/**/\*.#{C\_EXT}"].reject {|f| f =~  
/cropped/}  
DEPEND\_FILES = SRC\_FILES.ext("#{MF\_EXT}")  
OBJ\_FILES = SRC\_FILES.pathmap("#{OBJ\_DIR}/%n.#{OBJ\_EXT}")

###############################################################################

# Task definitions

###############################################################################  
desc ‘Default task to build debug version of dsp software’  
task :default =\> :debug\_build do  
OBJ\_FILES.each do |srcfile|  
#puts “source file: #{srcfile}”  
end  
DEPEND\_FILES.each do |depfile|  
#puts “source file: #{depfile}”  
end  
end

desc ‘Debug\_build task that depends on build\_depend and build\_obj’  
task :debug\_build =\> [:build\_depend, :build\_obj] do  
puts “almost ready to link…”  
end

desc ‘Release\_build task - not currently being called’  
task :release\_build =\> RELEASE\_BLD

desc ‘Build\_obj task that depends on the object directory and the object  
files’  
task :build\_obj =\> [OBJ\_DIR, OBJ\_FILES].flatten.uniq

desc ‘Build\_depend task that depends on the dependency files’  
task :build\_depend =\> DEPEND\_FILES do  
DEPEND\_FILES.each do |dep\_file|  
puts “Importing #{dep\_file}…”  
import “#{dep\_file}”  
end  
end

directory OBJ\_DIR

##############################################################################

# Rule definitions

##############################################################################  
rule “.#{DEPEND\_EXT}” =\> “.#{C\_EXT}” do |t|  
puts “Building dependency file for #{t.source}”  
sh “#{COMPILER} #{C\_OPTS} #{C\_DEPEND\_OPTS} #{C\_OBJ\_DIR}  
#{C\_INC\_PATHS} #{C\_FLAGS} #{C\_TARGET} #{t.source}”  
end

rule “.#{OBJ\_EXT}” =\> lambda{|objfile| find\_source(objfile)} do |t|  
puts “Building object file for #{t.source}”  
sh “#{COMPILER} #{C\_OPTS} #{C\_OBJ\_DIR} #{C\_INC\_PATHS} #{C\_FLAGS}  
#{C\_TARGET} #{t.source}”  
end

rule “.#{MF\_EXT}” =\> “.#{DEPEND\_EXT}” do |t|  
puts “Copying #{t.source} to #{t.name}”  
sh “cp #{t.source} #{t.name}”  
end

rule “.#{BIN\_EXT}” do |t|  
puts “Linking…”  
end  
###############################################################################  
###############################################################################  
###############################################################################  
###############################################################################

Thanks, in advance, for the help!

Best Regards,  
Brock

---

<div class="post-metadata">

**Author:** ![rake\_newb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/2bfe46/32.png) [@rake\_newb](https://www.ruby-forum.com/u/rake_newb)\
**Post date:** [September 26, 2008, 6:10pm UTC](https://www.ruby-forum.com/t/problem-with-rake-and-dependencies/149588/2 "2008-09-26T18:10:14Z")

</div>

I am not yet a rake enthusiast – but just this morning I decided,  
“OK, it’s probably time for me to start learning about rake”. So,  
with that disclaimer, I would suggest that #import doesn’t do what you  
think it does. Looking at the rake documentation  
([http://rake.rubyforge.org/](http://rake.rubyforge.org/)), it describes File#import as a procedure  
that imports partial rakefiles. Not having played much with rake yet,  
I’m somewhat surprised that it doesn’t bomb when you import the code  
composer dependency file. But, be that as it may, what you probably  
want to do is to write a rake task that parses each line of the CCS  
file and adds a rake dependency based on what it finds there.

Of course, that may fly in the face of whatever FAQ/tutorial/book  
you’re using, in which case, I would say follow the other source since  
(s)he knows infinitely more about rake than I do :-).

Good luck!

–wpd

---

<div class="post-metadata">

**Author:** ![rake\_newb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/2bfe46/32.png) [@rake\_newb](https://www.ruby-forum.com/u/rake_newb)\
**Post date:** [September 26, 2008, 7:18pm UTC](https://www.ruby-forum.com/t/problem-with-rake-and-dependencies/149588/3 "2008-09-26T19:18:00Z")

</div>

On 2nd thought, perhaps this thread might help:

[http://www.ruby-forum.com/topic/58444](http://www.ruby-forum.com/topic/58444)

Look for the post from Jim W…

–wpd

---

<div class="post-metadata">

**Author:** ![rake\_newb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/2bfe46/32.png) [@rake\_newb](https://www.ruby-forum.com/u/rake_newb)\
**Post date:** [September 26, 2008, 7:29pm UTC](https://www.ruby-forum.com/t/problem-with-rake-and-dependencies/149588/4 "2008-09-26T19:29:34Z")

</div>

Patrick D. wrote:

> On 2nd thought, perhaps this thread might help:
> 
> [Incremental rebuild with Rake - Ruby - Ruby-Forum](http://www.ruby-forum.com/topic/58444)
> 
> Look for the post from Jim W…
> 
> –wpd

Hello Jim:

Actually, I am very familiar with that thread. Been studying that all  
week. One of the differences is that thread references makedepend -  
which output format I am not familiar. I haven’t been successful find a  
sample of makedepends output. So I am not sure if my preprocessor is  
even outputting in a format that is accurately parsed via  
rake/loaders/makefile.

Brock

---

<div class="post-metadata">

**Author:** ![rake\_newb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/2bfe46/32.png) [@rake\_newb](https://www.ruby-forum.com/u/rake_newb)\
**Post date:** [September 26, 2008, 8:39pm UTC](https://www.ruby-forum.com/t/problem-with-rake-and-dependencies/149588/5 "2008-09-26T20:39:14Z")

</div>

Hi Brock,  
I think I may have just found the source of your problem:

If you look at rake/loaders/makefile.rb (which, on my Windoze system  
is somewhere near  
ruby/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake/loaders/makefile.rb),  
you will see something that looks like:

```
# Process one logical line of makefile data.
def process_line(line)
  file_task, args = line.split(':')
  return if args.nil?
  dependents = args.split
  file file_task => dependents
end

```

This will not handle C:\blah filenames correctly – it split’s them at  
the first colon (":").

You could use that file as a source of inspiration to write your own  
Rake::MakefileLoader#load method that correctly parses CCS generated  
dependency files (perhaps splitting the file task from its dependents  
after the first “.obj:”, perhaps recognizing/depending on the hope  
that/ CCS only places one dependency per line, etc…).

I’m not yet proficient enough in Ruby, and especially regular  
expression matching to just rattle this off (but I know resources are  
online to fill in all the bits I’m missing, or have gotten just plain  
wrong), but you could probably replace the line of code that reads

require ‘rake/loaders/makefile’

with something like (freely inspired by rake/loaders/makefile.rb)

module Rake

# Makefile loader to be used with the import file loader.

class MakefileLoader

```
# Load the makefile dependencies in +fn+.
def load(fn)
  buffer = ''
  open(fn) do |mf|
    mf.each do |line|
      # (I'm certain I've got the regular expression thing wrong 

```

here)  
matches = line.match("(._.obj):\w_(.\*)$")  
file\_task = matches[0]  
dependency = matches[1]  
file file\_task =\> dependents  
end  
end  
end  
process\_line(buffer) if buffer != ‘’  
end

# Install the handler

Rake.application.add\_loader(‘mf’, MakefileLoader.new)  
end

Does that make sense? (Once you figure out the right way to do  
pattern matching in Ruby)

–wpd

---

<div class="post-metadata">

**Author:** ![rake\_newb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/2bfe46/32.png) [@rake\_newb](https://www.ruby-forum.com/u/rake_newb)\
**Post date:** [September 26, 2008, 10:52pm UTC](https://www.ruby-forum.com/t/problem-with-rake-and-dependencies/149588/6 "2008-09-26T22:52:15Z")

</div>

Patrick D. wrote:

> Hi Brock,  
> I think I may have just found the source of your problem:
> 
> If you look at rake/loaders/makefile.rb (which, on my Windoze system  
> is somewhere near  
> ruby/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake/loaders/makefile.rb),  
> you will see something that looks like:
> 
> ```
> # Process one logical line of makefile data.
> def process_line(line)
> file_task, args = line.split(':')
> return if args.nil?
> dependents = args.split
> file file_task => dependents
> end
> 
> ```
> 
> This will not handle C:\blah filenames correctly – it split’s them at  
> the first colon (":").
> 
> You could use that file as a source of inspiration to write your own  
> Rake::MakefileLoader#load method that correctly parses CCS generated  
> dependency files (perhaps splitting the file task from its dependents  
> after the first “.obj:”, perhaps recognizing/depending on the hope  
> that/ CCS only places one dependency per line, etc…).
> 
> I’m not yet proficient enough in Ruby, and especially regular  
> expression matching to just rattle this off (but I know resources are  
> online to fill in all the bits I’m missing, or have gotten just plain  
> wrong), but you could probably replace the line of code that reads
> 
> ----- snip! -------
> 
> Does that make sense? (Once you figure out the right way to do  
> pattern matching in Ruby)
> 
> –wpd

Patrick:

You da man!

You “inspired” me to write my own CCS-generated dependency file parser.  
It was actually quite simple - thanks to your hints above. I am finally  
moving ahead again. In case you, or anyone else, is interested, here is  
what I modified from my original rakefile (added 2 def’s to process the  
dependency files and modified the :build\_depend task to call).

###############################################################################  
desc ‘Build\_depend task that depends on the dependency files’  
task :build\_depend =\> DEPEND\_FILES do  
puts “Importing file dependencies…”  
DEPEND\_FILES.each do |dep\_file|  
process\_dpend\_file(dep\_file)  
end  
end

def process\_dpend\_line(line)  
objfile, prereq = line.split(’: ')  
return if prereq.nil?  
file objfile =\> prereq  
end

def process\_dpend\_file(dfile)  
open(dfile) do |file\_lines|  
file\_lines.each do |line|  
process\_dpend\_line(line.chomp)  
end  
end  
end  
###############################################################################

Thanks again,  
Brock
