From: Joe Van Dyk Date: 2005-07-16T05:22:53+09:00 Subject: Re: rake question On 7/15/05, Olaf Klischat wrote: > 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. Hm. So, are there any work arounds, other than to rebuild the entire thing when a .h file changes? What I'm trying to do is become a better software developer. So, I've got a couple C and C++ books. I want to do the examples in them. So I'll have directories like / /c/ /c/problem_1_1/ /c/problem_1_2/ /c/problem_1_2/main.c /c/problem_1_2/foo.c /c/problem_1_2/foo.h /c/problem_1_2/test_foo.c /c++/ And so on. I want a Rake file that will go into the directory structure, compile all the code, compile all the test code, and run the tests. Then I want it to create syntax-highlighted webpages that shows for each example the code and the output and the tests, and then posts them to a website where I can get comments on them. Perhaps I'll have separate build directories (so I can build and test the code on Windows, Linux, FreeBSD, and OS X).. So, I'm looking for help for that. Thanks! Joe