mkrf 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. data/CHANGELOG +14 -1
  2. data/README +50 -22
  3. data/Rakefile +2 -1
  4. data/lib/mkrf.rb +1 -1
  5. data/lib/mkrf/availability.rb +60 -9
  6. data/lib/mkrf/generator.rb +32 -12
  7. data/lib/mkrf/rakehelper.rb +123 -0
  8. data/test/{sample_files/libtrivial/libtrivial.bundle → fixtures/some_binary} +0 -0
  9. data/test/integration/test_sample_projects.rb +1 -1
  10. data/test/sample_files/libtrivial/ext/extconf.rb +3 -0
  11. data/test/sample_files/libtrivial/{lib → ext}/libtrivial.c +0 -0
  12. data/test/unit/test_availability.rb +27 -2
  13. data/test/unit/test_generator.rb +55 -0
  14. metadata +144 -180
  15. data/test/mkrf.log +0 -1
  16. data/test/sample_files/libtrivial/Rakefile +0 -33
  17. data/test/sample_files/libtrivial/extconf.rb +0 -3
  18. data/test/sample_files/libtrivial/lib/libtrivial.o +0 -0
  19. data/test/sample_files/libtrivial/mkrf.log +0 -2
  20. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/Rakefile +0 -33
  21. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/cbg.o +0 -0
  22. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/libxml.o +0 -0
  23. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/libxml_so.bundle +0 -0
  24. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/mkrf.log +0 -21
  25. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_attr.o +0 -0
  26. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_attribute.o +0 -0
  27. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_document.o +0 -0
  28. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_dtd.o +0 -0
  29. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_input_cbg.o +0 -0
  30. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_node.o +0 -0
  31. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_node_set.o +0 -0
  32. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_ns.o +0 -0
  33. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_parser.o +0 -0
  34. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_parser_context.o +0 -0
  35. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_sax_parser.o +0 -0
  36. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_schema.o +0 -0
  37. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_tree.o +0 -0
  38. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_xinclude.o +0 -0
  39. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_xpath.o +0 -0
  40. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_xpath_context.o +0 -0
  41. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_xpointer.o +0 -0
  42. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_xpointer_context.o +0 -0
  43. data/test/sample_files/syck-0.55/ext/ruby/ext/syck/Rakefile +0 -33
  44. data/test/sample_files/syck-0.55/ext/ruby/ext/syck/bytecode.o +0 -0
  45. data/test/sample_files/syck-0.55/ext/ruby/ext/syck/emitter.o +0 -0
  46. data/test/sample_files/syck-0.55/ext/ruby/ext/syck/gram.o +0 -0
  47. data/test/sample_files/syck-0.55/ext/ruby/ext/syck/handler.o +0 -0
  48. data/test/sample_files/syck-0.55/ext/ruby/ext/syck/implicit.o +0 -0
  49. data/test/sample_files/syck-0.55/ext/ruby/ext/syck/mkrf.log +0 -3
  50. data/test/sample_files/syck-0.55/ext/ruby/ext/syck/node.o +0 -0
  51. data/test/sample_files/syck-0.55/ext/ruby/ext/syck/rubyext.o +0 -0
  52. data/test/sample_files/syck-0.55/ext/ruby/ext/syck/syck.bundle +0 -0
  53. data/test/sample_files/syck-0.55/ext/ruby/ext/syck/syck.o +0 -0
  54. data/test/sample_files/syck-0.55/ext/ruby/ext/syck/token.o +0 -0
  55. data/test/sample_files/syck-0.55/ext/ruby/ext/syck/yaml2byte.o +0 -0
