bleak_house 7.1 → 7.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1 @@
1
+ ����Gg�;��3ip|���7���ƿ��=�4BR[�so����_��k��A��THe5��o�*ٟ�3I�N�K�i�>c��!x@ L�x`1�I%� �s��y��~�����xB�6S��Qt��{2`�I�u�K�� �$,b\�[�*ڸ����wi�o"����C���Ә�t'jK��Tk�C�n��2��Ԅ�#�����/�A�|��E�V����F'��egz��k�<D��YU#��4Y�u},q�ݭW6]Ȥ1�p2
data/CHANGELOG CHANGED
@@ -1,25 +1,65 @@
1
1
 
2
- v7.1. RDoc documentation; use new Echoe setup; fix for namespaced controllers.
2
+ v7.2. Bump version to prevent gemcutter from picking up an ancient mirror.
3
3
 
4
- v7. Detect if core keys are present or not; fixes for analyzing non-Rails apps.
4
+ v4.6.1. Allow snapshotting without running the GC first.
5
5
 
6
- v6. Log heap usage; remove pure-Ruby profiler.
6
+ v4.5. Enable SET_CURRENT_SOURCE() for better reporting (tmm1, joedamato).
7
7
 
8
- v5.3. Subtract Rails core counts from action counts and join paired frames.
8
+ v4.4. Switch to Ruby 1.8.7p174.
9
9
 
10
- v5.2. Change smoothing algorithm to be more intuitive and so mem usage is correct.
10
+ v4.3. Build against OpenSSL 0.9.8j or later (kennethkalmer). Bugfixes (Pete Hodgson, joshuabates).
11
11
 
12
- v5.1. Close file properly.
12
+ v4.2.1. Harden patch/build process. Fix bug.
13
13
 
14
- v5. C instrumentation with YAML output.
14
+ v4.1.1. Update bundled Ruby to patchlevel 230.
15
15
 
16
- v4. Log memory usage on *nix.
16
+ v4.1. Support calculating deltas in analyze utility.
17
17
 
18
- v3.1. Fix nil directory traversal error on Windows.
18
+ v4.0. Track spawn points live instead of sampling.
19
19
 
20
- v3. Gem version
20
+ v3.7.1. Fix some nil issues with corrupted dumps (cody caughlan).
21
21
 
22
- v2. Dumped Rublique; replaced with a lightweight non-delta marshalling version.
22
+ v3.7. Sample object contents. Restore Rails 1.2.x compatibility.
23
23
 
24
- v1. First version
24
+ v3.6. Rails 2.0.2 compatibility.
25
+
26
+ v3.5.1. Update bundled Ruby to patchlevel 110.
27
+
28
+ v3.5. Explain when you need more frames. Use a cross-platform version of 'which'. Slight accuracy improvement.
29
+
30
+ v3.4. Clearer output descriptions; work around a Marshal bug on x64; fix for missing immortal leaks.
31
+
32
+ v3.3. Build Ruby in gem install step; bundle Ruby 1.8.6 source; fixes for truncated final frames.
33
+
34
+ v3.2. Use Ccsv for faster parsing.
35
+
36
+ v3.0.3. Caching; build task; impact factor.
37
+
38
+ v3.0.1. Rewrite. Remove Gruffs and graphs. Become a standard compiled extension. Walk the symbol table. Track object histories. Use custom CSV format instead of YAML.
39
+
40
+ v2.7. Version renumbering; apologies if this messes anyone up.
41
+
42
+ v2.6. RDoc documentation; use new Echoe setup; fix for namespaced controllers.
43
+
44
+ v2.5. Detect if core keys are present or not; fixes for analyzing non-Rails apps.
45
+
46
+ v2.4. Log heap usage; remove pure-Ruby profiler.
47
+
48
+ v2.3. Subtract Rails core counts from action counts and join paired frames.
49
+
50
+ v2.2. Change smoothing algorithm to be more intuitive and so mem usage is correct.
51
+
52
+ v2.1. Close file properly.
53
+
54
+ v2. C instrumentation with YAML output.
55
+
56
+ v1.3. Log memory usage on *nix.
57
+
58
+ v1.2. Fix nil directory traversal error on Windows.
59
+
60
+ v1.1. Gem version
61
+
62
+ v1. Dumped Rublique; replaced with a lightweight non-delta marshalling version.
63
+
64
+ v0. First version
25
65
 
data/Manifest CHANGED
@@ -1,21 +1,21 @@
1
- test/unit/test_bleak_house.rb
2
- test/misc/direct.rb
3
- tasks/bleak_house_tasks.rake
4
- patches/gc.c.patch
5
- lib/bleak_house.rb
6
- lib/bleak_house/support_methods.rb
7
- lib/bleak_house/rake_task_redefine_task.rb
8
- lib/bleak_house/gruff_hacks.rb
9
- lib/bleak_house/dispatcher.rb
10
- lib/bleak_house/c.rb
11
- lib/bleak_house/bleak_house.rb
12
- lib/bleak_house/analyze.rb
13
- lib/bleak_house/action_controller.rb
14
- install.rb
15
- init.rb
16
- Rakefile
17
- README
18
- Manifest
19
- LICENSE_BSD
20
- LICENSE
21
1
  CHANGELOG
2
+ LICENSE
3
+ LICENSE_BSD
4
+ Manifest
5
+ README
6
+ Rakefile
7
+ TODO
8
+ bin/bleak
9
+ ext/build_ruby.rb
10
+ ext/build_snapshot.rb
11
+ ext/extconf.rb
12
+ ext/snapshot.c
13
+ ext/snapshot.h
14
+ lib/bleak_house.rb
15
+ lib/bleak_house/analyzer.rb
16
+ lib/bleak_house/hook.rb
17
+ ruby/ruby-1.8.7-p174.tar.bz2
18
+ ruby/ruby-1.8.7.patch
19
+ test/benchmark/bench.rb
20
+ test/test_helper.rb
21
+ test/unit/test_bleak_house.rb
data/README CHANGED
@@ -1,68 +1,121 @@
1
1
 
2
2
  BleakHouse
3
3
 
4
- A library and Rails plugin for finding memory leaks.
4
+ A library for finding memory leaks.
5
5
 
6
6
  == License
7
7
 
8
- Copyright 2007 Cloudburst, LLC. See the included LICENSE file. Portions copyright 2006 Eric Hodel and used with permission. See included the LICENSE_BSD file.
8
+ Copyright 2007, 2008 Cloudburst, LLC. Licensed under the AFL 3. See the included LICENSE file. Portions copyright 2006 Eric Hodel and used with permission. See the included LICENSE_BSD file.
9
+
10
+ The public certificate for this gem is here[http://rubyforge.org/frs/download.php/25331/evan_weaver-original-public_cert.pem].
11
+
12
+ If you use this software, please {make a donation}[http://blog.evanweaver.com/donate/], or {recommend Evan}[http://www.workingwithrails.com/person/7739-evan-weaver] at Working with Rails.
9
13
 
10
14
  == Features
11
15
 
12
16
  * leak-proof C instrumentation
13
- * logs object counts, real and virtual memory usage, and filled/free heap slots
14
- * easy Rails integration
15
- * automatic generation of nested object charts
17
+ * minimal impact on runtime performance
18
+ * fast analysis step
19
+ * tracks all objects allocated on the heap, including internal types like <tt>T_NODE</tt>
20
+ * easy integration into any program, not just Rails
16
21
 
17
22
  == Requirements
18
23
 
19
- * A unix-like operating system.
20
- * Ruby 1.8.6
24
+ * A unix-like operating system
25
+ * Ruby 1.8.7
21
26
 
22
27
  = Usage
23
28
 
24
29
  == Installation
25
30
 
26
- First, install the plugin in your Rails app:
27
- ./script/plugin install svn://rubyforge.org/var/svn/fauna/bleak_house/trunk
31
+ Install the gem:
32
+ sudo gem install bleak_house
33
+
34
+ The installation takes a long time because it compiles a patched Ruby 1.8.7 binary for you. It is installed as <tt>ruby-bleak-house</tt> alongside your regular <tt>ruby</tt> binary.
35
+
36
+ Please see the forum ( http://rubyforge.org/forum/forum.php?forum_id=13983 ) if you have installation problems.
37
+
38
+ == Usage
28
39
 
29
- You need to compile the BleakHouse patched Ruby build. In the plugin directory, run:
30
- rake ruby:build
31
-
32
- This gives you a Ruby binary named <tt>ruby-bleak-house</tt> alongside your regular binary.
33
-
34
- (BleakHouse is also available as a gem: <tt>sudo gem install bleak_house</tt>. If you use the gem, <tt>require 'bleak_house'</tt> in <tt>config/environment.rb</tt>. You will also have to manually install the <tt>bleak_house:analyze</tt> Rake task.)
40
+ We will profile a Rails app as an example. Note that BleakHouse works equally well in any Ruby program.
35
41
 
36
- == Profiling a Rails app
42
+ First, to setup the app for profiling, add the following at the bottom of <tt>config/environment.rb</tt>:
43
+ require 'bleak_house' if ENV['BLEAK_HOUSE']
37
44
 
38
- To profile your application (ideally, in production mode, on an actual application server):
39
- RAILS_ENV=production BLEAK_HOUSE=true ruby-bleak-house ./script/server
45
+ Then, to engage the logger (possibly in a live deployment situation), start a server instance as so:
46
+ RAILS_ENV=production BLEAK_HOUSE=1 ruby-bleak-house ./script/server
40
47
 
41
- Browse around manually, thrash your entire app with a script, target troublesome controllers/actions, etc.
48
+ Look for the message:
49
+ ** Bleakhouse: installed
42
50
 
43
- Then, to analyze:
44
- RAILS_ENV=production rake bleak_house:analyze
51
+ Exercise your app. After a couple hundred requests, hit CTRL-C. The server will stop and BleakHouse will produce a dumpfile in <tt>/tmp</tt>:
45
52
 
46
- And then look in <tt>log/bleak_house/</tt>.
53
+ ** BleakHouse: working...
54
+ ** BleakHouse: complete
55
+ ** Bleakhouse: run 'bleak /tmp/bleak.5979.000.dump' to analyze.
56
+
57
+ To analyze it, just run the listed command. The top 20 leakiest lines will be listed:
58
+
59
+ 191691 total objects
60
+ Final heap size 191691 filled, 220961 free
61
+ Displaying top 20 most common line/class pairs
62
+ 89513 __null__:__null__:__node__
63
+ 41438 __null__:__null__:String
64
+ 2348 /opt/local//lib/ruby/site_ruby/1.8/rubygems/specification.rb:557:Array
65
+ 1508 /opt/local//lib/ruby/gems/1.8/specifications/gettext-1.90.0.gemspec:14:String
66
+ 1021 /opt/local//lib/ruby/gems/1.8/specifications/heel-0.2.0.gemspec:14:String
67
+ 951 /opt/local//lib/ruby/site_ruby/1.8/rubygems/version.rb:111:String
68
+ 935 /opt/local//lib/ruby/site_ruby/1.8/rubygems/specification.rb:557:String
69
+ 834 /opt/local//lib/ruby/site_ruby/1.8/rubygems/version.rb:146:Array
70
+ ...
71
+
72
+ You can pass an integer as the second parameter to <tt>bleak</tt> if you want to see more lines than the default.
73
+
74
+ The underscored types are special Ruby internal structs, but can be real leaks just as easily as fullblown classes.
47
75
 
48
76
  = Extras
49
77
 
50
- == Options
78
+ == Injecting a signal
79
+
80
+ You can send <tt>SIGUSR2</tt> to a BleakHouse-instrumented program to snag a dump at any time. Once the dump completes, the program will continue to run. Dumps are named based on the host process id, and sequential dumps are numbered in ascending order.
81
+
82
+ == Tips
83
+
84
+ Do not try to detect Rails leaks in <tt>development</tt> mode. Make a separate <tt>benchmark</tt> environment if you need to, and make sure all your production caching is turned on.
85
+
86
+ It is normal to see lots of <tt>null:null</tt> references, especially for nodes. Using <tt>eval()</tt> too much can be a cause of node leaks. You can sometimes track <tt>eval()</tt> by using sourceline macros in your code:
87
+
88
+ eval("CODE", nil, __FILE__, __LINE__)
89
+
90
+ You may get library require errors if you install <tt>ruby-bleak-house</tt> 1.8.7 alongside a different verson of Ruby. You could try to patch your local version of Ruby instead, or you can get <tt>ruby-bleak-house</tt> to lie about its version. Just make sure that the <tt>bleak-house</tt> library is the first thing required (even before Rubygems):
91
+
92
+ ruby-bleak-house -I `ruby -e 'puts \`gem which bleak_house\`.split("\n")[1][0..-16]'` -rbleak_house
93
+
94
+ It is not recommended that you use <tt>ruby-bleak-house</tt> as your production Ruby binary, since it will be slightly slower and use slightly more memory. It is unlikely, however, to affect stability.
95
+
96
+ If BleakHouse doesn't report any heap growth but you still have memory growth, you might have a broken C extension, or have encounted a {real leak in the interpreter}[http://groups.google.com/group/god-rb/browse_thread/thread/01cca2b7c4a581c2]. Try using Valgrind[http://blog.evanweaver.com/articles/2008/02/05/valgrind-and-ruby/] instead.
97
+
98
+ == Methods
99
+
100
+ The easiest way to fix a leak is to make it repeatable.
51
101
 
52
- You also can set the SMOOTHNESS environment variable if you want. The SMOOTHNESS setting just averages frames together. This is not a rolling average: 10 frames become 5 at <tt>SMOOTHNESS=2</tt>.
102
+ First, write a script that exercises your app in a deterministic way. Run it for a small number of loops; then run <tt>bleak</tt>. Then run it for a larger number of loops, and run <tt>bleak</tt> again. The lines that grow significantly between runs are your leaks for that codepath.
53
103
 
54
- == Using BleakHouse outside of Rails
104
+ Now, look at those lines in the source and try to figure out what references them. Where do the return values go? Add some breakpoints or output backtraces to <tt>STDERR</tt> as you go. Eventually you should find a point where it is relatively clear that a reference is getting maintained.
55
105
 
56
- If you want finer snapshots than every action, or want to use the plugin outside of Rails, see the BleakHouse::CLogger class.
106
+ Try to remove that reference, run your script again, and see if the object counts have dropped.
57
107
 
58
- == Troubleshooting
108
+ == Reporting problems
59
109
 
60
- If you see the error <tt>Symbol not found: _rb_gc_heaps_used</tt>, it means you installed the patched binary, but tried to profile the server with the regular binary.
110
+ The support forum is here[http://rubyforge.org/forum/forum.php?forum_id=13983].
61
111
 
62
- You may get library require errors if you install <tt>ruby-bleak-house</tt> 1.8.6 alongside a different verson of Ruby. You could try to patch your local version of Ruby instead, or you could just upgrade to 1.8.6, which has a good trackrecord of stability.
112
+ Patches and contributions are very welcome. Please note that contributors are required to assign copyright for their additions to Cloudburst, LLC.
63
113
 
64
114
  == Further resources
65
115
 
66
- * http://blog.evanweaver.com/pages/code#bleak_house
67
- * http://rubyforge.org/forum/forum.php?forum_id=13983
116
+ * http://blog.evanweaver.com/articles/2008/04/06/bleakhouse-4/
117
+ * http://blog.evanweaver.com/articles/2008/02/05/valgrind-and-ruby/
118
+ * http://blog.evanweaver.com/articles/2007/05/12/let-me-hit-you-with-some-knowledge
119
+ * http://blog.evanweaver.com/articles/2007/05/06/leak-proof-direct-heap-instrumentation-for-bleak_house
120
+ * http://blog.evanweaver.com/articles/2007/04/28/bleak_house
68
121
 
data/Rakefile CHANGED
@@ -1,85 +1,12 @@
1
1
 
2
- require 'rubygems'
3
- require 'rake'
4
- require 'lib/bleak_house/rake_task_redefine_task'
5
-
6
- DIR = File.dirname(__FILE__)
7
-
8
- begin
9
- require 'echoe'
10
-
11
- taskmsg = File.open(DIR + "/tasks/bleak_house_tasks.rake").readlines
12
- taskmsg = taskmsg[0..3] + [taskmsg[9][2..-1]] + taskmsg[12..-1] # XXX weak
13
-
14
- echoe = Echoe.new("bleak_house") do |p|
15
- p.author = "Evan Weaver"
16
- p.project = "fauna"
17
- p.summary = "A Rails plugin for finding memory leaks."
18
- p.url = "http://blog.evanweaver.com/pages/code#bleak_house"
19
- p.docs_host = 'blog.evanweaver.com:~/www/snax/public/files/doc/'
20
- p.rdoc_pattern = /^(bin|tasks)|analyze|bleak_house\/bleak_house\.rb|c\.rb|^README|^CHANGELOG|^TODO|^LICENSE$/
21
- p.dependencies = ['gruff =0.2.8', 'rmagick', 'activesupport', 'RubyInline']
22
- p.install_message = "
23
- Thanks for installing BleakHouse.
24
-
25
- For each Rails app you want to profile, you will need to add the
26
- following rake task in RAILS_ROOT/lib/tasks/bleak_house_tasks.rake:
27
- " + taskmsg.join(" ") + "\n"
28
- end
29
-
30
- rescue LoadError
31
- end
32
-
33
- desc 'Run tests.'
34
- Rake::Task.redefine_task("test") do
35
- system "ruby-bleak-house -Ibin:lib:test test/unit/test_bleak_house.rb #{ENV['METHOD'] ? "--name=#{ENV['METHOD']}" : ""}"
2
+ require 'echoe'
3
+
4
+ Echoe.new("bleak_house") do |p|
5
+ p.author = "Evan Weaver"
6
+ p.project = "fauna"
7
+ p.summary = "A library for finding memory leaks."
8
+ p.url = "http://blog.evanweaver.com/files/doc/fauna/bleak_house/"
9
+ p.docs_host = 'blog.evanweaver.com:~/www/bax/public/files/doc/'
10
+ p.require_signed = true
11
+ p.rdoc_pattern = /^ext.*\.c|lib.*|^README|^CHANGELOG|^TODO|^LICENSE|^COPYING$/
36
12
  end
37
-
38
- desc 'Build a patched binary.'
39
- namespace :ruby do
40
- task :build do
41
- if RUBY_PLATFORM =~ /win32|windows/
42
- puts "ERROR: windows not supported."
43
- exit
44
- end
45
- require 'fileutils'
46
- puts "building patched Ruby binary"
47
- tmp = "/tmp/"
48
- Dir.chdir(tmp) do
49
- build_dir = "bleak_house"
50
- binary_dir = File.dirname(`which ruby`)
51
- FileUtils.rm_rf(build_dir) rescue nil
52
- Dir.mkdir(build_dir)
53
- begin
54
- Dir.chdir(build_dir) do
55
- puts " downloading Ruby source"
56
- bz2 = "ruby-1.8.6.tar.bz2"
57
- system("wget 'http://rubyforge.org/frs/download.php/20425/ruby-1.8.6.tar.bz2' &> wget.log")
58
- puts " extracting"
59
- system("tar xjf #{bz2} &> tar.log")
60
- File.delete bz2
61
- Dir.chdir("ruby-1.8.6") do
62
- puts " patching" or system("patch -p0 < \'#{DIR}/patches/gc.c.patch\' &> ../patch.log")
63
- puts " configuring" or system("./configure --prefix=#{binary_dir[0..-5]} &> ../configure.log") # --with-static-linked-ext
64
- puts " making" or system("make &> ../make.log")
65
-
66
- binary = "#{binary_dir}/ruby-bleak-house"
67
- puts " installing as #{binary}"
68
- FileUtils.cp("./ruby", binary)
69
- FileUtils.chmod(0755, binary)
70
- puts " done"
71
- end
72
- end
73
- rescue Object => e
74
- puts "ERROR: please see the last modified log file in #{tmp}#{build_dir}, perhaps\nit will contain a clue."
75
- end
76
- end
77
- end
78
- end
79
-
80
- #def check_configure_size
81
- # if (size = File.size("configure")) != 476155
82
- # raise "Configure size is wrong (got #{size})"
83
- # end
84
- #end
85
-
data/TODO ADDED
@@ -0,0 +1,10 @@
1
+
2
+ * Figure out why Rubygems 1.2.0 is a hard requirement
3
+
4
+ * Override Kernel#eval to always include sourceline macros.
5
+ * Mimic Valgrind's output format as much as possible
6
+ * Log remaining heap reference traces
7
+ * Add some kind of start/end delta support
8
+ * Log entire backtrace by allocating pointer arrays on the heap
9
+ - Add some kind of hashing procedure to avoid duplicating identical backtrace pointer arrays
10
+ * Report individual types of nodes
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+
5
+ if !ARGV[0]
6
+ puts "Please specify up to two BleakHouse logfiles"
7
+ exit
8
+ else
9
+ $LOAD_PATH << "#{File.dirname(__FILE__)}/../lib/"
10
+ require 'bleak_house/analyzer'
11
+ require 'ruby-debug' if ENV['DEBUG']
12
+ BleakHouse::Analyzer.run(*ARGV)
13
+ end
@@ -0,0 +1,36 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{bleak_house}
5
+ s.version = "7.2"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Evan Weaver"]
9
+ s.cert_chain = ["/Users/eweaver/p/configuration/gem_certificates/evan_weaver-original-public_cert.pem"]
10
+ s.date = %q{2009-11-18}
11
+ s.default_executable = %q{bleak}
12
+ s.description = %q{A library for finding memory leaks.}
13
+ s.email = %q{}
14
+ s.executables = ["bleak"]
15
+ s.extensions = ["ext/extconf.rb"]
16
+ s.extra_rdoc_files = ["CHANGELOG", "LICENSE", "LICENSE_BSD", "README", "TODO", "ext/snapshot.c", "lib/bleak_house.rb", "lib/bleak_house/analyzer.rb", "lib/bleak_house/hook.rb"]
17
+ s.files = ["CHANGELOG", "LICENSE", "LICENSE_BSD", "Manifest", "README", "Rakefile", "TODO", "bin/bleak", "ext/build_ruby.rb", "ext/build_snapshot.rb", "ext/extconf.rb", "ext/snapshot.c", "ext/snapshot.h", "lib/bleak_house.rb", "lib/bleak_house/analyzer.rb", "lib/bleak_house/hook.rb", "ruby/ruby-1.8.7-p174.tar.bz2", "ruby/ruby-1.8.7.patch", "test/benchmark/bench.rb", "test/test_helper.rb", "test/unit/test_bleak_house.rb", "bleak_house.gemspec"]
18
+ s.homepage = %q{http://blog.evanweaver.com/files/doc/fauna/bleak_house/}
19
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Bleak_house", "--main", "README"]
20
+ s.require_paths = ["lib", "ext"]
21
+ s.rubyforge_project = %q{fauna}
22
+ s.rubygems_version = %q{1.3.5}
23
+ s.signing_key = %q{/Users/eweaver/p/configuration/gem_certificates/evan_weaver-original-private_key.pem}
24
+ s.summary = %q{A library for finding memory leaks.}
25
+ s.test_files = ["test/test_helper.rb", "test/unit/test_bleak_house.rb"]
26
+
27
+ if s.respond_to? :specification_version then
28
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
29
+ s.specification_version = 3
30
+
31
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
32
+ else
33
+ end
34
+ else
35
+ end
36
+ end
@@ -0,0 +1,114 @@
1
+
2
+ # Extension abuse in order to build our patched binary as part of the gem install process.
3
+
4
+ raise "Windows is not supported." if RUBY_PLATFORM =~ /win32|windows/
5
+
6
+ source_dir = File.expand_path(File.dirname(__FILE__)) + "/../ruby"
7
+ tmp = "/tmp/"
8
+
9
+ require 'fileutils'
10
+ require 'rbconfig'
11
+
12
+ def execute(command)
13
+ puts command
14
+ unless system(command)
15
+ puts "Failed: #{command.inspect}"
16
+ exit -1
17
+ end
18
+ end
19
+
20
+ def which(basename)
21
+ # execute('which') is not compatible across Linux and BSD
22
+ ENV['PATH'].split(File::PATH_SEPARATOR).detect do |directory|
23
+ path = File.join(directory, basename.to_s)
24
+ path if File.exist? path
25
+ end
26
+ end
27
+
28
+ if which('ruby-bleak-house') and
29
+ (patchlevel = `ruby-bleak-house -e "puts RUBY_PATCHLEVEL"`.to_i) >= 905
30
+ puts "** Binary `ruby-bleak-house` is already available (patchlevel #{patchlevel})"
31
+ else
32
+ # Build
33
+ Dir.chdir(tmp) do
34
+ build_dir = "bleak_house"
35
+
36
+ FileUtils.rm_rf(build_dir) rescue nil
37
+ if File.exist? build_dir
38
+ raise "Could not delete previous build dir #{Dir.pwd}/#{build_dir}"
39
+ end
40
+
41
+ Dir.mkdir(build_dir)
42
+
43
+ begin
44
+ Dir.chdir(build_dir) do
45
+
46
+ puts "** Copy Ruby source"
47
+ bz2 = "ruby-1.8.7-p174.tar.bz2"
48
+ FileUtils.copy "#{source_dir}/#{bz2}", bz2
49
+
50
+ puts "** Extract"
51
+ execute("tar xjf #{bz2}")
52
+ File.delete bz2
53
+
54
+ Dir.chdir("ruby-1.8.7-p174") do
55
+
56
+ puts "** Patch Ruby"
57
+ execute("patch -p1 < '#{source_dir}/ruby-1.8.7.patch'")
58
+
59
+ env = Config::CONFIG.map do |key, value|
60
+ "#{key}=#{value.inspect}" if key.upcase == key and value
61
+ end.compact.join(" ")
62
+
63
+ puts "** Configure"
64
+
65
+ args = Config::CONFIG['configure_args']
66
+ args.sub("'--enable-shared'", "")
67
+ args << " --disable-shared"
68
+ args << " --enable-valgrind" if which("valgrind")
69
+ execute("env #{env} ./configure #{args}")
70
+
71
+ puts "Patch Makefile"
72
+ # FIXME Why is this necessary?
73
+ makefile = File.read('Makefile')
74
+ %w{arch sitearch sitedir}.each do | key |
75
+ makefile.gsub!(/#{key} = .*/, "#{key} = #{Config::CONFIG[key]}")
76
+ end
77
+ File.open('Makefile', 'w'){|f| f.puts(makefile)}
78
+
79
+ puts "Patch config.h"
80
+ constants = {
81
+ 'RUBY_LIB' => 'rubylibdir',
82
+ 'RUBY_SITE_LIB' => 'sitedir',
83
+ 'RUBY_SITE_LIB2' => 'sitelibdir',
84
+ 'RUBY_PLATFORM' => 'arch',
85
+ 'RUBY_ARCHLIB' => 'topdir',
86
+ 'RUBY_SITE_ARCHLIB' => 'sitearchdir'
87
+ }
88
+ config_h = File.read('config.h')
89
+ constants.each do | const, key |
90
+ config_h.gsub!(/#define #{const} .*/, "#define #{const} \"#{Config::CONFIG[key]}\"")
91
+ end
92
+ File.open('config.h', 'w') do |f|
93
+ f.puts(config_h)
94
+ end
95
+
96
+ puts "** Make"
97
+ execute("env #{env} make")
98
+
99
+ bleak_binary = "#{Config::CONFIG['bindir']}/ruby-bleak-house"
100
+ ruby_binary = Config::CONFIG["RUBY_INSTALL_NAME"] || "ruby"
101
+
102
+ puts "** Install binary"
103
+ raise unless File.exist? ruby_binary
104
+ File.delete bleak_binary if File.exist? bleak_binary # Avoid "Text file busy" error
105
+ exec("cp ./#{ruby_binary} #{bleak_binary}; chmod 755 #{bleak_binary}")
106
+ end
107
+
108
+ end
109
+ end
110
+
111
+ puts "Success"
112
+ end
113
+
114
+ end