Reputation: 5648
So I'm learning ruby
at the moment and discovered rake
. I like to learn new tools by implementing things I already know with them, so I try to convert a Makefile
I have to rake
.
Let's say it looks like this:
main: build/*.o
clang -c $^ -o $@
build/%.o: src/%.c | build
clang -c $< -o $@
build:
mkdir build
What's special about this Makefile is:
%
| build
Is there some way to implement this logic using rake
or do I have to use ruby
itself? E.g.
task :default => "main"
file "main" => "build/%.o" do
sh "clang -o 'main' ??"
end
file 'build/%.o' => "src/%.c" do # order only dependency on `build`
sh "clang -c ?? ??"
end
Upvotes: 4
Views: 1052
Reputation: 16394
This is something that rake is quite good at, and that is tragically underused:
task :default => "main"
# This assumes that your "main" is created by linking
# all *.o files, each of which is the product of compiling a *.c file
# FileList[] creates a list of all *.c source files. The pathmap then
# changes the directory from /src/ to /out/ and the extension to .o
file "main" => FileList["src/**/*.c"].pathmap("%{^src,out}d/%n.o") do |t|
sh "ld #{t.sources.join(" ")} #{t.name}"
end
# This is the rule that says: if you need a
# file out/bla.o, this will create it from /src/bla.c.
rule /out\/.+.o/ => ->(target) { target.pathmap("%{^out,src}d/%n.c") } do |t|
sh "cp #{t.source} #{t.name}"
end
Some notes:
Upvotes: 2