data/CHANGELOG CHANGED
@@ -1,3 +1,16 @@
1
+ = 0.2.0 2/3/07
2
+ * [NEW] Added paths option to has_library?
3
+ * [NEW] Added Generator#abort! for when that critical library just isn't there.
4
+ * [NEW] Added Zed Shaw's rakehelper lib (from rfuzz, with permission).
5
+ * [NEW] Extensions using mkrf can now build properly in RubyGems!
6
+ * [NEW] Extension configurations should now be named mkrf_conf.rb to not conflict with the mkmf settings in RubyGems.
7
+ * [NEW] Added example extensions.
8
+ * [NEW] Add install task to generated Rakefile.
9
+ * [CLEAN-UP] Preprocessor define handling moved to Availability from Generator.
10
+ * [NEW] find_executable method added to Availability.
11
+ * [FIXED] include_header and has_header? now properly set preprocessor defines.
12
+ * [FIXED] Defaults on Generator work again. [44]
13
+
1
14
  = 0.1.2 10/4/06
2
15
  * [CLEAN-UP] Removed useless add_source from Generator. We've got a constructor for that. [35]
3
16
  * [FIXED] Generator.new defaults to sources in the local directory, so extconfs can (and should) be kept in the same directory as the extension files (PROJ_ROOT/ext) and won't clobber pre-existing Rakefiles. [35]
@@ -19,4 +32,4 @@
19
32
  * [FIXED] default source pattern for Generator [17]
20
33
 
21
34
  = 0.1.0 6/28/06
22
- * First release.
35
+ * First release.
data/README CHANGED
@@ -1,30 +1,35 @@
1
1
  = mkrf -- making C extensions for Ruby a bit easier
2
2
 
3
- <tt>mkrf</tt> is intended to replace <tt>mkmf</tt> which is a library for building
4
- Makefiles to build C extensions to Ruby. The major differences between the two is
5
- that +mkrf+ builds you a Rakefile instead of a Makefile, and also that +mkrf+
6
- provides an object-oriented interface.
3
+ <tt>mkrf</tt> is a library for generating Rakefiles to build Ruby
4
+ extension modules written in C. It is intended as a replacement for
5
+ <tt>mkrf</tt>. The major difference between the two is that +mkrf+
6
+ builds you a Rakefile instead of a Makefile.
7
7
 
8
- Major goals of mkrf are
8
+ Major goals of mkrf include
9
9
  * easy code reuse of its <tt>Availability</tt> class and
10
10
  * simple, well documented, use of the <tt>Generator</tt> class.
11
11
 
12
12
  == Basic Usage
13
13
 
14
- <tt>mkrf</tt> works similarly to <tt>mkmf</tt> in that a user writes an
15
- extension configuration file (usually named <tt>extconf.rb</tt>) and then runs
16
- it (<tt>ruby ./extconf.rb</tt>), which generates a <tt>Rakefile</tt> in the
17
- current directory.
14
+ <tt>mkrf</tt> works similarly to <tt>mkmf</tt> in that a user writes
15
+ an extension configuration file and then runs it, generating a
16
+ <tt>Rakefile</tt> in the current directory.
18
17
 
19
- In general, <tt>extconf.rb</tt> should be placed in the root directory of the
20
- extension (ex. <tt>PROJECT_ROOT/ext/<i>name_of_module</i></tt>) and it expects,
21
- by default, that files to be compiled have a <tt>.c</tt> extension and reside in
22
- that same directory. If your project contains multiple extension modules, then
23
- each one would get its own subdirectory under <tt>PROJECT_ROOT/ext/</tt> and
24
- have its own <tt>extconf.rb</tt> file.
18
+ With mkmf it was customary to name the extension configuration file
19
+ "<tt>extconf.rb</tt>". With mkrf, you should name this file
20
+ "<tt>mkrf_conf.rb</tt>".
25
21
 
26
- The most basic usage looks like the following, where the name of the extension
27
- module being built is "libtrivial":
22
+ In general, <tt>mkrf_conf.rb</tt> should be placed in the root
23
+ directory of the extension
24
+ (ex. <tt>PROJECT_ROOT/ext/<i>name_of_module</i></tt>) and it expects,
25
+ by default, that files to be compiled have a <tt>.c</tt> extension and
26
+ reside in that same directory. If your project contains multiple
27
+ extension modules, then each one would get its own subdirectory under
28
+ <tt>PROJECT_ROOT/ext/</tt> and each would have its own
29
+ <tt>mkrf_conf.rb</tt> file.
30
+
31
+ The most basic usage looks like the following, where the name of the
32
+ extension module being built is "libtrivial":
28
33
 
