root / trunk / Rakefile

Revision 300, 7.0 kB (checked in by jgarber, 7 months ago)

Wrote a rake task to benchmark compilaton time/memory, test time/memory, and final size.
Switched Ragel code generation style to the best.

Line 
1require 'rake'
2require 'rake/clean'
3require 'rake/gempackagetask'
4require 'rake/rdoctask'
5require 'rake/testtask'
6require 'fileutils'
7include FileUtils
8
9NAME = "redcloth"
10OLD_NAME = "RedCloth"
11SUMMARY = "a fast library for formatting Textile as HTML"
12REV = `svn info`[/Revision: (\d+)/, 1] rescue nil
13VERS = ENV['VERSION'] || "3" + (REV ? ".#{REV}" : "")
14CLEAN.include ['ext/redcloth_scan/*.{bundle,so,obj,pdb,lib,def,exp,c,o,xml}', 'ext/redcloth_scan/Makefile', '**/.*.sw?', '*.gem', '.config']
15CLOBBER.include ['lib/*.{bundle,so,obj,pdb,lib,def,exp}']
16
17desc "Does a full compile, test run"
18task :default => [:compile, :test]
19
20desc "Compiles all extensions"
21task :compile => [:version, :redcloth_scan] do
22  if Dir.glob(File.join("lib","redcloth_scan.*")).length == 0
23    STDERR.puts "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
24    STDERR.puts "Gem actually failed to build.  Your system is"
25    STDERR.puts "NOT configured properly to build redcloth."
26    STDERR.puts "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
27    exit(1)
28  end
29end
30
31desc "Packages up RedCloth."
32task :package => [:clean, :compile]
33
34desc "Releases packages for all RedCloth packages and platforms."
35task :release => [:package, :rubygems_win32]
36
37desc "Run all the tests"
38Rake::TestTask.new do |t|
39    t.libs << "test"
40    t.test_files = FileList['test/test_*.rb']
41    t.verbose = true
42end
43
44# Run specific tests or test files
45#
46# rake test:parser
47# => Runs the full TestParser unit test
48#
49# rake test:parser:textism
50# => Runs the tests matching /textism/ in the TestParser unit test
51rule "" do |t|
52  # test:file:method
53  if /test:(.*)(:([^.]+))?$/.match(t.name)
54    arguments = t.name.split(":")[1..-1]
55    file_name = arguments.first
56    test_name = arguments[1..-1]
57   
58    if File.exist?("test/test_#{file_name}.rb")
59      run_file_name = "test_#{file_name}.rb"
60    end
61   
62    sh "ruby -Ilib:test test/#{run_file_name} -n /#{test_name}/"
63  end
64end
65
66Rake::RDocTask.new do |rdoc|
67    rdoc.rdoc_dir = 'doc/rdoc'
68    # rdoc.options += RDOC_OPTS
69    # rdoc.template = "extras/flipbook_rdoc.rb"
70    rdoc.main = "README"
71    rdoc.title = "RedCloth Documentation"
72    rdoc.rdoc_files.add ['README', 'CHANGELOG', 'COPYING', 'lib/**/*.rb', 'ext/**/*.c']
73end
74
75spec =
76    Gem::Specification.new do |s|
77        s.name = OLD_NAME
78        s.version = VERS
79        s.platform = Gem::Platform::RUBY
80        s.has_rdoc = true
81        s.extra_rdoc_files = ["README", "CHANGELOG", "COPYING"]
82        s.summary = SUMMARY
83        s.description = s.summary
84        s.author = "Jason Garber"
85        s.email = 'redcloth-upwards@rubyforge.org'
86        s.homepage = 'http://code.whytheluckystiff.net/redcloth/'
87
88        s.files = %w(COPYING README Rakefile) +
89          Dir.glob("{bin,doc,test,lib,extras}/**/*") +
90          Dir.glob("ext/**/*.{h,c,rb,rl}") +
91          %w[ext/redcloth_scan/redcloth_scan.c] # needed because it's generated later
92       
93        s.require_path = "lib"
94        #s.autorequire = "redcloth"  # no no no this is tHe 3v1l
95        s.extensions = FileList["ext/**/extconf.rb"].to_a
96        s.executables = ["redcloth"]
97    end
98
99Rake::GemPackageTask.new(spec) do |p|
100    p.need_tar = true
101    p.gem_spec = spec
102end
103
104extension = "redcloth_scan"
105ext = "ext/redcloth_scan"
106ext_so = "#{ext}/#{extension}.#{Config::CONFIG['DLEXT']}"
107ext_files = FileList[
108  "#{ext}/redcloth_scan.c",
109  "#{ext}/redcloth_inline.c",
110  "#{ext}/extconf.rb",
111  "#{ext}/Makefile",
112  "lib"
113]
114
115file ext_so => ext_files do
116  Dir.chdir(ext) do
117    sh(PLATFORM =~ /win32/ ? 'nmake' : 'make')
118  end
119  cp ext_so, "lib"
120end
121
122task "lib" do
123  directory "lib"
124end
125
126["#{ext}/redcloth_scan.c","#{ext}/redcloth_inline.c"].each do |name|
127  @code_style ||= "T0"
128  source = name.sub(/\.c$/, '.rl')
129  file name => [source, "#{ext}/redcloth_common.rl", "#{ext}/redcloth.h"] do
130    @ragel_v ||= `ragel -v`[/(version )(\S*)/,2].split('.').map{|s| s.to_i}
131    if @ragel_v[0] > 6 || (@ragel_v[0] == 6 && @ragel_v[1] >= 1)
132      sh %{ragel #{source} -#{@code_style} -o #{name}}
133    else
134      STDERR.puts "Ragel 6.1 or greater is required to generate #{name}."
135      exit(1)
136    end
137  end
138end
139
140desc "Builds just the #{extension} extension"
141task extension.to_sym => ["#{ext}/Makefile", ext_so ]
142
143file "#{ext}/Makefile" => ["#{ext}/extconf.rb", "#{ext}/redcloth_scan.c","#{ext}/redcloth_inline.c"] do
144  Dir.chdir(ext) do ruby "extconf.rb" end
145end
146
147PKG_FILES = FileList[
148  "test/**/*.{rb,html,xhtml}",
149  "lib/**/*.rb",
150  "ext/**/*.{c,rb,h,rl}",
151  "CHANGELOG", "README", "Rakefile", "COPYING",
152  "extras/**/*", "lib/redcloth_scan.so"]
153
154Win32Spec = Gem::Specification.new do |s|
155  s.name = OLD_NAME
156  s.version = VERS
157  s.platform = 'mswin32'
158  s.has_rdoc = false
159  s.extra_rdoc_files = ["README", "CHANGELOG", "COPYING"]
160  s.summary = SUMMARY
161  s.description = s.summary
162  s.author = "Jason Garber"
163  s.email = 'redcloth-upwards@rubyforge.org'
164  s.homepage = 'http://code.whytheluckystiff.net/redcloth/'
165
166  s.files = PKG_FILES
167
168  s.require_path = "lib"
169  #s.autorequire = "redcloth"  # no no no this is tHe 3v1l
170  s.extensions = []
171  s.bindir = "bin"
172end
173 
174WIN32_PKG_DIR = "#{OLD_NAME}-#{VERS}"
175
176file WIN32_PKG_DIR => [:package] do
177  sh "tar zxf pkg/#{WIN32_PKG_DIR}.tgz"
178end
179
180desc "Cross-compile the redcloth_scan extension for win32"
181file "redcloth_scan_win32" => [WIN32_PKG_DIR] do
182  cp "extras/mingw-rbconfig.rb", "#{WIN32_PKG_DIR}/ext/redcloth_scan/rbconfig.rb"
183  sh "cd #{WIN32_PKG_DIR}/ext/redcloth_scan/ && ruby -I. extconf.rb && make"
184  mv "#{WIN32_PKG_DIR}/ext/redcloth_scan/redcloth_scan.so", "#{WIN32_PKG_DIR}/lib"
185end
186
187desc "Build the binary RubyGems package for win32"
188task :rubygems_win32 => ["redcloth_scan_win32"] do
189  Dir.chdir("#{WIN32_PKG_DIR}") do
190    Gem::Builder.new(Win32Spec).build
191    verbose(true) {
192      mv Dir["*.gem"].first, "../pkg/#{OLD_NAME}-#{VERS}-mswin32.gem"
193    }
194  end
195end
196
197CLEAN.include WIN32_PKG_DIR
198
199task :install => [:package] do
200  sh %{sudo gem install pkg/#{OLD_NAME}-#{VERS}}
201end
202
203task :uninstall => [:clean] do
204  sh %{sudo gem uninstall #{OLD_NAME}}
205end
206
207task :version do
208  File.open("lib/version.rb", "w") do |file|
209    file.puts <<EOD
210module RedClothVersion
211  VERSION = "#{VERS}"
212end
213EOD
214  end
215end
216
217RAGEL_CODE_GENERATION_STYLES = {
218  'T0' => "Table driven FSM (default)",
219  'T1' => "Faster table driven FSM",
220  'F0' => "Flat table driven FSM",
221  'F1' => "Faster flat table-driven FSM",
222  'G0' => "Goto-driven FSM",
223  'G1' => "Faster goto-driven FSM",
224  'G2' => "Really fast goto-driven FSM"
225}
226
227task :optimize do
228  require 'extras/ragel_profiler'
229  results = []
230  RAGEL_CODE_GENERATION_STYLES.each do |style, name|
231    @code_style = style
232    profiler = RagelProfiler.new(style + " " + name)
233   
234    # Hack to get everything to invoke again.  Could use #execute, but then it
235    # doesn't execute prerequisites the second+ time
236    Rake::Task.tasks.each {|t| t.instance_eval "@already_invoked = false" }
237   
238    Rake::Task['clobber'].invoke
239   
240    profiler.measure(:compile) do
241      Rake::Task['compile'].invoke
242    end
243    profiler.measure(:test) do
244      Rake::Task['test'].invoke
245    end
246    profiler.ext_size(ext_so)
247   
248  end
249  puts RagelProfiler.results
250end
Note: See TracBrowser for help on using the browser.