Saturday, June 22, 2013

Rakefiles and Generated Sources

A quick note on something that confused me.  I was working on a Rakefile for a project that has generated sources.  Generated sources aren't that unusual.  For example, people will often write a gemspec file from their Rakefile.

In my case, it started with a generated source file that needed to be added to my gemspec.  I had done the usual "file = Dir["**/*/*.rb"] and assumed that the file would be picked up when the :gem task was run. In other words, when the gem task is finally called it should figure out what should be included.  Yet it didn't do that.  Why?

My code to fill in the gemspec is an anonymous function (aka do-block) that is getting passed into the constructor for the gem task.  That function is being evaluated when the object is being constructed.  As a result, my generated sources didn't exist and thus weren't making it into the gem.

Rakefile Snippets

First, I explicitly constructed the list of generated sources:
GSRC_VERSION = File.join('lib', 'amatchpp', 'version.rb') GSRC_PROTODOC = "protodoc.rb" GSRCS = [GSRC_VERSION, GSRC_PROTODOC]

Then I construct a file-rule to construct a file
file GSRC_VERSION => "Rakefile" do desc m = "Writing version.rb information for #{PKG_VERSION}" puts m File.open(GSRC_VERSION, 'w') do |v| v.puts version_text end end
I add a task which depends on the file.
task :version => GSRC_VERSION

I have a :generated task that depends on all constructed sources.
task :generated => GSRCS

I add the :generated task as a dependency to other tasks as needed. For example, I add it to the :doc task as show below.
############################################################ # Documentation ############################################################ RDoc::Task.new(:doc) do |rd| rd.main = "README" rd.title = "#{PKG_NAME} - Enhanced Approximate Matching" rd.rdoc_files.include( PKG_DOC_FILES) rd.rdoc_dir = "doc" end task :doc => :generated

No comments:

Post a Comment