Le 28/4/2005, "Jim Weirich" <jim@weirichhouse.org> a écrit:
>On Wednesday 27 April 2005 07:38 pm, Mark Probert wrote:
>> Hi ..
>>
>> I am not sure how to create a set of Rake rules to do the following. Can
>> anyone prove assistance?
>
>I think the following Rakefile will do what you want. I added extensive
>comments to the file rather than do commentary in this message. Let me know
>if you have problems.
>
>-- Rakefile ----------------------------------------------------------------
>require 'rake/clean'
>
># Create some constants for later reference.
>
>PROG = "foo"
>LIBNAME = PROG
>LIBFILE = "lib#{LIBNAME}.a"
>
># For SRC, we just find all files in the project ending in '.c'. This
># will work with nested source directories too (like might be found in
># a Java project).
>
>SRC = FileList['**/*.c']
>
># Generate the OBJ list by striping off the directory portion of the
># source file name and flattening the names into a single level obj
># directory. This assumes that all the base file names are unique,
># but that is given by the problem statement. (Note that the +ext+
># function is available in Rake 0.5.3 or later).
>
>OBJDIR = 'obj'
>OBJ = SRC.collect { |fn| File.join(OBJDIR, File.basename(fn).ext('o')) }
>
># Define our clean and clobber targets.
>
>CLEAN.include(OBJ, OBJDIR, LIBFILE)
>CLOBBER.include(PROG)
>
># The default task builds, then runs the program
>
>task :default => [:build, :run]
>
># The build task just depends upon the program being present.
>
>task :build => [PROG]
>
># The run task requires the program to be present, and then runs that
># program.
>
>task :run => [PROG] do
> sh "./#{PROG}"
>end
>
># The program depends only on the library file.
>
>file PROG => [LIBFILE] do
> sh "cc -o #{PROG} -L . -l#{LIBNAME}"
>end
>
># The library file depends only on the list of objects we constructed
># at the top of the file.
>
>file LIBFILE => OBJ do
> sh "ar cr #{LIBFILE} #{OBJ}"
> sh "ranlib #{LIBFILE}"
>end
>
># The directory directive defines the directory OBJDIR as a task that
># can be used in a prerequisites list in a task declaration.
>
>directory OBJDIR
>
># Ok, this is the tricky part. This rule generates .o files from a
># source file described by a lambda function. Finding the source file
># is tricky because the object file does not indicate /which/ source
># directory contains the matching .c file. We punt by writing a
># special function to locate the source. (Originally I did this
># inline in the lambda, but I think it reads better split out into a
># separate functions).
>#
># Note that we invoke the OBJDIR task directly in this rule. Because
># it is a rule, there is no opportunity to list OBJDIR as a
># dependency. By invoking it directly, we will build that directory
># if it is needed (but only if it is needed).
>
>rule '.o' => lambda{ |objfile| find_source(objfile) } do |t|
> Task[OBJDIR].invoke
> sh "cc -c -o #{t.name} #{t.source}"
>end
>
># It turns out that finding the source file is not that difficult. We
># just search the list of source files for a match on the basename of
># the object file. Obviously this might have a performance problem
># with a _large_ list of source files. In that case, I would build a
># hash at the top of the Rakefile and use that hash here when looking
># up the source.
>
>def find_source(objfile)
> base = File.basename(objfile, '.o')
> SRC.find { |s| File.basename(s, '.c') == base }
>end
>-----------------------------------------------------------------
This subfolder-sourcing seems like a common usage pattern,
perhaps worthy of some sort of an abstraction? Is there any
sort of a 'common Rake task idioms' collection anywhere?
>-- Jim Weirich
E
--
template<typename duck>
void quack(duck& d) { d.quack(); }