29
34
  require 'mkrf'
30
35
  Mkrf::Generator.new('libtrivial')
@@ -47,16 +52,39 @@ Another example:
47
52
  end
48
53
 
49
54
 
55
+ == Helpers
56
+
57
+ mkrf also comes with <tt>rakehelper.rb</tt> -- a module which contains
58
+ methods you may want to use in your project's top-level Rakefile. The
59
+ docs on using rakehelper do not exist at the moment, but for the time
60
+ being, have a look at <tt>examples/trivial/Rakefile</tt> to get an
61
+ idea of how they're used.
62
+
63
+
50
64
  == Credits
51
65
  * Jim Weirich for writing Rake
52
66
 
67
+
53
68
  == Licence
54
69
  mkrf is available under an MIT-style license.
55
70
 
56
71
  Copyright (c) 2006 Kevin Clark
57
72
 
58
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
59
-
60
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
61
-
62
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
73
+ Permission is hereby granted, free of charge, to any person obtaining
74
+ a copy of this software and associated documentation files (the
75
+ "Software"), to deal in the Software without restriction, including
76
+ without limitation the rights to use, copy, modify, merge, publish,
77
+ distribute, sublicense, and/or sell copies of the Software, and to
78
+ permit persons to whom the Software is furnished to do so, subject to
79
+ the following conditions:
80
+
81
+ The above copyright notice and this permission notice shall be
82
+ included in all copies or substantial portions of the Software.
83
+
84
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
85
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
86
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
87
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
88
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
89
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
90
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile CHANGED
@@ -41,7 +41,7 @@ namespace :test do
41
41
  BASE_DIR = File.dirname(__FILE__) + '/test/sample_files'
42
42
 
43
43
  SAMPLE_DIRS = {
44
- :trivial => BASE_DIR + '/libtrivial/',
44
+ :trivial => BASE_DIR + '/libtrivial/ext/',
45
45
  :syck => BASE_DIR + '/syck-0.55/ext/ruby/ext/syck/',
46
46
  :libxml => BASE_DIR + '/libxml-ruby-0.3.8/ext/xml/'
47
47
  }
@@ -103,6 +103,7 @@ spec = Gem::Specification.new do |s|
103
103
  s.homepage = "http://glu.ttono.us"
104
104
 
105
105
  s.has_rdoc = true
106
+ s.rdoc_options << '--main' << 'README' << '--title' << 'mkrf'
106
107
  s.requirements << 'rake'
107
108
  s.require_path = 'lib'
108
109
  s.autorequire = 'mkrf'
data/lib/mkrf.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  require File.dirname(__FILE__) + '/mkrf/availability'
2
2
  require File.dirname(__FILE__) + '/mkrf/generator'
3
3
 
4
- Mkrf::VERSION = "0.1.2"
4
+ Mkrf::VERSION = "0.2.0"
@@ -16,23 +16,26 @@ module Mkrf
16
16
  TEMP_SOURCE_FILE = "temp_source.c"
17
17
  TEMP_EXECUTABLE = "temp_executable"
18
18
 
19
- attr_reader :headers, :loaded_libs, :includes, :logger
19
+ attr_reader :headers, :loaded_libs, :includes, :logger, :defines
20
20
 
21
21
  # Create a new Availability instance.
22
22
  #
23
23
  # Valid keys for the options hash include:
24
24
  # * <tt>:loaded_libs</tt> -- libraries to load by default
25
+ # * <tt>:library_paths</tt> -- libraries paths to include by default
25
26
  # * <tt>:headers</tt> -- headers to load by default
26
27
  # * <tt>:compiler</tt> -- which compiler to use when determining availability
27
28
  # * <tt>:includes</tt> -- directories that should be searched for include files
28
29
  def initialize(options = {})
29
30
 
30
31
  @loaded_libs = (options[:loaded_libs] || Config::CONFIG["LIBS"].gsub('-l', '').split).to_a
32
+ @library_paths = (options[:library_paths] || "").to_a
31
33
  # Not sure what COMMON_HEADERS looks like when populated
32
34
  @headers = options[:headers] || [] # Config::CONFIG["COMMON_HEADERS"]
33
35
  @compiler = options[:compiler] || Config::CONFIG["CC"]
34
36
  @includes = (options[:includes] || DEFAULT_INCLUDES).to_a
35
37
  @logger = Logger.new('mkrf.log')
38
+ @defines = []
36
39
  end
37
40
 
38
41
  # Include a library in the list of available libs. Returns +false+ if the
@@ -41,12 +44,18 @@ module Mkrf
41
44
  # Params:
42
45
  # * <tt>library</tt> -- the library to be included as a string.
43
46
  # * <tt>function</tt> -- a method to base the inclusion of the library on. +main+ by default.
44
- def include_library(library, function = "main")
47
+ # * <tt>paths</tt> -- an optional list of search paths if the library is not found in the default paths.
48
+ def include_library(library, function = "main", *paths)
49
+ paths.each do |library_dir|
50
+ @library_paths << library_dir
51
+ end
45
52
  @loaded_libs << library if has_library?(library, function)
46
53
  end
47
54
 
48
55
  # Include a header in the list of availiable headers. Returns +false+ if the
49
- # header is not available. Returns non-false otherwise.
56
+ # header is not available. Returns non-false otherwise. If the header is
57
+ # found, the preprocessor constant HAVE_BLAH is defined where BLAH is the name
58
+ # of the header in uppercase without the file extension.
50
59
  #
51
60
  # Params:
52
61
  # * <tt>header</tt> -- the name of the header to be included as a string.
@@ -61,21 +70,30 @@ module Mkrf
61
70
  # Params:
62
71
  # * <tt>library</tt> -- the library to be included as a string
63
72
  # * <tt>function</tt> -- a method to base the inclusion of the library on. +main+ by default.
64
- def has_library?(library, function = "main")
73
+ # * <tt>paths</tt> -- an optional list of search paths if the library is not found in the default paths
74
+ def has_library?(library, function = "main", *paths)
65
75
  logger.info "Checking for library: #{library}"
66
76
  return true if library_already_loaded?(library)
77
+ # Should this be only found_library? or a specialized version with
78
+ # path searching?
67
79
  found_library?(library, function)
68
80
  end
69
81
 
70
82
  # Returns +true+ if the header is found in the default search path or in
71
- # optional paths passed as an argument, +false+ otherwise.
83
+ # optional paths passed as an argument, +false+ otherwise. If the header is
84
+ # found, the preprocessor constant HAVE_BLAH is defined where BLAH is the name
85
+ # of the header in uppercase without the file extension.
72
86
  #
73
87
  # Params:
74
88
  # * <tt>header</tt> -- the header to be searched for
75
89
  # * <tt>paths</tt> -- an optional list of search paths if the header is not found in the default paths
76
90
  def has_header?(header, *paths)
77
- return true if header_already_loaded?(header) || header_can_link?(header) ||
91
+ if header_already_loaded?(header) || header_can_link?(header) ||
78
92
  header_found_in_paths?(header, paths)
93
+ defines << format("HAVE_%s", header.tr("a-z./\055", "A-Z___"))
94
+ return true
95
+ end
96
+
79
97
  logger.warn "Header not found: #{header}"
80
98
  return false
81
99
  end
@@ -124,11 +142,28 @@ module Mkrf
124
142
  @loaded_libs.collect {|l| "-l#{l}"}.join(' ')
125
143
  end
126
144
 
145
+ # Returns a string of libraries directories formatted for compilation
146
+ def library_paths_compile_string
147
+ @library_paths.collect {|l| "-L#{l}"}.join(' ')
148
+ end
149
+
127
150
  # Returns a string of include directories formatted for compilation
128
151
  def includes_compile_string
129
152
  @includes.collect {|i| "-I#{i}"}.join(' ')
