From: Olaf Klischat Date: 2005-07-15T21:10:53+09:00 Subject: Re: rake question Joe Van Dyk writes: > On 7/14/05, Joe Van Dyk wrote: >> rule '.o' => ['.c'] do |t| >> sh "cc #{t.source} -c -o #{t.name}" >> end >> >> But, when I change the .c source file, it doesn't get compiled again. >> Why is that? >> >> Example: >> >> PowerBook:~/that_stuff/test1 joe$ ls >> Rakefile another_test.h test.cpp >> another_test.cpp main.cpp test.h >> >> PowerBook:~/that_stuff/test1 joe$ cat Rakefile >> require 'rake/clean' >> CLEAN.include '*.o', 'test' >> CPP_SOURCE = FileList['*.cpp'] >> OBJS = CPP_SOURCE.ext 'o' >> >> task :default => :run >> task :run => "test" do >> sh "./test" >> end >> file "test" => OBJS do >> sh "g++ -o test #{OBJS}" >> end >> rule '.o' => '.cpp' do |t| >> sh "g++ -c -o #{t.name} #{t.source}" >> end >> CPP_SOURCE.each do |cpp| >> headers = File.read(cpp).scan(/^#include "(.+)"/) >> task cpp => headers >> end >> >> PowerBook:~/that_stuff/test1 joe$ rake >> (in /Users/joe/that_stuff/test1) >> g++ -c -o another_test.o another_test.cpp >> g++ -c -o main.o main.cpp >> g++ -c -o test.o test.cpp >> g++ -o test another_test.o main.o test.o >> ./test >> Whassup >> what's up! >> >> >> PowerBook:~/that_stuff/test1 joe$ touch main.cpp >> PowerBook:~/that_stuff/test1 joe$ rake >> (in /Users/joe/that_stuff/test1) >> ./test >> Whassup >> what's up! >> >> It should've recompiled main.cpp and relinked everything, right? > > When I comment out >> CPP_SOURCE.each do |cpp| >> headers = File.read(cpp).scan(/^#include "(.+)"/) >> task cpp => headers >> end > > Then it works as expected. So, "task cpp => headers" is the culprit. > But I'm still not sure why it breaks everything else. Well, AFAICS it happens to be the case that, when you have defined an explicit task like foo.cpp, then rules matching the task name won't be considered when computing the dependencies of the task. See Task.[] in rake.rb for details -- given a task name, it just returns the task if it is defined, without considering additional dependencies imposed by rules matching the task's name. This could be considered unfortunate behaviour or a bug :) A related problem I had is that rules can only define a single prerequisite, which seems like a quite arbitrary restriction to me.