rubysl-mkmf 1.0.0 → 2.0.1
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.
- checksums.yaml +4 -4
- data/.travis.yml +6 -0
- data/lib/rubysl/mkmf/mkmf.rb +2208 -1514
- data/lib/rubysl/mkmf/version.rb +1 -1
- data/rubysl-mkmf.gemspec +6 -0
- metadata +48 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9a3cec3459dba8709d26961f5bfd14b1200ea666
|
4
|
+
data.tar.gz: 140f79d5b37aeaeff68cdeee470c6212716e5cbd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: de622c4cb95dcb2e39d2c5af458dc15fc84afd04d6aaf2c79ab3bcc20f3700f04222eb886b77f7c94b4a520a3796333c29f8e44954e6920cef915cfebf87d0ef
|
7
|
+
data.tar.gz: e0f5b03b5227f440ddc9a61fb8ff5d74030b699e5b49686d42cd0b78ebf984ffcaa592e5eabb2cd8adbbf9153faf35b938a3ec859fcd7a1774c4fb9c83439b2e
|
data/.travis.yml
ADDED
data/lib/rubysl/mkmf/mkmf.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# -*- coding: us-ascii -*-
|
1
2
|
# module to create Makefile for extension modules
|
2
3
|
# invoke like: ruby -r mkmf extconf.rb
|
3
4
|
|
@@ -5,1848 +6,2541 @@ require 'rbconfig'
|
|
5
6
|
require 'fileutils'
|
6
7
|
require 'shellwords'
|
7
8
|
|
8
|
-
|
9
|
-
|
9
|
+
# :stopdoc:
|
10
|
+
class String
|
11
|
+
# Wraps a string in escaped quotes if it contains whitespace.
|
12
|
+
def quote
|
13
|
+
/\s/ =~ self ? "\"#{self}\"" : "#{self}"
|
14
|
+
end
|
10
15
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
end
|
15
|
-
SRC_EXT = %w[c m].concat(CXX_EXT)
|
16
|
-
$static = $config_h = nil
|
17
|
-
$default_static = $static
|
18
|
-
|
19
|
-
unless defined? $configure_args
|
20
|
-
$configure_args = {}
|
21
|
-
args = CONFIG["configure_args"]
|
22
|
-
if ENV["CONFIGURE_ARGS"]
|
23
|
-
args << " " << ENV["CONFIGURE_ARGS"]
|
24
|
-
end
|
25
|
-
for arg in Shellwords::shellwords(args)
|
26
|
-
arg, val = arg.split('=', 2)
|
27
|
-
next unless arg
|
28
|
-
arg.tr!('_', '-')
|
29
|
-
if arg.sub!(/^(?!--)/, '--')
|
30
|
-
val or next
|
31
|
-
arg.downcase!
|
32
|
-
end
|
33
|
-
next if /^--(?:top|topsrc|src|cur)dir$/ =~ arg
|
34
|
-
$configure_args[arg] = val || true
|
35
|
-
end
|
36
|
-
for arg in ARGV
|
37
|
-
arg, val = arg.split('=', 2)
|
38
|
-
next unless arg
|
39
|
-
arg.tr!('_', '-')
|
40
|
-
if arg.sub!(/^(?!--)/, '--')
|
41
|
-
val or next
|
42
|
-
arg.downcase!
|
43
|
-
end
|
44
|
-
$configure_args[arg] = val || true
|
16
|
+
# Escape whitespaces for Makefile.
|
17
|
+
def unspace
|
18
|
+
gsub(/\s/, '\\\\\\&')
|
45
19
|
end
|
46
|
-
end
|
47
20
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
$sitelibdir = CONFIG["sitelibdir"]
|
53
|
-
$sitearchdir = CONFIG["sitearchdir"]
|
54
|
-
$vendordir = CONFIG["vendordir"]
|
55
|
-
$vendorlibdir = CONFIG["vendorlibdir"]
|
56
|
-
$vendorarchdir = CONFIG["vendorarchdir"]
|
57
|
-
|
58
|
-
$mswin = /mswin/ =~ RUBY_PLATFORM
|
59
|
-
$bccwin = /bccwin/ =~ RUBY_PLATFORM
|
60
|
-
$mingw = /mingw/ =~ RUBY_PLATFORM
|
61
|
-
$cygwin = /cygwin/ =~ RUBY_PLATFORM
|
62
|
-
$human = /human/ =~ RUBY_PLATFORM
|
63
|
-
$netbsd = /netbsd/ =~ RUBY_PLATFORM
|
64
|
-
$os2 = /os2/ =~ RUBY_PLATFORM
|
65
|
-
$beos = /beos/ =~ RUBY_PLATFORM
|
66
|
-
$solaris = /solaris/ =~ RUBY_PLATFORM
|
67
|
-
$dest_prefix_pattern = (File::PATH_SEPARATOR == ';' ? /\A([[:alpha:]]:)?/ : /\A/)
|
21
|
+
# Generates a string used as cpp macro name.
|
22
|
+
def tr_cpp
|
23
|
+
strip.upcase.tr_s("^A-Z0-9_*", "_").tr_s("*", "P")
|
24
|
+
end
|
68
25
|
|
69
|
-
|
26
|
+
def funcall_style
|
27
|
+
/\)\z/ =~ self ? dup : "#{self}()"
|
28
|
+
end
|
70
29
|
|
71
|
-
def
|
72
|
-
|
30
|
+
def sans_arguments
|
31
|
+
self[/\A[^()]+/]
|
32
|
+
end
|
73
33
|
end
|
74
34
|
|
75
|
-
|
76
|
-
|
35
|
+
class Array
|
36
|
+
# Wraps all strings in escaped quotes if they contain whitespace.
|
37
|
+
def quote
|
38
|
+
map {|s| s.quote}
|
39
|
+
end
|
77
40
|
end
|
41
|
+
# :startdoc:
|
78
42
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
[dir_re('archdir'), "$(RUBYARCHDIR)"],
|
85
|
-
[dir_re('sitelibdir'), "$(RUBYLIBDIR)"],
|
86
|
-
[dir_re('vendorlibdir'), "$(RUBYLIBDIR)"],
|
87
|
-
[dir_re('sitearchdir'), "$(RUBYARCHDIR)"],
|
88
|
-
[dir_re('bindir'), "$(BINDIR)"],
|
89
|
-
[dir_re('vendorarchdir'), "$(RUBYARCHDIR)"],
|
90
|
-
]
|
91
|
-
|
92
|
-
def install_dirs(target_prefix = nil)
|
93
|
-
if $extout
|
94
|
-
dirs = [
|
95
|
-
['BINDIR', '$(extout)/bin'],
|
96
|
-
['RUBYCOMMONDIR', '$(extout)/common'],
|
97
|
-
['RUBYLIBDIR', '$(RUBYCOMMONDIR)$(target_prefix)'],
|
98
|
-
['RUBYARCHDIR', '$(extout)/$(arch)$(target_prefix)'],
|
99
|
-
['extout', "#$extout"],
|
100
|
-
['extout_prefix', "#$extout_prefix"],
|
101
|
-
]
|
102
|
-
elsif $extmk
|
103
|
-
dirs = [
|
104
|
-
['BINDIR', '$(bindir)'],
|
105
|
-
['RUBYCOMMONDIR', '$(rubylibdir)'],
|
106
|
-
['RUBYLIBDIR', '$(rubylibdir)$(target_prefix)'],
|
107
|
-
['RUBYARCHDIR', '$(archdir)$(target_prefix)'],
|
108
|
-
]
|
109
|
-
elsif $configure_args.has_key?('--vendor')
|
110
|
-
dirs = [
|
111
|
-
['BINDIR', '$(bindir)'],
|
112
|
-
['RUBYCOMMONDIR', '$(vendordir)$(target_prefix)'],
|
113
|
-
['RUBYLIBDIR', '$(vendorlibdir)$(target_prefix)'],
|
114
|
-
['RUBYARCHDIR', '$(vendorarchdir)$(target_prefix)'],
|
115
|
-
]
|
116
|
-
else
|
117
|
-
dirs = [
|
118
|
-
['BINDIR', '$(bindir)'],
|
119
|
-
['RUBYCOMMONDIR', '$(sitedir)$(target_prefix)'],
|
120
|
-
['RUBYLIBDIR', '$(sitelibdir)$(target_prefix)'],
|
121
|
-
['RUBYARCHDIR', '$(sitearchdir)$(target_prefix)'],
|
122
|
-
]
|
123
|
-
end
|
124
|
-
dirs << ['target_prefix', (target_prefix ? "/#{target_prefix}" : "")]
|
125
|
-
dirs
|
126
|
-
end
|
43
|
+
##
|
44
|
+
# mkmf.rb is used by ruby C extensions to generate a Makefile which will
|
45
|
+
# correctly compile and link the C extension to ruby and a third-party
|
46
|
+
# library.
|
47
|
+
module MakeMakefile
|
127
48
|
|
128
|
-
|
129
|
-
|
130
|
-
map.inject(dir) {|dir, (orig, new)| dir.gsub(orig, new)}
|
131
|
-
end
|
49
|
+
##
|
50
|
+
# The makefile configuration using the defaults from when ruby was built.
|
132
51
|
|
133
|
-
|
134
|
-
|
135
|
-
$topdir = "#{dir}/vm/capi/18/include"
|
136
|
-
else
|
137
|
-
$topdir = RbConfig::CONFIG["rubyhdrdir"]
|
138
|
-
end
|
52
|
+
CONFIG = RbConfig::MAKEFILE_CONFIG
|
53
|
+
ORIG_LIBPATH = ENV['LIB']
|
139
54
|
|
140
|
-
|
141
|
-
|
55
|
+
##
|
56
|
+
# Extensions for files compiled with a C compiler
|
142
57
|
|
143
|
-
|
144
|
-
abort "mkmf.rb can't find header files for ruby at #{$hdrdir}/ruby.h"
|
145
|
-
end
|
146
|
-
# ----------------------------------------------------------------------------
|
58
|
+
C_EXT = %w[c m]
|
147
59
|
|
148
|
-
|
149
|
-
|
60
|
+
##
|
61
|
+
# Extensions for files complied with a C++ compiler
|
150
62
|
|
151
|
-
|
63
|
+
CXX_EXT = %w[cc mm cxx cpp]
|
64
|
+
if File::FNM_SYSCASE.zero?
|
65
|
+
CXX_EXT.concat(%w[C])
|
66
|
+
end
|
152
67
|
|
153
|
-
|
154
|
-
#
|
155
|
-
|
156
|
-
|
68
|
+
##
|
69
|
+
# Extensions for source files
|
70
|
+
|
71
|
+
SRC_EXT = C_EXT + CXX_EXT
|
72
|
+
|
73
|
+
##
|
74
|
+
# Extensions for header files
|
75
|
+
|
76
|
+
HDR_EXT = %w[h hpp]
|
77
|
+
$static = nil
|
78
|
+
$config_h = '$(arch_hdrdir)/ruby/config.h'
|
79
|
+
$default_static = $static
|
80
|
+
|
81
|
+
unless defined? $configure_args
|
82
|
+
$configure_args = {}
|
83
|
+
args = CONFIG["configure_args"]
|
84
|
+
if ENV["CONFIGURE_ARGS"]
|
85
|
+
args << " " << ENV["CONFIGURE_ARGS"]
|
86
|
+
end
|
87
|
+
for arg in Shellwords::shellwords(args)
|
88
|
+
arg, val = arg.split('=', 2)
|
89
|
+
next unless arg
|
90
|
+
arg.tr!('_', '-')
|
91
|
+
if arg.sub!(/^(?!--)/, '--')
|
92
|
+
val or next
|
93
|
+
arg.downcase!
|
94
|
+
end
|
95
|
+
next if /^--(?:top|topsrc|src|cur)dir$/ =~ arg
|
96
|
+
$configure_args[arg] = val || true
|
97
|
+
end
|
98
|
+
for arg in ARGV
|
99
|
+
arg, val = arg.split('=', 2)
|
100
|
+
next unless arg
|
101
|
+
arg.tr!('_', '-')
|
102
|
+
if arg.sub!(/^(?!--)/, '--')
|
103
|
+
val or next
|
104
|
+
arg.downcase!
|
105
|
+
end
|
106
|
+
$configure_args[arg] = val || true
|
107
|
+
end
|
157
108
|
end
|
158
109
|
|
159
|
-
|
160
|
-
|
161
|
-
|
110
|
+
$libdir = CONFIG["libdir"]
|
111
|
+
$rubylibdir = CONFIG["rubylibdir"]
|
112
|
+
$archdir = CONFIG["archdir"]
|
113
|
+
$sitedir = CONFIG["sitedir"]
|
114
|
+
$sitelibdir = CONFIG["sitelibdir"]
|
115
|
+
$sitearchdir = CONFIG["sitearchdir"]
|
116
|
+
$vendordir = CONFIG["vendordir"]
|
117
|
+
$vendorlibdir = CONFIG["vendorlibdir"]
|
118
|
+
$vendorarchdir = CONFIG["vendorarchdir"]
|
119
|
+
|
120
|
+
$mswin = /mswin/ =~ RUBY_PLATFORM
|
121
|
+
$bccwin = /bccwin/ =~ RUBY_PLATFORM
|
122
|
+
$mingw = /mingw/ =~ RUBY_PLATFORM
|
123
|
+
$cygwin = /cygwin/ =~ RUBY_PLATFORM
|
124
|
+
$netbsd = /netbsd/ =~ RUBY_PLATFORM
|
125
|
+
$os2 = /os2/ =~ RUBY_PLATFORM
|
126
|
+
$beos = /beos/ =~ RUBY_PLATFORM
|
127
|
+
$haiku = /haiku/ =~ RUBY_PLATFORM
|
128
|
+
$solaris = /solaris/ =~ RUBY_PLATFORM
|
129
|
+
$universal = /universal/ =~ RUBY_PLATFORM
|
130
|
+
$dest_prefix_pattern = (File::PATH_SEPARATOR == ';' ? /\A([[:alpha:]]:)?/ : /\A/)
|
131
|
+
|
132
|
+
# :stopdoc:
|
133
|
+
|
134
|
+
def config_string(key, config = CONFIG)
|
135
|
+
s = config[key] and !s.empty? and block_given? ? yield(s) : s
|
162
136
|
end
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
map {|s| s.quote}
|
137
|
+
module_function :config_string
|
138
|
+
|
139
|
+
def dir_re(dir)
|
140
|
+
Regexp.new('\$(?:\('+dir+'\)|\{'+dir+'\})(?:\$(?:\(target_prefix\)|\{target_prefix\}))?')
|
168
141
|
end
|
169
|
-
|
142
|
+
module_function :dir_re
|
170
143
|
|
171
|
-
def
|
172
|
-
|
173
|
-
|
144
|
+
def relative_from(path, base)
|
145
|
+
dir = File.join(path, "")
|
146
|
+
if File.expand_path(dir) == File.expand_path(dir, base)
|
147
|
+
path
|
148
|
+
else
|
149
|
+
File.join(base, path)
|
150
|
+
end
|
151
|
+
end
|
174
152
|
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
153
|
+
INSTALL_DIRS = [
|
154
|
+
[dir_re('commondir'), "$(RUBYCOMMONDIR)"],
|
155
|
+
[dir_re('sitedir'), "$(RUBYCOMMONDIR)"],
|
156
|
+
[dir_re('vendordir'), "$(RUBYCOMMONDIR)"],
|
157
|
+
[dir_re('rubylibdir'), "$(RUBYLIBDIR)"],
|
158
|
+
[dir_re('archdir'), "$(RUBYARCHDIR)"],
|
159
|
+
[dir_re('sitelibdir'), "$(RUBYLIBDIR)"],
|
160
|
+
[dir_re('vendorlibdir'), "$(RUBYLIBDIR)"],
|
161
|
+
[dir_re('sitearchdir'), "$(RUBYARCHDIR)"],
|
162
|
+
[dir_re('vendorarchdir'), "$(RUBYARCHDIR)"],
|
163
|
+
[dir_re('rubyhdrdir'), "$(RUBYHDRDIR)"],
|
164
|
+
[dir_re('sitehdrdir'), "$(SITEHDRDIR)"],
|
165
|
+
[dir_re('vendorhdrdir'), "$(VENDORHDRDIR)"],
|
166
|
+
[dir_re('bindir'), "$(BINDIR)"],
|
167
|
+
]
|
168
|
+
|
169
|
+
def install_dirs(target_prefix = nil)
|
170
|
+
if $extout
|
171
|
+
dirs = [
|
172
|
+
['BINDIR', '$(extout)/bin'],
|
173
|
+
['RUBYCOMMONDIR', '$(extout)/common'],
|
174
|
+
['RUBYLIBDIR', '$(RUBYCOMMONDIR)$(target_prefix)'],
|
175
|
+
['RUBYARCHDIR', '$(extout)/$(arch)$(target_prefix)'],
|
176
|
+
['HDRDIR', '$(extout)/include/ruby$(target_prefix)'],
|
177
|
+
['ARCHHDRDIR', '$(extout)/include/$(arch)/ruby$(target_prefix)'],
|
178
|
+
['extout', "#$extout"],
|
179
|
+
['extout_prefix', "#$extout_prefix"],
|
180
|
+
]
|
181
|
+
elsif $extmk
|
182
|
+
dirs = [
|
183
|
+
['BINDIR', '$(bindir)'],
|
184
|
+
['RUBYCOMMONDIR', '$(rubylibdir)'],
|
185
|
+
['RUBYLIBDIR', '$(rubylibdir)$(target_prefix)'],
|
186
|
+
['RUBYARCHDIR', '$(archdir)$(target_prefix)'],
|
187
|
+
['HDRDIR', '$(rubyhdrdir)/ruby$(target_prefix)'],
|
188
|
+
['ARCHHDRDIR', '$(rubyhdrdir)/$(arch)/ruby$(target_prefix)'],
|
189
|
+
]
|
190
|
+
elsif $configure_args.has_key?('--vendor')
|
191
|
+
dirs = [
|
192
|
+
['BINDIR', '$(DESTDIR)$(bindir)'],
|
193
|
+
['RUBYCOMMONDIR', '$(DESTDIR)$(vendordir)$(target_prefix)'],
|
194
|
+
['RUBYLIBDIR', '$(DESTDIR)$(vendorlibdir)$(target_prefix)'],
|
195
|
+
['RUBYARCHDIR', '$(DESTDIR)$(vendorarchdir)$(target_prefix)'],
|
196
|
+
['HDRDIR', '$(DESTDIR)$(rubyhdrdir)/ruby$(target_prefix)'],
|
197
|
+
['ARCHHDRDIR', '$(DESTDIR)$(rubyhdrdir)/$(arch)/ruby$(target_prefix)'],
|
198
|
+
]
|
199
|
+
else
|
200
|
+
dirs = [
|
201
|
+
['BINDIR', '$(DESTDIR)$(bindir)'],
|
202
|
+
['RUBYCOMMONDIR', '$(DESTDIR)$(sitedir)$(target_prefix)'],
|
203
|
+
['RUBYLIBDIR', '$(DESTDIR)$(sitelibdir)$(target_prefix)'],
|
204
|
+
['RUBYARCHDIR', '$(DESTDIR)$(sitearchdir)$(target_prefix)'],
|
205
|
+
['HDRDIR', '$(DESTDIR)$(rubyhdrdir)/ruby$(target_prefix)'],
|
206
|
+
['ARCHHDRDIR', '$(DESTDIR)$(rubyhdrdir)/$(arch)/ruby$(target_prefix)'],
|
207
|
+
]
|
208
|
+
end
|
209
|
+
dirs << ['target_prefix', (target_prefix ? "/#{target_prefix}" : "")]
|
210
|
+
dirs
|
211
|
+
end
|
182
212
|
|
183
|
-
def
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
213
|
+
def map_dir(dir, map = nil)
|
214
|
+
map ||= INSTALL_DIRS
|
215
|
+
map.inject(dir) {|d, (orig, new)| d.gsub(orig, new)}
|
216
|
+
end
|
217
|
+
|
218
|
+
topdir = File.dirname(File.dirname(__FILE__))
|
219
|
+
path = File.expand_path($0)
|
220
|
+
until (dir = File.dirname(path)) == path
|
221
|
+
if File.identical?(dir, topdir)
|
222
|
+
$extmk = true if %r"\A(?:ext|enc|tool|test)\z" =~ File.basename(path)
|
223
|
+
break
|
194
224
|
end
|
195
|
-
|
225
|
+
path = dir
|
226
|
+
end
|
227
|
+
$extmk ||= false
|
228
|
+
if not $extmk and File.exist?(($hdrdir = RbConfig::CONFIG["rubyhdrdir"]) + "/ruby/ruby.h")
|
229
|
+
$topdir = $hdrdir
|
230
|
+
$top_srcdir = $hdrdir
|
231
|
+
$arch_hdrdir = RbConfig::CONFIG["rubyarchhdrdir"]
|
232
|
+
elsif File.exist?(($hdrdir = ($top_srcdir ||= topdir) + "/include") + "/ruby.h")
|
233
|
+
$topdir ||= RbConfig::CONFIG["topdir"]
|
234
|
+
$arch_hdrdir = "$(extout)/include/$(arch)"
|
235
|
+
else
|
236
|
+
abort "mkmf.rb can't find header files for ruby at #{$hdrdir}/ruby.h"
|
196
237
|
end
|
197
|
-
end
|
198
238
|
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
239
|
+
OUTFLAG = CONFIG['OUTFLAG']
|
240
|
+
COUTFLAG = CONFIG['COUTFLAG']
|
241
|
+
CPPOUTFILE = CONFIG['CPPOUTFILE']
|
242
|
+
|
243
|
+
CONFTEST_C = "conftest.c".freeze
|
244
|
+
|
245
|
+
def rm_f(*files)
|
246
|
+
opt = (Hash === files.last ? [files.pop] : [])
|
247
|
+
FileUtils.rm_f(Dir[*files.flatten], *opt)
|
248
|
+
end
|
249
|
+
module_function :rm_f
|
250
|
+
|
251
|
+
def rm_rf(*files)
|
252
|
+
opt = (Hash === files.last ? [files.pop] : [])
|
253
|
+
FileUtils.rm_rf(Dir[*files.flatten], *opt)
|
254
|
+
end
|
255
|
+
module_function :rm_rf
|
256
|
+
|
257
|
+
# Returns time stamp of the +target+ file if it exists and is newer than or
|
258
|
+
# equal to all of +times+.
|
259
|
+
def modified?(target, times)
|
260
|
+
(t = File.mtime(target)) rescue return nil
|
261
|
+
Array === times or times = [times]
|
262
|
+
t if times.all? {|n| n <= t}
|
222
263
|
end
|
223
264
|
|
224
|
-
def
|
225
|
-
|
226
|
-
@log.sync = true
|
227
|
-
@log.printf(*s)
|
265
|
+
def split_libs(*strs)
|
266
|
+
strs.map {|s| s.split(/\s+(?=-|\z)/)}.flatten
|
228
267
|
end
|
229
268
|
|
230
|
-
def
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
269
|
+
def merge_libs(*libs)
|
270
|
+
libs.inject([]) do |x, y|
|
271
|
+
y = y.inject([]) {|ary, e| ary.last == e ? ary : ary << e}
|
272
|
+
y.each_with_index do |v, yi|
|
273
|
+
if xi = x.rindex(v)
|
274
|
+
x[(xi+1)..-1] = merge_libs(y[(yi+1)..-1], x[(xi+1)..-1])
|
275
|
+
x[xi, 0] = y[0...yi]
|
276
|
+
break
|
277
|
+
end
|
278
|
+
end and x.concat(y)
|
279
|
+
x
|
236
280
|
end
|
237
281
|
end
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
282
|
+
|
283
|
+
# This is a custom logging module. It generates an mkmf.log file when you
|
284
|
+
# run your extconf.rb script. This can be useful for debugging unexpected
|
285
|
+
# failures.
|
286
|
+
#
|
287
|
+
# This module and its associated methods are meant for internal use only.
|
288
|
+
#
|
289
|
+
module Logging
|
290
|
+
@log = nil
|
291
|
+
@logfile = 'mkmf.log'
|
292
|
+
@orgerr = $stderr.dup
|
293
|
+
@orgout = $stdout.dup
|
294
|
+
@postpone = 0
|
295
|
+
@quiet = $extmk
|
296
|
+
|
297
|
+
def self::log_open
|
298
|
+
@log ||= File::open(@logfile, 'wb')
|
299
|
+
@log.sync = true
|
300
|
+
end
|
301
|
+
|
302
|
+
def self::open
|
303
|
+
log_open
|
304
|
+
$stderr.reopen(@log)
|
305
|
+
$stdout.reopen(@log)
|
306
|
+
yield
|
307
|
+
ensure
|
308
|
+
$stderr.reopen(@orgerr)
|
309
|
+
$stdout.reopen(@orgout)
|
310
|
+
end
|
311
|
+
|
312
|
+
def self::message(*s)
|
313
|
+
log_open
|
314
|
+
@log.printf(*s)
|
315
|
+
end
|
316
|
+
|
317
|
+
def self::logfile file
|
318
|
+
@logfile = file
|
319
|
+
log_close
|
320
|
+
end
|
321
|
+
|
322
|
+
def self::log_close
|
323
|
+
if @log and not @log.closed?
|
324
|
+
@log.flush
|
246
325
|
@log.close
|
247
|
-
|
248
|
-
ensure
|
249
|
-
@log, @logfile, @orgout, @orgerr = log, *save
|
250
|
-
@postpone -= 1
|
251
|
-
rm_f tmplog
|
326
|
+
@log = nil
|
252
327
|
end
|
253
328
|
end
|
254
|
-
end
|
255
329
|
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
330
|
+
def self::postpone
|
331
|
+
tmplog = "mkmftmp#{@postpone += 1}.log"
|
332
|
+
open do
|
333
|
+
log, *save = @log, @logfile, @orgout, @orgerr
|
334
|
+
@log, @logfile, @orgout, @orgerr = nil, tmplog, log, log
|
335
|
+
begin
|
336
|
+
log.print(open {yield @log})
|
337
|
+
ensure
|
338
|
+
@log.close if @log and not @log.closed?
|
339
|
+
File::open(tmplog) {|t| FileUtils.copy_stream(t, log)} if File.exist?(tmplog)
|
340
|
+
@log, @logfile, @orgout, @orgerr = log, *save
|
341
|
+
@postpone -= 1
|
342
|
+
MakeMakefile.rm_f tmplog
|
343
|
+
end
|
344
|
+
end
|
345
|
+
end
|
260
346
|
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
vars = Hash.new {|h, k| h[k] = ''; ENV[k]}
|
265
|
-
command = command.dup
|
266
|
-
nil while command.gsub!(varpat) {vars[$1||$2]}
|
347
|
+
class << self
|
348
|
+
attr_accessor :quiet
|
349
|
+
end
|
267
350
|
end
|
268
|
-
|
269
|
-
|
270
|
-
|
351
|
+
|
352
|
+
def xsystem command, opts = nil
|
353
|
+
varpat = /\$\((\w+)\)|\$\{(\w+)\}/
|
354
|
+
if varpat =~ command
|
355
|
+
vars = Hash.new {|h, k| h[k] = ''; ENV[k]}
|
356
|
+
command = command.dup
|
357
|
+
nil while command.gsub!(varpat) {vars[$1||$2]}
|
358
|
+
end
|
359
|
+
Logging::open do
|
360
|
+
puts command.quote
|
361
|
+
if opts and opts[:werror]
|
362
|
+
result = nil
|
363
|
+
Logging.postpone do |log|
|
364
|
+
result = (system(command) and File.zero?(log.path))
|
365
|
+
""
|
366
|
+
end
|
367
|
+
result
|
368
|
+
else
|
369
|
+
system(command)
|
370
|
+
end
|
371
|
+
end
|
271
372
|
end
|
272
|
-
end
|
273
373
|
|
274
|
-
def xpopen command, *mode, &block
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
374
|
+
def xpopen command, *mode, &block
|
375
|
+
Logging::open do
|
376
|
+
case mode[0]
|
377
|
+
when nil, /^r/
|
378
|
+
puts "#{command} |"
|
379
|
+
else
|
380
|
+
puts "| #{command}"
|
381
|
+
end
|
382
|
+
IO.popen(command, *mode, &block)
|
281
383
|
end
|
282
|
-
IO.popen(command, *mode, &block)
|
283
384
|
end
|
284
|
-
end
|
285
385
|
|
286
|
-
def log_src(src)
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
386
|
+
def log_src(src, heading="checked program was")
|
387
|
+
src = src.split(/^/)
|
388
|
+
fmt = "%#{src.size.to_s.size}d: %s"
|
389
|
+
Logging::message <<"EOM"
|
390
|
+
#{heading}:
|
291
391
|
/* begin */
|
292
392
|
EOM
|
293
|
-
|
294
|
-
|
393
|
+
src.each_with_index {|line, no| Logging::message fmt, no+1, line}
|
394
|
+
Logging::message <<"EOM"
|
295
395
|
/* end */
|
296
396
|
|
297
397
|
EOM
|
298
|
-
end
|
398
|
+
end
|
299
399
|
|
300
|
-
def create_tmpsrc(src)
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
400
|
+
def create_tmpsrc(src)
|
401
|
+
src = "#{COMMON_HEADERS}\n#{src}"
|
402
|
+
src = yield(src) if block_given?
|
403
|
+
src.gsub!(/[ \t]+$/, '')
|
404
|
+
src.gsub!(/\A\n+|^\n+$/, '')
|
405
|
+
src.sub!(/[^\n]\z/, "\\&\n")
|
406
|
+
count = 0
|
407
|
+
begin
|
408
|
+
open(CONFTEST_C, "wb") do |cfile|
|
409
|
+
cfile.print src
|
410
|
+
end
|
411
|
+
rescue Errno::EACCES
|
412
|
+
if (count += 1) < 5
|
413
|
+
sleep 0.2
|
414
|
+
retry
|
415
|
+
end
|
416
|
+
end
|
417
|
+
src
|
305
418
|
end
|
306
|
-
src
|
307
|
-
end
|
308
419
|
|
309
|
-
def
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
420
|
+
def have_devel?
|
421
|
+
unless defined? $have_devel
|
422
|
+
$have_devel = true
|
423
|
+
$have_devel = try_link(MAIN_DOES_NOTHING)
|
424
|
+
end
|
425
|
+
$have_devel
|
426
|
+
end
|
315
427
|
|
316
|
-
def
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
428
|
+
def try_do(src, command, *opts, &b)
|
429
|
+
unless have_devel?
|
430
|
+
raise <<MSG
|
431
|
+
The compiler failed to generate an executable file.
|
432
|
+
You have to install development tools first.
|
433
|
+
MSG
|
434
|
+
end
|
435
|
+
begin
|
436
|
+
src = create_tmpsrc(src, &b)
|
437
|
+
xsystem(command, *opts)
|
438
|
+
ensure
|
439
|
+
log_src(src)
|
440
|
+
MakeMakefile.rm_rf 'conftest.dSYM'
|
441
|
+
end
|
442
|
+
end
|
329
443
|
|
330
|
-
def
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
444
|
+
def link_command(ldflags, opt="", libpath=$DEFLIBPATH|$LIBPATH)
|
445
|
+
librubyarg = $extmk ? $LIBRUBYARG_STATIC : "$(LIBRUBYARG)"
|
446
|
+
conf = RbConfig::CONFIG.merge('hdrdir' => $hdrdir.quote,
|
447
|
+
'src' => "#{CONFTEST_C}",
|
448
|
+
'arch_hdrdir' => $arch_hdrdir.quote,
|
449
|
+
'top_srcdir' => $top_srcdir.quote,
|
450
|
+
'INCFLAGS' => "#$INCFLAGS",
|
451
|
+
'CPPFLAGS' => "#$CPPFLAGS",
|
452
|
+
'CFLAGS' => "#$CFLAGS",
|
453
|
+
'ARCH_FLAG' => "#$ARCH_FLAG",
|
454
|
+
'LDFLAGS' => "#$LDFLAGS #{ldflags}",
|
455
|
+
'LOCAL_LIBS' => "#$LOCAL_LIBS #$libs",
|
456
|
+
'LIBS' => "#{librubyarg} #{opt} #$LIBS")
|
457
|
+
conf['LIBPATH'] = libpathflag(libpath.map {|s| RbConfig::expand(s.dup, conf)})
|
458
|
+
RbConfig::expand(TRY_LINK.dup, conf)
|
459
|
+
end
|
460
|
+
|
461
|
+
def cc_command(opt="")
|
462
|
+
conf = RbConfig::CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote,
|
463
|
+
'arch_hdrdir' => $arch_hdrdir.quote,
|
464
|
+
'top_srcdir' => $top_srcdir.quote)
|
465
|
+
RbConfig::expand("$(CC) #$INCFLAGS #$CPPFLAGS #$CFLAGS #$ARCH_FLAG #{opt} -c #{CONFTEST_C}",
|
466
|
+
conf)
|
467
|
+
end
|
468
|
+
|
469
|
+
def cpp_command(outfile, opt="")
|
470
|
+
conf = RbConfig::CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote,
|
471
|
+
'arch_hdrdir' => $arch_hdrdir.quote,
|
472
|
+
'top_srcdir' => $top_srcdir.quote)
|
473
|
+
if $universal and (arch_flag = conf['ARCH_FLAG']) and !arch_flag.empty?
|
474
|
+
conf['ARCH_FLAG'] = arch_flag.gsub(/(?:\G|\s)-arch\s+\S+/, '')
|
475
|
+
end
|
476
|
+
RbConfig::expand("$(CPP) #$INCFLAGS #$CPPFLAGS #$CFLAGS #{opt} #{CONFTEST_C} #{outfile}",
|
477
|
+
conf)
|
478
|
+
end
|
335
479
|
|
336
|
-
def
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
480
|
+
def libpathflag(libpath=$DEFLIBPATH|$LIBPATH)
|
481
|
+
libpath.map{|x|
|
482
|
+
case x
|
483
|
+
when "$(topdir)", /\A\./
|
484
|
+
LIBPATHFLAG
|
485
|
+
else
|
486
|
+
LIBPATHFLAG+RPATHFLAG
|
487
|
+
end % x.quote
|
488
|
+
}.join
|
489
|
+
end
|
341
490
|
|
342
|
-
def
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
491
|
+
def with_werror(opt, opts = nil)
|
492
|
+
if opts
|
493
|
+
if opts[:werror] and config_string("WERRORFLAG") {|flag| opt = opt ? "#{opt} #{flag}" : flag}
|
494
|
+
(opts = opts.dup).delete(:werror)
|
495
|
+
end
|
496
|
+
yield(opt, opts)
|
347
497
|
else
|
348
|
-
|
349
|
-
end
|
350
|
-
|
351
|
-
end
|
498
|
+
yield(opt)
|
499
|
+
end
|
500
|
+
end
|
352
501
|
|
353
|
-
def try_link0(src, opt="", &b)
|
354
|
-
|
355
|
-
|
502
|
+
def try_link0(src, opt="", *opts, &b) # :nodoc:
|
503
|
+
cmd = link_command("", opt)
|
504
|
+
if $universal
|
505
|
+
require 'tmpdir'
|
506
|
+
Dir.mktmpdir("mkmf_", oldtmpdir = ENV["TMPDIR"]) do |tmpdir|
|
507
|
+
begin
|
508
|
+
ENV["TMPDIR"] = tmpdir
|
509
|
+
try_do(src, cmd, *opts, &b)
|
510
|
+
ensure
|
511
|
+
ENV["TMPDIR"] = oldtmpdir
|
512
|
+
end
|
513
|
+
end
|
514
|
+
else
|
515
|
+
try_do(src, cmd, *opts, &b)
|
516
|
+
end and File.executable?("conftest#{$EXEEXT}")
|
517
|
+
end
|
518
|
+
|
519
|
+
# Returns whether or not the +src+ can be compiled as a C source and linked
|
520
|
+
# with its depending libraries successfully. +opt+ is passed to the linker
|
521
|
+
# as options. Note that +$CFLAGS+ and +$LDFLAGS+ are also passed to the
|
522
|
+
# linker.
|
523
|
+
#
|
524
|
+
# If a block given, it is called with the source before compilation. You can
|
525
|
+
# modify the source in the block.
|
526
|
+
#
|
527
|
+
# [+src+] a String which contains a C source
|
528
|
+
# [+opt+] a String which contains linker options
|
529
|
+
def try_link(src, opt="", *opts, &b)
|
530
|
+
try_link0(src, opt, *opts, &b)
|
531
|
+
ensure
|
532
|
+
MakeMakefile.rm_f "conftest*", "c0x32*"
|
533
|
+
end
|
534
|
+
|
535
|
+
# Returns whether or not the +src+ can be compiled as a C source. +opt+ is
|
536
|
+
# passed to the C compiler as options. Note that +$CFLAGS+ is also passed to
|
537
|
+
# the compiler.
|
538
|
+
#
|
539
|
+
# If a block given, it is called with the source before compilation. You can
|
540
|
+
# modify the source in the block.
|
541
|
+
#
|
542
|
+
# [+src+] a String which contains a C source
|
543
|
+
# [+opt+] a String which contains compiler options
|
544
|
+
def try_compile(src, opt="", *opts, &b)
|
545
|
+
with_werror(opt, *opts) {|_opt, *_opts| try_do(src, cc_command(_opt), *_opts, &b)} and
|
546
|
+
File.file?("conftest.#{$OBJEXT}")
|
547
|
+
ensure
|
548
|
+
MakeMakefile.rm_f "conftest*"
|
549
|
+
end
|
550
|
+
|
551
|
+
# Returns whether or not the +src+ can be preprocessed with the C
|
552
|
+
# preprocessor. +opt+ is passed to the preprocessor as options. Note that
|
553
|
+
# +$CFLAGS+ is also passed to the preprocessor.
|
554
|
+
#
|
555
|
+
# If a block given, it is called with the source before preprocessing. You
|
556
|
+
# can modify the source in the block.
|
557
|
+
#
|
558
|
+
# [+src+] a String which contains a C source
|
559
|
+
# [+opt+] a String which contains preprocessor options
|
560
|
+
def try_cpp(src, opt="", *opts, &b)
|
561
|
+
try_do(src, cpp_command(CPPOUTFILE, opt), *opts, &b) and
|
562
|
+
File.file?("conftest.i")
|
563
|
+
ensure
|
564
|
+
MakeMakefile.rm_f "conftest*"
|
565
|
+
end
|
356
566
|
|
357
|
-
|
358
|
-
try_link0(src, opt, &b)
|
359
|
-
ensure
|
360
|
-
rm_f "conftest*", "c0x32*"
|
361
|
-
end
|
567
|
+
alias_method :try_header, (config_string('try_header') || :try_cpp)
|
362
568
|
|
363
|
-
def
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
569
|
+
def cpp_include(header)
|
570
|
+
if header
|
571
|
+
header = [header] unless header.kind_of? Array
|
572
|
+
header.map {|h| String === h ? "#include <#{h}>\n" : h}.join
|
573
|
+
else
|
574
|
+
""
|
575
|
+
end
|
576
|
+
end
|
368
577
|
|
369
|
-
def
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
578
|
+
def with_cppflags(flags)
|
579
|
+
cppflags = $CPPFLAGS
|
580
|
+
$CPPFLAGS = flags
|
581
|
+
ret = yield
|
582
|
+
ensure
|
583
|
+
$CPPFLAGS = cppflags unless ret
|
584
|
+
end
|
374
585
|
|
375
|
-
def
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
else
|
380
|
-
""
|
586
|
+
def try_cppflags(flags)
|
587
|
+
with_cppflags(flags) do
|
588
|
+
try_header("int main() {return 0;}")
|
589
|
+
end
|
381
590
|
end
|
382
|
-
end
|
383
591
|
|
384
|
-
def
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
ensure
|
389
|
-
|
390
|
-
end
|
592
|
+
def with_cflags(flags)
|
593
|
+
cflags = $CFLAGS
|
594
|
+
$CFLAGS = flags
|
595
|
+
ret = yield
|
596
|
+
ensure
|
597
|
+
$CFLAGS = cflags unless ret
|
598
|
+
end
|
391
599
|
|
392
|
-
def
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
$CFLAGS = cflags unless ret
|
398
|
-
end
|
600
|
+
def try_cflags(flags)
|
601
|
+
with_cflags(flags) do
|
602
|
+
try_compile("int main() {return 0;}")
|
603
|
+
end
|
604
|
+
end
|
399
605
|
|
400
|
-
def with_ldflags(flags)
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
ensure
|
405
|
-
|
406
|
-
end
|
606
|
+
def with_ldflags(flags)
|
607
|
+
ldflags = $LDFLAGS
|
608
|
+
$LDFLAGS = flags
|
609
|
+
ret = yield
|
610
|
+
ensure
|
611
|
+
$LDFLAGS = ldflags unless ret
|
612
|
+
end
|
407
613
|
|
408
|
-
def
|
409
|
-
|
410
|
-
|
411
|
-
|
614
|
+
def try_ldflags(flags)
|
615
|
+
with_ldflags(flags) do
|
616
|
+
try_link("int main() {return 0;}")
|
617
|
+
end
|
618
|
+
end
|
619
|
+
|
620
|
+
def try_static_assert(expr, headers = nil, opt = "", &b)
|
621
|
+
headers = cpp_include(headers)
|
622
|
+
try_compile(<<SRC, opt, &b)
|
412
623
|
#{headers}
|
413
624
|
/*top*/
|
414
625
|
int conftest_const[(#{expr}) ? 1 : -1];
|
415
626
|
SRC
|
416
|
-
end
|
627
|
+
end
|
417
628
|
|
418
|
-
def try_constant(const, headers = nil, opt = "", &b)
|
419
|
-
|
420
|
-
|
421
|
-
if
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
else
|
429
|
-
# not a constant
|
430
|
-
return nil
|
431
|
-
end
|
432
|
-
upper = 1
|
433
|
-
lower = 0
|
434
|
-
until try_static_assert("#{const} <= #{upper}", headers, opt)
|
435
|
-
lower = upper
|
436
|
-
upper <<= 1
|
437
|
-
end
|
438
|
-
return nil unless lower
|
439
|
-
while upper > lower + 1
|
440
|
-
mid = (upper + lower) / 2
|
441
|
-
if try_static_assert("#{const} > #{mid}", headers, opt)
|
442
|
-
lower = mid
|
629
|
+
def try_constant(const, headers = nil, opt = "", &b)
|
630
|
+
includes = cpp_include(headers)
|
631
|
+
neg = try_static_assert("#{const} < 0", headers, opt)
|
632
|
+
if CROSS_COMPILING
|
633
|
+
if neg
|
634
|
+
const = "-(#{const})"
|
635
|
+
elsif try_static_assert("#{const} > 0", headers, opt)
|
636
|
+
# positive constant
|
637
|
+
elsif try_static_assert("#{const} == 0", headers, opt)
|
638
|
+
return 0
|
443
639
|
else
|
444
|
-
|
640
|
+
# not a constant
|
641
|
+
return nil
|
445
642
|
end
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
643
|
+
upper = 1
|
644
|
+
lower = 0
|
645
|
+
until try_static_assert("#{const} <= #{upper}", headers, opt)
|
646
|
+
lower = upper
|
647
|
+
upper <<= 1
|
648
|
+
end
|
649
|
+
return nil unless lower
|
650
|
+
while upper > lower + 1
|
651
|
+
mid = (upper + lower) / 2
|
652
|
+
if try_static_assert("#{const} > #{mid}", headers, opt)
|
653
|
+
lower = mid
|
654
|
+
else
|
655
|
+
upper = mid
|
656
|
+
end
|
657
|
+
end
|
658
|
+
upper = -upper if neg
|
659
|
+
return upper
|
660
|
+
else
|
661
|
+
src = %{#{includes}
|
452
662
|
#include <stdio.h>
|
453
663
|
/*top*/
|
454
|
-
|
455
|
-
|
664
|
+
typedef#{neg ? '' : ' unsigned'}
|
665
|
+
#ifdef PRI_LL_PREFIX
|
666
|
+
#define PRI_CONFTEST_PREFIX PRI_LL_PREFIX
|
667
|
+
LONG_LONG
|
668
|
+
#else
|
669
|
+
#define PRI_CONFTEST_PREFIX "l"
|
670
|
+
long
|
671
|
+
#endif
|
672
|
+
conftest_type;
|
673
|
+
conftest_type conftest_const = (conftest_type)(#{const});
|
674
|
+
int main() {printf("%"PRI_CONFTEST_PREFIX"#{neg ? 'd' : 'u'}\\n", conftest_const); return 0;}
|
456
675
|
}
|
457
|
-
|
458
|
-
|
459
|
-
|
676
|
+
begin
|
677
|
+
if try_link0(src, opt, &b)
|
678
|
+
xpopen("./conftest") do |f|
|
679
|
+
return Integer(f.gets)
|
680
|
+
end
|
681
|
+
end
|
682
|
+
ensure
|
683
|
+
MakeMakefile.rm_f "conftest*"
|
460
684
|
end
|
461
685
|
end
|
686
|
+
nil
|
462
687
|
end
|
463
|
-
nil
|
464
|
-
end
|
465
688
|
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
#
|
689
|
+
# You should use +have_func+ rather than +try_func+.
|
690
|
+
#
|
691
|
+
# [+func+] a String which contains a symbol name
|
692
|
+
# [+libs+] a String which contains library names.
|
693
|
+
# [+headers+] a String or an Array of strings which contains names of header
|
694
|
+
# files.
|
695
|
+
def try_func(func, libs, headers = nil, opt = "", &b)
|
696
|
+
headers = cpp_include(headers)
|
697
|
+
case func
|
698
|
+
when /^&/
|
699
|
+
decltype = proc {|x|"const volatile void *#{x}"}
|
700
|
+
when /\)$/
|
701
|
+
call = func
|
702
|
+
else
|
703
|
+
call = "#{func}()"
|
704
|
+
decltype = proc {|x| "void ((*#{x})())"}
|
705
|
+
end
|
706
|
+
if opt and !opt.empty?
|
707
|
+
[[:to_str], [:join, " "], [:to_s]].each do |meth, *args|
|
708
|
+
if opt.respond_to?(meth)
|
709
|
+
break opt = opt.send(meth, *args)
|
710
|
+
end
|
711
|
+
end
|
712
|
+
opt = "#{opt} #{libs}"
|
713
|
+
else
|
714
|
+
opt = libs
|
715
|
+
end
|
716
|
+
decltype && try_link(<<"SRC", opt, &b) or
|
470
717
|
#{headers}
|
471
718
|
/*top*/
|
472
|
-
int
|
473
|
-
int t() {
|
719
|
+
extern int t(void);
|
720
|
+
int t(void) { #{decltype["volatile p"]}; p = (#{decltype[]})#{func}; return 0; }
|
721
|
+
#{MAIN_DOES_NOTHING "t"}
|
474
722
|
SRC
|
723
|
+
call && try_link(<<"SRC", opt, &b)
|
475
724
|
#{headers}
|
476
725
|
/*top*/
|
477
|
-
int
|
478
|
-
int t() { #{
|
726
|
+
extern int t(void);
|
727
|
+
int t(void) { #{call}; return 0; }
|
728
|
+
#{MAIN_DOES_NOTHING "t"}
|
479
729
|
SRC
|
480
|
-
end
|
730
|
+
end
|
481
731
|
|
482
|
-
|
483
|
-
headers =
|
484
|
-
|
485
|
-
|
732
|
+
# You should use +have_var+ rather than +try_var+.
|
733
|
+
def try_var(var, headers = nil, opt = "", &b)
|
734
|
+
headers = cpp_include(headers)
|
735
|
+
try_compile(<<"SRC", opt, &b)
|
486
736
|
#{headers}
|
487
737
|
/*top*/
|
488
|
-
int
|
489
|
-
int t() { const volatile void *volatile p; p = &(&#{var})[0]; return 0; }
|
738
|
+
extern int t(void);
|
739
|
+
int t(void) { const volatile void *volatile p; p = &(&#{var})[0]; return 0; }
|
740
|
+
#{MAIN_DOES_NOTHING "t"}
|
490
741
|
SRC
|
491
|
-
end
|
742
|
+
end
|
492
743
|
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
744
|
+
# Returns whether or not the +src+ can be preprocessed with the C
|
745
|
+
# preprocessor and matches with +pat+.
|
746
|
+
#
|
747
|
+
# If a block given, it is called with the source before compilation. You can
|
748
|
+
# modify the source in the block.
|
749
|
+
#
|
750
|
+
# [+pat+] a Regexp or a String
|
751
|
+
# [+src+] a String which contains a C source
|
752
|
+
# [+opt+] a String which contains preprocessor options
|
753
|
+
#
|
754
|
+
# NOTE: When pat is a Regexp the matching will be checked in process,
|
755
|
+
# otherwise egrep(1) will be invoked to check it.
|
756
|
+
def egrep_cpp(pat, src, opt = "", &b)
|
757
|
+
src = create_tmpsrc(src, &b)
|
758
|
+
xpopen(cpp_command('', opt)) do |f|
|
759
|
+
if Regexp === pat
|
760
|
+
puts(" ruby -ne 'print if #{pat.inspect}'")
|
761
|
+
f.grep(pat) {|l|
|
762
|
+
puts "#{f.lineno}: #{l}"
|
763
|
+
return true
|
764
|
+
}
|
765
|
+
false
|
766
|
+
else
|
767
|
+
puts(" egrep '#{pat}'")
|
768
|
+
begin
|
769
|
+
stdin = $stdin.dup
|
770
|
+
$stdin.reopen(f)
|
771
|
+
system("egrep", pat)
|
772
|
+
ensure
|
773
|
+
$stdin.reopen(stdin)
|
774
|
+
end
|
511
775
|
end
|
512
776
|
end
|
777
|
+
ensure
|
778
|
+
MakeMakefile.rm_f "conftest*"
|
779
|
+
log_src(src)
|
513
780
|
end
|
514
|
-
ensure
|
515
|
-
rm_f "conftest*"
|
516
|
-
log_src(src)
|
517
|
-
end
|
518
781
|
|
519
|
-
# This is used internally by the have_macro? method.
|
520
|
-
def macro_defined?(macro, src, opt = "", &b)
|
521
|
-
|
522
|
-
|
782
|
+
# This is used internally by the have_macro? method.
|
783
|
+
def macro_defined?(macro, src, opt = "", &b)
|
784
|
+
src = src.sub(/[^\n]\z/, "\\&\n")
|
785
|
+
try_compile(src + <<"SRC", opt, &b)
|
523
786
|
/*top*/
|
524
787
|
#ifndef #{macro}
|
525
788
|
# error
|
526
|
-
|
789
|
+
|:/ === #{macro} undefined === /:|
|
527
790
|
#endif
|
528
791
|
SRC
|
529
|
-
end
|
530
|
-
|
531
|
-
def try_run(src, opt = "", &b)
|
532
|
-
if try_link0(src, opt, &b)
|
533
|
-
xsystem("./conftest")
|
534
|
-
else
|
535
|
-
nil
|
536
792
|
end
|
537
|
-
ensure
|
538
|
-
rm_f "conftest*"
|
539
|
-
end
|
540
793
|
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
794
|
+
# Returns whether or not:
|
795
|
+
# * the +src+ can be compiled as a C source,
|
796
|
+
# * the result object can be linked with its depending libraries
|
797
|
+
# successfully,
|
798
|
+
# * the linked file can be invoked as an executable
|
799
|
+
# * and the executable exits successfully
|
800
|
+
#
|
801
|
+
# +opt+ is passed to the linker as options. Note that +$CFLAGS+ and
|
802
|
+
# +$LDFLAGS+ are also passed to the linker.
|
803
|
+
#
|
804
|
+
# If a block given, it is called with the source before compilation. You can
|
805
|
+
# modify the source in the block.
|
806
|
+
#
|
807
|
+
# [+src+] a String which contains a C source
|
808
|
+
# [+opt+] a String which contains linker options
|
809
|
+
#
|
810
|
+
# Returns true when the executable exits successfully, false when it fails,
|
811
|
+
# or nil when preprocessing, compilation or link fails.
|
812
|
+
def try_run(src, opt = "", &b)
|
813
|
+
if try_link0(src, opt, &b)
|
814
|
+
xsystem("./conftest")
|
555
815
|
else
|
556
|
-
|
557
|
-
files = File.join(srcdir, files)
|
558
|
-
len = srcdir.size
|
559
|
-
end
|
560
|
-
f = nil
|
561
|
-
Dir.glob(files) do |f|
|
562
|
-
f[0..len] = "" if len
|
563
|
-
case File.basename(f)
|
564
|
-
when *$NONINSTALLFILES
|
565
|
-
next
|
566
|
-
end
|
567
|
-
d = File.dirname(f)
|
568
|
-
d.sub!(prefix, "") if prefix
|
569
|
-
d = (d.empty? || d == ".") ? dir : File.join(dir, d)
|
570
|
-
f = File.join(srcprefix, f) if len
|
571
|
-
path[d] << f
|
816
|
+
nil
|
572
817
|
end
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
818
|
+
ensure
|
819
|
+
MakeMakefile.rm_f "conftest*"
|
820
|
+
end
|
821
|
+
|
822
|
+
def install_files(mfile, ifiles, map = nil, srcprefix = nil)
|
823
|
+
ifiles or return
|
824
|
+
ifiles.empty? and return
|
825
|
+
srcprefix ||= "$(srcdir)/#{srcprefix}".chomp('/')
|
826
|
+
RbConfig::expand(srcdir = srcprefix.dup)
|
827
|
+
dirs = []
|
828
|
+
path = Hash.new {|h, i| h[i] = dirs.push([i])[-1]}
|
829
|
+
ifiles.each do |files, dir, prefix|
|
830
|
+
dir = map_dir(dir, map)
|
831
|
+
prefix &&= %r|\A#{Regexp.quote(prefix)}/?|
|
832
|
+
if /\A\.\// =~ files
|
833
|
+
# install files which are in current working directory.
|
834
|
+
files = files[2..-1]
|
835
|
+
len = nil
|
836
|
+
else
|
837
|
+
# install files which are under the $(srcdir).
|
838
|
+
files = File.join(srcdir, files)
|
839
|
+
len = srcdir.size
|
840
|
+
end
|
841
|
+
f = nil
|
842
|
+
Dir.glob(files) do |fx|
|
843
|
+
f = fx
|
844
|
+
f[0..len] = "" if len
|
845
|
+
case File.basename(f)
|
846
|
+
when *$NONINSTALLFILES
|
847
|
+
next
|
848
|
+
end
|
849
|
+
d = File.dirname(f)
|
850
|
+
d.sub!(prefix, "") if prefix
|
851
|
+
d = (d.empty? || d == ".") ? dir : File.join(dir, d)
|
852
|
+
f = File.join(srcprefix, f) if len
|
853
|
+
path[d] << f
|
854
|
+
end
|
855
|
+
unless len or f
|
856
|
+
d = File.dirname(files)
|
857
|
+
d.sub!(prefix, "") if prefix
|
858
|
+
d = (d.empty? || d == ".") ? dir : File.join(dir, d)
|
859
|
+
path[d] << files
|
860
|
+
end
|
578
861
|
end
|
862
|
+
dirs
|
579
863
|
end
|
580
|
-
dirs
|
581
|
-
end
|
582
864
|
|
583
|
-
def install_rb(mfile, dest, srcdir = nil)
|
584
|
-
|
585
|
-
end
|
865
|
+
def install_rb(mfile, dest, srcdir = nil)
|
866
|
+
install_files(mfile, [["lib/**/*.rb", dest, "lib"]], nil, srcdir)
|
867
|
+
end
|
586
868
|
|
587
|
-
def append_library(libs, lib) # :no-doc:
|
588
|
-
|
589
|
-
end
|
869
|
+
def append_library(libs, lib) # :no-doc:
|
870
|
+
format(LIBARG, lib) + " " + libs
|
871
|
+
end
|
590
872
|
|
591
|
-
def message(*s)
|
592
|
-
|
593
|
-
|
594
|
-
|
873
|
+
def message(*s)
|
874
|
+
unless Logging.quiet and not $VERBOSE
|
875
|
+
printf(*s)
|
876
|
+
$stdout.flush
|
877
|
+
end
|
595
878
|
end
|
596
|
-
end
|
597
879
|
|
598
|
-
# This emits a string to stdout that allows users to see the results of the
|
599
|
-
# various have* and find* methods as they are tested.
|
600
|
-
#
|
601
|
-
# Internal use only.
|
602
|
-
#
|
603
|
-
def checking_for(m, fmt = nil)
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
end
|
880
|
+
# This emits a string to stdout that allows users to see the results of the
|
881
|
+
# various have* and find* methods as they are tested.
|
882
|
+
#
|
883
|
+
# Internal use only.
|
884
|
+
#
|
885
|
+
def checking_for(m, fmt = nil)
|
886
|
+
f = caller[0][/in `([^<].*)'$/, 1] and f << ": " #` for vim #'
|
887
|
+
m = "checking #{/\Acheck/ =~ f ? '' : 'for '}#{m}... "
|
888
|
+
message "%s", m
|
889
|
+
a = r = nil
|
890
|
+
Logging::postpone do
|
891
|
+
r = yield
|
892
|
+
a = (fmt ? "#{fmt % r}" : r ? "yes" : "no") << "\n"
|
893
|
+
"#{f}#{m}-------------------- #{a}\n"
|
894
|
+
end
|
895
|
+
message(a)
|
896
|
+
Logging::message "--------------------\n\n"
|
897
|
+
r
|
898
|
+
end
|
617
899
|
|
618
|
-
def checking_message(target, place = nil, opt = nil)
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
900
|
+
def checking_message(target, place = nil, opt = nil)
|
901
|
+
[["in", place], ["with", opt]].inject("#{target}") do |msg, (pre, noun)|
|
902
|
+
if noun
|
903
|
+
[[:to_str], [:join, ","], [:to_s]].each do |meth, *args|
|
904
|
+
if noun.respond_to?(meth)
|
905
|
+
break noun = noun.send(meth, *args)
|
906
|
+
end
|
624
907
|
end
|
908
|
+
msg << " #{pre} #{noun}" unless noun.empty?
|
625
909
|
end
|
626
|
-
msg
|
910
|
+
msg
|
627
911
|
end
|
628
|
-
msg
|
629
912
|
end
|
630
|
-
end
|
631
913
|
|
632
|
-
# :startdoc:
|
914
|
+
# :startdoc:
|
633
915
|
|
634
|
-
# Returns whether or not +macro+ is defined either in the common header
|
635
|
-
# files or within any +headers+ you provide.
|
636
|
-
#
|
637
|
-
# Any options you pass to +opt+ are passed along to the compiler.
|
638
|
-
#
|
639
|
-
def have_macro(macro, headers = nil, opt = "", &b)
|
640
|
-
|
641
|
-
|
916
|
+
# Returns whether or not +macro+ is defined either in the common header
|
917
|
+
# files or within any +headers+ you provide.
|
918
|
+
#
|
919
|
+
# Any options you pass to +opt+ are passed along to the compiler.
|
920
|
+
#
|
921
|
+
def have_macro(macro, headers = nil, opt = "", &b)
|
922
|
+
checking_for checking_message(macro, headers, opt) do
|
923
|
+
macro_defined?(macro, cpp_include(headers), opt, &b)
|
924
|
+
end
|
642
925
|
end
|
643
|
-
end
|
644
926
|
|
645
|
-
# Returns whether or not the given entry point +func+ can be found within
|
646
|
-
# +lib+. If +func+ is nil
|
647
|
-
# If found, it adds the library to list of libraries to be used
|
648
|
-
# your extension.
|
649
|
-
#
|
650
|
-
# If +headers+ are provided, it will include those header files as the
|
651
|
-
# header files it looks in when searching for +func+.
|
652
|
-
#
|
653
|
-
# The real name of the library to be linked can be altered by
|
654
|
-
#
|
655
|
-
#
|
656
|
-
def have_library(lib, func = nil, headers = nil, &b)
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
true
|
662
|
-
else
|
663
|
-
libs = append_library($libs, lib)
|
664
|
-
if try_func(func, libs, headers, &b)
|
665
|
-
$libs = libs
|
927
|
+
# Returns whether or not the given entry point +func+ can be found within
|
928
|
+
# +lib+. If +func+ is +nil+, the <code>main()</code> entry point is used by
|
929
|
+
# default. If found, it adds the library to list of libraries to be used
|
930
|
+
# when linking your extension.
|
931
|
+
#
|
932
|
+
# If +headers+ are provided, it will include those header files as the
|
933
|
+
# header files it looks in when searching for +func+.
|
934
|
+
#
|
935
|
+
# The real name of the library to be linked can be altered by
|
936
|
+
# <code>--with-FOOlib</code> configuration option.
|
937
|
+
#
|
938
|
+
def have_library(lib, func = nil, headers = nil, opt = "", &b)
|
939
|
+
func = "main" if !func or func.empty?
|
940
|
+
lib = with_config(lib+'lib', lib)
|
941
|
+
checking_for checking_message(func.funcall_style, LIBARG%lib, opt) do
|
942
|
+
if COMMON_LIBS.include?(lib)
|
666
943
|
true
|
667
944
|
else
|
668
|
-
|
945
|
+
libs = append_library($libs, lib)
|
946
|
+
if try_func(func, libs, headers, opt, &b)
|
947
|
+
$libs = libs
|
948
|
+
true
|
949
|
+
else
|
950
|
+
false
|
951
|
+
end
|
669
952
|
end
|
670
953
|
end
|
671
954
|
end
|
672
|
-
end
|
673
955
|
|
674
|
-
# Returns whether or not the entry point +func+ can be found within the
|
675
|
-
# +lib+ in one of the +paths+ specified, where +paths+ is an array
|
676
|
-
# If +func+ is nil , then the main() function is
|
677
|
-
#
|
678
|
-
#
|
679
|
-
#
|
680
|
-
#
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
956
|
+
# Returns whether or not the entry point +func+ can be found within the
|
957
|
+
# library +lib+ in one of the +paths+ specified, where +paths+ is an array
|
958
|
+
# of strings. If +func+ is +nil+ , then the <code>main()</code> function is
|
959
|
+
# used as the entry point.
|
960
|
+
#
|
961
|
+
# If +lib+ is found, then the path it was found on is added to the list of
|
962
|
+
# library paths searched and linked against.
|
963
|
+
#
|
964
|
+
def find_library(lib, func, *paths, &b)
|
965
|
+
func = "main" if !func or func.empty?
|
966
|
+
lib = with_config(lib+'lib', lib)
|
967
|
+
paths = paths.collect {|path| path.split(File::PATH_SEPARATOR)}.flatten
|
968
|
+
checking_for checking_message(func.funcall_style, LIBARG%lib) do
|
969
|
+
libpath = $LIBPATH
|
970
|
+
libs = append_library($libs, lib)
|
971
|
+
begin
|
972
|
+
until r = try_func(func, libs, &b) or paths.empty?
|
973
|
+
$LIBPATH = libpath | [paths.shift]
|
974
|
+
end
|
975
|
+
if r
|
976
|
+
$libs = libs
|
977
|
+
libpath = nil
|
978
|
+
end
|
979
|
+
ensure
|
980
|
+
$LIBPATH = libpath if libpath
|
691
981
|
end
|
692
|
-
|
693
|
-
|
694
|
-
|
982
|
+
r
|
983
|
+
end
|
984
|
+
end
|
985
|
+
|
986
|
+
# Returns whether or not the function +func+ can be found in the common
|
987
|
+
# header files, or within any +headers+ that you provide. If found, a macro
|
988
|
+
# is passed as a preprocessor constant to the compiler using the function
|
989
|
+
# name, in uppercase, prepended with +HAVE_+.
|
990
|
+
#
|
991
|
+
# To check functions in an additional library, you need to check that
|
992
|
+
# library first using <code>have_library()</code>. The +func+ shall be
|
993
|
+
# either mere function name or function name with arguments.
|
994
|
+
#
|
995
|
+
# For example, if <code>have_func('foo')</code> returned +true+, then the
|
996
|
+
# +HAVE_FOO+ preprocessor macro would be passed to the compiler.
|
997
|
+
#
|
998
|
+
def have_func(func, headers = nil, opt = "", &b)
|
999
|
+
checking_for checking_message(func.funcall_style, headers, opt) do
|
1000
|
+
if try_func(func, $libs, headers, opt, &b)
|
1001
|
+
$defs << "-DHAVE_#{func.sans_arguments.tr_cpp}"
|
1002
|
+
true
|
1003
|
+
else
|
1004
|
+
false
|
695
1005
|
end
|
696
|
-
ensure
|
697
|
-
$LIBPATH = libpath if libpath
|
698
1006
|
end
|
699
|
-
r
|
700
1007
|
end
|
701
|
-
end
|
702
1008
|
|
703
|
-
# Returns whether or not the
|
704
|
-
# header files, or within any +headers+ that you provide. If found, a
|
705
|
-
#
|
706
|
-
#
|
707
|
-
#
|
708
|
-
#
|
709
|
-
#
|
710
|
-
#
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
1009
|
+
# Returns whether or not the variable +var+ can be found in the common
|
1010
|
+
# header files, or within any +headers+ that you provide. If found, a macro
|
1011
|
+
# is passed as a preprocessor constant to the compiler using the variable
|
1012
|
+
# name, in uppercase, prepended with +HAVE_+.
|
1013
|
+
#
|
1014
|
+
# To check variables in an additional library, you need to check that
|
1015
|
+
# library first using <code>have_library()</code>.
|
1016
|
+
#
|
1017
|
+
# For example, if <code>have_var('foo')</code> returned true, then the
|
1018
|
+
# +HAVE_FOO+ preprocessor macro would be passed to the compiler.
|
1019
|
+
#
|
1020
|
+
def have_var(var, headers = nil, opt = "", &b)
|
1021
|
+
checking_for checking_message(var, headers, opt) do
|
1022
|
+
if try_var(var, headers, opt, &b)
|
1023
|
+
$defs.push(format("-DHAVE_%s", var.tr_cpp))
|
1024
|
+
true
|
1025
|
+
else
|
1026
|
+
false
|
1027
|
+
end
|
718
1028
|
end
|
719
1029
|
end
|
720
|
-
end
|
721
1030
|
|
722
|
-
# Returns whether or not the
|
723
|
-
#
|
724
|
-
#
|
725
|
-
#
|
726
|
-
#
|
727
|
-
#
|
728
|
-
#
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
1031
|
+
# Returns whether or not the given +header+ file can be found on your system.
|
1032
|
+
# If found, a macro is passed as a preprocessor constant to the compiler
|
1033
|
+
# using the header file name, in uppercase, prepended with +HAVE_+.
|
1034
|
+
#
|
1035
|
+
# For example, if <code>have_header('foo.h')</code> returned true, then the
|
1036
|
+
# +HAVE_FOO_H+ preprocessor macro would be passed to the compiler.
|
1037
|
+
#
|
1038
|
+
def have_header(header, preheaders = nil, opt = "", &b)
|
1039
|
+
checking_for header do
|
1040
|
+
if try_header(cpp_include(preheaders)+cpp_include(header), opt, &b)
|
1041
|
+
$defs.push(format("-DHAVE_%s", header.tr_cpp))
|
1042
|
+
true
|
1043
|
+
else
|
1044
|
+
false
|
1045
|
+
end
|
737
1046
|
end
|
738
1047
|
end
|
739
|
-
end
|
740
1048
|
|
741
|
-
# Returns whether or not the given +
|
742
|
-
# If found, a macro is passed as a preprocessor constant to the compiler
|
743
|
-
# the
|
744
|
-
#
|
745
|
-
# For example, if
|
746
|
-
# preprocessor macro would be passed to the
|
747
|
-
#
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
1049
|
+
# Returns whether or not the given +framework+ can be found on your system.
|
1050
|
+
# If found, a macro is passed as a preprocessor constant to the compiler
|
1051
|
+
# using the framework name, in uppercase, prepended with +HAVE_FRAMEWORK_+.
|
1052
|
+
#
|
1053
|
+
# For example, if <code>have_framework('Ruby')</code> returned true, then
|
1054
|
+
# the +HAVE_FRAMEWORK_RUBY+ preprocessor macro would be passed to the
|
1055
|
+
# compiler.
|
1056
|
+
#
|
1057
|
+
def have_framework(fw, &b)
|
1058
|
+
checking_for fw do
|
1059
|
+
src = cpp_include("#{fw}/#{fw}.h") << "\n" "int main(void){return 0;}"
|
1060
|
+
opt = " -framework #{fw}"
|
1061
|
+
if try_link(src, "-ObjC#{opt}", &b)
|
1062
|
+
$defs.push(format("-DHAVE_FRAMEWORK_%s", fw.tr_cpp))
|
1063
|
+
# TODO: non-worse way than this hack, to get rid of separating
|
1064
|
+
# option and its argument.
|
1065
|
+
$LDFLAGS << " -ObjC" unless /(\A|\s)-ObjC(\s|\z)/ =~ $LDFLAGS
|
1066
|
+
$LDFLAGS << opt
|
1067
|
+
true
|
1068
|
+
else
|
1069
|
+
false
|
1070
|
+
end
|
755
1071
|
end
|
756
1072
|
end
|
757
|
-
end
|
758
1073
|
|
759
|
-
# Instructs mkmf to search for the given +header+ in any of the +paths+
|
760
|
-
# provided, and returns whether or not it was found in those paths.
|
761
|
-
#
|
762
|
-
# If the header is found then the path it was found on is added to the list
|
763
|
-
# of included directories that are sent to the compiler (via the
|
764
|
-
#
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
1074
|
+
# Instructs mkmf to search for the given +header+ in any of the +paths+
|
1075
|
+
# provided, and returns whether or not it was found in those paths.
|
1076
|
+
#
|
1077
|
+
# If the header is found then the path it was found on is added to the list
|
1078
|
+
# of included directories that are sent to the compiler (via the
|
1079
|
+
# <code>-I</code> switch).
|
1080
|
+
#
|
1081
|
+
def find_header(header, *paths)
|
1082
|
+
message = checking_message(header, paths)
|
1083
|
+
header = cpp_include(header)
|
1084
|
+
checking_for message do
|
1085
|
+
if try_header(header)
|
1086
|
+
true
|
1087
|
+
else
|
1088
|
+
found = false
|
1089
|
+
paths.each do |dir|
|
1090
|
+
opt = "-I#{dir}".quote
|
1091
|
+
if try_header(header, opt)
|
1092
|
+
$INCFLAGS << " " << opt
|
1093
|
+
found = true
|
1094
|
+
break
|
1095
|
+
end
|
779
1096
|
end
|
1097
|
+
found
|
780
1098
|
end
|
781
|
-
found
|
782
1099
|
end
|
783
1100
|
end
|
784
|
-
end
|
785
1101
|
|
786
|
-
# Returns whether or not the struct of type +type+ contains +member+. If
|
787
|
-
# it does not, or the struct type can't be found, then false is returned.
|
788
|
-
# may optionally specify additional +headers+ in which to look for the
|
789
|
-
# (in addition to the common header files).
|
790
|
-
#
|
791
|
-
# If found, a macro is passed as a preprocessor constant to the compiler
|
792
|
-
# the member name, in uppercase, prepended with
|
793
|
-
#
|
794
|
-
#
|
795
|
-
#
|
796
|
-
#
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
#
|
1102
|
+
# Returns whether or not the struct of type +type+ contains +member+. If
|
1103
|
+
# it does not, or the struct type can't be found, then false is returned.
|
1104
|
+
# You may optionally specify additional +headers+ in which to look for the
|
1105
|
+
# struct (in addition to the common header files).
|
1106
|
+
#
|
1107
|
+
# If found, a macro is passed as a preprocessor constant to the compiler
|
1108
|
+
# using the type name and the member name, in uppercase, prepended with
|
1109
|
+
# +HAVE_+.
|
1110
|
+
#
|
1111
|
+
# For example, if <code>have_struct_member('struct foo', 'bar')</code>
|
1112
|
+
# returned true, then the +HAVE_STRUCT_FOO_BAR+ preprocessor macro would be
|
1113
|
+
# passed to the compiler.
|
1114
|
+
#
|
1115
|
+
# +HAVE_ST_BAR+ is also defined for backward compatibility.
|
1116
|
+
#
|
1117
|
+
def have_struct_member(type, member, headers = nil, opt = "", &b)
|
1118
|
+
checking_for checking_message("#{type}.#{member}", headers) do
|
1119
|
+
if try_compile(<<"SRC", opt, &b)
|
801
1120
|
#{cpp_include(headers)}
|
802
1121
|
/*top*/
|
803
|
-
int main() { return 0; }
|
804
1122
|
int s = (char *)&((#{type}*)0)->#{member} - (char *)0;
|
1123
|
+
#{MAIN_DOES_NOTHING "s"}
|
805
1124
|
SRC
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
1125
|
+
$defs.push(format("-DHAVE_%s_%s", type.tr_cpp, member.tr_cpp))
|
1126
|
+
$defs.push(format("-DHAVE_ST_%s", member.tr_cpp)) # backward compatibility
|
1127
|
+
true
|
1128
|
+
else
|
1129
|
+
false
|
1130
|
+
end
|
810
1131
|
end
|
811
1132
|
end
|
812
|
-
end
|
813
1133
|
|
814
|
-
|
815
|
-
|
816
|
-
#
|
1134
|
+
# Returns whether or not the static type +type+ is defined.
|
1135
|
+
#
|
1136
|
+
# See also +have_type+
|
1137
|
+
#
|
1138
|
+
def try_type(type, headers = nil, opt = "", &b)
|
1139
|
+
if try_compile(<<"SRC", opt, &b)
|
817
1140
|
#{cpp_include(headers)}
|
818
1141
|
/*top*/
|
819
1142
|
typedef #{type} conftest_type;
|
820
1143
|
int conftestval[sizeof(conftest_type)?1:-1];
|
821
1144
|
SRC
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
1145
|
+
$defs.push(format("-DHAVE_TYPE_%s", type.tr_cpp))
|
1146
|
+
true
|
1147
|
+
else
|
1148
|
+
false
|
1149
|
+
end
|
826
1150
|
end
|
827
|
-
end
|
828
1151
|
|
829
|
-
# Returns whether or not the static type +type+ is defined. You may
|
830
|
-
# optionally pass additional +headers+ to check against in addition to the
|
831
|
-
# common header files.
|
832
|
-
#
|
833
|
-
# You may also pass additional flags to +opt+ which are then passed along to
|
834
|
-
# the compiler.
|
835
|
-
#
|
836
|
-
# If found, a macro is passed as a preprocessor constant to the compiler
|
837
|
-
# the type name, in uppercase, prepended with
|
838
|
-
#
|
839
|
-
# For example, if have_type('foo') returned true, then the
|
840
|
-
# preprocessor macro would be passed to the compiler.
|
841
|
-
#
|
842
|
-
def have_type(type, headers = nil, opt = "", &b)
|
843
|
-
|
844
|
-
|
1152
|
+
# Returns whether or not the static type +type+ is defined. You may
|
1153
|
+
# optionally pass additional +headers+ to check against in addition to the
|
1154
|
+
# common header files.
|
1155
|
+
#
|
1156
|
+
# You may also pass additional flags to +opt+ which are then passed along to
|
1157
|
+
# the compiler.
|
1158
|
+
#
|
1159
|
+
# If found, a macro is passed as a preprocessor constant to the compiler
|
1160
|
+
# using the type name, in uppercase, prepended with +HAVE_TYPE_+.
|
1161
|
+
#
|
1162
|
+
# For example, if <code>have_type('foo')</code> returned true, then the
|
1163
|
+
# +HAVE_TYPE_FOO+ preprocessor macro would be passed to the compiler.
|
1164
|
+
#
|
1165
|
+
def have_type(type, headers = nil, opt = "", &b)
|
1166
|
+
checking_for checking_message(type, headers, opt) do
|
1167
|
+
try_type(type, headers, opt, &b)
|
1168
|
+
end
|
845
1169
|
end
|
846
|
-
end
|
847
1170
|
|
848
|
-
# Returns where the static type +type+ is defined.
|
849
|
-
#
|
850
|
-
# You may also pass additional flags to +opt+ which are then passed along to
|
851
|
-
# the compiler.
|
852
|
-
#
|
853
|
-
# See also +have_type+.
|
854
|
-
#
|
855
|
-
def find_type(type, opt, *headers, &b)
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
|
862
|
-
|
863
|
-
|
1171
|
+
# Returns where the static type +type+ is defined.
|
1172
|
+
#
|
1173
|
+
# You may also pass additional flags to +opt+ which are then passed along to
|
1174
|
+
# the compiler.
|
1175
|
+
#
|
1176
|
+
# See also +have_type+.
|
1177
|
+
#
|
1178
|
+
def find_type(type, opt, *headers, &b)
|
1179
|
+
opt ||= ""
|
1180
|
+
fmt = "not found"
|
1181
|
+
def fmt.%(x)
|
1182
|
+
x ? x.respond_to?(:join) ? x.join(",") : x : self
|
1183
|
+
end
|
1184
|
+
checking_for checking_message(type, nil, opt), fmt do
|
1185
|
+
headers.find do |h|
|
1186
|
+
try_type(type, h, opt, &b)
|
1187
|
+
end
|
864
1188
|
end
|
865
1189
|
end
|
866
|
-
end
|
867
1190
|
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
#
|
1191
|
+
# Returns whether or not the constant +const+ is defined.
|
1192
|
+
#
|
1193
|
+
# See also +have_const+
|
1194
|
+
#
|
1195
|
+
def try_const(const, headers = nil, opt = "", &b)
|
1196
|
+
const, type = *const
|
1197
|
+
if try_compile(<<"SRC", opt, &b)
|
872
1198
|
#{cpp_include(headers)}
|
873
1199
|
/*top*/
|
874
1200
|
typedef #{type || 'int'} conftest_type;
|
875
1201
|
conftest_type conftestval = #{type ? '' : '(int)'}#{const};
|
876
1202
|
SRC
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
|
1203
|
+
$defs.push(format("-DHAVE_CONST_%s", const.tr_cpp))
|
1204
|
+
true
|
1205
|
+
else
|
1206
|
+
false
|
1207
|
+
end
|
881
1208
|
end
|
882
|
-
end
|
883
1209
|
|
884
|
-
# Returns whether or not the constant +const+ is defined. You may
|
885
|
-
# optionally pass the +type+ of +const+ as <code>[const, type]</code>,
|
886
|
-
#
|
887
|
-
#
|
888
|
-
# have_const(%w[PTHREAD_MUTEX_INITIALIZER pthread_mutex_t], "pthread.h")
|
889
|
-
#
|
890
|
-
# You may also pass additional +headers+ to check against in addition
|
891
|
-
#
|
892
|
-
#
|
893
|
-
#
|
894
|
-
# If found, a macro is passed as a preprocessor constant to the compiler
|
895
|
-
# the type name, in uppercase, prepended with
|
896
|
-
#
|
897
|
-
# For example, if have_const('foo') returned true, then the
|
898
|
-
# preprocessor macro would be passed to the compiler.
|
899
|
-
#
|
900
|
-
def have_const(const, headers = nil, opt = "", &b)
|
901
|
-
|
902
|
-
|
1210
|
+
# Returns whether or not the constant +const+ is defined. You may
|
1211
|
+
# optionally pass the +type+ of +const+ as <code>[const, type]</code>,
|
1212
|
+
# such as:
|
1213
|
+
#
|
1214
|
+
# have_const(%w[PTHREAD_MUTEX_INITIALIZER pthread_mutex_t], "pthread.h")
|
1215
|
+
#
|
1216
|
+
# You may also pass additional +headers+ to check against in addition to the
|
1217
|
+
# common header files, and additional flags to +opt+ which are then passed
|
1218
|
+
# along to the compiler.
|
1219
|
+
#
|
1220
|
+
# If found, a macro is passed as a preprocessor constant to the compiler
|
1221
|
+
# using the type name, in uppercase, prepended with +HAVE_CONST_+.
|
1222
|
+
#
|
1223
|
+
# For example, if <code>have_const('foo')</code> returned true, then the
|
1224
|
+
# +HAVE_CONST_FOO+ preprocessor macro would be passed to the compiler.
|
1225
|
+
#
|
1226
|
+
def have_const(const, headers = nil, opt = "", &b)
|
1227
|
+
checking_for checking_message([*const].compact.join(' '), headers, opt) do
|
1228
|
+
try_const(const, headers, opt, &b)
|
1229
|
+
end
|
903
1230
|
end
|
904
|
-
end
|
905
1231
|
|
906
|
-
#
|
907
|
-
|
908
|
-
#
|
909
|
-
# If found, a macro is passed as a preprocessor constant to the compiler using
|
910
|
-
# the type name, in uppercase, prepended with 'SIZEOF_', followed by the type
|
911
|
-
# name, followed by '=X' where 'X' is the actual size.
|
912
|
-
#
|
913
|
-
# For example, if check_sizeof('mystruct') returned 12, then the
|
914
|
-
# SIZEOF_MYSTRUCT=12 preprocessor macro would be passed to the compiler.
|
915
|
-
#
|
916
|
-
def check_sizeof(type, headers = nil, &b)
|
917
|
-
expr = "sizeof(#{type})"
|
918
|
-
fmt = "%d"
|
919
|
-
def fmt.%(x)
|
1232
|
+
# :stopdoc:
|
1233
|
+
STRING_OR_FAILED_FORMAT = "%s"
|
1234
|
+
def STRING_OR_FAILED_FORMAT.%(x) # :nodoc:
|
920
1235
|
x ? super : "failed"
|
921
1236
|
end
|
922
|
-
|
923
|
-
|
924
|
-
|
925
|
-
|
1237
|
+
|
1238
|
+
def typedef_expr(type, headers)
|
1239
|
+
typename, member = type.split('.', 2)
|
1240
|
+
prelude = cpp_include(headers).split(/$/)
|
1241
|
+
prelude << "typedef #{typename} rbcv_typedef_;\n"
|
1242
|
+
return "rbcv_typedef_", member, prelude
|
1243
|
+
end
|
1244
|
+
|
1245
|
+
def try_signedness(type, member, headers = nil, opts = nil)
|
1246
|
+
raise ArgumentError, "don't know how to tell signedness of members" if member
|
1247
|
+
if try_static_assert("(#{type})-1 < 0", headers, opts)
|
1248
|
+
return -1
|
1249
|
+
elsif try_static_assert("(#{type})-1 > 0", headers, opts)
|
1250
|
+
return +1
|
1251
|
+
end
|
1252
|
+
end
|
1253
|
+
|
1254
|
+
# :startdoc:
|
1255
|
+
|
1256
|
+
# Returns the size of the given +type+. You may optionally specify
|
1257
|
+
# additional +headers+ to search in for the +type+.
|
1258
|
+
#
|
1259
|
+
# If found, a macro is passed as a preprocessor constant to the compiler
|
1260
|
+
# using the type name, in uppercase, prepended with +SIZEOF_+, followed by
|
1261
|
+
# the type name, followed by <code>=X</code> where "X" is the actual size.
|
1262
|
+
#
|
1263
|
+
# For example, if <code>check_sizeof('mystruct')</code> returned 12, then
|
1264
|
+
# the <code>SIZEOF_MYSTRUCT=12</code> preprocessor macro would be passed to
|
1265
|
+
# the compiler.
|
1266
|
+
#
|
1267
|
+
def check_sizeof(type, headers = nil, opts = "", &b)
|
1268
|
+
typedef, member, prelude = typedef_expr(type, headers)
|
1269
|
+
prelude << "static #{typedef} *rbcv_ptr_;\n"
|
1270
|
+
prelude = [prelude]
|
1271
|
+
expr = "sizeof((*rbcv_ptr_)#{"." << member if member})"
|
1272
|
+
fmt = STRING_OR_FAILED_FORMAT
|
1273
|
+
checking_for checking_message("size of #{type}", headers), fmt do
|
1274
|
+
if size = try_constant(expr, prelude, opts, &b)
|
1275
|
+
$defs.push(format("-DSIZEOF_%s=%s", type.tr_cpp, size))
|
1276
|
+
size
|
1277
|
+
end
|
1278
|
+
end
|
1279
|
+
end
|
1280
|
+
|
1281
|
+
# Returns the signedness of the given +type+. You may optionally specify
|
1282
|
+
# additional +headers+ to search in for the +type+.
|
1283
|
+
#
|
1284
|
+
# If the +type+ is found and is a numeric type, a macro is passed as a
|
1285
|
+
# preprocessor constant to the compiler using the +type+ name, in uppercase,
|
1286
|
+
# prepended with +SIGNEDNESS_OF_+, followed by the +type+ name, followed by
|
1287
|
+
# <code>=X</code> where "X" is positive integer if the +type+ is unsigned
|
1288
|
+
# and a negative integer if the +type+ is signed.
|
1289
|
+
#
|
1290
|
+
# For example, if +size_t+ is defined as unsigned, then
|
1291
|
+
# <code>check_signedness('size_t')</code> would return +1 and the
|
1292
|
+
# <code>SIGNEDNESS_OF_SIZE_T=+1</code> preprocessor macro would be passed to
|
1293
|
+
# the compiler. The <code>SIGNEDNESS_OF_INT=-1</code> macro would be set
|
1294
|
+
# for <code>check_signedness('int')</code>
|
1295
|
+
#
|
1296
|
+
def check_signedness(type, headers = nil, opts = nil, &b)
|
1297
|
+
typedef, member, prelude = typedef_expr(type, headers)
|
1298
|
+
signed = nil
|
1299
|
+
checking_for("signedness of #{type}", STRING_OR_FAILED_FORMAT) do
|
1300
|
+
signed = try_signedness(typedef, member, [prelude], opts, &b) or next nil
|
1301
|
+
$defs.push("-DSIGNEDNESS_OF_%s=%+d" % [type.tr_cpp, signed])
|
1302
|
+
signed < 0 ? "signed" : "unsigned"
|
1303
|
+
end
|
1304
|
+
signed
|
1305
|
+
end
|
1306
|
+
|
1307
|
+
# Returns the convertible integer type of the given +type+. You may
|
1308
|
+
# optionally specify additional +headers+ to search in for the +type+.
|
1309
|
+
# _convertible_ means actually the same type, or typedef'd from the same
|
1310
|
+
# type.
|
1311
|
+
#
|
1312
|
+
# If the +type+ is a integer type and the _convertible_ type is found,
|
1313
|
+
# the following macros are passed as preprocessor constants to the compiler
|
1314
|
+
# using the +type+ name, in uppercase.
|
1315
|
+
#
|
1316
|
+
# * +TYPEOF_+, followed by the +type+ name, followed by <code>=X</code>
|
1317
|
+
# where "X" is the found _convertible_ type name.
|
1318
|
+
# * +TYP2NUM+ and +NUM2TYP+,
|
1319
|
+
# where +TYP+ is the +type+ name in uppercase with replacing an +_t+
|
1320
|
+
# suffix with "T", followed by <code>=X</code> where "X" is the macro name
|
1321
|
+
# to convert +type+ to an Integer object, and vice versa.
|
1322
|
+
#
|
1323
|
+
# For example, if +foobar_t+ is defined as unsigned long, then
|
1324
|
+
# <code>convertible_int("foobar_t")</code> would return "unsigned long", and
|
1325
|
+
# define these macros:
|
1326
|
+
#
|
1327
|
+
# #define TYPEOF_FOOBAR_T unsigned long
|
1328
|
+
# #define FOOBART2NUM ULONG2NUM
|
1329
|
+
# #define NUM2FOOBART NUM2ULONG
|
1330
|
+
#
|
1331
|
+
def convertible_int(type, headers = nil, opts = nil, &b)
|
1332
|
+
type, macname = *type
|
1333
|
+
checking_for("convertible type of #{type}", STRING_OR_FAILED_FORMAT) do
|
1334
|
+
if UNIVERSAL_INTS.include?(type)
|
1335
|
+
type
|
1336
|
+
else
|
1337
|
+
typedef, member, prelude = typedef_expr(type, headers, &b)
|
1338
|
+
if member
|
1339
|
+
prelude << "static rbcv_typedef_ rbcv_var;"
|
1340
|
+
compat = UNIVERSAL_INTS.find {|t|
|
1341
|
+
try_static_assert("sizeof(rbcv_var.#{member}) == sizeof(#{t})", [prelude], opts, &b)
|
1342
|
+
}
|
1343
|
+
else
|
1344
|
+
next unless signed = try_signedness(typedef, member, [prelude])
|
1345
|
+
u = "unsigned " if signed > 0
|
1346
|
+
prelude << "extern rbcv_typedef_ foo();"
|
1347
|
+
compat = UNIVERSAL_INTS.find {|t|
|
1348
|
+
try_compile([prelude, "extern #{u}#{t} foo();"].join("\n"), opts, :werror=>true, &b)
|
1349
|
+
}
|
1350
|
+
end
|
1351
|
+
if compat
|
1352
|
+
macname ||= type.sub(/_(?=t\z)/, '').tr_cpp
|
1353
|
+
conv = (compat == "long long" ? "LL" : compat.upcase)
|
1354
|
+
compat = "#{u}#{compat}"
|
1355
|
+
typename = type.tr_cpp
|
1356
|
+
$defs.push(format("-DSIZEOF_%s=SIZEOF_%s", typename, compat.tr_cpp))
|
1357
|
+
$defs.push(format("-DTYPEOF_%s=%s", typename, compat.quote))
|
1358
|
+
$defs.push(format("-DPRI_%s_PREFIX=PRI_%s_PREFIX", macname, conv))
|
1359
|
+
conv = (u ? "U" : "") + conv
|
1360
|
+
$defs.push(format("-D%s2NUM=%s2NUM", macname, conv))
|
1361
|
+
$defs.push(format("-DNUM2%s=NUM2%s", macname, conv))
|
1362
|
+
compat
|
1363
|
+
end
|
1364
|
+
end
|
1365
|
+
end
|
1366
|
+
end
|
1367
|
+
# :stopdoc:
|
1368
|
+
|
1369
|
+
# Used internally by the what_type? method to determine if +type+ is a scalar
|
1370
|
+
# pointer.
|
1371
|
+
def scalar_ptr_type?(type, member = nil, headers = nil, &b)
|
1372
|
+
try_compile(<<"SRC", &b) # pointer
|
1373
|
+
#{cpp_include(headers)}
|
1374
|
+
/*top*/
|
1375
|
+
volatile #{type} conftestval;
|
1376
|
+
extern int t(void);
|
1377
|
+
int t(void) {return (int)(1-*(conftestval#{member ? ".#{member}" : ""}));}
|
1378
|
+
#{MAIN_DOES_NOTHING "t"}
|
1379
|
+
SRC
|
1380
|
+
end
|
1381
|
+
|
1382
|
+
# Used internally by the what_type? method to determine if +type+ is a scalar
|
1383
|
+
# pointer.
|
1384
|
+
def scalar_type?(type, member = nil, headers = nil, &b)
|
1385
|
+
try_compile(<<"SRC", &b) # pointer
|
1386
|
+
#{cpp_include(headers)}
|
1387
|
+
/*top*/
|
1388
|
+
volatile #{type} conftestval;
|
1389
|
+
extern int t(void);
|
1390
|
+
int t(void) {return (int)(1-(conftestval#{member ? ".#{member}" : ""}));}
|
1391
|
+
#{MAIN_DOES_NOTHING "t"}
|
1392
|
+
SRC
|
1393
|
+
end
|
1394
|
+
|
1395
|
+
# Used internally by the what_type? method to check if the _typeof_ GCC
|
1396
|
+
# extension is available.
|
1397
|
+
def have_typeof?
|
1398
|
+
return $typeof if defined?($typeof)
|
1399
|
+
$typeof = %w[__typeof__ typeof].find do |t|
|
1400
|
+
try_compile(<<SRC)
|
1401
|
+
int rbcv_foo;
|
1402
|
+
#{t}(rbcv_foo) rbcv_bar;
|
1403
|
+
SRC
|
1404
|
+
end
|
1405
|
+
end
|
1406
|
+
|
1407
|
+
def what_type?(type, member = nil, headers = nil, &b)
|
1408
|
+
m = "#{type}"
|
1409
|
+
var = val = "*rbcv_var_"
|
1410
|
+
func = "rbcv_func_(void)"
|
1411
|
+
if member
|
1412
|
+
m << "." << member
|
1413
|
+
else
|
1414
|
+
type, member = type.split('.', 2)
|
1415
|
+
end
|
1416
|
+
if member
|
1417
|
+
val = "(#{var}).#{member}"
|
1418
|
+
end
|
1419
|
+
prelude = [cpp_include(headers).split(/^/)]
|
1420
|
+
prelude << ["typedef #{type} rbcv_typedef_;\n",
|
1421
|
+
"extern rbcv_typedef_ *#{func};\n",
|
1422
|
+
"static rbcv_typedef_ #{var};\n",
|
1423
|
+
]
|
1424
|
+
type = "rbcv_typedef_"
|
1425
|
+
fmt = member && !(typeof = have_typeof?) ? "seems %s" : "%s"
|
1426
|
+
if typeof
|
1427
|
+
var = "*rbcv_member_"
|
1428
|
+
func = "rbcv_mem_func_(void)"
|
1429
|
+
member = nil
|
1430
|
+
type = "rbcv_mem_typedef_"
|
1431
|
+
prelude[-1] << "typedef #{typeof}(#{val}) #{type};\n"
|
1432
|
+
prelude[-1] << "extern #{type} *#{func};\n"
|
1433
|
+
prelude[-1] << "static #{type} #{var};\n"
|
1434
|
+
val = var
|
1435
|
+
end
|
1436
|
+
def fmt.%(x)
|
1437
|
+
x ? super : "unknown"
|
1438
|
+
end
|
1439
|
+
checking_for checking_message(m, headers), fmt do
|
1440
|
+
if scalar_ptr_type?(type, member, prelude, &b)
|
1441
|
+
if try_static_assert("sizeof(*#{var}) == 1", prelude)
|
1442
|
+
return "string"
|
1443
|
+
end
|
1444
|
+
ptr = "*"
|
1445
|
+
elsif scalar_type?(type, member, prelude, &b)
|
1446
|
+
unless member and !typeof or try_static_assert("(#{type})-1 < 0", prelude)
|
1447
|
+
unsigned = "unsigned"
|
1448
|
+
end
|
1449
|
+
ptr = ""
|
1450
|
+
else
|
1451
|
+
next
|
1452
|
+
end
|
1453
|
+
type = UNIVERSAL_INTS.find do |t|
|
1454
|
+
pre = prelude
|
1455
|
+
unless member
|
1456
|
+
pre += [["static #{unsigned} #{t} #{ptr}#{var};\n",
|
1457
|
+
"extern #{unsigned} #{t} #{ptr}*#{func};\n"]]
|
1458
|
+
end
|
1459
|
+
try_static_assert("sizeof(#{ptr}#{val}) == sizeof(#{unsigned} #{t})", pre)
|
1460
|
+
end
|
1461
|
+
type or next
|
1462
|
+
[unsigned, type, ptr].join(" ").strip
|
926
1463
|
end
|
927
1464
|
end
|
928
|
-
end
|
929
|
-
|
930
|
-
# :stopdoc:
|
931
1465
|
|
932
|
-
#
|
933
|
-
#
|
934
|
-
|
935
|
-
|
936
|
-
|
937
|
-
|
938
|
-
|
939
|
-
|
940
|
-
|
941
|
-
|
942
|
-
|
943
|
-
end
|
944
|
-
|
945
|
-
# Used internally by the what_type? method to determine if +type+ is a scalar
|
946
|
-
# pointer.
|
947
|
-
def scalar_type?(type, member = nil, headers = nil, &b)
|
948
|
-
try_compile(<<"SRC", &b) # pointer
|
949
|
-
#{COMMON_HEADERS}
|
950
|
-
#{cpp_include(headers)}
|
951
|
-
/*top*/
|
952
|
-
volatile #{type} conftestval;
|
953
|
-
int main() { return 0; }
|
954
|
-
int t() {return (int)(1-(conftestval#{member ? ".#{member}" : ""}));}
|
955
|
-
SRC
|
956
|
-
end
|
1466
|
+
# This method is used internally by the find_executable method.
|
1467
|
+
#
|
1468
|
+
# Internal use only.
|
1469
|
+
#
|
1470
|
+
def find_executable0(bin, path = nil)
|
1471
|
+
executable_file = proc do |name|
|
1472
|
+
begin
|
1473
|
+
stat = File.stat(name)
|
1474
|
+
rescue SystemCallError
|
1475
|
+
else
|
1476
|
+
next name if stat.file? and stat.executable?
|
1477
|
+
end
|
1478
|
+
end
|
957
1479
|
|
958
|
-
|
959
|
-
|
960
|
-
|
961
|
-
|
962
|
-
|
963
|
-
name = "(((#{type} *)0)->#{member})"
|
964
|
-
end
|
965
|
-
fmt = "seems %s"
|
966
|
-
def fmt.%(x)
|
967
|
-
x ? super : "unknown"
|
968
|
-
end
|
969
|
-
checking_for checking_message(m, headers), fmt do
|
970
|
-
if scalar_ptr_type?(type, member, headers, &b)
|
971
|
-
if try_static_assert("sizeof(*#{name}) == 1", headers)
|
972
|
-
"string"
|
1480
|
+
exts = config_string('EXECUTABLE_EXTS') {|s| s.split} || config_string('EXEEXT') {|s| [s]}
|
1481
|
+
if File.expand_path(bin) == bin
|
1482
|
+
return bin if executable_file.call(bin)
|
1483
|
+
if exts
|
1484
|
+
exts.each {|ext| executable_file.call(file = bin + ext) and return file}
|
973
1485
|
end
|
974
|
-
|
975
|
-
|
976
|
-
|
977
|
-
|
978
|
-
|
979
|
-
|
980
|
-
|
981
|
-
|
982
|
-
|
983
|
-
|
984
|
-
|
1486
|
+
return nil
|
1487
|
+
end
|
1488
|
+
if path ||= ENV['PATH']
|
1489
|
+
path = path.split(File::PATH_SEPARATOR)
|
1490
|
+
else
|
1491
|
+
path = %w[/usr/local/bin /usr/ucb /usr/bin /bin]
|
1492
|
+
end
|
1493
|
+
file = nil
|
1494
|
+
path.each do |dir|
|
1495
|
+
return file if executable_file.call(file = File.join(dir, bin))
|
1496
|
+
if exts
|
1497
|
+
exts.each {|ext| executable_file.call(ext = file + ext) and return ext}
|
985
1498
|
end
|
986
1499
|
end
|
1500
|
+
nil
|
987
1501
|
end
|
988
|
-
end
|
989
1502
|
|
990
|
-
#
|
991
|
-
|
992
|
-
#
|
993
|
-
#
|
994
|
-
|
995
|
-
|
996
|
-
|
997
|
-
|
998
|
-
|
999
|
-
|
1000
|
-
|
1001
|
-
|
1002
|
-
|
1003
|
-
|
1004
|
-
|
1005
|
-
end
|
1006
|
-
file = nil
|
1007
|
-
path.each do |dir|
|
1008
|
-
return file if File.executable?(file = File.join(dir, bin))
|
1009
|
-
return file if ext and File.executable?(file << ext)
|
1503
|
+
# :startdoc:
|
1504
|
+
|
1505
|
+
# Searches for the executable +bin+ on +path+. The default path is your
|
1506
|
+
# +PATH+ environment variable. If that isn't defined, it will resort to
|
1507
|
+
# searching /usr/local/bin, /usr/ucb, /usr/bin and /bin.
|
1508
|
+
#
|
1509
|
+
# If found, it will return the full path, including the executable name, of
|
1510
|
+
# where it was found.
|
1511
|
+
#
|
1512
|
+
# Note that this method does not actually affect the generated Makefile.
|
1513
|
+
#
|
1514
|
+
def find_executable(bin, path = nil)
|
1515
|
+
checking_for checking_message(bin, path) do
|
1516
|
+
find_executable0(bin, path)
|
1517
|
+
end
|
1010
1518
|
end
|
1011
|
-
nil
|
1012
|
-
end
|
1013
1519
|
|
1014
|
-
# :
|
1520
|
+
# :stopdoc:
|
1015
1521
|
|
1016
|
-
|
1017
|
-
|
1018
|
-
|
1019
|
-
|
1020
|
-
|
1021
|
-
|
1022
|
-
|
1023
|
-
|
1024
|
-
|
1025
|
-
|
1026
|
-
|
1027
|
-
|
1522
|
+
def arg_config(config, default=nil, &block)
|
1523
|
+
$arg_config << [config, default]
|
1524
|
+
defaults = []
|
1525
|
+
if default
|
1526
|
+
defaults << default
|
1527
|
+
elsif !block
|
1528
|
+
defaults << nil
|
1529
|
+
end
|
1530
|
+
$configure_args.fetch(config.tr('_', '-'), *defaults, &block)
|
1531
|
+
end
|
1532
|
+
|
1533
|
+
# :startdoc:
|
1534
|
+
|
1535
|
+
# Tests for the presence of a <tt>--with-</tt>_config_ or
|
1536
|
+
# <tt>--without-</tt>_config_ option. Returns +true+ if the with option is
|
1537
|
+
# given, +false+ if the without option is given, and the default value
|
1538
|
+
# otherwise.
|
1539
|
+
#
|
1540
|
+
# This can be useful for adding custom definitions, such as debug
|
1541
|
+
# information.
|
1542
|
+
#
|
1543
|
+
# Example:
|
1544
|
+
#
|
1545
|
+
# if with_config("debug")
|
1546
|
+
# $defs.push("-DOSSL_DEBUG") unless $defs.include? "-DOSSL_DEBUG"
|
1547
|
+
# end
|
1548
|
+
#
|
1549
|
+
def with_config(config, default=nil)
|
1550
|
+
config = config.sub(/^--with[-_]/, '')
|
1551
|
+
val = arg_config("--with-"+config) do
|
1552
|
+
if arg_config("--without-"+config)
|
1553
|
+
false
|
1554
|
+
elsif block_given?
|
1555
|
+
yield(config, default)
|
1556
|
+
else
|
1557
|
+
break default
|
1558
|
+
end
|
1559
|
+
end
|
1560
|
+
case val
|
1561
|
+
when "yes"
|
1562
|
+
true
|
1563
|
+
when "no"
|
1564
|
+
false
|
1565
|
+
else
|
1566
|
+
val
|
1567
|
+
end
|
1028
1568
|
end
|
1029
|
-
end
|
1030
|
-
|
1031
|
-
# :stopdoc:
|
1032
|
-
|
1033
|
-
def arg_config(config, *defaults, &block)
|
1034
|
-
$arg_config << [config, *defaults]
|
1035
|
-
defaults << nil if !block and defaults.empty?
|
1036
|
-
$configure_args.fetch(config.tr('_', '-'), *defaults, &block)
|
1037
|
-
end
|
1038
|
-
|
1039
|
-
# :startdoc:
|
1040
1569
|
|
1041
|
-
# Tests for the presence of
|
1042
|
-
# option. Returns true if the
|
1043
|
-
# option is given, and the default value
|
1044
|
-
#
|
1045
|
-
#
|
1046
|
-
#
|
1047
|
-
#
|
1048
|
-
#
|
1049
|
-
#
|
1050
|
-
#
|
1051
|
-
#
|
1052
|
-
#
|
1053
|
-
|
1054
|
-
|
1055
|
-
|
1056
|
-
if arg_config("--
|
1570
|
+
# Tests for the presence of an <tt>--enable-</tt>_config_ or
|
1571
|
+
# <tt>--disable-</tt>_config_ option. Returns +true+ if the enable option is
|
1572
|
+
# given, +false+ if the disable option is given, and the default value
|
1573
|
+
# otherwise.
|
1574
|
+
#
|
1575
|
+
# This can be useful for adding custom definitions, such as debug
|
1576
|
+
# information.
|
1577
|
+
#
|
1578
|
+
# Example:
|
1579
|
+
#
|
1580
|
+
# if enable_config("debug")
|
1581
|
+
# $defs.push("-DOSSL_DEBUG") unless $defs.include? "-DOSSL_DEBUG"
|
1582
|
+
# end
|
1583
|
+
#
|
1584
|
+
def enable_config(config, default=nil)
|
1585
|
+
if arg_config("--enable-"+config)
|
1586
|
+
true
|
1587
|
+
elsif arg_config("--disable-"+config)
|
1057
1588
|
false
|
1058
1589
|
elsif block_given?
|
1059
|
-
yield(config,
|
1590
|
+
yield(config, default)
|
1060
1591
|
else
|
1061
|
-
|
1592
|
+
return default
|
1062
1593
|
end
|
1063
1594
|
end
|
1064
|
-
case val
|
1065
|
-
when "yes"
|
1066
|
-
true
|
1067
|
-
when "no"
|
1068
|
-
false
|
1069
|
-
else
|
1070
|
-
val
|
1071
|
-
end
|
1072
|
-
end
|
1073
1595
|
|
1074
|
-
#
|
1075
|
-
#
|
1076
|
-
#
|
1077
|
-
#
|
1078
|
-
#
|
1079
|
-
#
|
1080
|
-
#
|
1081
|
-
#
|
1082
|
-
#
|
1083
|
-
#
|
1084
|
-
#
|
1085
|
-
#
|
1086
|
-
|
1087
|
-
|
1088
|
-
|
1089
|
-
|
1090
|
-
|
1091
|
-
|
1092
|
-
|
1093
|
-
|
1094
|
-
|
1095
|
-
|
1096
|
-
|
1596
|
+
# Generates a header file consisting of the various macro definitions
|
1597
|
+
# generated by other methods such as have_func and have_header. These are
|
1598
|
+
# then wrapped in a custom <code>#ifndef</code> based on the +header+ file
|
1599
|
+
# name, which defaults to "extconf.h".
|
1600
|
+
#
|
1601
|
+
# For example:
|
1602
|
+
#
|
1603
|
+
# # extconf.rb
|
1604
|
+
# require 'mkmf'
|
1605
|
+
# have_func('realpath')
|
1606
|
+
# have_header('sys/utime.h')
|
1607
|
+
# create_header
|
1608
|
+
# create_makefile('foo')
|
1609
|
+
#
|
1610
|
+
# The above script would generate the following extconf.h file:
|
1611
|
+
#
|
1612
|
+
# #ifndef EXTCONF_H
|
1613
|
+
# #define EXTCONF_H
|
1614
|
+
# #define HAVE_REALPATH 1
|
1615
|
+
# #define HAVE_SYS_UTIME_H 1
|
1616
|
+
# #endif
|
1617
|
+
#
|
1618
|
+
# Given that the create_header method generates a file based on definitions
|
1619
|
+
# set earlier in your extconf.rb file, you will probably want to make this
|
1620
|
+
# one of the last methods you call in your script.
|
1621
|
+
#
|
1622
|
+
def create_header(header = "extconf.h")
|
1623
|
+
message "creating %s\n", header
|
1624
|
+
sym = header.tr_cpp
|
1625
|
+
hdr = ["#ifndef #{sym}\n#define #{sym}\n"]
|
1626
|
+
for line in $defs
|
1627
|
+
case line
|
1628
|
+
when /^-D([^=]+)(?:=(.*))?/
|
1629
|
+
hdr << "#define #$1 #{$2 ? Shellwords.shellwords($2)[0].gsub(/(?=\t+)/, "\\\n") : 1}\n"
|
1630
|
+
when /^-U(.*)/
|
1631
|
+
hdr << "#undef #$1\n"
|
1632
|
+
end
|
1633
|
+
end
|
1634
|
+
hdr << "#endif\n"
|
1635
|
+
hdr = hdr.join("")
|
1636
|
+
log_src(hdr, "#{header} is")
|
1637
|
+
unless (IO.read(header) == hdr rescue false)
|
1638
|
+
open(header, "wb") do |hfile|
|
1639
|
+
hfile.write(hdr)
|
1640
|
+
end
|
1641
|
+
end
|
1642
|
+
$extconf_h = header
|
1643
|
+
end
|
1644
|
+
|
1645
|
+
# Sets a +target+ name that the user can then use to configure various
|
1646
|
+
# "with" options with on the command line by using that name. For example,
|
1647
|
+
# if the target is set to "foo", then the user could use the
|
1648
|
+
# <code>--with-foo-dir</code> command line option.
|
1649
|
+
#
|
1650
|
+
# You may pass along additional "include" or "lib" defaults via the
|
1651
|
+
# +idefault+ and +ldefault+ parameters, respectively.
|
1652
|
+
#
|
1653
|
+
# Note that dir_config only adds to the list of places to search for
|
1654
|
+
# libraries and include files. It does not link the libraries into your
|
1655
|
+
# application.
|
1656
|
+
#
|
1657
|
+
def dir_config(target, idefault=nil, ldefault=nil)
|
1658
|
+
if dir = with_config(target + "-dir", (idefault unless ldefault))
|
1659
|
+
defaults = Array === dir ? dir : dir.split(File::PATH_SEPARATOR)
|
1660
|
+
idefault = ldefault = nil
|
1661
|
+
end
|
1097
1662
|
|
1098
|
-
|
1099
|
-
|
1100
|
-
|
1101
|
-
#
|
1102
|
-
#
|
1103
|
-
# For example:
|
1104
|
-
#
|
1105
|
-
# # extconf.rb
|
1106
|
-
# require 'mkmf'
|
1107
|
-
# have_func('realpath')
|
1108
|
-
# have_header('sys/utime.h')
|
1109
|
-
# create_header
|
1110
|
-
# create_makefile('foo')
|
1111
|
-
#
|
1112
|
-
# The above script would generate the following extconf.h file:
|
1113
|
-
#
|
1114
|
-
# #ifndef EXTCONF_H
|
1115
|
-
# #define EXTCONF_H
|
1116
|
-
# #define HAVE_REALPATH 1
|
1117
|
-
# #define HAVE_SYS_UTIME_H 1
|
1118
|
-
# #endif
|
1119
|
-
#
|
1120
|
-
# Given that the create_header method generates a file based on definitions
|
1121
|
-
# set earlier in your extconf.rb file, you will probably want to make this
|
1122
|
-
# one of the last methods you call in your script.
|
1123
|
-
#
|
1124
|
-
def create_header(header = "extconf.h")
|
1125
|
-
message "creating %s\n", header
|
1126
|
-
sym = header.tr("a-z./\055", "A-Z___")
|
1127
|
-
hdr = ["#ifndef #{sym}\n#define #{sym}\n"]
|
1128
|
-
for line in $defs
|
1129
|
-
case line
|
1130
|
-
when /^-D([^=]+)(?:=(.*))?/
|
1131
|
-
hdr << "#define #$1 #{$2 ? Shellwords.shellwords($2)[0] : 1}\n"
|
1132
|
-
when /^-U(.*)/
|
1133
|
-
hdr << "#undef #$1\n"
|
1134
|
-
end
|
1135
|
-
end
|
1136
|
-
hdr << "#endif\n"
|
1137
|
-
hdr = hdr.join
|
1138
|
-
unless (IO.read(header) == hdr rescue false)
|
1139
|
-
open(header, "w") do |hfile|
|
1140
|
-
hfile.write(hdr)
|
1141
|
-
end
|
1142
|
-
end
|
1143
|
-
$extconf_h = header
|
1144
|
-
end
|
1663
|
+
idir = with_config(target + "-include", idefault)
|
1664
|
+
$arg_config.last[1] ||= "${#{target}-dir}/include"
|
1665
|
+
ldir = with_config(target + "-lib", ldefault)
|
1666
|
+
$arg_config.last[1] ||= "${#{target}-dir}/#{@libdir_basename}"
|
1145
1667
|
|
1146
|
-
|
1147
|
-
|
1148
|
-
|
1149
|
-
|
1150
|
-
|
1151
|
-
# You may pass along additional 'include' or 'lib' defaults via the +idefault+
|
1152
|
-
# and +ldefault+ parameters, respectively.
|
1153
|
-
#
|
1154
|
-
# Note that dir_config only adds to the list of places to search for libraries
|
1155
|
-
# and include files. It does not link the libraries into your application.
|
1156
|
-
#
|
1157
|
-
def dir_config(target, idefault=nil, ldefault=nil)
|
1158
|
-
if dir = with_config(target + "-dir", (idefault unless ldefault))
|
1159
|
-
defaults = Array === dir ? dir : dir.split(File::PATH_SEPARATOR)
|
1160
|
-
idefault = ldefault = nil
|
1161
|
-
end
|
1162
|
-
|
1163
|
-
idir = with_config(target + "-include", idefault)
|
1164
|
-
$arg_config.last[1] ||= "${#{target}-dir}/include"
|
1165
|
-
ldir = with_config(target + "-lib", ldefault)
|
1166
|
-
$arg_config.last[1] ||= "${#{target}-dir}/lib"
|
1167
|
-
|
1168
|
-
idirs = idir ? Array === idir ? idir : idir.split(File::PATH_SEPARATOR) : []
|
1169
|
-
if defaults
|
1170
|
-
idirs.concat(defaults.collect {|dir| dir + "/include"})
|
1171
|
-
idir = ([idir] + idirs).compact.join(File::PATH_SEPARATOR)
|
1172
|
-
end
|
1173
|
-
unless idirs.empty?
|
1174
|
-
idirs.collect! {|dir| "-I" + dir}
|
1175
|
-
idirs -= Shellwords.shellwords($CPPFLAGS)
|
1668
|
+
idirs = idir ? Array === idir ? idir.dup : idir.split(File::PATH_SEPARATOR) : []
|
1669
|
+
if defaults
|
1670
|
+
idirs.concat(defaults.collect {|d| d + "/include"})
|
1671
|
+
idir = ([idir] + idirs).compact.join(File::PATH_SEPARATOR)
|
1672
|
+
end
|
1176
1673
|
unless idirs.empty?
|
1177
|
-
|
1674
|
+
idirs.collect! {|d| "-I" + d}
|
1675
|
+
idirs -= Shellwords.shellwords($CPPFLAGS)
|
1676
|
+
unless idirs.empty?
|
1677
|
+
$CPPFLAGS = (idirs.quote << $CPPFLAGS).join(" ")
|
1678
|
+
end
|
1178
1679
|
end
|
1179
|
-
end
|
1180
1680
|
|
1181
|
-
|
1182
|
-
|
1183
|
-
|
1184
|
-
|
1681
|
+
ldirs = ldir ? Array === ldir ? ldir.dup : ldir.split(File::PATH_SEPARATOR) : []
|
1682
|
+
if defaults
|
1683
|
+
ldirs.concat(defaults.collect {|d| "#{d}/#{@libdir_basename}"})
|
1684
|
+
ldir = ([ldir] + ldirs).compact.join(File::PATH_SEPARATOR)
|
1685
|
+
end
|
1686
|
+
$LIBPATH = ldirs | $LIBPATH
|
1687
|
+
|
1688
|
+
[idir, ldir]
|
1689
|
+
end
|
1690
|
+
|
1691
|
+
# :stopdoc:
|
1692
|
+
|
1693
|
+
# Handles meta information about installed libraries. Uses your platform's
|
1694
|
+
# pkg-config program if it has one.
|
1695
|
+
#
|
1696
|
+
# The actual command name can be overridden by
|
1697
|
+
# <code>--with-pkg-config</code> command line option.
|
1698
|
+
def pkg_config(pkg)
|
1699
|
+
if pkgconfig = with_config("#{pkg}-config") and find_executable0(pkgconfig)
|
1700
|
+
# iff package specific config command is given
|
1701
|
+
get = proc {|opt| `#{pkgconfig} --#{opt}`.strip}
|
1702
|
+
elsif ($PKGCONFIG ||=
|
1703
|
+
(pkgconfig = with_config("pkg-config", ("pkg-config" unless CROSS_COMPILING))) &&
|
1704
|
+
find_executable0(pkgconfig) && pkgconfig) and
|
1705
|
+
system("#{$PKGCONFIG} --exists #{pkg}")
|
1706
|
+
# default to pkg-config command
|
1707
|
+
get = proc {|opt| `#{$PKGCONFIG} --#{opt} #{pkg}`.strip}
|
1708
|
+
elsif find_executable0(pkgconfig = "#{pkg}-config")
|
1709
|
+
# default to package specific config command, as a last resort.
|
1710
|
+
get = proc {|opt| `#{pkgconfig} --#{opt}`.strip}
|
1711
|
+
end
|
1712
|
+
orig_ldflags = $LDFLAGS
|
1713
|
+
if get and try_ldflags(ldflags = get['libs'])
|
1714
|
+
cflags = get['cflags']
|
1715
|
+
libs = get['libs-only-l']
|
1716
|
+
ldflags = (Shellwords.shellwords(ldflags) - Shellwords.shellwords(libs)).quote.join(" ")
|
1717
|
+
$CFLAGS += " " << cflags
|
1718
|
+
$LDFLAGS = [orig_ldflags, ldflags].join(' ')
|
1719
|
+
$libs += " " << libs
|
1720
|
+
Logging::message "package configuration for %s\n", pkg
|
1721
|
+
Logging::message "cflags: %s\nldflags: %s\nlibs: %s\n\n",
|
1722
|
+
cflags, ldflags, libs
|
1723
|
+
[cflags, ldflags, libs]
|
1724
|
+
else
|
1725
|
+
Logging::message "package configuration for %s is not found\n", pkg
|
1726
|
+
nil
|
1727
|
+
end
|
1185
1728
|
end
|
1186
|
-
$LIBPATH = ldirs | $LIBPATH
|
1187
|
-
|
1188
|
-
[idir, ldir]
|
1189
|
-
end
|
1190
|
-
|
1191
|
-
# :stopdoc:
|
1192
1729
|
|
1193
|
-
|
1194
|
-
|
1195
|
-
|
1196
|
-
|
1197
|
-
# iff package specific config command is given
|
1198
|
-
get = proc {|opt| `#{pkgconfig} --#{opt}`.chomp}
|
1199
|
-
elsif ($PKGCONFIG ||=
|
1200
|
-
(pkgconfig = with_config("pkg-config", ("pkg-config" unless CROSS_COMPILING))) &&
|
1201
|
-
find_executable0(pkgconfig) && pkgconfig) and
|
1202
|
-
system("#{$PKGCONFIG} --exists #{pkg}")
|
1203
|
-
# default to pkg-config command
|
1204
|
-
get = proc {|opt| `#{$PKGCONFIG} --#{opt} #{pkg}`.chomp}
|
1205
|
-
elsif find_executable0(pkgconfig = "#{pkg}-config")
|
1206
|
-
# default to package specific config command, as a last resort.
|
1207
|
-
get = proc {|opt| `#{pkgconfig} --#{opt}`.chomp}
|
1208
|
-
end
|
1209
|
-
if get
|
1210
|
-
cflags = get['cflags']
|
1211
|
-
ldflags = get['libs']
|
1212
|
-
libs = get['libs-only-l']
|
1213
|
-
ldflags = (Shellwords.shellwords(ldflags) - Shellwords.shellwords(libs)).quote.join(" ")
|
1214
|
-
$CFLAGS += " " << cflags
|
1215
|
-
$LDFLAGS += " " << ldflags
|
1216
|
-
$libs += " " << libs
|
1217
|
-
Logging::message "package configuration for %s\n", pkg
|
1218
|
-
Logging::message "cflags: %s\nldflags: %s\nlibs: %s\n\n",
|
1219
|
-
cflags, ldflags, libs
|
1220
|
-
[cflags, ldflags, libs]
|
1221
|
-
else
|
1222
|
-
Logging::message "package configuration for %s is not found\n", pkg
|
1223
|
-
nil
|
1730
|
+
def with_destdir(dir)
|
1731
|
+
return dir unless $extmk
|
1732
|
+
dir = dir.sub($dest_prefix_pattern, '')
|
1733
|
+
/\A\$[\(\{]/ =~ dir ? dir : "$(DESTDIR)"+dir
|
1224
1734
|
end
|
1225
|
-
end
|
1226
|
-
|
1227
|
-
def with_destdir(dir)
|
1228
|
-
dir = dir.sub($dest_prefix_pattern, '')
|
1229
|
-
/\A\$[\(\{]/ =~ dir ? dir : "$(DESTDIR)"+dir
|
1230
|
-
end
|
1231
1735
|
|
1232
|
-
# Converts forward slashes to backslashes. Aimed at MS Windows.
|
1233
|
-
#
|
1234
|
-
# Internal use only.
|
1235
|
-
#
|
1236
|
-
def winsep(s)
|
1237
|
-
|
1238
|
-
end
|
1239
|
-
|
1240
|
-
# Converts native path to format acceptable in Makefile
|
1241
|
-
#
|
1242
|
-
# Internal use only.
|
1243
|
-
#
|
1244
|
-
if !CROSS_COMPILING
|
1245
|
-
case CONFIG['build_os']
|
1246
|
-
when 'mingw32'
|
1247
|
-
def mkintpath(path)
|
1248
|
-
# mingw uses make from msys and it needs special care
|
1249
|
-
# converts from C:\some\path to /C/some/path
|
1250
|
-
path = path.dup
|
1251
|
-
path.tr!('\\', '/')
|
1252
|
-
path.sub!(/\A([A-Za-z]):(?=\/)/, '/\1')
|
1253
|
-
path
|
1254
|
-
end
|
1255
|
-
end
|
1256
|
-
end
|
1257
|
-
unless defined?(mkintpath)
|
1258
|
-
def mkintpath(path)
|
1259
|
-
path
|
1736
|
+
# Converts forward slashes to backslashes. Aimed at MS Windows.
|
1737
|
+
#
|
1738
|
+
# Internal use only.
|
1739
|
+
#
|
1740
|
+
def winsep(s)
|
1741
|
+
s.tr('/', '\\')
|
1260
1742
|
end
|
1261
|
-
end
|
1262
1743
|
|
1263
|
-
|
1264
|
-
|
1265
|
-
|
1744
|
+
# Converts native path to format acceptable in Makefile
|
1745
|
+
#
|
1746
|
+
# Internal use only.
|
1747
|
+
#
|
1266
1748
|
if !CROSS_COMPILING
|
1267
1749
|
case CONFIG['build_os']
|
1750
|
+
when 'mingw32'
|
1751
|
+
def mkintpath(path)
|
1752
|
+
# mingw uses make from msys and it needs special care
|
1753
|
+
# converts from C:\some\path to /C/some/path
|
1754
|
+
path = path.dup
|
1755
|
+
path.tr!('\\', '/')
|
1756
|
+
path.sub!(/\A([A-Za-z]):(?=\/)/, '/\1')
|
1757
|
+
path
|
1758
|
+
end
|
1268
1759
|
when 'cygwin'
|
1269
1760
|
if CONFIG['target_os'] != 'cygwin'
|
1270
|
-
|
1761
|
+
def mkintpath(path)
|
1762
|
+
IO.popen(["cygpath", "-u", path], &:read).chomp
|
1763
|
+
end
|
1271
1764
|
end
|
1272
|
-
when 'msdosdjgpp'
|
1273
|
-
CONFIG['PATH_SEPARATOR'] = ';'
|
1274
1765
|
end
|
1275
1766
|
end
|
1276
|
-
|
1767
|
+
unless method_defined?(:mkintpath)
|
1768
|
+
def mkintpath(path)
|
1769
|
+
path
|
1770
|
+
end
|
1771
|
+
end
|
1772
|
+
|
1773
|
+
def configuration(srcdir)
|
1774
|
+
mk = []
|
1775
|
+
vpath = $VPATH.dup
|
1776
|
+
CONFIG["hdrdir"] ||= $hdrdir
|
1777
|
+
mk << %{
|
1277
1778
|
SHELL = /bin/sh
|
1278
1779
|
|
1780
|
+
# V=0 quiet, V=1 verbose. other values don't work.
|
1781
|
+
V = 0
|
1782
|
+
Q1 = $(V:1=)
|
1783
|
+
Q = $(Q1:0=@)
|
1784
|
+
ECHO1 = $(V:1=@#{CONFIG['NULLCMD']})
|
1785
|
+
ECHO = $(ECHO1:0=@echo)
|
1786
|
+
|
1279
1787
|
#### Start of system configuration section. ####
|
1280
|
-
#{
|
1281
|
-
|
1282
|
-
|
1283
|
-
|
1284
|
-
}
|
1285
|
-
|
1286
|
-
topdir = #{mkintpath($extmk ? CONFIG["topdir"] : $topdir).quote}
|
1287
|
-
hdrdir = #{$extmk ? mkintpath(CONFIG["hdrdir"]).quote : '$(topdir)'}
|
1788
|
+
#{"top_srcdir = " + $top_srcdir.sub(%r"\A#{Regexp.quote($topdir)}/", "$(topdir)/") if $extmk}
|
1789
|
+
srcdir = #{srcdir.gsub(/\$\((srcdir)\)|\$\{(srcdir)\}/) {mkintpath(CONFIG[$1||$2]).unspace}}
|
1790
|
+
topdir = #{mkintpath(topdir = $extmk ? CONFIG["topdir"] : $topdir).unspace}
|
1791
|
+
hdrdir = #{(hdrdir = CONFIG["hdrdir"]) == topdir ? "$(topdir)" : mkintpath(hdrdir).unspace}
|
1792
|
+
arch_hdrdir = #{$arch_hdrdir.quote}
|
1793
|
+
PATH_SEPARATOR = #{CONFIG['PATH_SEPARATOR']}
|
1288
1794
|
VPATH = #{vpath.join(CONFIG['PATH_SEPARATOR'])}
|
1289
1795
|
}
|
1290
|
-
|
1291
|
-
|
1292
|
-
|
1293
|
-
|
1294
|
-
|
1295
|
-
|
1296
|
-
|
1297
|
-
|
1298
|
-
|
1299
|
-
|
1300
|
-
|
1301
|
-
|
1302
|
-
|
1303
|
-
|
1304
|
-
|
1305
|
-
|
1306
|
-
|
1307
|
-
|
1308
|
-
|
1309
|
-
|
1310
|
-
|
1311
|
-
|
1312
|
-
|
1796
|
+
if $extmk
|
1797
|
+
mk << "RUBYLIB =\n""RUBYOPT = -\n"
|
1798
|
+
end
|
1799
|
+
prefix = mkintpath(CONFIG["prefix"])
|
1800
|
+
if destdir = prefix[$dest_prefix_pattern, 1]
|
1801
|
+
mk << "\nDESTDIR = #{destdir}\n"
|
1802
|
+
end
|
1803
|
+
mk << "prefix = #{with_destdir(prefix).unspace}\n"
|
1804
|
+
CONFIG.each do |key, var|
|
1805
|
+
mk << "#{key} = #{with_destdir(mkintpath(var)).unspace}\n" if /.prefix$/ =~ key
|
1806
|
+
end
|
1807
|
+
CONFIG.each do |key, var|
|
1808
|
+
next if /^abs_/ =~ key
|
1809
|
+
next if /^(?:src|top|hdr)dir$/ =~ key
|
1810
|
+
next unless /dir$/ =~ key
|
1811
|
+
mk << "#{key} = #{with_destdir(var)}\n"
|
1812
|
+
end
|
1813
|
+
if !$extmk and !$configure_args.has_key?('--ruby') and
|
1814
|
+
sep = config_string('BUILD_FILE_SEPARATOR')
|
1815
|
+
sep = ":/=#{sep}"
|
1816
|
+
else
|
1817
|
+
sep = ""
|
1818
|
+
end
|
1819
|
+
possible_command = (proc {|s| s if /top_srcdir/ !~ s} unless $extmk)
|
1820
|
+
extconf_h = $extconf_h ? "-DRUBY_EXTCONF_H=\\\"$(RUBY_EXTCONF_H)\\\" " : $defs.join(" ") << " "
|
1821
|
+
headers = %w[$(hdrdir)/ruby.h $(hdrdir)/ruby/defines.h]
|
1822
|
+
if RULE_SUBST
|
1823
|
+
headers.each {|h| h.sub!(/.*/, &RULE_SUBST.method(:%))}
|
1824
|
+
end
|
1825
|
+
headers << $config_h
|
1826
|
+
headers << '$(RUBY_EXTCONF_H)' if $extconf_h
|
1827
|
+
mk << %{
|
1828
|
+
|
1313
1829
|
CC = #{CONFIG['CC']}
|
1830
|
+
CXX = #{CONFIG['CXX']}
|
1314
1831
|
LIBRUBY = #{CONFIG['LIBRUBY']}
|
1315
1832
|
LIBRUBY_A = #{CONFIG['LIBRUBY_A']}
|
1316
1833
|
LIBRUBYARG_SHARED = #$LIBRUBYARG_SHARED
|
1317
1834
|
LIBRUBYARG_STATIC = #$LIBRUBYARG_STATIC
|
1835
|
+
empty =
|
1836
|
+
OUTFLAG = #{OUTFLAG}$(empty)
|
1837
|
+
COUTFLAG = #{COUTFLAG}$(empty)
|
1318
1838
|
|
1319
1839
|
RUBY_EXTCONF_H = #{$extconf_h}
|
1320
|
-
|
1840
|
+
cflags = #{CONFIG['cflags']}
|
1841
|
+
optflags = #{CONFIG['optflags']}
|
1842
|
+
debugflags = #{CONFIG['debugflags']}
|
1843
|
+
warnflags = #{$warnflags}
|
1844
|
+
CCDLFLAGS = #{$static ? '' : CONFIG['CCDLFLAGS']}
|
1845
|
+
CFLAGS = $(CCDLFLAGS) #$CFLAGS $(ARCH_FLAG)
|
1321
1846
|
INCFLAGS = -I. #$INCFLAGS
|
1322
1847
|
DEFS = #{CONFIG['DEFS']}
|
1323
1848
|
CPPFLAGS = #{extconf_h}#{$CPPFLAGS}
|
1324
|
-
CXXFLAGS = $(
|
1849
|
+
CXXFLAGS = $(CCDLFLAGS) #{CONFIG['CXXFLAGS']} $(ARCH_FLAG)
|
1325
1850
|
ldflags = #{$LDFLAGS}
|
1326
|
-
dldflags = #{$DLDFLAGS}
|
1327
|
-
|
1328
|
-
DLDFLAGS = $(ldflags) $(dldflags) $(
|
1851
|
+
dldflags = #{$DLDFLAGS} #{CONFIG['EXTDLDFLAGS']}
|
1852
|
+
ARCH_FLAG = #{$ARCH_FLAG}
|
1853
|
+
DLDFLAGS = $(ldflags) $(dldflags) $(ARCH_FLAG)
|
1329
1854
|
LDSHARED = #{CONFIG['LDSHARED']}
|
1855
|
+
LDSHAREDXX = #{config_string('LDSHAREDXX') || '$(LDSHARED)'}
|
1330
1856
|
AR = #{CONFIG['AR']}
|
1331
1857
|
EXEEXT = #{CONFIG['EXEEXT']}
|
1332
1858
|
|
1333
|
-
|
1334
|
-
|
1859
|
+
}
|
1860
|
+
CONFIG.each do |key, val|
|
1861
|
+
mk << "#{key} = #{val}\n" if /^RUBY.*NAME/ =~ key
|
1862
|
+
end
|
1863
|
+
mk << %{
|
1335
1864
|
arch = #{CONFIG['arch']}
|
1336
1865
|
sitearch = #{CONFIG['sitearch']}
|
1337
1866
|
ruby_version = #{RbConfig::CONFIG['ruby_version']}
|
1338
|
-
ruby = #{$ruby}
|
1867
|
+
ruby = #{$ruby.sub(%r[\A#{Regexp.quote(RbConfig::CONFIG['bindir'])}(?=/|\z)]) {'$(bindir)'}}
|
1339
1868
|
RUBY = $(ruby#{sep})
|
1340
|
-
|
1341
|
-
|
1342
|
-
|
1869
|
+
ruby_headers = #{headers.join(' ')}
|
1870
|
+
|
1871
|
+
RM = #{config_string('RM', &possible_command) || '$(RUBY) -run -e rm -- -f'}
|
1872
|
+
RM_RF = #{'$(RUBY) -run -e rm -- -rf'}
|
1873
|
+
RMDIRS = #{config_string('RMDIRS', &possible_command) || '$(RUBY) -run -e rmdir -- -p'}
|
1874
|
+
MAKEDIRS = #{config_string('MAKEDIRS', &possible_command) || '@$(RUBY) -run -e mkdir -- -p'}
|
1875
|
+
INSTALL = #{config_string('INSTALL', &possible_command) || '@$(RUBY) -run -e install -- -vp'}
|
1343
1876
|
INSTALL_PROG = #{config_string('INSTALL_PROG') || '$(INSTALL) -m 0755'}
|
1344
1877
|
INSTALL_DATA = #{config_string('INSTALL_DATA') || '$(INSTALL) -m 0644'}
|
1345
|
-
COPY = #{config_string('CP') || '@$(RUBY) -run -e cp -- -v'}
|
1878
|
+
COPY = #{config_string('CP', &possible_command) || '@$(RUBY) -run -e cp -- -v'}
|
1879
|
+
TOUCH = exit >
|
1346
1880
|
|
1347
1881
|
#### End of system configuration section. ####
|
1348
1882
|
|
1349
|
-
preload = #{$preload ? $preload.join(' ') : ''}
|
1883
|
+
preload = #{defined?($preload) && $preload ? $preload.join(' ') : ''}
|
1350
1884
|
}
|
1351
|
-
|
1352
|
-
|
1353
|
-
|
1354
|
-
|
1355
|
-
|
1356
|
-
|
1885
|
+
if $nmake == ?b
|
1886
|
+
mk.each do |x|
|
1887
|
+
x.gsub!(/^(MAKEDIRS|INSTALL_(?:PROG|DATA))+\s*=.*\n/) do
|
1888
|
+
"!ifndef " + $1 + "\n" +
|
1889
|
+
$& +
|
1890
|
+
"!endif\n"
|
1891
|
+
end
|
1357
1892
|
end
|
1358
1893
|
end
|
1894
|
+
mk
|
1359
1895
|
end
|
1360
|
-
mk
|
1361
|
-
end
|
1362
1896
|
|
1363
|
-
def
|
1364
|
-
|
1897
|
+
def timestamp_file(name)
|
1898
|
+
name = name.gsub(/(\$[({]|[})])|(\/+)|[^-.\w]+/) {$1 ? "" : $2 ? ".-." : "_"}
|
1899
|
+
"./.#{name}.time"
|
1900
|
+
end
|
1901
|
+
# :startdoc:
|
1902
|
+
|
1903
|
+
# creates a stub Makefile.
|
1904
|
+
#
|
1905
|
+
def dummy_makefile(srcdir)
|
1906
|
+
configuration(srcdir) << <<RULES << CLEANINGS
|
1365
1907
|
CLEANFILES = #{$cleanfiles.join(' ')}
|
1366
1908
|
DISTCLEANFILES = #{$distcleanfiles.join(' ')}
|
1367
1909
|
|
1368
1910
|
all install static install-so install-rb: Makefile
|
1911
|
+
.PHONY: all install static install-so install-rb
|
1912
|
+
.PHONY: clean clean-so clean-static clean-rb
|
1369
1913
|
|
1370
1914
|
RULES
|
1371
|
-
end
|
1372
|
-
# :startdoc:
|
1373
|
-
|
1374
|
-
# Generates the Makefile for your extension, passing along any options and
|
1375
|
-
# preprocessor constants that you may have generated through other methods.
|
1376
|
-
#
|
1377
|
-
# The +target+ name should correspond the name of the global function name
|
1378
|
-
# defined within your C extension, minus the 'Init_'. For example, if your
|
1379
|
-
# C extension is defined as 'Init_foo', then your target would simply be 'foo'.
|
1380
|
-
#
|
1381
|
-
# If any '/' characters are present in the target name, only the last name
|
1382
|
-
# is interpreted as the target name, and the rest are considered toplevel
|
1383
|
-
# directory names, and the generated Makefile will be altered accordingly to
|
1384
|
-
# follow that directory structure.
|
1385
|
-
#
|
1386
|
-
# For example, if you pass 'test/foo' as a target name, your extension will
|
1387
|
-
# be installed under the 'test' directory. This means that in order to
|
1388
|
-
# load the file within a Ruby program later, that directory structure will
|
1389
|
-
# have to be followed, e.g. "require 'test/foo'".
|
1390
|
-
#
|
1391
|
-
# The +srcprefix+ should be used when your source files are not in the same
|
1392
|
-
# directory as your build script. This will not only eliminate the need for
|
1393
|
-
# you to manually copy the source files into the same directory as your build
|
1394
|
-
# script, but it also sets the proper +target_prefix+ in the generated
|
1395
|
-
# Makefile.
|
1396
|
-
#
|
1397
|
-
# Setting the +target_prefix+ will, in turn, install the generated binary in
|
1398
|
-
# a directory under your RbConfig::CONFIG['sitearchdir'] that mimics your local
|
1399
|
-
# filesystem when you run 'make install'.
|
1400
|
-
#
|
1401
|
-
# For example, given the following file tree:
|
1402
|
-
#
|
1403
|
-
# ext/
|
1404
|
-
# extconf.rb
|
1405
|
-
# test/
|
1406
|
-
# foo.c
|
1407
|
-
#
|
1408
|
-
# And given the following code:
|
1409
|
-
#
|
1410
|
-
# create_makefile('test/foo', 'test')
|
1411
|
-
#
|
1412
|
-
# That will set the +target_prefix+ in the generated Makefile to 'test'. That,
|
1413
|
-
# in turn, will create the following file tree when installed via the
|
1414
|
-
# 'make install' command:
|
1415
|
-
#
|
1416
|
-
# /path/to/ruby/sitearchdir/test/foo.so
|
1417
|
-
#
|
1418
|
-
# It is recommended that you use this approach to generate your makefiles,
|
1419
|
-
# instead of copying files around manually, because some third party
|
1420
|
-
# libraries may depend on the +target_prefix+ being set properly.
|
1421
|
-
#
|
1422
|
-
# The +srcprefix+ argument can be used to override the default source
|
1423
|
-
# directory, i.e. the current directory . It is included as part of the VPATH
|
1424
|
-
# and added to the list of INCFLAGS.
|
1425
|
-
#
|
1426
|
-
def create_makefile(target, srcprefix = nil)
|
1427
|
-
$target = target
|
1428
|
-
libpath = $DEFLIBPATH|$LIBPATH
|
1429
|
-
message "creating Makefile\n"
|
1430
|
-
rm_f "conftest*"
|
1431
|
-
if CONFIG["DLEXT"] == $OBJEXT
|
1432
|
-
for lib in libs = $libs.split
|
1433
|
-
lib.sub!(/-l(.*)/, %%"lib\\1.#{$LIBEXT}"%)
|
1434
|
-
end
|
1435
|
-
$defs.push(format("-DEXTLIB='%s'", libs.join(",")))
|
1436
|
-
end
|
1437
|
-
|
1438
|
-
if target.include?('/')
|
1439
|
-
target_prefix, target = File.split(target)
|
1440
|
-
target_prefix[0,0] = '/'
|
1441
|
-
else
|
1442
|
-
target_prefix = ""
|
1443
1915
|
end
|
1444
1916
|
|
1445
|
-
|
1446
|
-
|
1447
|
-
|
1448
|
-
|
1449
|
-
|
1450
|
-
|
1451
|
-
|
1452
|
-
|
1453
|
-
|
1917
|
+
def each_compile_rules # :nodoc:
|
1918
|
+
vpath_splat = /\$\(\*VPATH\*\)/
|
1919
|
+
COMPILE_RULES.each do |rule|
|
1920
|
+
if vpath_splat =~ rule
|
1921
|
+
$VPATH.each do |path|
|
1922
|
+
yield rule.sub(vpath_splat) {path}
|
1923
|
+
end
|
1924
|
+
else
|
1925
|
+
yield rule
|
1926
|
+
end
|
1454
1927
|
end
|
1455
|
-
elsif !(srcs = $srcs)
|
1456
|
-
srcs = $objs.collect {|obj| obj.sub(/\.o\z/, '.c')}
|
1457
1928
|
end
|
1458
|
-
$srcs = srcs
|
1459
|
-
for i in $objs
|
1460
|
-
i.sub!(/\.o\z/, ".#{$OBJEXT}")
|
1461
|
-
end
|
1462
|
-
$objs = $objs.join(" ")
|
1463
1929
|
|
1464
|
-
|
1930
|
+
# Processes the data contents of the "depend" file. Each line of this file
|
1931
|
+
# is expected to be a file name.
|
1932
|
+
#
|
1933
|
+
# Returns the output of findings, in Makefile format.
|
1934
|
+
#
|
1935
|
+
def depend_rules(depend)
|
1936
|
+
suffixes = []
|
1937
|
+
depout = []
|
1938
|
+
cont = implicit = nil
|
1939
|
+
impconv = proc do
|
1940
|
+
each_compile_rules {|rule| depout << (rule % implicit[0]) << implicit[1]}
|
1941
|
+
implicit = nil
|
1942
|
+
end
|
1943
|
+
ruleconv = proc do |line|
|
1944
|
+
if implicit
|
1945
|
+
if /\A\t/ =~ line
|
1946
|
+
implicit[1] << line
|
1947
|
+
next
|
1948
|
+
else
|
1949
|
+
impconv[]
|
1950
|
+
end
|
1951
|
+
end
|
1952
|
+
if m = /\A\.(\w+)\.(\w+)(?:\s*:)/.match(line)
|
1953
|
+
suffixes << m[1] << m[2]
|
1954
|
+
implicit = [[m[1], m[2]], [m.post_match]]
|
1955
|
+
next
|
1956
|
+
elsif RULE_SUBST and /\A(?!\s*\w+\s*=)[$\w][^#]*:/ =~ line
|
1957
|
+
line.gsub!(%r"(\s)(?!\.)([^$(){}+=:\s\/\\,]+)(?=\s|\z)") {$1 + RULE_SUBST % $2}
|
1958
|
+
end
|
1959
|
+
depout << line
|
1960
|
+
end
|
1961
|
+
depend.each_line do |line|
|
1962
|
+
line.gsub!(/\.o\b/, ".#{$OBJEXT}")
|
1963
|
+
line.gsub!(/\$\((?:hdr|top)dir\)\/config.h/, $config_h)
|
1964
|
+
line.gsub!(%r"\$\(hdrdir\)/(?!ruby(?![^:;/\s]))(?=[-\w]+\.h)", '\&ruby/')
|
1965
|
+
if $nmake && /\A\s*\$\(RM|COPY\)/ =~ line
|
1966
|
+
line.gsub!(%r"[-\w\./]{2,}"){$&.tr("/", "\\")}
|
1967
|
+
line.gsub!(/(\$\((?!RM|COPY)[^:)]+)(?=\))/, '\1:/=\\')
|
1968
|
+
end
|
1969
|
+
if /(?:^|[^\\])(?:\\\\)*\\$/ =~ line
|
1970
|
+
(cont ||= []) << line
|
1971
|
+
next
|
1972
|
+
elsif cont
|
1973
|
+
line = (cont << line).join
|
1974
|
+
cont = nil
|
1975
|
+
end
|
1976
|
+
ruleconv.call(line)
|
1977
|
+
end
|
1978
|
+
if cont
|
1979
|
+
ruleconv.call(cont.join)
|
1980
|
+
elsif implicit
|
1981
|
+
impconv.call
|
1982
|
+
end
|
1983
|
+
unless suffixes.empty?
|
1984
|
+
depout.unshift(".SUFFIXES: ." + suffixes.uniq.join(" .") + "\n\n")
|
1985
|
+
end
|
1986
|
+
depout.unshift("$(OBJS): $(RUBY_EXTCONF_H)\n\n") if $extconf_h
|
1987
|
+
depout.flatten!
|
1988
|
+
depout
|
1989
|
+
end
|
1990
|
+
|
1991
|
+
# Generates the Makefile for your extension, passing along any options and
|
1992
|
+
# preprocessor constants that you may have generated through other methods.
|
1993
|
+
#
|
1994
|
+
# The +target+ name should correspond the name of the global function name
|
1995
|
+
# defined within your C extension, minus the +Init_+. For example, if your
|
1996
|
+
# C extension is defined as +Init_foo+, then your target would simply be
|
1997
|
+
# "foo".
|
1998
|
+
#
|
1999
|
+
# If any "/" characters are present in the target name, only the last name
|
2000
|
+
# is interpreted as the target name, and the rest are considered toplevel
|
2001
|
+
# directory names, and the generated Makefile will be altered accordingly to
|
2002
|
+
# follow that directory structure.
|
2003
|
+
#
|
2004
|
+
# For example, if you pass "test/foo" as a target name, your extension will
|
2005
|
+
# be installed under the "test" directory. This means that in order to
|
2006
|
+
# load the file within a Ruby program later, that directory structure will
|
2007
|
+
# have to be followed, e.g. <code>require 'test/foo'</code>.
|
2008
|
+
#
|
2009
|
+
# The +srcprefix+ should be used when your source files are not in the same
|
2010
|
+
# directory as your build script. This will not only eliminate the need for
|
2011
|
+
# you to manually copy the source files into the same directory as your
|
2012
|
+
# build script, but it also sets the proper +target_prefix+ in the generated
|
2013
|
+
# Makefile.
|
2014
|
+
#
|
2015
|
+
# Setting the +target_prefix+ will, in turn, install the generated binary in
|
2016
|
+
# a directory under your <code>RbConfig::CONFIG['sitearchdir']</code> that
|
2017
|
+
# mimics your local filesystem when you run <code>make install</code>.
|
2018
|
+
#
|
2019
|
+
# For example, given the following file tree:
|
2020
|
+
#
|
2021
|
+
# ext/
|
2022
|
+
# extconf.rb
|
2023
|
+
# test/
|
2024
|
+
# foo.c
|
2025
|
+
#
|
2026
|
+
# And given the following code:
|
2027
|
+
#
|
2028
|
+
# create_makefile('test/foo', 'test')
|
2029
|
+
#
|
2030
|
+
# That will set the +target_prefix+ in the generated Makefile to "test".
|
2031
|
+
# That, in turn, will create the following file tree when installed via the
|
2032
|
+
# <code>make install</code> command:
|
2033
|
+
#
|
2034
|
+
# /path/to/ruby/sitearchdir/test/foo.so
|
2035
|
+
#
|
2036
|
+
# It is recommended that you use this approach to generate your makefiles,
|
2037
|
+
# instead of copying files around manually, because some third party
|
2038
|
+
# libraries may depend on the +target_prefix+ being set properly.
|
2039
|
+
#
|
2040
|
+
# The +srcprefix+ argument can be used to override the default source
|
2041
|
+
# directory, i.e. the current directory. It is included as part of the
|
2042
|
+
# +VPATH+ and added to the list of +INCFLAGS+.
|
2043
|
+
#
|
2044
|
+
def create_makefile(target, srcprefix = nil)
|
2045
|
+
$target = target
|
2046
|
+
libpath = $DEFLIBPATH|$LIBPATH
|
2047
|
+
message "creating Makefile\n"
|
2048
|
+
MakeMakefile.rm_f "conftest*"
|
2049
|
+
if CONFIG["DLEXT"] == $OBJEXT
|
2050
|
+
for lib in libs = $libs.split
|
2051
|
+
lib.sub!(/-l(.*)/, %%"lib\\1.#{$LIBEXT}"%)
|
2052
|
+
end
|
2053
|
+
$defs.push(format("-DEXTLIB='%s'", libs.join(",")))
|
2054
|
+
end
|
2055
|
+
|
2056
|
+
if target.include?('/')
|
2057
|
+
target_prefix, target = File.split(target)
|
2058
|
+
target_prefix[0,0] = '/'
|
2059
|
+
else
|
2060
|
+
target_prefix = ""
|
2061
|
+
end
|
1465
2062
|
|
1466
|
-
|
1467
|
-
|
1468
|
-
|
1469
|
-
|
1470
|
-
|
2063
|
+
srcprefix ||= "$(srcdir)/#{srcprefix}".chomp('/')
|
2064
|
+
RbConfig.expand(srcdir = srcprefix.dup)
|
2065
|
+
|
2066
|
+
ext = ".#{$OBJEXT}"
|
2067
|
+
orig_srcs = Dir[File.join(srcdir, "*.{#{SRC_EXT.join(%q{,})}}")]
|
2068
|
+
if not $objs
|
2069
|
+
srcs = $srcs || orig_srcs
|
2070
|
+
objs = srcs.inject(Hash.new {[]}) {|h, f| h[File.basename(f, ".*") << ext] <<= f; h}
|
2071
|
+
$objs = objs.keys
|
2072
|
+
unless objs.delete_if {|b, f| f.size == 1}.empty?
|
2073
|
+
dups = objs.sort.map {|b, f|
|
2074
|
+
"#{b[/.*\./]}{#{f.collect {|n| n[/([^.]+)\z/]}.join(',')}}"
|
2075
|
+
}
|
2076
|
+
abort "source files duplication - #{dups.join(", ")}"
|
1471
2077
|
end
|
1472
2078
|
else
|
1473
|
-
|
2079
|
+
$objs.collect! {|o| File.basename(o, ".*") << ext} unless $OBJEXT == "o"
|
2080
|
+
srcs = $srcs || $objs.collect {|o| o.chomp(ext) << ".c"}
|
1474
2081
|
end
|
1475
|
-
|
1476
|
-
|
1477
|
-
|
1478
|
-
|
2082
|
+
$srcs = srcs
|
2083
|
+
|
2084
|
+
hdrs = Dir[File.join(srcdir, "*.{#{HDR_EXT.join(%q{,})}}")]
|
2085
|
+
|
2086
|
+
target = nil if $objs.empty?
|
2087
|
+
|
2088
|
+
if target and EXPORT_PREFIX
|
2089
|
+
if File.exist?(File.join(srcdir, target + '.def'))
|
2090
|
+
deffile = "$(srcdir)/$(TARGET).def"
|
2091
|
+
unless EXPORT_PREFIX.empty?
|
2092
|
+
makedef = %{-pe "$_.sub!(/^(?=\\w)/,'#{EXPORT_PREFIX}') unless 1../^EXPORTS$/i"}
|
2093
|
+
end
|
2094
|
+
else
|
2095
|
+
makedef = %{-e "puts 'EXPORTS', '$(TARGET_ENTRY)'"}
|
2096
|
+
end
|
2097
|
+
if makedef
|
2098
|
+
$cleanfiles << '$(DEFFILE)'
|
2099
|
+
origdef = deffile
|
2100
|
+
deffile = "$(TARGET)-$(arch).def"
|
2101
|
+
end
|
1479
2102
|
end
|
1480
|
-
|
1481
|
-
origdef ||= ''
|
2103
|
+
origdef ||= ''
|
1482
2104
|
|
1483
|
-
|
2105
|
+
if $extout and $INSTALLFILES
|
2106
|
+
$cleanfiles.concat($INSTALLFILES.collect {|files, dir|File.join(dir, files.sub(/\A\.\//, ''))})
|
2107
|
+
$distcleandirs.concat($INSTALLFILES.collect {|files, dir| dir})
|
2108
|
+
end
|
2109
|
+
|
2110
|
+
if $extmk and not $extconf_h
|
2111
|
+
create_header
|
2112
|
+
end
|
2113
|
+
|
2114
|
+
libpath = libpathflag(libpath)
|
1484
2115
|
|
1485
|
-
|
1486
|
-
|
1487
|
-
|
1488
|
-
|
1489
|
-
|
2116
|
+
dllib = target ? "$(TARGET).#{CONFIG['DLEXT']}" : ""
|
2117
|
+
staticlib = target ? "$(TARGET).#$LIBEXT" : ""
|
2118
|
+
mfile = open("Makefile", "wb")
|
2119
|
+
conf = configuration(srcprefix)
|
2120
|
+
conf = yield(conf) if block_given?
|
2121
|
+
mfile.puts(conf)
|
2122
|
+
mfile.print "
|
1490
2123
|
libpath = #{($DEFLIBPATH|$LIBPATH).join(" ")}
|
1491
2124
|
LIBPATH = #{libpath}
|
1492
2125
|
DEFFILE = #{deffile}
|
1493
2126
|
|
1494
2127
|
CLEANFILES = #{$cleanfiles.join(' ')}
|
1495
2128
|
DISTCLEANFILES = #{$distcleanfiles.join(' ')}
|
2129
|
+
DISTCLEANDIRS = #{$distcleandirs.join(' ')}
|
1496
2130
|
|
1497
|
-
extout = #{$extout}
|
2131
|
+
extout = #{$extout && $extout.quote}
|
1498
2132
|
extout_prefix = #{$extout_prefix}
|
1499
2133
|
target_prefix = #{target_prefix}
|
1500
2134
|
LOCAL_LIBS = #{$LOCAL_LIBS}
|
1501
2135
|
LIBS = #{$LIBRUBYARG} #{$libs} #{$LIBS}
|
1502
|
-
|
1503
|
-
|
2136
|
+
ORIG_SRCS = #{orig_srcs.collect(&File.method(:basename)).join(' ')}
|
2137
|
+
SRCS = $(ORIG_SRCS) #{(srcs - orig_srcs).collect(&File.method(:basename)).join(' ')}
|
2138
|
+
OBJS = #{$objs.join(" ")}
|
2139
|
+
HDRS = #{hdrs.map{|h| '$(srcdir)/' + File.basename(h)}.join(' ')}
|
1504
2140
|
TARGET = #{target}
|
2141
|
+
TARGET_NAME = #{target && target[/\A\w+/]}
|
2142
|
+
TARGET_ENTRY = #{EXPORT_PREFIX || ''}Init_$(TARGET_NAME)
|
1505
2143
|
DLLIB = #{dllib}
|
1506
2144
|
EXTSTATIC = #{$static || ""}
|
1507
2145
|
STATIC_LIB = #{staticlib unless $static.nil?}
|
1508
2146
|
#{!$extout && defined?($installed_list) ? "INSTALLED_LIST = #{$installed_list}\n" : ""}
|
1509
|
-
"
|
1510
|
-
|
1511
|
-
|
1512
|
-
|
2147
|
+
" #"
|
2148
|
+
# TODO: fixme
|
2149
|
+
install_dirs.each {|d| mfile.print("%-14s= %s\n" % d) if /^[[:upper:]]/ =~ d[0]}
|
2150
|
+
n = ($extout ? '$(RUBYARCHDIR)/' : '') + '$(TARGET)'
|
2151
|
+
mfile.print "
|
1513
2152
|
TARGET_SO = #{($extout ? '$(RUBYARCHDIR)/' : '')}$(DLLIB)
|
1514
|
-
CLEANLIBS = #{n}
|
1515
|
-
CLEANOBJS = *.#{$OBJEXT}
|
2153
|
+
CLEANLIBS = #{n}.#{CONFIG['DLEXT']} #{config_string('cleanlibs') {|t| t.gsub(/\$\*/) {n}}}
|
2154
|
+
CLEANOBJS = *.#{$OBJEXT} #{config_string('cleanobjs') {|t| t.gsub(/\$\*/, "$(TARGET)#{deffile ? '-$(arch)': ''}")} if target} *.bak
|
1516
2155
|
|
1517
|
-
all:
|
1518
|
-
static:
|
2156
|
+
all: #{$extout ? "install" : target ? "$(DLLIB)" : "Makefile"}
|
2157
|
+
static: $(STATIC_LIB)#{$extout ? " install-rb" : ""}
|
2158
|
+
.PHONY: all install static install-so install-rb
|
2159
|
+
.PHONY: clean clean-so clean-static clean-rb
|
1519
2160
|
"
|
1520
|
-
|
1521
|
-
|
1522
|
-
|
1523
|
-
|
1524
|
-
|
1525
|
-
|
1526
|
-
|
1527
|
-
|
1528
|
-
|
1529
|
-
|
1530
|
-
|
1531
|
-
|
1532
|
-
|
1533
|
-
|
1534
|
-
|
1535
|
-
|
1536
|
-
|
1537
|
-
|
1538
|
-
|
1539
|
-
|
1540
|
-
|
1541
|
-
|
1542
|
-
|
2161
|
+
mfile.print CLEANINGS
|
2162
|
+
fsep = config_string('BUILD_FILE_SEPARATOR') {|s| s unless s == "/"}
|
2163
|
+
if fsep
|
2164
|
+
sep = ":/=#{fsep}"
|
2165
|
+
fseprepl = proc {|s|
|
2166
|
+
s = s.gsub("/", fsep)
|
2167
|
+
s = s.gsub(/(\$\(\w+)(\))/) {$1+sep+$2}
|
2168
|
+
s = s.gsub(/(\$\{\w+)(\})/) {$1+sep+$2}
|
2169
|
+
}
|
2170
|
+
rsep = ":#{fsep}=/"
|
2171
|
+
else
|
2172
|
+
fseprepl = proc {|s| s}
|
2173
|
+
sep = ""
|
2174
|
+
rsep = ""
|
2175
|
+
end
|
2176
|
+
dirs = []
|
2177
|
+
mfile.print "install: install-so install-rb\n\n"
|
2178
|
+
sodir = (dir = "$(RUBYARCHDIR)").dup
|
2179
|
+
mfile.print("install-so: ")
|
2180
|
+
if target
|
2181
|
+
f = "$(DLLIB)"
|
2182
|
+
dest = "#{dir}/#{f}"
|
2183
|
+
if $extout
|
2184
|
+
mfile.puts dest
|
2185
|
+
mfile.print "clean-so::\n"
|
2186
|
+
mfile.print "\t-$(Q)$(RM) #{fseprepl[dest]}\n"
|
2187
|
+
mfile.print "\t-$(Q)$(RMDIRS) #{fseprepl[dir]}#{$ignore_error}\n"
|
2188
|
+
else
|
2189
|
+
mfile.print "#{f} #{timestamp_file(dir)}\n"
|
2190
|
+
mfile.print "\t$(INSTALL_PROG) #{fseprepl[f]} #{dir}\n"
|
2191
|
+
if defined?($installed_list)
|
2192
|
+
mfile.print "\t@echo #{dir}/#{File.basename(f)}>>$(INSTALLED_LIST)\n"
|
2193
|
+
end
|
1543
2194
|
end
|
2195
|
+
mfile.print "clean-static::\n"
|
2196
|
+
mfile.print "\t-$(Q)$(RM) $(STATIC_LIB)\n"
|
2197
|
+
else
|
2198
|
+
mfile.puts "Makefile"
|
1544
2199
|
end
|
1545
|
-
|
1546
|
-
mfile.
|
1547
|
-
|
1548
|
-
|
1549
|
-
|
1550
|
-
|
1551
|
-
|
1552
|
-
|
1553
|
-
|
1554
|
-
|
1555
|
-
|
1556
|
-
|
1557
|
-
|
2200
|
+
mfile.print("install-rb: pre-install-rb install-rb-default\n")
|
2201
|
+
mfile.print("install-rb-default: pre-install-rb-default\n")
|
2202
|
+
mfile.print("pre-install-rb: Makefile\n")
|
2203
|
+
mfile.print("pre-install-rb-default: Makefile\n")
|
2204
|
+
for sfx, i in [["-default", [["lib/**/*.rb", "$(RUBYLIBDIR)", "lib"]]], ["", $INSTALLFILES]]
|
2205
|
+
files = install_files(mfile, i, nil, srcprefix) or next
|
2206
|
+
for dir, *files in files
|
2207
|
+
unless dirs.include?(dir)
|
2208
|
+
dirs << dir
|
2209
|
+
mfile.print "pre-install-rb#{sfx}: #{timestamp_file(dir)}\n"
|
2210
|
+
end
|
2211
|
+
for f in files
|
2212
|
+
dest = "#{dir}/#{File.basename(f)}"
|
2213
|
+
mfile.print("install-rb#{sfx}: #{dest}\n")
|
2214
|
+
mfile.print("#{dest}: #{f} #{timestamp_file(dir)}\n")
|
2215
|
+
mfile.print("\t$(Q) $(#{$extout ? 'COPY' : 'INSTALL_DATA'}) #{f} $(@D#{sep})\n")
|
2216
|
+
if defined?($installed_list) and !$extout
|
2217
|
+
mfile.print("\t@echo #{dest}>>$(INSTALLED_LIST)\n")
|
2218
|
+
end
|
2219
|
+
if $extout
|
2220
|
+
mfile.print("clean-rb#{sfx}::\n")
|
2221
|
+
mfile.print("\t-$(Q)$(RM) #{fseprepl[dest]}\n")
|
2222
|
+
end
|
2223
|
+
end
|
1558
2224
|
end
|
1559
|
-
|
1560
|
-
|
1561
|
-
|
1562
|
-
|
1563
|
-
|
1564
|
-
|
1565
|
-
|
1566
|
-
|
1567
|
-
|
1568
|
-
|
1569
|
-
else
|
1570
|
-
sep = ""
|
1571
|
-
end
|
1572
|
-
mfile.print("#{f} $(@D#{sep})\n")
|
1573
|
-
if defined?($installed_list) and !$extout
|
1574
|
-
mfile.print("\t@echo #{dest}>>$(INSTALLED_LIST)\n")
|
1575
|
-
end
|
2225
|
+
mfile.print "pre-install-rb#{sfx}:\n"
|
2226
|
+
mfile.print("\t$(ECHO) installing#{sfx.sub(/^-/, " ")} #{target} libraries\n")
|
2227
|
+
if $extout
|
2228
|
+
dirs.uniq!
|
2229
|
+
unless dirs.empty?
|
2230
|
+
mfile.print("clean-rb#{sfx}::\n")
|
2231
|
+
for dir in dirs.sort_by {|d| -d.count('/')}
|
2232
|
+
mfile.print("\t-$(Q)$(RMDIRS) #{fseprepl[dir]}#{$ignore_error}\n")
|
2233
|
+
end
|
2234
|
+
end
|
1576
2235
|
end
|
1577
2236
|
end
|
1578
|
-
|
1579
|
-
|
1580
|
-
|
2237
|
+
dirs.unshift(sodir) if target and !dirs.include?(sodir)
|
2238
|
+
dirs.each do |d|
|
2239
|
+
t = timestamp_file(d)
|
2240
|
+
mfile.print "#{t}:\n\t$(Q) $(MAKEDIRS) #{d}\n\t$(Q) $(TOUCH) $@\n"
|
2241
|
+
end
|
1581
2242
|
|
1582
|
-
|
2243
|
+
mfile.print <<-SITEINSTALL
|
1583
2244
|
|
1584
2245
|
site-install: site-install-so site-install-rb
|
1585
2246
|
site-install-so: install-so
|
1586
2247
|
site-install-rb: install-rb
|
1587
2248
|
|
1588
|
-
|
2249
|
+
SITEINSTALL
|
1589
2250
|
|
1590
|
-
|
2251
|
+
return unless target
|
1591
2252
|
|
1592
|
-
|
1593
|
-
|
1594
|
-
|
2253
|
+
mfile.puts SRC_EXT.collect {|e| ".path.#{e} = $(VPATH)"} if $nmake == ?b
|
2254
|
+
mfile.print ".SUFFIXES: .#{SRC_EXT.join(' .')} .#{$OBJEXT}\n"
|
2255
|
+
mfile.print "\n"
|
1595
2256
|
|
1596
|
-
|
1597
|
-
|
1598
|
-
|
1599
|
-
|
2257
|
+
compile_command = "\n\t$(ECHO) compiling $(<#{rsep})\n\t$(Q) %s\n\n"
|
2258
|
+
CXX_EXT.each do |e|
|
2259
|
+
each_compile_rules do |rule|
|
2260
|
+
mfile.printf(rule, e, $OBJEXT)
|
2261
|
+
mfile.printf(compile_command, COMPILE_CXX)
|
2262
|
+
end
|
1600
2263
|
end
|
1601
|
-
|
1602
|
-
|
1603
|
-
|
1604
|
-
|
1605
|
-
|
2264
|
+
C_EXT.each do |e|
|
2265
|
+
each_compile_rules do |rule|
|
2266
|
+
mfile.printf(rule, e, $OBJEXT)
|
2267
|
+
mfile.printf(compile_command, COMPILE_C)
|
2268
|
+
end
|
1606
2269
|
end
|
1607
|
-
end
|
1608
2270
|
|
1609
|
-
|
1610
|
-
|
1611
|
-
|
1612
|
-
|
1613
|
-
|
1614
|
-
|
1615
|
-
|
1616
|
-
|
1617
|
-
|
1618
|
-
|
1619
|
-
|
1620
|
-
config_string('RANLIB') do |ranlib|
|
1621
|
-
mfile.print "\n\t@-#{ranlib} $(DLLIB) 2> /dev/null || true"
|
2271
|
+
mfile.print "$(RUBYARCHDIR)/" if $extout
|
2272
|
+
mfile.print "$(DLLIB): "
|
2273
|
+
mfile.print "$(DEFFILE) " if makedef
|
2274
|
+
mfile.print "$(OBJS) Makefile"
|
2275
|
+
mfile.print " #{timestamp_file('$(RUBYARCHDIR)')}" if $extout
|
2276
|
+
mfile.print "\n"
|
2277
|
+
mfile.print "\t$(ECHO) linking shared-object #{target_prefix.sub(/\A\/(.*)/, '\1/')}$(DLLIB)\n"
|
2278
|
+
mfile.print "\t-$(Q)$(RM) $(@#{sep})\n"
|
2279
|
+
link_so = LINK_SO.gsub(/^/, "\t$(Q) ")
|
2280
|
+
if srcs.any?(&%r"\.(?:#{CXX_EXT.join('|')})\z".method(:===))
|
2281
|
+
link_so = link_so.sub(/\bLDSHARED\b/, '\&XX')
|
1622
2282
|
end
|
1623
|
-
|
1624
|
-
|
1625
|
-
|
1626
|
-
|
1627
|
-
|
1628
|
-
|
1629
|
-
|
1630
|
-
depend = File.join(srcdir, "depend")
|
1631
|
-
if File.exist?(depend)
|
1632
|
-
suffixes = []
|
1633
|
-
depout = []
|
1634
|
-
open(depend, "r") do |dfile|
|
1635
|
-
mfile.printf "###\n"
|
1636
|
-
cont = implicit = nil
|
1637
|
-
impconv = proc do
|
1638
|
-
COMPILE_RULES.each {|rule| depout << (rule % implicit[0]) << implicit[1]}
|
1639
|
-
implicit = nil
|
1640
|
-
end
|
1641
|
-
ruleconv = proc do |line|
|
1642
|
-
if implicit
|
1643
|
-
if /\A\t/ =~ line
|
1644
|
-
implicit[1] << line
|
1645
|
-
next
|
1646
|
-
else
|
1647
|
-
impconv[]
|
1648
|
-
end
|
1649
|
-
end
|
1650
|
-
if m = /\A\.(\w+)\.(\w+)(?:\s*:)/.match(line)
|
1651
|
-
suffixes << m[1] << m[2]
|
1652
|
-
implicit = [[m[1], m[2]], [m.post_match]]
|
1653
|
-
next
|
1654
|
-
elsif RULE_SUBST and /\A(?!\s*\w+\s*=)[$\w][^#]*:/ =~ line
|
1655
|
-
line.gsub!(%r"(\s)(?!\.)([^$(){}+=:\s\/\\,]+)(?=\s|\z)") {$1 + RULE_SUBST % $2}
|
1656
|
-
end
|
1657
|
-
depout << line
|
1658
|
-
end
|
1659
|
-
while line = dfile.gets()
|
1660
|
-
line.gsub!(/\.o\b/, ".#{$OBJEXT}")
|
1661
|
-
line.gsub!(/\$\((?:hdr|top)dir\)\/config.h/, $config_h) if $config_h
|
1662
|
-
if /(?:^|[^\\])(?:\\\\)*\\$/ =~ line
|
1663
|
-
(cont ||= []) << line
|
1664
|
-
next
|
1665
|
-
elsif cont
|
1666
|
-
line = (cont << line).join
|
1667
|
-
cont = nil
|
1668
|
-
end
|
1669
|
-
ruleconv.call(line)
|
1670
|
-
end
|
1671
|
-
if cont
|
1672
|
-
ruleconv.call(cont.join)
|
1673
|
-
elsif implicit
|
1674
|
-
impconv.call
|
2283
|
+
mfile.print link_so, "\n\n"
|
2284
|
+
unless $static.nil?
|
2285
|
+
mfile.print "$(STATIC_LIB): $(OBJS)\n\t-$(Q)$(RM) $(@#{sep})\n\t"
|
2286
|
+
mfile.print "$(ECHO) linking static-library $(@#{rsep})\n\t$(Q) "
|
2287
|
+
mfile.print "$(AR) #{config_string('ARFLAGS') || 'cru '}$@ $(OBJS)"
|
2288
|
+
config_string('RANLIB') do |ranlib|
|
2289
|
+
mfile.print "\n\t-$(Q)#{ranlib} $(DLLIB) 2> /dev/null || true"
|
1675
2290
|
end
|
1676
2291
|
end
|
1677
|
-
|
1678
|
-
|
2292
|
+
mfile.print "\n\n"
|
2293
|
+
if makedef
|
2294
|
+
mfile.print "$(DEFFILE): #{origdef}\n"
|
2295
|
+
mfile.print "\t$(ECHO) generating $(@#{rsep})\n"
|
2296
|
+
mfile.print "\t$(Q) $(RUBY) #{makedef} #{origdef} > $@\n\n"
|
1679
2297
|
end
|
1680
|
-
|
1681
|
-
|
1682
|
-
|
1683
|
-
|
1684
|
-
|
1685
|
-
|
2298
|
+
|
2299
|
+
depend = File.join(srcdir, "depend")
|
2300
|
+
if File.exist?(depend)
|
2301
|
+
mfile.print("###\n", *depend_rules(File.read(depend)))
|
2302
|
+
else
|
2303
|
+
mfile.print "$(OBJS): $(HDRS) $(ruby_headers)\n"
|
1686
2304
|
end
|
1687
|
-
headers << $config_h if $config_h
|
1688
|
-
headers << "$(RUBY_EXTCONF_H)" if $extconf_h
|
1689
|
-
mfile.print "$(OBJS): ", headers.join(' '), "\n"
|
1690
|
-
end
|
1691
2305
|
|
1692
|
-
|
1693
|
-
ensure
|
1694
|
-
|
1695
|
-
end
|
2306
|
+
$makefile_created = true
|
2307
|
+
ensure
|
2308
|
+
mfile.close if mfile
|
2309
|
+
end
|
2310
|
+
|
2311
|
+
# :stopdoc:
|
2312
|
+
|
2313
|
+
def init_mkmf(config = CONFIG, rbconfig = RbConfig::CONFIG)
|
2314
|
+
$makefile_created = false
|
2315
|
+
$arg_config = []
|
2316
|
+
$enable_shared = config['ENABLE_SHARED'] == 'yes'
|
2317
|
+
$defs = []
|
2318
|
+
$extconf_h = nil
|
2319
|
+
if $warnflags = CONFIG['warnflags'] and CONFIG['GCC'] == 'yes'
|
2320
|
+
# turn warnings into errors only for bundled extensions.
|
2321
|
+
config['warnflags'] = $warnflags.gsub(/(\A|\s)-Werror[-=]/, '\1-W')
|
2322
|
+
RbConfig.expand(rbconfig['warnflags'] = config['warnflags'].dup)
|
2323
|
+
config.each do |key, val|
|
2324
|
+
RbConfig.expand(rbconfig[key] = val.dup) if /warnflags/ =~ val
|
2325
|
+
end
|
2326
|
+
$warnflags = config['warnflags'] unless $extmk
|
2327
|
+
end
|
2328
|
+
$CFLAGS = with_config("cflags", arg_config("CFLAGS", config["CFLAGS"])).dup
|
2329
|
+
$ARCH_FLAG = with_config("arch_flag", arg_config("ARCH_FLAG", config["ARCH_FLAG"])).dup
|
2330
|
+
$CPPFLAGS = with_config("cppflags", arg_config("CPPFLAGS", config["CPPFLAGS"])).dup
|
2331
|
+
$LDFLAGS = with_config("ldflags", arg_config("LDFLAGS", config["LDFLAGS"])).dup
|
2332
|
+
$INCFLAGS = "-I$(arch_hdrdir)"
|
2333
|
+
$INCFLAGS << " -I$(hdrdir)/ruby/backward" unless $extmk
|
2334
|
+
$INCFLAGS << " -I$(hdrdir) -I$(srcdir)"
|
2335
|
+
$DLDFLAGS = with_config("dldflags", arg_config("DLDFLAGS", config["DLDFLAGS"])).dup
|
2336
|
+
$LIBEXT = config['LIBEXT'].dup
|
2337
|
+
$OBJEXT = config["OBJEXT"].dup
|
2338
|
+
$EXEEXT = config["EXEEXT"].dup
|
2339
|
+
$LIBS = "#{config['LIBS']} #{config['DLDLIBS']}"
|
2340
|
+
$LIBRUBYARG = ""
|
2341
|
+
$LIBRUBYARG_STATIC = config['LIBRUBYARG_STATIC']
|
2342
|
+
$LIBRUBYARG_SHARED = config['LIBRUBYARG_SHARED']
|
2343
|
+
$DEFLIBPATH = [$extmk ? "$(topdir)" : "$(libdir)"]
|
2344
|
+
$DEFLIBPATH.unshift(".")
|
2345
|
+
$LIBPATH = []
|
2346
|
+
$INSTALLFILES = []
|
2347
|
+
$NONINSTALLFILES = [/~\z/, /\A#.*#\z/, /\A\.#/, /\.bak\z/i, /\.orig\z/, /\.rej\z/, /\.l[ao]\z/, /\.o\z/]
|
2348
|
+
$VPATH = %w[$(srcdir) $(arch_hdrdir)/ruby $(hdrdir)/ruby]
|
2349
|
+
|
2350
|
+
$objs = nil
|
2351
|
+
$srcs = nil
|
2352
|
+
$libs = ""
|
2353
|
+
if $enable_shared or RbConfig.expand(config["LIBRUBY"].dup) != RbConfig.expand(config["LIBRUBY_A"].dup)
|
2354
|
+
$LIBRUBYARG = config['LIBRUBYARG']
|
2355
|
+
end
|
1696
2356
|
|
1697
|
-
|
2357
|
+
$LOCAL_LIBS = ""
|
1698
2358
|
|
1699
|
-
|
1700
|
-
|
1701
|
-
|
1702
|
-
|
1703
|
-
|
1704
|
-
|
1705
|
-
|
1706
|
-
|
1707
|
-
|
1708
|
-
$LDFLAGS = with_config("ldflags", arg_config("LDFLAGS", config["LDFLAGS"])).dup
|
1709
|
-
$INCFLAGS = "-I$(topdir) -I$(hdrdir) -I$(srcdir)"
|
1710
|
-
$DLDFLAGS = with_config("dldflags", arg_config("DLDFLAGS", config["DLDFLAGS"])).dup
|
1711
|
-
$LIBEXT = config['LIBEXT'].dup
|
1712
|
-
$OBJEXT = config["OBJEXT"].dup
|
1713
|
-
$LIBS = "#{config['LIBS']} #{config['DLDLIBS']}"
|
1714
|
-
$LIBRUBYARG = ""
|
1715
|
-
$LIBRUBYARG_STATIC = config['LIBRUBYARG_STATIC']
|
1716
|
-
$LIBRUBYARG_SHARED = config['LIBRUBYARG_SHARED']
|
1717
|
-
$DEFLIBPATH = [$extmk ? "$(topdir)" : "$(libdir)"]
|
1718
|
-
$DEFLIBPATH.unshift(".")
|
1719
|
-
|
1720
|
-
# ---------------------- Changed for Rubinius --------------------------------
|
1721
|
-
# Make sure that we include the lib paths here that we may find libraries so
|
1722
|
-
# that built in extensions will also find them if they have been configured
|
1723
|
-
# at build time for Rubinius.
|
1724
|
-
Rubinius::BUILD_CONFIG[:include_dirs].each do |inc|
|
1725
|
-
$INCFLAGS << " -I#{inc.quote}"
|
1726
|
-
end
|
1727
|
-
Rubinius::BUILD_CONFIG[:lib_dirs].each do |lib|
|
1728
|
-
$DEFLIBPATH << lib
|
1729
|
-
end
|
1730
|
-
# ----------------------------------------------------------------------------
|
1731
|
-
|
1732
|
-
$LIBPATH = []
|
1733
|
-
$INSTALLFILES = []
|
1734
|
-
$NONINSTALLFILES = [/~\z/, /\A#.*#\z/, /\A\.#/, /\.bak\z/i, /\.orig\z/, /\.rej\z/, /\.l[ao]\z/, /\.o\z/]
|
1735
|
-
|
1736
|
-
$objs = nil
|
1737
|
-
$srcs = nil
|
1738
|
-
$libs = ""
|
1739
|
-
if $enable_shared or RbConfig.expand(config["LIBRUBY"].dup) != RbConfig.expand(config["LIBRUBY_A"].dup)
|
1740
|
-
$LIBRUBYARG = config['LIBRUBYARG']
|
1741
|
-
end
|
1742
|
-
|
1743
|
-
$LOCAL_LIBS = ""
|
1744
|
-
|
1745
|
-
$cleanfiles = config_string('CLEANFILES') {|s| Shellwords.shellwords(s)} || []
|
1746
|
-
$cleanfiles << "mkmf.log"
|
1747
|
-
$distcleanfiles = config_string('DISTCLEANFILES') {|s| Shellwords.shellwords(s)} || []
|
1748
|
-
|
1749
|
-
$extout ||= nil
|
1750
|
-
$extout_prefix ||= nil
|
1751
|
-
|
1752
|
-
$arg_config.clear
|
1753
|
-
dir_config("opt")
|
1754
|
-
end
|
2359
|
+
$cleanfiles = config_string('CLEANFILES') {|s| Shellwords.shellwords(s)} || []
|
2360
|
+
$cleanfiles << "mkmf.log"
|
2361
|
+
$distcleanfiles = config_string('DISTCLEANFILES') {|s| Shellwords.shellwords(s)} || []
|
2362
|
+
$distcleandirs = config_string('DISTCLEANDIRS') {|s| Shellwords.shellwords(s)} || []
|
2363
|
+
|
2364
|
+
$extout ||= nil
|
2365
|
+
$extout_prefix ||= nil
|
2366
|
+
|
2367
|
+
@libdir_basename = config["libdir"] && config["libdir"][/\A\$\(exec_prefix\)\/(.*)/, 1] or "lib"
|
1755
2368
|
|
1756
|
-
|
1757
|
-
|
1758
|
-
|
1759
|
-
|
2369
|
+
$arg_config.clear
|
2370
|
+
dir_config("opt")
|
2371
|
+
end
|
2372
|
+
|
2373
|
+
FailedMessage = <<MESSAGE
|
2374
|
+
Could not create Makefile due to some reason, probably lack of necessary
|
2375
|
+
libraries and/or headers. Check the mkmf.log file for more details. You may
|
2376
|
+
need configuration options.
|
1760
2377
|
|
1761
2378
|
Provided configuration options:
|
1762
2379
|
MESSAGE
|
1763
2380
|
|
1764
|
-
# Returns whether or not the Makefile was successfully generated. If not,
|
1765
|
-
# the script will abort with an error message.
|
1766
|
-
#
|
1767
|
-
# Internal use only.
|
1768
|
-
#
|
1769
|
-
def mkmf_failed(path)
|
1770
|
-
|
1771
|
-
|
1772
|
-
|
2381
|
+
# Returns whether or not the Makefile was successfully generated. If not,
|
2382
|
+
# the script will abort with an error message.
|
2383
|
+
#
|
2384
|
+
# Internal use only.
|
2385
|
+
#
|
2386
|
+
def mkmf_failed(path)
|
2387
|
+
unless $makefile_created or File.exist?("Makefile")
|
2388
|
+
opts = $arg_config.collect {|t, n| "\t#{t}#{n ? "=#{n}" : ""}\n"}
|
2389
|
+
abort "*** #{path} failed ***\n" + FailedMessage + opts.join
|
2390
|
+
end
|
1773
2391
|
end
|
1774
|
-
end
|
1775
2392
|
|
1776
|
-
|
2393
|
+
def MAIN_DOES_NOTHING(*refs)
|
2394
|
+
src = MAIN_DOES_NOTHING
|
2395
|
+
unless refs.empty?
|
2396
|
+
src = src.sub(/\{/) do
|
2397
|
+
$& +
|
2398
|
+
"\n if (argc > 1000000) {\n" +
|
2399
|
+
refs.map {|n|" printf(\"%p\", &#{n});\n"}.join("") +
|
2400
|
+
" }\n"
|
2401
|
+
end
|
2402
|
+
end
|
2403
|
+
src
|
2404
|
+
end
|
1777
2405
|
|
1778
|
-
|
2406
|
+
extend self
|
2407
|
+
init_mkmf
|
1779
2408
|
|
1780
|
-
$make = with_config("make-prog", ENV["MAKE"] || "make")
|
1781
|
-
make, = Shellwords.shellwords($make)
|
1782
|
-
$nmake = nil
|
1783
|
-
case
|
1784
|
-
when $mswin
|
1785
|
-
|
1786
|
-
when $bccwin
|
1787
|
-
|
1788
|
-
end
|
2409
|
+
$make = with_config("make-prog", ENV["MAKE"] || "make")
|
2410
|
+
make, = Shellwords.shellwords($make)
|
2411
|
+
$nmake = nil
|
2412
|
+
case
|
2413
|
+
when $mswin
|
2414
|
+
$nmake = ?m if /nmake/i =~ make
|
2415
|
+
when $bccwin
|
2416
|
+
$nmake = ?b if /Borland/i =~ `#{make} -h`
|
2417
|
+
end
|
2418
|
+
$ignore_error = $nmake ? '' : ' 2> /dev/null || true'
|
1789
2419
|
|
1790
|
-
RbConfig::CONFIG["srcdir"] = CONFIG["srcdir"] =
|
1791
|
-
|
1792
|
-
$configure_args["--topsrcdir"] ||= $srcdir
|
1793
|
-
if $curdir = arg_config("--curdir")
|
1794
|
-
|
1795
|
-
else
|
1796
|
-
|
1797
|
-
end
|
1798
|
-
unless File.expand_path(RbConfig::CONFIG["topdir"]) == File.expand_path(curdir)
|
1799
|
-
|
1800
|
-
|
1801
|
-
end
|
1802
|
-
$configure_args["--topdir"] ||= $curdir
|
1803
|
-
$ruby = arg_config("--ruby", File.join(RbConfig::CONFIG["bindir"], CONFIG["ruby_install_name"]))
|
2420
|
+
RbConfig::CONFIG["srcdir"] = CONFIG["srcdir"] =
|
2421
|
+
$srcdir = arg_config("--srcdir", File.dirname($0))
|
2422
|
+
$configure_args["--topsrcdir"] ||= $srcdir
|
2423
|
+
if $curdir = arg_config("--curdir")
|
2424
|
+
RbConfig.expand(curdir = $curdir.dup)
|
2425
|
+
else
|
2426
|
+
curdir = $curdir = "."
|
2427
|
+
end
|
2428
|
+
unless File.expand_path(RbConfig::CONFIG["topdir"]) == File.expand_path(curdir)
|
2429
|
+
CONFIG["topdir"] = $curdir
|
2430
|
+
RbConfig::CONFIG["topdir"] = curdir
|
2431
|
+
end
|
2432
|
+
$configure_args["--topdir"] ||= $curdir
|
2433
|
+
$ruby = arg_config("--ruby", File.join(RbConfig::CONFIG["bindir"], CONFIG["ruby_install_name"]))
|
1804
2434
|
|
1805
|
-
|
2435
|
+
# :startdoc:
|
1806
2436
|
|
1807
|
-
|
2437
|
+
split = Shellwords.method(:shellwords).to_proc
|
1808
2438
|
|
1809
|
-
|
1810
|
-
|
1811
|
-
|
1812
|
-
|
2439
|
+
EXPORT_PREFIX = config_string('EXPORT_PREFIX') {|s| s.strip}
|
2440
|
+
|
2441
|
+
hdr = ['#include "ruby.h"' "\n"]
|
2442
|
+
config_string('COMMON_MACROS') do |s|
|
2443
|
+
Shellwords.shellwords(s).each do |w|
|
2444
|
+
w, v = w.split(/=/, 2)
|
2445
|
+
hdr << "#ifndef #{w}"
|
2446
|
+
hdr << "#define #{[w, v].compact.join(" ")}"
|
2447
|
+
hdr << "#endif /* #{w} */"
|
2448
|
+
end
|
1813
2449
|
end
|
1814
|
-
|
1815
|
-
|
1816
|
-
|
1817
|
-
|
1818
|
-
|
1819
|
-
|
1820
|
-
|
1821
|
-
|
1822
|
-
|
1823
|
-
|
1824
|
-
|
1825
|
-
|
1826
|
-
|
1827
|
-
|
1828
|
-
|
1829
|
-
|
1830
|
-
|
1831
|
-
|
1832
|
-
|
1833
|
-
|
2450
|
+
config_string('COMMON_HEADERS') do |s|
|
2451
|
+
Shellwords.shellwords(s).each {|w| hdr << "#include <#{w}>"}
|
2452
|
+
end
|
2453
|
+
|
2454
|
+
##
|
2455
|
+
# Common headers for ruby C extensions
|
2456
|
+
|
2457
|
+
COMMON_HEADERS = hdr.join("\n")
|
2458
|
+
|
2459
|
+
##
|
2460
|
+
# Common libraries for ruby C extensions
|
2461
|
+
|
2462
|
+
COMMON_LIBS = config_string('COMMON_LIBS', &split) || []
|
2463
|
+
|
2464
|
+
##
|
2465
|
+
# make compile rules
|
2466
|
+
|
2467
|
+
COMPILE_RULES = config_string('COMPILE_RULES', &split) || %w[.%s.%s:]
|
2468
|
+
RULE_SUBST = config_string('RULE_SUBST')
|
2469
|
+
|
2470
|
+
##
|
2471
|
+
# Command which will compile C files in the generated Makefile
|
2472
|
+
|
2473
|
+
COMPILE_C = config_string('COMPILE_C') || '$(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $<'
|
2474
|
+
|
2475
|
+
##
|
2476
|
+
# Command which will compile C++ files in the generated Makefile
|
2477
|
+
|
2478
|
+
COMPILE_CXX = config_string('COMPILE_CXX') || '$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<'
|
2479
|
+
|
2480
|
+
##
|
2481
|
+
# Command which will compile a program in order to test linking a library
|
2482
|
+
|
2483
|
+
TRY_LINK = config_string('TRY_LINK') ||
|
2484
|
+
"$(CC) #{OUTFLAG}conftest#{$EXEEXT} $(INCFLAGS) $(CPPFLAGS) " \
|
2485
|
+
"$(CFLAGS) $(src) $(LIBPATH) $(LDFLAGS) $(ARCH_FLAG) $(LOCAL_LIBS) $(LIBS)"
|
2486
|
+
|
2487
|
+
##
|
2488
|
+
# Command which will link a shared library
|
2489
|
+
|
2490
|
+
LINK_SO = (config_string('LINK_SO') || "").sub(/^$/) do
|
2491
|
+
if CONFIG["DLEXT"] == $OBJEXT
|
2492
|
+
"ld $(DLDFLAGS) -r -o $@ $(OBJS)\n"
|
2493
|
+
else
|
2494
|
+
"$(LDSHARED) #{OUTFLAG}$@ $(OBJS) " \
|
2495
|
+
"$(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS)"
|
2496
|
+
end
|
1834
2497
|
end
|
1835
|
-
LIBPATHFLAG = config_string('LIBPATHFLAG') || ' -L"%s"'
|
1836
|
-
RPATHFLAG = config_string('RPATHFLAG') || ''
|
1837
|
-
LIBARG = config_string('LIBARG') || '-l%s'
|
1838
2498
|
|
1839
|
-
|
1840
|
-
|
1841
|
-
|
1842
|
-
|
2499
|
+
##
|
2500
|
+
# Argument which will add a library path to the linker
|
2501
|
+
|
2502
|
+
LIBPATHFLAG = config_string('LIBPATHFLAG') || ' -L%s'
|
2503
|
+
RPATHFLAG = config_string('RPATHFLAG') || ''
|
2504
|
+
|
2505
|
+
##
|
2506
|
+
# Argument which will add a library to the linker
|
1843
2507
|
|
1844
|
-
|
1845
|
-
@-$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log
|
1846
|
-
@-$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES#{sep})
|
2508
|
+
LIBARG = config_string('LIBARG') || '-l%s'
|
1847
2509
|
|
1848
|
-
|
2510
|
+
##
|
2511
|
+
# A C main function which does no work
|
2512
|
+
|
2513
|
+
MAIN_DOES_NOTHING = config_string('MAIN_DOES_NOTHING') || "int main(int argc, char **argv)\n{\n return 0;\n}"
|
2514
|
+
UNIVERSAL_INTS = config_string('UNIVERSAL_INTS') {|s| Shellwords.shellwords(s)} ||
|
2515
|
+
%w[int short long long\ long]
|
2516
|
+
|
2517
|
+
sep = config_string('BUILD_FILE_SEPARATOR') {|s| ":/=#{s}" if s != "/"} || ""
|
2518
|
+
|
2519
|
+
##
|
2520
|
+
# Makefile rules that will clean the extension build directory
|
2521
|
+
|
2522
|
+
CLEANINGS = "
|
2523
|
+
clean-static::
|
2524
|
+
clean-rb-default::
|
2525
|
+
clean-rb::
|
2526
|
+
clean-so::
|
2527
|
+
clean: clean-so clean-static clean-rb-default clean-rb
|
2528
|
+
\t\t-$(Q)$(RM) $(CLEANLIBS#{sep}) $(CLEANOBJS#{sep}) $(CLEANFILES#{sep}) .*.time
|
2529
|
+
|
2530
|
+
distclean-rb-default::
|
2531
|
+
distclean-rb::
|
2532
|
+
distclean-so::
|
2533
|
+
distclean-static::
|
2534
|
+
distclean: clean distclean-so distclean-static distclean-rb-default distclean-rb
|
2535
|
+
\t\t-$(Q)$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log
|
2536
|
+
\t\t-$(Q)$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES#{sep})
|
2537
|
+
\t\t-$(Q)$(RMDIRS) $(DISTCLEANDIRS#{sep})#{$ignore_error}
|
2538
|
+
|
2539
|
+
realclean: distclean
|
1849
2540
|
"
|
2541
|
+
end
|
2542
|
+
|
2543
|
+
include MakeMakefile
|
1850
2544
|
|
1851
2545
|
if not $extmk and /\A(extconf|makefile).rb\z/ =~ File.basename($0)
|
1852
2546
|
END {mkmf_failed($0)}
|