130
153
  end
131
154
 
155
+ # Takes the name of an executable and an optional set of paths to search.
156
+ # If no paths are given, the environmental path is used by default.
157
+ # Returns the absolute path to an executable, or nil if not found.
158
+ def find_executable(bin, *paths)
159
+ paths = ENV['PATH'].split(File::PATH_SEPARATOR) if paths.empty?
160
+ paths.each do |path|
161
+ file = File.join(path, bin)
162
+ return file if File.executable?(file)
163
+ end
164
+ return nil
165
+ end
166
+
132
167
  private
133
168
 
134
169
  def found_library?(library, function)
@@ -171,6 +206,19 @@ module Mkrf
171
206
  return false
172
207
  end
173
208
 
209
+ # def library_found_in_paths?(library, paths)
210
+ # paths.each do |include_path|
211
+ #
212
+ # if with_libs(include_path) { library_can_link?(header) }
213
+ # @libspath << include_path
214
+ # return true
215
+ # end
216
+ # end
217
+ #
218
+ # return false
219
+ #
220
+ # end
221
+
174
222
  def header_found_in_paths?(header, paths)
175
223
  paths.each do |include_path|
176
224
  if with_includes(include_path) { header_can_link?(header) }
@@ -197,8 +245,11 @@ module Mkrf
197
245
  end
198
246
 
199
247
  def link_command
200
- "#{@compiler} -o #{TEMP_EXECUTABLE} #{library_compile_string} " +
201
- "#{includes_compile_string} #{TEMP_SOURCE_FILE}"
248
+ # This current implementation just splats the library_paths in
249
+ # unconditionally. Is this problematic?
250
+ "#{@compiler} -o #{TEMP_EXECUTABLE} #{library_paths_compile_string}" +
251
+ " #{library_compile_string} #{includes_compile_string}" +
252
+ " #{TEMP_SOURCE_FILE}"
202
253
  end
203
254
 
204
255
  # Creates a temporary source file with the string passed
@@ -263,4 +314,4 @@ module Mkrf
263
314
  end
264
315
 
265
316
  end
266
- end
317
+ end
@@ -32,6 +32,12 @@ module Mkrf
32
32
  # '/usr/include/libxml2')
33
33
  # end
34
34
  #
35
+ # It is also possible to specify the library paths in
36
+ # include_library
37
+ # Mkrf::Generator.new('libxml') do |g|
38
+ # g.include_library('socket','socket', '/usr/local/lib/libxml')
39
+ # end
40
+ #
35
41
  class Generator
36
42
  include Rake
37
43
 
@@ -63,15 +69,17 @@ module Mkrf
63
69
  # Params:
64
70
  # * +extension_name+ -- the name of the extension
65
71
  # * +source_patterns+ -- an array of patterns describing source files to be compiled. ["*.c"] is the default.
72
+
66
73
  def initialize(extension_name, source_patterns = ["*.c"], availability_options = {})
67
74
  @sources = source_patterns
68
75
  @extension_name = extension_name + ".#{CONFIG['DLEXT']}"
69
76
  @available = Mkrf::Availability.new(availability_options)
70
77
  @defines = []
78
+ @cc = CONFIG['CC']
71
79
 
72
- objects = ''
73
- ldshared = CONFIG['LDSHARED']
74
- cflags = "#{CONFIG['CCDLFLAGS']} #{CONFIG['CFLAGS']} #{CONFIG['ARCH_FLAG']}"
80
+ @objects = ''
81
+ @ldshared = ''
82
+ @cflags = "#{CONFIG['CCDLFLAGS']} #{CONFIG['CFLAGS']} #{CONFIG['ARCH_FLAG']}"
75
83
 
76
84
  yield self if block_given?
77
85
  write_rakefile
@@ -85,13 +93,13 @@ module Mkrf
85
93
  # Add a define to the compile string. Example:
86
94
  #
87
95
  # Mkrf::Generator.new('my_library') do |g|
88
- # g.add_define(HAVE_PTHREADS)
96
+ # g.add_define('HAVE_PTHREADS')
89
97
  # end
90
98
  #
91
99
  # Params:
92
100
  # * +defn+ -- string to add to compile time defines
93
101
  def add_define(defn)
94
- @defines.push(defn)
102
+ @available.defines << defn
95
103
  end
96
104
 
97
105
  # Include a library in the compile. Returns +false+ if the
@@ -129,22 +137,26 @@ module Mkrf
129
137
  @available.logger
130
138
  end
131
139
 
140
+ # Logs a fatal error and exits with a non-zero code (defaults to 1)
141
+ def abort!(str, code = 1)
142
+ logger.fatal str
143
+ exit code
144
+ end
145
+
132
146
  def write_rakefile(filename = "Rakefile") # :nodoc:
133
147
  File.open(filename, "w+") do |f|
134
148
  f.puts rakefile_contents
135
149
  end
136
- @available.logger.info "Rakefile written"
150
+ logger.info "Rakefile written"
137
151
  end
138
152
 
139
153
  def defines_compile_string # :nodoc:
140
- (@defines.collect {|define| "-D#{define}" } +
141
- @available.headers.collect { |header|
142
- format("-DHAVE_%s", header.tr("a-z./\055", "A-Z___"))
143
- }).join(' ')
154
+ @available.defines.collect {|define| "-D#{define}"}.join(' ')
144
155
  end
145
156
 
146
157
  def rakefile_contents # :nodoc:
147
158
  <<-END_RAKEFILE
159
+ # Generated by mkrf
148
160
  require 'rake/clean'
149
161
 
150
162
  CLEAN.include('*.o')
@@ -152,13 +164,13 @@ CLOBBER.include('#{@extension_name}', 'mkrf.log')
152
164
 
