Skip to content

Commit 89c56ed

Browse files
committed
Make maintaining versions and patchlevels easier
Unfortunately 1.9.1 is too hard to build yet. :(
1 parent 2459df1 commit 89c56ed

File tree

2 files changed

+125
-43
lines changed

2 files changed

+125
-43
lines changed

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
1-
/src/mingw*/eval_exerb.c
21
/data/exerb/*
32
/tmp/*

Rakefile

Lines changed: 125 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,70 @@
11
require 'rbconfig'
22
require 'ostruct'
3-
require 'generator'
3+
4+
SUPPORTED_VERSIONS = {
5+
"1.8.6" => 383,
6+
"1.8.7" => 174,
7+
#"1.9.1" => 243,
8+
}
9+
10+
NEEDS_PATCHING = {
11+
"1.8.6" => ["eval.c", "variable.c"],
12+
"1.8.7" => ["eval.c", "variable.c"],
13+
#"1.9.1" => ["encoding.c", "load.c", "variable.c"],
14+
}
15+
16+
EXERB_CFLAGS = {
17+
#"1.9.1" => "-DRUBY19",
18+
}
419

520
RUBY_SRC_DIR = nil
21+
RUBY_SRC_MISSING = {
22+
"1.8.6" => ["fileblocks.c", "crypt.c", "flock.c"],
23+
"1.8.7" => ["fileblocks.c", "crypt.c", "flock.c"],
24+
#"1.9.1" => ["langinfo.c", "fileblocks.c", "crypt.c", "flock.c", "lgamma_r.c", "strlcpy.c", "strlcat.c"],
25+
}
26+
RUBY_SRC_IGNORE = [
27+
# 1.8
28+
"main.c",
29+
"winmain.c",
30+
"lex.c",
31+
"dmydln.c",
32+
# 1.9
33+
"blockinlining.c",
34+
"dmyencoding.c",
35+
"eval_error.c",
36+
"eval_jump.c",
37+
"golf_prelude.c",
38+
"goruby.c",
39+
"id.c",
40+
"miniprelude.c",
41+
"thread_pthread.c",
42+
"thread_win32.c",
43+
"vm_eval.c",
44+
"vm_exec.c",
45+
"vm_insnhelper.c",
46+
"vm_method.c",
47+
]
48+
649
C = OpenStruct.new
750
c = RbConfig::CONFIG
851
C.cc = "#{c['CC'] || 'gcc'}"
952
C.cflags = "#{c['CFLAGS'] || '-Os'}"
1053
C.xcflags = "#{c['XCFLAGS'] || '-DRUBY_EXPORT'}"
54+
C.exerb_cflags = "#{EXERB_CFLAGS[RUBY_VERSION]}"
1155
C.cppflags = "#{c['CPPFLAGS']}"
12-
C.incflags = "-Isrc/mingw -I#{c['archdir']}"
56+
C.incflags = "-Isrc/mingw"
57+
if c['rubyhdrdir']
58+
C.incflags = "#{C.incflags} -I#{c['rubyhdrdir']}/#{c['arch']} -I#{c['rubyhdrdir']}" if c['rubyhdrdir']
59+
else
60+
C.incflags = "#{C.incflags} -I#{c['archdir']}"
61+
end
1362
C.ldflags = "-L#{c['libdir']}"
1463
C.xldflags = "#{c['XLDFLAGS'] || '-Wl,--stack,0x02000000'}"
1564
C.rubylib = "#{c['LIBRUBYARG_STATIC']}"
1665
C.libs = "#{c['LIBS']} -lstdc++"
66+
C.ver = RUBY_VERSION.gsub('.','')
67+
C.src_dir = "src/mingw#{C.ver}"
1768

1869
def make_resource(target, source, type)
1970
file target => source do
@@ -62,7 +113,7 @@ end
62113
def link_cpp(target, options)
63114
sources = options[:sources]
64115
cc = C.cc
65-
cflags = "#{C.cflags} #{C.xcflags} #{C.cppflags} #{C.incflags}"
116+
cflags = "#{C.cflags} #{C.xcflags} #{C.exerb_cflags} #{C.cppflags} #{C.incflags}"
66117
ldflags = "#{C.ldflags} #{C.xldflags}"
67118
dllflags = options[:isdll] ? "-shared" : ""
68119
guiflags = options[:gui] ? "-mwindows" : ""
@@ -101,78 +152,110 @@ def make_def_proxy(target, source, proxy)
101152
end
102153
end
103154

104-
ver = RUBY_VERSION.gsub('.','')
105-
exerb_dll_base = "exerb50"
155+
# Ruby 1.9.1 doesn't have SyncEnumerator
156+
# This function is inspired by Python's zip
157+
def zip(*enums)
158+
r = block_given? ? nil : []
159+
len = enums.collect { |x| x.size }.max
160+
len.times do |i|
161+
val = enums.collect { |x| x[i] }
162+
if block_given?
163+
yield val
164+
else
165+
r << val
166+
end
167+
end
168+
r
169+
end
106170

171+
exerb_dll_base = "exerb50"
172+
file_resource_rc = "src/exerb/resource.rc"
107173
file_resource_dll_o = "tmp/resource_dll.o"
108174
file_resource_cui_o = "tmp/resource_cui.o"
109175
file_resource_gui_o = "tmp/resource_gui.o"
110176
file_exerb_def = "tmp/#{exerb_dll_base}.def"
111177
file_exerb_lib = "tmp/#{exerb_dll_base}.dll.a"
112178
file_exerb_rt_def = "tmp/#{exerb_dll_base}_rt.def"
113179
file_exerb_dll = "data/exerb/#{exerb_dll_base}.dll"
114-
file_ruby_cui = "data/exerb/ruby#{ver}c.exc"
115-
file_ruby_cui_rt = "data/exerb/ruby#{ver}crt.exc"
116-
file_ruby_gui = "data/exerb/ruby#{ver}g.exc"
117-
file_ruby_gui_rt = "data/exerb/ruby#{ver}grt.exc"
118-
file_eval_c = "src/mingw#{ver}/eval.c"
119-
file_eval_exerb_c = "tmp/eval_exerb.c"
120-
file_eval_exerb_o = "tmp/eval_exerb.o"
121-
file_variable_c = "src/mingw#{ver}/variable.c"
122-
file_variable_exerb_c = "tmp/variable_exerb.c"
123-
file_variable_exerb_o = "tmp/variable_exerb.o"
124-
ruby_src = [file_eval_exerb_c, file_variable_exerb_c]
125-
ruby_obj = [file_eval_exerb_o, file_variable_exerb_o]
180+
file_ruby_cui = "data/exerb/ruby#{C.ver}c.exc"
181+
file_ruby_cui_rt = "data/exerb/ruby#{C.ver}crt.exc"
182+
file_ruby_gui = "data/exerb/ruby#{C.ver}g.exc"
183+
file_ruby_gui_rt = "data/exerb/ruby#{C.ver}grt.exc"
184+
185+
C.patchlevel = SUPPORTED_VERSIONS[RUBY_VERSION]
186+
C.needs_patching = NEEDS_PATCHING[RUBY_VERSION]
187+
unless C.patchlevel and C.needs_patching
188+
fail <<-END
189+
Ruby #{RUBY_VERSION} is not yet supported.
190+
Try copying relevant files from ruby source tarball to #{C.src_dir}
191+
and update NEEDS_PATCHING and SUPPORTED_VERSIONS at the top of this
192+
Rakefile.
193+
END
194+
end
195+
196+
ruby_src = []
126197
ruby_lib = nil
127198

128199
if RUBY_SRC_DIR
129200
C.cflags = "-Os" # optimize for size
130-
C.incflags = "#{C.incflags} -I#{RUBY_SRC_DIR}"
131201
C.rubylib = ""
132-
file_eval_c = "#{RUBY_SRC_DIR}/eval.c"
133-
file_variable_c = "#{RUBY_SRC_DIR}/variable.c"
134-
ruby_src = []
135-
Dir["#{RUBY_SRC_DIR}/*.c"].each do |filename|
136-
next if filename =~ /lex\.c/i
137-
next if filename =~ /eval\.c/i
138-
next if filename =~ /main\.c/i
139-
next if filename =~ /variable\.c/i
202+
C.src_dir = RUBY_SRC_DIR
203+
files = Dir["#{RUBY_SRC_DIR}/*.c"] + Dir["#{RUBY_SRC_DIR}/win32/*.c"]
204+
files.each do |filename|
205+
name = File.basename(filename).downcase
206+
next if RUBY_SRC_IGNORE.include? name
207+
next if C.needs_patching.include? name
140208
ruby_src << filename
141209
end
142-
Dir["#{RUBY_SRC_DIR}/win32/*.c"].each do |filename|
143-
next if filename =~ /winmain\.c/i
144-
ruby_src << filename
210+
if RUBY_SRC_MISSING[RUBY_VERSION]
211+
RUBY_SRC_MISSING[RUBY_VERSION].each do |name|
212+
ruby_src << "#{RUBY_SRC_DIR}/missing/#{name}"
213+
end
145214
end
146-
["fileblocks.c", "crypt.c", "flock.c"].each do |name|
147-
ruby_src << "#{RUBY_SRC_DIR}/missing/#{name}"
215+
# TODO: ruby 1.9 requires builtin encodings + prelude.c
216+
ruby_lib = "tmp/libruby#{C.ver}.a"
217+
else
218+
unless C.patchlevel == RUBY_PATCHLEVEL
219+
fail <<-END
220+
Ruby #{RUBY_VERSION}-p#{C.patchlevel} expected, but you are running #{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}.
221+
Try updating relevant files in #{C.src_dir} from ruby source tarball
222+
and update SUPPORTED_VERSIONS at the top of this Rakefile.
223+
END
148224
end
149-
ruby_src << file_eval_exerb_c
150-
ruby_src << file_variable_exerb_c
151-
ruby_obj = ruby_src.map { |filename| filename.sub(RUBY_SRC_DIR, 'tmp').gsub(/\.c\Z/i, '.o') }
152-
ruby_lib = "tmp/libruby#{ver}.a"
153-
make_archive ruby_lib, ruby_obj
154225
end
226+
C.incflags = "#{C.incflags} -I#{C.src_dir}"
227+
228+
ruby_src_unpatched = C.needs_patching.map { |name| "#{C.src_dir}/#{name}" }
229+
ruby_src_patched = ruby_src_unpatched.map { |name| "tmp/patched/#{File.basename(name)}" }
230+
ruby_src += ruby_src_patched
231+
ruby_obj = ruby_src.map { |name| "tmp/#{File.basename(name).gsub(/\.c\Z/i, '.o')}" }
155232

156233
lib_sources = Dir["src/exerb/{exerb,module,utility}.cpp"] + (ruby_lib ? [ruby_lib] : ruby_obj)
157234
dll_sources = [file_resource_dll_o]
158235
cui_sources = ["src/exerb/cui.cpp", file_resource_cui_o]
159236
gui_sources = ["src/exerb/gui.cpp", file_resource_gui_o]
160237

161-
patch_rb_require file_eval_exerb_c, file_eval_c
162-
patch_rb_require file_variable_exerb_c, file_variable_c
163-
SyncEnumerator.new(ruby_obj, ruby_src).each do |target, source|
238+
zip(ruby_src_patched, ruby_src_unpatched) do |target, source|
239+
patch_rb_require target, source
240+
end
241+
242+
zip(ruby_obj, ruby_src) do |target, source|
164243
compile_c target, source
165244
end
166245

167-
make_resource file_resource_dll_o, "src/exerb/resource.rc", "RUNTIME"
246+
if ruby_lib
247+
make_archive ruby_lib, ruby_obj
248+
end
249+
250+
make_resource file_resource_dll_o, file_resource_rc, "RUNTIME"
168251
link_cpp file_exerb_dll, :sources => (dll_sources + lib_sources), :isdll => true, :def => file_exerb_def, :implib => file_exerb_lib
169252
make_def_proxy file_exerb_rt_def, file_exerb_def, exerb_dll_base
170253

171-
make_resource file_resource_cui_o, "src/exerb/resource.rc", "CUI"
254+
make_resource file_resource_cui_o, file_resource_rc, "CUI"
172255
link_cpp file_ruby_cui, :sources => (cui_sources + lib_sources + [file_exerb_def])
173256
link_cpp file_ruby_cui_rt, :sources => (cui_sources + [file_exerb_lib, file_exerb_rt_def]), :rubylib => ""
174257

175-
make_resource file_resource_gui_o, "src/exerb/resource.rc", "GUI"
258+
make_resource file_resource_gui_o, file_resource_rc, "GUI"
176259
link_cpp file_ruby_gui, :sources => (gui_sources + lib_sources + [file_exerb_def]), :gui => true
177260
link_cpp file_ruby_gui_rt, :sources => (gui_sources + [file_exerb_lib, file_exerb_rt_def]), :rubylib => "", :gui => true
178261

0 commit comments

Comments
 (0)