mkrf 0.1.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +14 -1
- data/README +50 -22
- data/Rakefile +2 -1
- data/lib/mkrf.rb +1 -1
- data/lib/mkrf/availability.rb +60 -9
- data/lib/mkrf/generator.rb +32 -12
- data/lib/mkrf/rakehelper.rb +123 -0
- data/test/{sample_files/libtrivial/libtrivial.bundle → fixtures/some_binary} +0 -0
- data/test/integration/test_sample_projects.rb +1 -1
- data/test/sample_files/libtrivial/ext/extconf.rb +3 -0
- data/test/sample_files/libtrivial/{lib → ext}/libtrivial.c +0 -0
- data/test/unit/test_availability.rb +27 -2
- data/test/unit/test_generator.rb +55 -0
- metadata +144 -180
- data/test/mkrf.log +0 -1
- data/test/sample_files/libtrivial/Rakefile +0 -33
- data/test/sample_files/libtrivial/extconf.rb +0 -3
- data/test/sample_files/libtrivial/lib/libtrivial.o +0 -0
- data/test/sample_files/libtrivial/mkrf.log +0 -2
- data/test/sample_files/libxml-ruby-0.3.8/ext/xml/Rakefile +0 -33
- data/test/sample_files/libxml-ruby-0.3.8/ext/xml/cbg.o +0 -0
- data/test/sample_files/libxml-ruby-0.3.8/ext/xml/libxml.o +0 -0
- data/test/sample_files/libxml-ruby-0.3.8/ext/xml/libxml_so.bundle +0 -0
- data/test/sample_files/libxml-ruby-0.3.8/ext/xml/mkrf.log +0 -21
- data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_attr.o +0 -0
- data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_attribute.o +0 -0
- data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_document.o +0 -0
- data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_dtd.o +0 -0
- data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_input_cbg.o +0 -0
- data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_node.o +0 -0
- data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_node_set.o +0 -0
- data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_ns.o +0 -0
- data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_parser.o +0 -0
- data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_parser_context.o +0 -0
- data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_sax_parser.o +0 -0
- data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_schema.o +0 -0
- data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_tree.o +0 -0
- data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_xinclude.o +0 -0
- data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_xpath.o +0 -0
- data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_xpath_context.o +0 -0
- data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_xpointer.o +0 -0
- data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_xpointer_context.o +0 -0
- data/test/sample_files/syck-0.55/ext/ruby/ext/syck/Rakefile +0 -33
- data/test/sample_files/syck-0.55/ext/ruby/ext/syck/bytecode.o +0 -0
- data/test/sample_files/syck-0.55/ext/ruby/ext/syck/emitter.o +0 -0
- data/test/sample_files/syck-0.55/ext/ruby/ext/syck/gram.o +0 -0
- data/test/sample_files/syck-0.55/ext/ruby/ext/syck/handler.o +0 -0
- data/test/sample_files/syck-0.55/ext/ruby/ext/syck/implicit.o +0 -0
- data/test/sample_files/syck-0.55/ext/ruby/ext/syck/mkrf.log +0 -3
- data/test/sample_files/syck-0.55/ext/ruby/ext/syck/node.o +0 -0
- data/test/sample_files/syck-0.55/ext/ruby/ext/syck/rubyext.o +0 -0
- data/test/sample_files/syck-0.55/ext/ruby/ext/syck/syck.bundle +0 -0
- data/test/sample_files/syck-0.55/ext/ruby/ext/syck/syck.o +0 -0
- data/test/sample_files/syck-0.55/ext/ruby/ext/syck/token.o +0 -0
- 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
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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
|
|
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
|
|
15
|
-
extension configuration file
|
|
16
|
-
|
|
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
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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
|
-
|
|
27
|
-
|
|
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
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
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
data/lib/mkrf/availability.rb
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
201
|
-
|
|
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
|
data/lib/mkrf/generator.rb
CHANGED
|
@@ -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 =
|
|
74
|
-
cflags
|
|
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
|
|
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
|
-
|
|
150
|
+
logger.info "Rakefile written"
|
|
137
151
|
end
|
|
138
152
|
|
|
139
153
|
def defines_compile_string # :nodoc:
|
|
140
|
-
|
|
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 =
|
|
167
|
+
CC = '#{@cc}'
|
|
156
168
|
|
|
157
169
|
ADDITIONAL_OBJECTS = '#{objects}'
|
|
158
170
|
|
|
159
171
|
LDSHARED = "#{CONFIG['LDSHARED']} #{ldshared}"
|
|
160
172
|
|
|
161
|
-
LIBPATH =
|
|
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
|