Skip to content

Instantly share code, notes, and snippets.

@AaronLasseigne
Last active April 21, 2020 19:10
Show Gist options
  • Save AaronLasseigne/ffb2684f4e00056f25daa6b75988b750 to your computer and use it in GitHub Desktop.
Save AaronLasseigne/ffb2684f4e00056f25daa6b75988b750 to your computer and use it in GitHub Desktop.
Making an mruby gem

Making an mruby gem

Official Doc

mrbgem.rake

spec.dir: The top level directory where the mrbgem.rake file exists.

Dynamic Linking Your Library

Do not use spec.linker.flags for everything. The flags are placed at the beginning of the linker call. If you want to include a library, it will add those flags before everything else which does not work on linux (gcc).

Bad:

spec.linker.flags << '-Lsome/lib'
spec.linker.flags << '-lsome'

Good:

spec.linker.library_paths << 'some/lib'
spec.linker.libraries << 'some'

Statically Linking Your Library

spec.linker.flags_after_libraries << 'some/lib/libsome.a'

C to mruby object (mrb_value) conversions

Array

mrb_ary_new_from_values(mrb_state, size, vals)

Boolean

mrb_bool_value(boolean/conditional)
mrb_true_value()
mrb_false_value()

Float

This may not exist if MRB_WITHOUT_FLOAT is used.

mrb_float_value(mrb_state, float)

Integer

mrb_fixnum_value(int)

NULL

mrb_nil_value()

String

mrb_str_new_cstr(mrb_state, char *)

Symbol

mrb_symbol_value(mrb_intern_cstr(mrb_state, char *))

mruby object (mrb_value) to C conversions

Float

This may not exist if MRB_WITHOUT_FLOAT is used.

mrb_float(mrb_value)

Integer

If you have an mrb_int type it can be used in places you would use a C int. For example, in a for loop you can directly use an mrb_int. If you explicitly need an int you can do:

mrb_fixnum(mrb_value)

String

mrb_string_value_cstr(mrb_state, &mrb_value)

Symbol

mrb_string_value_cstr(mrb_state, &mrb_sym2str(mrb, mrb_symbol(mrb_value)))

Calling an mruby method on an object

If we wanted to call to_s on an object:

mrb_funcall(mrb_state, mrb_value, "to_s", 0)

The last value is the arg count. After that it's variadic and takes any args to pass. There's also a "type safe" version called mrb_funcall_argv and mrb_funcall_with_block for when a block is needed.

Debugging Tests (in C)

When tests are run, they're actually compiled into an executable in the build directory. It can be found at bin/mrbtest. Adding conf.enable_debug to your build will let you debug the final executable. After running ruby minirake test to build the tests and run them, you can re-run them with a debugger (e.g. lldb .build/mruby/bin/mrbtest).

GC

Described in high level terms in the gc.c code.

Ruby Objects Handed to C

These need to be marked with mrb_gc_register() to keep the object from the GC. When you're done it needs to be returned with mrb_gc_unregister().

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment