Class: MRuby::Build

Inherits:
#Object show all
Includes:
LoadGems, Rake::DSL
Defined in:
ext/enterprise_script_service/mruby/lib/mruby/build.rb

Direct Known Subclasses

CrossBuild

Defined Under Namespace

Classes: Exts

Constant Summary collapse

COMPILERS =
%w(cc cxx objc asm)
COMMANDS =
COMPILERS + %w(linker archiver yacc gperf git exts mrbc)

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from LoadGems

#enable_gems?, #gem, #gembox, #load_special_path_gem

Constructor Details

#initialize(name = 'host', build_dir = nil, internal: false, &block) ⇒ Build

Returns a new instance of Build.

[View source]

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
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 85

def initialize(name='host', build_dir=nil, internal: false, &block)
  @name = name.to_s

  unless current = MRuby.targets[@name]
    if ENV['OS'] == 'Windows_NT'
      @exts = Exts.new('.o', '.exe', '.a', '.pi')
    else
      @exts = Exts.new('.o', '', '.a', '.pi')
    end

    build_dir = build_dir || ENV['MRUBY_BUILD_DIR'] || "#{MRUBY_ROOT}/build"

    @file_separator = '/'
    @build_dir = "#{build_dir}/#{@name}"
    @gem_clone_dir = "#{build_dir}/repos/#{@name}"
    @cc = Command::Compiler.new(self, %w(.c), label: "CC")
    @cxx = Command::Compiler.new(self, %w(.cc .cxx .cpp), label: "CXX")
    @objc = Command::Compiler.new(self, %w(.m), label: "OBJC")
    @asm = Command::Compiler.new(self, %w(.S .asm .s), label: "ASM")
    @linker = Command::Linker.new(self)
    @archiver = Command::Archiver.new(self)
    @yacc = Command::Yacc.new(self)
    @gperf = Command::Gperf.new(self)
    @git = Command::Git.new(self)
    @mrbc = Command::Mrbc.new(self)

    @products = []
    @bins = []
    @gems = MRuby::Gem::List.new
    @libmruby_core_objs = []
    @libmruby_objs = [@libmruby_core_objs]
    @enable_libmruby = true
    @build_mrbtest_lib_only = false
    @cxx_exception_enabled = false
    @cxx_exception_disabled = false
    @cxx_abi_enabled = false
    @enable_bintest = false
    @enable_test = false
    @enable_lock = true
    @enable_presym = true
    @mrbcfile_external = false
    @internal = internal
    @toolchains = []
    @gem_dir_to_repo_url = {}

    MRuby.targets[@name] = current = self
  end

  MRuby::Build.current = current
  current.instance_eval(&block)
  if current.libmruby_enabled? && !current.mrbcfile_external?
    if current.presym_enabled?
      current.create_mrbc_build if current.host? || current.gems["mruby-bin-mrbc"]
    elsif current.host?
      current.build_mrbc_exec
    end
  end
  current.presym = Presym.new(current) if current.presym_enabled?
end

Class Attribute Details

.currentObject

Returns the value of attribute current.


54
55
56
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 54

def current
  @current
end

Instance Attribute Details

#binsObject

Returns the value of attribute bins.


74
75
76
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 74

def bins
  @bins
end

#build_dirObject

Returns the value of attribute build_dir.


74
75
76
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 74

def build_dir
  @build_dir
end

#extsObject

Returns the value of attribute exts.


74
75
76
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 74

def exts
  @exts
end

#file_separatorObject

Returns the value of attribute file_separator.


74
75
76
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 74

def file_separator
  @file_separator
end

#gem_clone_dirObject

Returns the value of attribute gem_clone_dir.


74
75
76
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 74

def gem_clone_dir
  @gem_clone_dir
end

#gem_dir_to_repo_urlObject (readonly)

Returns the value of attribute gem_dir_to_repo_url.


75
76
77
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 75

def gem_dir_to_repo_url
  @gem_dir_to_repo_url
end

#gemsObject (readonly)

Returns the value of attribute gems.


75
76
77
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 75

def gems
  @gems
end

#libmruby_core_objsObject (readonly)

Returns the value of attribute libmruby_core_objs.


75
76
77
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 75

def libmruby_core_objs
  @libmruby_core_objs
end

#libmruby_objsObject (readonly) Also known as: libmruby

Returns the value of attribute libmruby_objs.


75
76
77
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 75

def libmruby_objs
  @libmruby_objs
end

#mrbc_buildObject (readonly)

Returns the value of attribute mrbc_build.


75
76
77
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 75

def mrbc_build
  @mrbc_build
end

#nameObject

Returns the value of attribute name.


74
75
76
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 74

def name
  @name
end

#presymObject

Returns the value of attribute presym.


75
76
77
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 75

def presym
  @presym
end

#productsObject (readonly)

Returns the value of attribute products.


75
76
77
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 75

def products
  @products
end

#toolchainsObject (readonly)

Returns the value of attribute toolchains.


75
76
77
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 75

def toolchains
  @toolchains
end

Class Method Details

.install_dirObject

[View source]

67
68
69
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 67

def install_dir
  @install_dir ||= ENV['INSTALL_DIR'] || "#{MRUBY_ROOT}/bin"
end

.mruby_config_pathObject

[View source]

56
57
58
59
60
61
62
63
64
65
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 56

def mruby_config_path
  path = ENV['MRUBY_CONFIG'] || ENV['CONFIG']
  if path.nil? || path.empty?
    path = "#{MRUBY_ROOT}/build_config/default.rb"
  elsif !File.file?(path) && !Pathname.new(path).absolute?
    f = "#{MRUBY_ROOT}/build_config/#{path}.rb"
    path = File.exist?(f) ? f : File.extname(path).empty? ? f : path
  end
  path
end

Instance Method Details

#bintest_enabled?Boolean

Returns:

  • (Boolean)
[View source]

278
279
280
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 278

def bintest_enabled?
  @enable_bintest
end

#build_mrbc_execObject

[View source]

311
312
313
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 311

def build_mrbc_exec
  gem :core => 'mruby-bin-mrbc' unless @gems['mruby-bin-mrbc']
end

#build_mrbtest_lib_onlyObject

[View source]

410
411
412
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 410

def build_mrbtest_lib_only
  @build_mrbtest_lib_only = true
end

#build_mrbtest_lib_only?Boolean

Returns:

  • (Boolean)
[View source]

414
415
416
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 414

def build_mrbtest_lib_only?
  @build_mrbtest_lib_only
end

#compile_as_cxx(src, cxx_src = nil, obj = nil, includes = []) ⇒ Object

[View source]

231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 231

def compile_as_cxx(src, cxx_src = nil, obj = nil, includes = [])
  #
  # If `cxx_src` is specified, this method behaves the same as before as
  # compatibility mode, but `.d` file is not read.
  #
  # If `cxx_src` is omitted, `.d` file is read by using mruby standard
  # Rake rule (C++ source name is also changed).
  #
  if cxx_src
    obj ||= cxx_src + @exts.object
    dsts = [obj]
    dsts << (cxx_src + @exts.presym_preprocessed) if presym_enabled?
    defines = []
    include_paths = ["#{MRUBY_ROOT}/src", *includes]
    dsts.each do |dst|
      file dst => cxx_src do |t|
        cxx.run t.name, t.prerequisites.first, defines, include_paths
      end
    end
  else
    cxx_src = "#{build_dir}/#{src.relative_path})".ext << "-cxx.cxx"
    obj = cxx_src.ext(@exts.object)
  end

  file cxx_src => [src, __FILE__] do |t|
    mkdir_p File.dirname t.name
    IO.write t.name, <<EOS
#define __STDC_CONSTANT_MACROS
#define __STDC_LIMIT_MACROS

#ifndef MRB_USE_CXX_ABI
extern "C" {
#endif
#include "#{File.absolute_path src}"
#ifndef MRB_USE_CXX_ABI
}
#endif
EOS
  end

  obj
end

#compilersObject

[View source]

340
341
342
343
344
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 340

def compilers
  COMPILERS.map do |c|
    instance_variable_get("@#{c}")
  end
end

#cxx_abi_enabled?Boolean

Returns:

  • (Boolean)
[View source]

213
214
215
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 213

def cxx_abi_enabled?
  @cxx_abi_enabled
end

#cxx_exception_enabled?Boolean

Returns:

  • (Boolean)
[View source]

209
210
211
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 209

def cxx_exception_enabled?
  @cxx_exception_enabled
end

#debug_enabled?Boolean

Returns:

  • (Boolean)
[View source]

153
154
155
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 153

def debug_enabled?
  @enable_debug
end

#define_installer(src) ⇒ Object

[View source]

362
363
364
365
366
367
368
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 362

def define_installer(src)
  dst = "#{self.class.install_dir}/#{File.basename(src)}"
  file dst => src do
    install_D src, dst
  end
  dst
end

#define_installer_if_needed(bin) ⇒ Object

[View source]

370
371
372
373
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 370

def define_installer_if_needed(bin)
  exe = exefile("#{build_dir}/bin/#{bin}")
  host? ? define_installer(exe) : exe
end

#define_rulesObject

[View source]

346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 346

def define_rules
  use_mrdb = @gems["mruby-bin-debugger"]
  compilers.each do |compiler|
    if respond_to?(:enable_gems?) && enable_gems?
      compiler.defines -= %w(MRB_NO_GEMS)
    else
      compiler.defines += %w(MRB_NO_GEMS)
    end
    compiler.defines |= %w(MRB_USE_DEBUG_HOOK) if use_mrdb
  end
  [@cc, *(@cxx if cxx_exception_enabled?)].each do |compiler|
    compiler.define_rules(@build_dir, MRUBY_ROOT, @exts.object)
    compiler.define_rules(@build_dir, MRUBY_ROOT, @exts.presym_preprocessed) if presym_enabled?
  end
end

#disable_cxx_exceptionObject

[View source]

188
189
190
191
192
193
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 188

def disable_cxx_exception
  if @cxx_exception_enabled or @cxx_abi_enabled
    raise "cxx_exception already enabled"
  end
  @cxx_exception_disabled = true
end

#disable_libmrubyObject

[View source]

149
150
151
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 149

def disable_libmruby
  @enable_libmruby = false
end

#disable_lockObject

[View source]

180
181
182
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 180

def disable_lock
  @enable_lock = false
end

#disable_presymObject

[View source]

173
174
175
176
177
178
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 173

def disable_presym
  if @enable_presym
    @enable_presym = false
    compilers.each{|c| c.defines << "MRB_NO_PRESYM"}
  end
end

#enable_bintestObject

[View source]

274
275
276
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 274

def enable_bintest
  @enable_bintest = true
end

#enable_cxx_abiObject

[View source]

217
218
219
220
221
222
223
224
225
226
227
228
229
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 217

def enable_cxx_abi
  return if @cxx_abi_enabled
  if @cxx_exception_enabled
    raise "cxx_exception already enabled"
  end
  compilers.each { |c|
    c.defines += %w(MRB_USE_CXX_EXCEPTION MRB_USE_CXX_ABI)
    c.flags << c.cxx_compile_flag
    c.flags = c.flags.flatten - c.cxx_invalid_flags.flatten
  }
  linker.command = cxx.command if toolchains.find { |v| v == 'gcc' }
  @cxx_abi_enabled = true
end

#enable_cxx_exceptionObject

[View source]

195
196
197
198
199
200
201
202
203
204
205
206
207
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 195

def enable_cxx_exception
  return if @cxx_exception_enabled
  return if @cxx_abi_enabled
  if @cxx_exception_disabled
    raise "cxx_exception disabled"
  end
  @cxx_exception_enabled = true
  compilers.each { |c|
    c.defines += %w(MRB_USE_CXX_EXCEPTION)
    c.flags << c.cxx_exception_flag
  }
  linker.command = cxx.command if toolchains.find { |v| v == 'gcc' }
end

#enable_debugObject

[View source]

157
158
159
160
161
162
163
164
165
166
167
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 157

def enable_debug
  compilers.each do |c|
    c.defines += %w(MRB_DEBUG)
    if toolchains.any? { |toolchain| toolchain == "gcc" }
      c.flags += %w(-g3 -O0)
    end
  end
  @mrbc.compile_options += ' -g'

  @enable_debug = true
end

#enable_testObject Also known as: build_mrbtest

[View source]

302
303
304
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 302

def enable_test
  @enable_test = true
end

#exefile(name) ⇒ Object

[View source]

383
384
385
386
387
388
389
390
391
392
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 383

def exefile(name)
  if name.is_a?(Array)
    name.flatten.map { |n| exefile(n) }
  elsif File.extname(name).empty?
    "#{name}#{exts.executable}"
  else
    # `name` sometimes have (non-standard) extension (e.g. `.bat`).
    name
  end
end

#filename(name) ⇒ Object

[View source]

375
376
377
378
379
380
381
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 375

def filename(name)
  if name.is_a?(Array)
    name.flatten.map { |n| filename(n) }
  else
    name.gsub('/', file_separator)
  end
end

#host?Boolean

Returns:

  • (Boolean)
[View source]

469
470
471
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 469

def host?
  @name == "host"
end

#internal?Boolean

Returns:

  • (Boolean)
[View source]

473
474
475
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 473

def internal?
  @internal
end

#libfile(name) ⇒ Object

[View source]

402
403
404
405
406
407
408
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 402

def libfile(name)
  if name.is_a?(Array)
    name.flatten.map { |n| libfile(n) }
  else
    "#{name}#{exts.library}"
  end
end

#libmruby_core_staticObject

[View source]

461
462
463
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 461

def libmruby_core_static
  libfile("#{build_dir}/lib/libmruby_core")
end

#libmruby_enabled?Boolean

Returns:

  • (Boolean)
[View source]

145
146
147
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 145

def libmruby_enabled?
  @enable_libmruby
end

#libmruby_staticObject

[View source]

457
458
459
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 457

def libmruby_static
  libfile("#{build_dir}/lib/libmruby")
end

#librariesObject

[View source]

465
466
467
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 465

def libraries
  [libmruby_static]
end

#lock_enabled?Boolean

Returns:

  • (Boolean)
[View source]

184
185
186
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 184

def lock_enabled?
  Lockfile.enabled? && @enable_lock
end

#locksObject

[View source]

315
316
317
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 315

def locks
  Lockfile.build(@name)
end

#mrbcfileObject

[View source]

319
320
321
322
323
324
325
326
327
328
329
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 319

def mrbcfile
  return @mrbcfile if @mrbcfile

  gem_name = "mruby-bin-mrbc"
  gem = @gems[gem_name]
  gem ||= (host = MRuby.targets["host"]) && host.gems[gem_name]
  unless gem
    fail "external mrbc or mruby-bin-mrbc gem in current('#{@name}') or 'host' build is required"
  end
  @mrbcfile = exefile("#{gem.build.build_dir}/bin/mrbc")
end

#mrbcfile=(path) ⇒ Object

[View source]

331
332
333
334
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 331

def mrbcfile=(path)
  @mrbcfile = path
  @mrbcfile_external = true
end

#mrbcfile_external?Boolean

Returns:

  • (Boolean)
[View source]

336
337
338
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 336

def mrbcfile_external?
  @mrbcfile_external
end

#objfile(name) ⇒ Object

[View source]

394
395
396
397
398
399
400
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 394

def objfile(name)
  if name.is_a?(Array)
    name.flatten.map { |n| objfile(n) }
  else
    "#{name}#{exts.object}"
  end
end

#presym_enabled?Boolean

Returns:

  • (Boolean)
[View source]

169
170
171
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 169

def presym_enabled?
  @enable_presym
end

#primary_toolchainObject

[View source]

294
295
296
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 294

def primary_toolchain
  @toolchains.first
end
[View source]

438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 438

def print_build_summary
  puts "================================================"
  puts "      Config Name: #{@name}"
  puts " Output Directory: #{self.build_dir.relative_path}"
  puts "         Binaries: #{@bins.join(', ')}" unless @bins.empty?
  unless @gems.empty?
    puts "    Included Gems:"
    gems = @gems.sort_by { |gem| gem.name }
    gems.each do |gem|
      gem_version = " - #{gem.version}" if gem.version != '0.0.0'
      gem_summary = " - #{gem.summary}" if gem.summary
      puts "             #{gem.name}#{gem_version}#{gem_summary}"
      puts "               - Binaries: #{gem.bins.join(', ')}" unless gem.bins.empty?
    end
  end
  puts "================================================"
  puts
end

#rootObject

[View source]

298
299
300
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 298

def root
  MRUBY_ROOT
end

#run_bintestObject

[View source]

429
430
431
432
433
434
435
436
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 429

def run_bintest
  puts ">>> Bintest #{name} <<<"
  targets = @gems.select { |v| File.directory? "#{v.dir}/bintest" }.map { |v| filename v.dir }
  targets << filename(".") if File.directory? "./bintest"
  mrbc = @gems["mruby-bin-mrbc"] ? exefile("#{@build_dir}/bin/mrbc") : mrbcfile
  env = {"BUILD_DIR" => @build_dir, "MRBCFILE" => mrbc}
  sh env, "ruby test/bintest.rb#{verbose_flag} #{targets.join ' '}"
end

#run_testObject

[View source]

422
423
424
425
426
427
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 422

def run_test
  puts ">>> Test #{name} <<<"
  mrbtest = exefile("#{build_dir}/bin/mrbtest")
  sh "#{filename mrbtest.relative_path}#{verbose_flag}"
  puts
end

#test_enabled?Boolean

Returns:

  • (Boolean)
[View source]

307
308
309
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 307

def test_enabled?
  @enable_test
end

#toolchain(name = Toolchain.guess, params = {}) ⇒ Object

[View source]

282
283
284
285
286
287
288
289
290
291
292
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 282

def toolchain(name=Toolchain.guess, params={})
  name = name.to_s
  tc = Toolchain.toolchains[name] || begin
    path = "#{MRUBY_ROOT}/tasks/toolchains/#{name}.rake"
    fail "Unknown #{name} toolchain" unless File.exist?(path)
    load path
    Toolchain.toolchains[name]
  end
  tc.setup(self, params)
  @toolchains.unshift name
end

#verbose_flagObject

[View source]

418
419
420
# File 'ext/enterprise_script_service/mruby/lib/mruby/build.rb', line 418

def verbose_flag
  Rake.verbose ? ' -v' : ''
end