153
165
  SRC = FileList[#{sources.join(',')}]
154
166
  OBJ = SRC.ext('o')
155
- CC = "gcc"
167
+ CC = '#{@cc}'
156
168
 
157
169
  ADDITIONAL_OBJECTS = '#{objects}'
158
170
 
159
171
  LDSHARED = "#{CONFIG['LDSHARED']} #{ldshared}"
160
172
 
161
- LIBPATH = '-L"#{CONFIG['rubylibdir']}"'
173
+ LIBPATH = "-L#{CONFIG['rubylibdir']} #{@available.library_paths_compile_string}"
162
174
 
163
175
  INCLUDES = "#{@available.includes_compile_string}"
164
176
 
@@ -166,6 +178,8 @@ LIBS = "#{@available.library_compile_string}"
166
178
 
167
179
  CFLAGS = "#{cflags} #{defines_compile_string}"
168
180
 
181
+ RUBYARCHDIR = "\#{ENV["RUBYARCHDIR"]}"
182
+
169
183
  task :default => ['#{@extension_name}']
170
184
 
171
185
  rule '.o' => '.c' do |t|
@@ -177,6 +191,12 @@ file '#{@extension_name}' => OBJ do
177
191
  sh "\#{LDSHARED} \#{LIBPATH} -o #{@extension_name} \#{OBJ} \#{ADDITIONAL_OBJECTS} \#{LIBS}"
178
192
  end
179
193
 
194
+ desc "Install this extension"
195
+ task :install => '#{@extension_name}' do
196
+ makedirs "\#{RUBYARCHDIR}"
197
+ install "#{@extension_name}", "\#{RUBYARCHDIR}"
198
+ end
199
+
180
200
  #{additional_code}
181
201
  END_RAKEFILE
182
202
  end
@@ -0,0 +1,123 @@
1
+ #
2
+ # Copyright (c) 2005 Zed A. Shaw with portions by Kevin Clark
3
+ # You can redistribute it and/or modify it under the same terms as Ruby.
4
+ #
5
+
6
+ def rake(rakedir)
7
+ Dir.chdir(rakedir) do
8
+ sh 'rake'
9
+ end
10
+ end
11
+
12
+
13
+ def mkrf_conf(dir)
14
+ Dir.chdir(dir) do ruby "mkrf_conf.rb" end
15
+ end
16
+
17
+
18
+ def setup_tests
19
+ Rake::TestTask.new do |t|
20
+ t.libs << "test"
21
+ t.test_files = FileList['test/test*.rb']
22
+ t.verbose = true
23
+ end
24
+ end
25
+
26
+
27
+ def setup_clean otherfiles
28
+ files = ['build/*', '**/*.o', '**/*.so', '**/*.a', 'lib/*-*', '**/*.log'] + otherfiles
29
+ CLEAN.include(files)
30
+ end
31
+
32
+
33
+ def setup_rdoc files
34
+ Rake::RDocTask.new do |rdoc|
35
+ rdoc.rdoc_dir = 'doc/rdoc'
36
+ rdoc.options << '--line-numbers'
37
+ rdoc.rdoc_files.add(files)
38
+ end
39
+ end
40
+
41
+
42
+ def setup_extension(dir, extension)
43
+ ext = "ext/#{dir}"
44
+ ext_so = "#{ext}/#{extension}.#{Config::CONFIG['DLEXT']}"
45
+ ext_files = FileList[
46
+ "#{ext}/*.c",
47
+ "#{ext}/*.h",
48
+ "#{ext}/mkrf_conf.rb",
49
+ "#{ext}/Rakefile",
50
+ "lib"
51
+ ]
52
+
53
+ task "lib" do
54
+ directory "lib"
55
+ end
56
+
57
+ desc "Builds just the #{extension} extension"
58
+ task extension.to_sym => ["#{ext}/Rakefile", ext_so ]
59
+
60
+ file "#{ext}/Rakefile" => ["#{ext}/mkrf_conf.rb"] do
61
+ mkrf_conf "#{ext}"
62
+ end
63
+
64
+ file ext_so => ext_files do
65
+ rake "#{ext}"
66
+ cp ext_so, "lib"
67
+ end
68
+ end
69
+
70
+
71
+ def base_gem_spec(pkg_name, pkg_version)
72
+ rm_rf "test/coverage"
73
+
74
+ pkg_version = pkg_version
75
+ pkg_name = pkg_name
76
+ pkg_file_name = "#{pkg_name}-#{pkg_version}"
77
+ Gem::Specification.new do |s|
78
+ s.name = pkg_name
79
+ s.version = pkg_version
80
+ s.platform = Gem::Platform::RUBY
81
+ s.has_rdoc = true
82
+ s.extra_rdoc_files = [ "README" ]
83
+
84
+ s.files = %w(Rakefile) +
85
+ Dir.glob("{bin,doc/rdoc,ext,examples}/**/*") +
86
+ Dir.glob("tools/*.rb") +
87
+ Dir.glob(RUBY_PLATFORM !~ /mswin/ ? "lib/**/*.rb" : "lib/**/*")
88
+
89
+ s.require_path = "lib"
90
+ s.bindir = "bin"
91
+ end
92
+ end
93
+
94
+ def setup_gem(pkg_name, pkg_version)
95
+ spec = base_gem_spec(pkg_name, pkg_version)
96
+ yield spec if block_given?
97
+
98
+
99
+ Rake::GemPackageTask.new(spec) do |p|
100
+ p.gem_spec = spec
101
+ p.need_tar = true if RUBY_PLATFORM !~ /mswin/
102
+ end
103
+ end
104
+
105
+ def sub_project(project, *targets)
106
+ targets.each do |target|
107
+ Dir.chdir "projects/#{project}" do
108
+ sh %{rake --trace #{target.to_s} }
109
+ end
110
+ end
111
+ end
112
+
113
+ # Conditional require rcov/rcovtask if present
114
+ begin
115
+ require 'rcov/rcovtask'
116
+
117
+ Rcov::RcovTask.new do |t|
118
+ t.test_files = FileList['test/test*.rb']
119
+ t.rcov_opts << "-x /usr"
120
+ t.output_dir = "test/coverage"
121
+ end
122
+ rescue Object
123
+ end