|
1 | 1 | require 'rbconfig'
|
2 | 2 | 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 | +} |
4 | 19 |
|
5 | 20 | 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 | + |
6 | 49 | C = OpenStruct.new
|
7 | 50 | c = RbConfig::CONFIG
|
8 | 51 | C.cc = "#{c['CC'] || 'gcc'}"
|
9 | 52 | C.cflags = "#{c['CFLAGS'] || '-Os'}"
|
10 | 53 | C.xcflags = "#{c['XCFLAGS'] || '-DRUBY_EXPORT'}"
|
| 54 | +C.exerb_cflags = "#{EXERB_CFLAGS[RUBY_VERSION]}" |
11 | 55 | 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 |
13 | 62 | C.ldflags = "-L#{c['libdir']}"
|
14 | 63 | C.xldflags = "#{c['XLDFLAGS'] || '-Wl,--stack,0x02000000'}"
|
15 | 64 | C.rubylib = "#{c['LIBRUBYARG_STATIC']}"
|
16 | 65 | C.libs = "#{c['LIBS']} -lstdc++"
|
| 66 | +C.ver = RUBY_VERSION.gsub('.','') |
| 67 | +C.src_dir = "src/mingw#{C.ver}" |
17 | 68 |
|
18 | 69 | def make_resource(target, source, type)
|
19 | 70 | file target => source do
|
|
62 | 113 | def link_cpp(target, options)
|
63 | 114 | sources = options[:sources]
|
64 | 115 | 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}" |
66 | 117 | ldflags = "#{C.ldflags} #{C.xldflags}"
|
67 | 118 | dllflags = options[:isdll] ? "-shared" : ""
|
68 | 119 | guiflags = options[:gui] ? "-mwindows" : ""
|
@@ -101,78 +152,110 @@ def make_def_proxy(target, source, proxy)
|
101 | 152 | end
|
102 | 153 | end
|
103 | 154 |
|
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 |
106 | 170 |
|
| 171 | +exerb_dll_base = "exerb50" |
| 172 | +file_resource_rc = "src/exerb/resource.rc" |
107 | 173 | file_resource_dll_o = "tmp/resource_dll.o"
|
108 | 174 | file_resource_cui_o = "tmp/resource_cui.o"
|
109 | 175 | file_resource_gui_o = "tmp/resource_gui.o"
|
110 | 176 | file_exerb_def = "tmp/#{exerb_dll_base}.def"
|
111 | 177 | file_exerb_lib = "tmp/#{exerb_dll_base}.dll.a"
|
112 | 178 | file_exerb_rt_def = "tmp/#{exerb_dll_base}_rt.def"
|
113 | 179 | 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 = [] |
126 | 197 | ruby_lib = nil
|
127 | 198 |
|
128 | 199 | if RUBY_SRC_DIR
|
129 | 200 | C.cflags = "-Os" # optimize for size
|
130 |
| - C.incflags = "#{C.incflags} -I#{RUBY_SRC_DIR}" |
131 | 201 | 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 |
140 | 208 | ruby_src << filename
|
141 | 209 | 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 |
145 | 214 | 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 |
148 | 224 | 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 |
154 | 225 | 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')}" } |
155 | 232 |
|
156 | 233 | lib_sources = Dir["src/exerb/{exerb,module,utility}.cpp"] + (ruby_lib ? [ruby_lib] : ruby_obj)
|
157 | 234 | dll_sources = [file_resource_dll_o]
|
158 | 235 | cui_sources = ["src/exerb/cui.cpp", file_resource_cui_o]
|
159 | 236 | gui_sources = ["src/exerb/gui.cpp", file_resource_gui_o]
|
160 | 237 |
|
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| |
164 | 243 | compile_c target, source
|
165 | 244 | end
|
166 | 245 |
|
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" |
168 | 251 | link_cpp file_exerb_dll, :sources => (dll_sources + lib_sources), :isdll => true, :def => file_exerb_def, :implib => file_exerb_lib
|
169 | 252 | make_def_proxy file_exerb_rt_def, file_exerb_def, exerb_dll_base
|
170 | 253 |
|
171 |
| -make_resource file_resource_cui_o, "src/exerb/resource.rc", "CUI" |
| 254 | +make_resource file_resource_cui_o, file_resource_rc, "CUI" |
172 | 255 | link_cpp file_ruby_cui, :sources => (cui_sources + lib_sources + [file_exerb_def])
|
173 | 256 | link_cpp file_ruby_cui_rt, :sources => (cui_sources + [file_exerb_lib, file_exerb_rt_def]), :rubylib => ""
|
174 | 257 |
|
175 |
| -make_resource file_resource_gui_o, "src/exerb/resource.rc", "GUI" |
| 258 | +make_resource file_resource_gui_o, file_resource_rc, "GUI" |
176 | 259 | link_cpp file_ruby_gui, :sources => (gui_sources + lib_sources + [file_exerb_def]), :gui => true
|
177 | 260 | link_cpp file_ruby_gui_rt, :sources => (gui_sources + [file_exerb_lib, file_exerb_rt_def]), :rubylib => "", :gui => true
|
178 | 261 |
|
|
0 commit comments