source: EcnlProtoTool/trunk/mruby-1.2.0/tasks/mruby_build_commands.rake@ 270

Last change on this file since 270 was 270, checked in by coas-nagasima, 7 years ago

mruby版ECNLプロトタイピング・ツールを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-ruby
File size: 10.3 KB
Line 
1require 'forwardable'
2
3module MRuby
4 class Command
5 include Rake::DSL
6 extend Forwardable
7 def_delegators :@build, :filename, :objfile, :libfile, :exefile, :cygwin_filename
8 attr_accessor :build, :command
9
10 def initialize(build)
11 @build = build
12 end
13
14 # clone is deep clone without @build
15 def clone
16 target = super
17 excepts = %w(@build)
18 instance_variables.each do |attr|
19 unless excepts.include?(attr.to_s)
20 val = Marshal::load(Marshal.dump(instance_variable_get(attr))) # deep clone
21 target.instance_variable_set(attr, val)
22 end
23 end
24 target
25 end
26
27 NotFoundCommands = {}
28
29 private
30 def _run(options, params={})
31 return sh command + ' ' + ( options % params ) if NotFoundCommands.key? @command
32 begin
33 sh build.filename(command) + ' ' + ( options % params )
34 rescue RuntimeError
35 NotFoundCommands[@command] = true
36 _run options, params
37 end
38 end
39 end
40
41 class Command::Compiler < Command
42 attr_accessor :flags, :include_paths, :defines, :source_exts
43 attr_accessor :compile_options, :option_define, :option_include_path, :out_ext
44
45 def initialize(build, source_exts=[])
46 super(build)
47 @command = ENV['CC'] || 'cc'
48 @flags = [ENV['CFLAGS'] || []]
49 @source_exts = source_exts
50 @include_paths = ["#{MRUBY_ROOT}/include"]
51 @defines = %w()
52 @option_include_path = '-I%s'
53 @option_define = '-D%s'
54 @compile_options = '%{flags} -o %{outfile} -c %{infile}'
55 end
56
57 alias header_search_paths include_paths
58 def search_header_path(name)
59 header_search_paths.find do |v|
60 File.exist? build.filename("#{v}/#{name}").sub(/^"(.*)"$/, '\1')
61 end
62 end
63
64 def search_header(name)
65 path = search_header_path name
66 path && build.filename("#{path}/#{name}").sub(/^"(.*)"$/, '\1')
67 end
68
69 def all_flags(_defineds=[], _include_paths=[], _flags=[])
70 define_flags = [defines, _defineds].flatten.map{ |d| option_define % d }
71 include_path_flags = [include_paths, _include_paths].flatten.map do |f|
72 if MRUBY_BUILD_HOST_IS_CYGWIN
73 option_include_path % cygwin_filename(f)
74 else
75 option_include_path % filename(f)
76 end
77 end
78 [flags, define_flags, include_path_flags, _flags].flatten.join(' ')
79 end
80
81 def run(outfile, infile, _defineds=[], _include_paths=[], _flags=[])
82 FileUtils.mkdir_p File.dirname(outfile)
83 _pp "CC", infile.relative_path, outfile.relative_path
84 if MRUBY_BUILD_HOST_IS_CYGWIN
85 _run compile_options, { :flags => all_flags(_defineds, _include_paths, _flags),
86 :infile => cygwin_filename(infile), :outfile => cygwin_filename(outfile) }
87 else
88 _run compile_options, { :flags => all_flags(_defineds, _include_paths, _flags),
89 :infile => filename(infile), :outfile => filename(outfile) }
90 end
91 end
92
93 def define_rules(build_dir, source_dir='')
94 @out_ext = build.exts.object
95 gemrake = File.join(source_dir, "mrbgem.rake")
96 rakedep = File.exist?(gemrake) ? [ gemrake ] : []
97
98 if build_dir.include? "mrbgems/"
99 generated_file_matcher = Regexp.new("^#{Regexp.escape build_dir}/(.*)#{Regexp.escape out_ext}$")
100 else
101 generated_file_matcher = Regexp.new("^#{Regexp.escape build_dir}/(?!mrbgems/.+/)(.*)#{Regexp.escape out_ext}$")
102 end
103 source_exts.each do |ext, compile|
104 rule generated_file_matcher => [
105 proc { |file|
106 file.sub(generated_file_matcher, "#{source_dir}/\\1#{ext}")
107 },
108 proc { |file|
109 get_dependencies(file) + rakedep
110 }
111 ] do |t|
112 run t.name, t.prerequisites.first
113 end
114
115 rule generated_file_matcher => [
116 proc { |file|
117 file.sub(generated_file_matcher, "#{build_dir}/\\1#{ext}")
118 },
119 proc { |file|
120 get_dependencies(file) + rakedep
121 }
122 ] do |t|
123 run t.name, t.prerequisites.first
124 end
125 end
126 end
127
128 private
129 def get_dependencies(file)
130 file = file.ext('d') unless File.extname(file) == '.d'
131 if File.exist?(file)
132 File.read(file).gsub("\\\n ", "").scan(/^\S+:\s+(.+)$/).flatten.map {|s| s.split(' ') }.flatten
133 else
134 []
135 end + [ MRUBY_CONFIG ]
136 end
137 end
138
139 class Command::Linker < Command
140 attr_accessor :flags, :library_paths, :flags_before_libraries, :libraries, :flags_after_libraries
141 attr_accessor :link_options, :option_library, :option_library_path
142
143 def initialize(build)
144 super
145 @command = ENV['LD'] || 'ld'
146 @flags = (ENV['LDFLAGS'] || [])
147 @flags_before_libraries, @flags_after_libraries = [], []
148 @libraries = []
149 @library_paths = []
150 @option_library = '-l%s'
151 @option_library_path = '-L%s'
152 @link_options = "%{flags} -o %{outfile} %{objs} %{flags_before_libraries} %{libs} %{flags_after_libraries}"
153 end
154
155 def all_flags(_library_paths=[], _flags=[])
156 library_path_flags = [library_paths, _library_paths].flatten.map do |f|
157 if MRUBY_BUILD_HOST_IS_CYGWIN
158 option_library_path % cygwin_filename(f)
159 else
160 option_library_path % filename(f)
161 end
162 end
163 [flags, library_path_flags, _flags].flatten.join(' ')
164 end
165
166 def library_flags(_libraries)
167 [libraries, _libraries].flatten.map{ |d| option_library % d }.join(' ')
168 end
169
170 def run(outfile, objfiles, _libraries=[], _library_paths=[], _flags=[], _flags_before_libraries=[], _flags_after_libraries=[])
171 FileUtils.mkdir_p File.dirname(outfile)
172 library_flags = [libraries, _libraries].flatten.map { |d| option_library % d }
173
174 _pp "LD", outfile.relative_path
175 if MRUBY_BUILD_HOST_IS_CYGWIN
176 _run link_options, { :flags => all_flags(_library_paths, _flags),
177 :outfile => cygwin_filename(outfile) , :objs => cygwin_filename(objfiles).join(' '),
178 :flags_before_libraries => [flags_before_libraries, _flags_before_libraries].flatten.join(' '),
179 :flags_after_libraries => [flags_after_libraries, _flags_after_libraries].flatten.join(' '),
180 :libs => library_flags.join(' ') }
181 else
182 _run link_options, { :flags => all_flags(_library_paths, _flags),
183 :outfile => filename(outfile) , :objs => filename(objfiles).join(' '),
184 :flags_before_libraries => [flags_before_libraries, _flags_before_libraries].flatten.join(' '),
185 :flags_after_libraries => [flags_after_libraries, _flags_after_libraries].flatten.join(' '),
186 :libs => library_flags.join(' ') }
187 end
188 end
189 end
190
191 class Command::Archiver < Command
192 attr_accessor :archive_options
193
194 def initialize(build)
195 super
196 @command = ENV['AR'] || 'ar'
197 @archive_options = 'rs %{outfile} %{objs}'
198 end
199
200 def run(outfile, objfiles)
201 FileUtils.mkdir_p File.dirname(outfile)
202 _pp "AR", outfile.relative_path
203 if MRUBY_BUILD_HOST_IS_CYGWIN
204 _run archive_options, { :outfile => cygwin_filename(outfile), :objs => cygwin_filename(objfiles).join(' ') }
205 else
206 _run archive_options, { :outfile => filename(outfile), :objs => filename(objfiles).join(' ') }
207 end
208 end
209 end
210
211 class Command::Yacc < Command
212 attr_accessor :compile_options
213
214 def initialize(build)
215 super
216 @command = 'bison'
217 @compile_options = '-o %{outfile} %{infile}'
218 end
219
220 def run(outfile, infile)
221 FileUtils.mkdir_p File.dirname(outfile)
222 _pp "YACC", infile.relative_path, outfile.relative_path
223 _run compile_options, { :outfile => filename(outfile) , :infile => filename(infile) }
224 end
225 end
226
227 class Command::Gperf < Command
228 attr_accessor :compile_options
229
230 def initialize(build)
231 super
232 @command = 'gperf'
233 @compile_options = '-L ANSI-C -C -p -j1 -i 1 -g -o -t -N mrb_reserved_word -k"1,3,$" %{infile} > %{outfile}'
234 end
235
236 def run(outfile, infile)
237 FileUtils.mkdir_p File.dirname(outfile)
238 _pp "GPERF", infile.relative_path, outfile.relative_path
239 _run compile_options, { :outfile => filename(outfile) , :infile => filename(infile) }
240 end
241 end
242
243 class Command::Git < Command
244 attr_accessor :flags
245 attr_accessor :clone_options, :pull_options, :checkout_options
246
247 def initialize(build)
248 super
249 @command = 'git'
250 @flags = %w[]
251 @clone_options = "clone %{flags} %{url} %{dir}"
252 @pull_options = "pull"
253 @checkout_options = "checkout %{checksum_hash}"
254 end
255
256 def run_clone(dir, url, _flags = [])
257 _pp "GIT", url, dir.relative_path
258 _run clone_options, { :flags => [flags, _flags].flatten.join(' '), :url => url, :dir => filename(dir) }
259 end
260
261 def run_pull(dir, url)
262 root = Dir.pwd
263 Dir.chdir dir
264 _pp "GIT PULL", url, dir.relative_path
265 _run pull_options
266 Dir.chdir root
267 end
268
269 def run_checkout(dir, checksum_hash)
270 root = Dir.pwd
271 Dir.chdir dir
272 _pp "GIT CHECKOUT", checksum_hash
273 _run checkout_options, { :checksum_hash => checksum_hash }
274 Dir.chdir root
275 end
276 end
277
278 class Command::Mrbc < Command
279 attr_accessor :compile_options
280
281 def initialize(build)
282 super
283 @command = nil
284 @compile_options = "-B%{funcname} -o-"
285 end
286
287 def run(out, infiles, funcname)
288 @command ||= @build.mrbcfile
289 infiles = [infiles].flatten
290 infiles.each do |f|
291 _pp "MRBC", f.relative_path, nil, :indent => 2
292 end
293 IO.popen("#{filename @command} #{@compile_options % {:funcname => funcname}} #{filename(infiles).join(' ')}", 'r+') do |io|
294 out.puts io.read
295 end
296 # if mrbc execution fail, drop the file
297 if $?.exitstatus != 0
298 File.delete(out.path)
299 exit(-1)
300 end
301 end
302 end
303
304 class Command::CrossTestRunner < Command
305 attr_accessor :runner_options
306 attr_accessor :verbose_flag
307 attr_accessor :flags
308
309 def initialize(build)
310 super
311 @command = nil
312 @runner_options = '%{flags} %{infile}'
313 @verbose_flag = ''
314 @flags = []
315 end
316
317 def run(testbinfile)
318 puts "TEST for " + @build.name
319 _run runner_options, { :flags => [flags, verbose_flag].flatten.join(' '), :infile => testbinfile }
320 end
321 end
322
323end
Note: See TracBrowser for help on using the repository browser.