forked from rubinius/rubinius
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathkernel.rake
253 lines (202 loc) · 6.68 KB
/
kernel.rake
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
# All the tasks to manage building the Rubinius kernel--which is essentially
# the Ruby core library plus Rubinius-specific files. The kernel bootstraps
# a Ruby environment to the point that user code can be loaded and executed.
#
# The basic rule is that any generated file should be specified as a file
# task, not hidden inside some arbitrary task. Generated files are created by
# rule (e.g. the rule for compiling a .rb file into a .rbc file) or by a block
# attached to the file task for that particular file.
#
# The only tasks should be those names needed by the user to invoke specific
# parts of the build (including the top-level build task for generating the
# entire kernel).
require "rakelib/digest_files"
# drake does not allow invoke to be called inside tasks
def kernel_clean
rm_rf Dir["**/*.rbc",
"**/.*.rbc",
"kernel/**/signature.rb",
"spec/capi/ext/*.{o,sig,#{$dlext}}",
],
:verbose => $verbose
end
# TODO: Build this functionality into the compiler
class KernelCompiler
def self.compile(file, output, line, transforms)
compiler = Rubinius::ToolSets::Build::Compiler.new :file, :compiled_file
parser = compiler.parser
parser.root Rubinius::ToolSets::Build::AST::Script
if transforms.kind_of? Array
transforms.each { |t| parser.enable_category t }
else
parser.enable_category transforms
end
parser.input file, line
generator = compiler.generator
generator.processor Rubinius::ToolSets::Build::Generator
writer = compiler.writer
writer.version = BUILD_CONFIG[:libversion].sub(/\D/, "")
writer.name = output
compiler.run
end
end
# The rule for compiling all kernel Ruby files
rule ".rbc" do |t|
source = t.prerequisites.first
puts "RBC #{source}"
KernelCompiler.compile source, t.name, 1, [:default, :kernel]
end
# Collection of all files in the kernel runtime. Modified by
# various tasks below.
runtime_files = FileList["runtime/platform.conf"]
# Names of subdirectories of the language directories.
dir_names = %w[
bootstrap
platform
common
delta
]
# Generate file tasks for all kernel and load_order files.
def file_task(re, runtime_files, signature, rb, rbc)
rbc ||= ((rb.sub(re, "runtime") if re) || rb) + "c"
file rbc => [rb, signature]
runtime_files << rbc
end
def kernel_file_task(runtime_files, signature, rb, rbc=nil)
file_task(/^kernel/, runtime_files, signature, rb, rbc)
end
# Generate a digest of the Rubinius runtime files
signature_file = "kernel/signature.rb"
bootstrap_files = FileList[
"library/rbconfig.rb",
"library/rubinius/build_config.rb",
]
runtime_gems_dir = BUILD_CONFIG[:runtime_gems_dir]
bootstrap_gems_dir = BUILD_CONFIG[:bootstrap_gems_dir]
if runtime_gems_dir and bootstrap_gems_dir
ffi_files = FileList[
"#{bootstrap_gems_dir}/**/*.ffi"
].each { |f| f.gsub!(/.ffi\z/, '') }
runtime_gem_files = FileList[
"#{runtime_gems_dir}/**/*.rb"
].exclude("#{runtime_gems_dir}/**/spec/**/*.rb",
"#{runtime_gems_dir}/**/test/**/*.rb")
bootstrap_gem_files = FileList[
"#{bootstrap_gems_dir}/**/*.rb"
].exclude("#{bootstrap_gems_dir}/**/spec/**/*.rb",
"#{bootstrap_gems_dir}/**/test/**/*.rb")
ext_files = FileList[
"#{bootstrap_gems_dir}/**/*.{c,h}pp",
"#{bootstrap_gems_dir}/**/grammar.y",
"#{bootstrap_gems_dir}/**/lex.c.*"
]
else
ffi_files = runtime_gem_files = bootstrap_gem_files = ext_files = []
end
kernel_files = FileList[
"kernel/**/*.txt",
"kernel/**/*.rb"
].exclude(signature_file)
config_files = FileList[
"Rakefile",
"config.rb",
"rakelib/*.rb",
"rakelib/*.rake"
]
signature_files = kernel_files + config_files + runtime_gem_files + ext_files - ffi_files
file signature_file => signature_files do
# Collapse the digest to a 64bit quantity
hd = digest_files signature_files
SIGNATURE_HASH = hd[0, 16].to_i(16) ^ hd[16,16].to_i(16) ^ hd[32,8].to_i(16)
File.open signature_file, "wb" do |file|
file.puts "# This file is generated by rakelib/kernel.rake. The signature"
file.puts "# is used to ensure that the runtime files and VM are in sync."
file.puts "#"
file.puts "Rubinius::Signature = #{SIGNATURE_HASH}"
end
end
signature_header = "vm/gen/signature.h"
file signature_header => signature_file do |t|
File.open t.name, "wb" do |file|
file.puts "#define RBX_SIGNATURE #{SIGNATURE_HASH}ULL"
end
end
# Index files for loading a particular version of the kernel.
directory(runtime_base_dir = "runtime")
runtime_files << runtime_base_dir
runtime_index = "#{runtime_base_dir}/index"
runtime_files << runtime_index
file runtime_index => runtime_base_dir do |t|
File.open t.name, "wb" do |file|
file.puts dir_names
end
end
signature = "runtime/signature"
file signature => signature_file do |t|
File.open t.name, "wb" do |file|
puts "GEN #{t.name}"
file.puts Rubinius::Signature
end
end
runtime_files << signature
# All the kernel files
dir_names.each do |dir|
directory(runtime_dir = "runtime/#{dir}")
runtime_files << runtime_dir
load_order = "runtime/#{dir}/load_order.txt"
runtime_files << load_order
kernel_load_order = "kernel/#{dir}/load_order.txt"
file load_order => [kernel_load_order, signature] do |t|
cp t.prerequisites.first, t.name, :verbose => $verbose
end
kernel_dir = "kernel/#{dir}/"
runtime_dir = "runtime/#{dir}/"
IO.foreach kernel_load_order do |name|
rbc = runtime_dir + name.chomp!
rb = kernel_dir + name.chop
kernel_file_task runtime_files, signature_file, rb, rbc
end
end
[ signature_file,
"kernel/alpha.rb",
"kernel/loader.rb",
"kernel/delta/converter_paths.rb"
].each do |name|
kernel_file_task runtime_files, signature_file, name
end
# Build the bootstrap files
bootstrap_files.each do |name|
file_task nil, runtime_files, signature_file, name, nil
end
# Build the gem files
runtime_gem_files.each do |name|
file_task nil, runtime_files, signature_file, name, nil
end
# Build the bootstrap gem files
bootstrap_gem_files.each do |name|
file_task nil, runtime_files, signature_file, name, nil
end
namespace :compiler do
task :load => ['compiler:generate'] do
require "rubinius/bridge"
require "rubinius/toolset"
Rubinius::ToolSets.create :build do
require "rubinius/melbourne"
require "rubinius/processor"
require "rubinius/compiler"
require "rubinius/ast"
end
require File.expand_path("../../kernel/signature", __FILE__)
end
task :generate => [signature_file]
end
desc "Build all kernel files (alias for kernel:build)"
task :kernel => 'kernel:build'
namespace :kernel do
desc "Build all kernel files"
task :build => ['compiler:load'] + runtime_files
desc "Delete all .rbc files"
task :clean do
kernel_clean
end
end