mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Add Support for Ruby Extensions, C Extensions and Test Integration
This commit is contained in:
+15
-13
@@ -17,29 +17,31 @@ export AR = ar
|
||||
.PHONY : all
|
||||
all : $(INIT).o all_gems
|
||||
|
||||
$(MMAKER_BIN) : $(MMAKER).o
|
||||
@echo "Build the generator which creates the driver and Gem Makefile"
|
||||
$(LL) -o $@ $(CC_FLAGS) $<
|
||||
all_gems : g/Makefile
|
||||
@echo "Build all gems"
|
||||
$(MAKE) -C g
|
||||
|
||||
$(MMAKER).o : $(MMAKER).c
|
||||
$(CC) $(CC_FLAGS) -MMD -c $< -o $@
|
||||
g/Makefile : $(MMAKER_BIN)
|
||||
@echo "Generate Gem Makefile"
|
||||
$(MMAKER_BIN) makefile > $@
|
||||
|
||||
$(INIT).c : $(MMAKER_BIN)
|
||||
@echo "Generate Gem driver"
|
||||
$(MMAKER_BIN) $(INIT) > $@
|
||||
|
||||
$(INIT).o : $(INIT).c
|
||||
@echo "Build the driver which initiailizes all gems"
|
||||
gcc $(CC_FLAGS) -c $< -o $@
|
||||
@echo "Build the driver which initializes all gems"
|
||||
$(CC) $(CC_FLAGS) -MMD -c $< -o $@
|
||||
$(AR) rs $(LIBR) $@
|
||||
|
||||
g/Makefile :
|
||||
@echo "Generate Gem Makefile"
|
||||
$(MMAKER_BIN) makefile > $@
|
||||
# Generator
|
||||
|
||||
all_gems : $(MMAKER_BIN) g/Makefile
|
||||
@echo "Build all gems"
|
||||
$(MAKE) -C g
|
||||
$(MMAKER_BIN) : $(MMAKER).o
|
||||
@echo "Build the generator which creates the driver and Gem Makefile"
|
||||
$(LL) -o $@ $(CC_FLAGS) $<
|
||||
|
||||
$(MMAKER).o : $(MMAKER).c
|
||||
$(CC) $(CC_FLAGS) -MMD -c $< -o $@
|
||||
|
||||
test :
|
||||
@$(MAKE) test -C g
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
include ../../Makefile4gem
|
||||
|
||||
GEM := hello_world
|
||||
GEM := clib_example
|
||||
|
||||
GEM_C_FILES := $(wildcard $(SRC_DIR)/*.c)
|
||||
GEM_OBJECTS := $(patsubst %.c, %.o, $(GEM_C_FILES))
|
||||
@@ -0,0 +1,4 @@
|
||||
CLib Extension Example
|
||||
=========
|
||||
|
||||
This is an example gem which implements a C extension.
|
||||
@@ -0,0 +1,17 @@
|
||||
#include <mruby.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static struct RClass *_class_clib;
|
||||
|
||||
static mrb_value
|
||||
mrb_clib_example(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
puts("A C Extension");
|
||||
return self;
|
||||
}
|
||||
|
||||
void
|
||||
mrb_clib_example_gem_init(mrb_state* mrb) {
|
||||
_class_clib = mrb_define_module(mrb, "CLib");
|
||||
mrb_define_class_method(mrb, _class_clib, "clib_method", mrb_clib_example, ARGS_NONE());
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
assert('CLib Extension') do
|
||||
CLib.respond_to? :clib_method
|
||||
end
|
||||
@@ -1,17 +0,0 @@
|
||||
#include <mruby.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static struct RClass *_class_hw;
|
||||
|
||||
static mrb_value
|
||||
mrb_hello_world(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
puts("Hello World");
|
||||
return self;
|
||||
}
|
||||
|
||||
void
|
||||
mrb_hello_world_gem_init(mrb_state* mrb) {
|
||||
_class_hw = mrb_define_module(mrb, "HW");
|
||||
mrb_define_class_method(mrb, _class_hw, "say", mrb_hello_world, ARGS_NONE());
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
assert('Hello World') do
|
||||
HW.respond_to? :say
|
||||
end
|
||||
@@ -0,0 +1,7 @@
|
||||
include ../../Makefile4gem
|
||||
|
||||
GEM := mrblib_example
|
||||
|
||||
gem-all :
|
||||
|
||||
gem-clean :
|
||||
@@ -0,0 +1,5 @@
|
||||
class MRBLib
|
||||
def MRBLib.mrblib_method
|
||||
puts "A Ruby Extension"
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,3 @@
|
||||
assert('MRBLib extension') do
|
||||
MRBLib.respond_to? :mrblib_method
|
||||
end
|
||||
+96
-12
@@ -1,22 +1,61 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <mrbconf.h>
|
||||
|
||||
static int
|
||||
one (const struct dirent *unused)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Does a directory exist?
|
||||
* yes => TRUE
|
||||
* no => FALSE
|
||||
* fs error => FALSE
|
||||
*
|
||||
*/
|
||||
static int
|
||||
directory_exists(char path[4096]) {
|
||||
DIR* dir = opendir(path);
|
||||
if (dir)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Template generator for each GEM
|
||||
*
|
||||
* Arguments:
|
||||
* before:
|
||||
* String before each GEM template
|
||||
* after:
|
||||
* String after each GEM template
|
||||
* start:
|
||||
* String at the start of the template
|
||||
* end:
|
||||
* String at the end of the template
|
||||
* skip_if_src_not_exist:
|
||||
* TRUE => skip template for GEMs with SRC directory
|
||||
* FALSE => template for all GEMs
|
||||
*
|
||||
*/
|
||||
void
|
||||
dir_list (char before[1024], char after[1024], char start[1024], char end[1024])
|
||||
for_each_gem (char before[1024], char after[1024],
|
||||
char start[1024], char end[1024],
|
||||
char dir_to_skip[1024])
|
||||
{
|
||||
struct dirent **eps;
|
||||
int n;
|
||||
char gemname[1024] = "";
|
||||
char gemname_path[4096] = "";
|
||||
char complete_line[4096] = "";
|
||||
char src_path[4096] = "";
|
||||
struct stat attribut;
|
||||
|
||||
strcat(complete_line, start);
|
||||
@@ -28,6 +67,8 @@ dir_list (char before[1024], char after[1024], char start[1024], char end[1024])
|
||||
strcpy(gemname, eps[cnt]->d_name);
|
||||
strcpy(gemname_path, "./g/");
|
||||
strcat(gemname_path, gemname);
|
||||
strcpy(src_path, gemname_path);
|
||||
strcat(src_path, "/src");
|
||||
|
||||
if (strcmp(gemname, ".") == 0)
|
||||
continue;
|
||||
@@ -35,13 +76,22 @@ dir_list (char before[1024], char after[1024], char start[1024], char end[1024])
|
||||
continue;
|
||||
|
||||
stat(gemname_path, &attribut);
|
||||
if (S_ISDIR(attribut.st_mode) == 0)
|
||||
if (S_ISDIR(attribut.st_mode) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmp(dir_to_skip, "") != 0) {
|
||||
strcpy(src_path, gemname_path);
|
||||
strcat(src_path, "/");
|
||||
strcat(src_path, dir_to_skip);
|
||||
|
||||
if (directory_exists(src_path) != TRUE)
|
||||
continue;
|
||||
}
|
||||
|
||||
strcat(complete_line, before);
|
||||
strcat(complete_line, gemname);
|
||||
strcat(complete_line, after);
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -65,8 +115,28 @@ make_gem_makefile()
|
||||
puts("");
|
||||
|
||||
puts(".PHONY : all");
|
||||
puts("all :");
|
||||
dir_list("\t@$(MAKE) -C ", " $(MAKE_FLAGS)\n", "", "");
|
||||
puts("all : all_gems mrblib_gem.o");
|
||||
puts("\t$(AR) rs ../../lib/libmruby.a mrblib_gem.o");
|
||||
puts("");
|
||||
|
||||
puts("all_gems :");
|
||||
for_each_gem("\t@$(MAKE) -C ", " $(MAKE_FLAGS)\n", "", "", "");
|
||||
puts("");
|
||||
|
||||
puts("mrblib_gem.o : mrblib_gem.c");
|
||||
puts("");
|
||||
|
||||
puts("mrblib_gem.c : mrblib_gem.ctmp");
|
||||
puts("\tcat $< > $@");
|
||||
puts("");
|
||||
|
||||
puts("mrblib_gem.ctmp : mrblib_gem.rbtmp");
|
||||
puts("\t../../bin/mrbc -Bmrblib_gem_irep -o$@ $<");
|
||||
puts("");
|
||||
|
||||
puts("mrblib_gem.rbtmp :");
|
||||
for_each_gem(" ", "/mrblib/*.rb", "\tcat", "> mrblib_gem.rbtmp", "mrblib");
|
||||
puts("");
|
||||
|
||||
puts(".PHONY : test");
|
||||
puts("test : mrbtest");
|
||||
@@ -93,13 +163,13 @@ make_gem_makefile()
|
||||
puts("");
|
||||
|
||||
puts("mrbtest.rbtmp :");
|
||||
dir_list("", "/test/*.rb ", "\tcat ../../test/assert.rb ", "> mrbtest.rbtmp");
|
||||
for_each_gem("", "/test/*.rb ", "\tcat ../../test/assert.rb ", "> mrbtest.rbtmp", "");
|
||||
puts("");
|
||||
|
||||
puts(".PHONY : clean");
|
||||
puts("clean :");
|
||||
puts("\t$(RM) *.c *.d *.rbtmp *.ctmp *.o mrbtest");
|
||||
dir_list("\t@$(MAKE) clean -C ", " $(MAKE_FLAGS)\n", "", "");
|
||||
for_each_gem("\t@$(MAKE) clean -C ", " $(MAKE_FLAGS)\n", "", "", "");
|
||||
}
|
||||
|
||||
void
|
||||
@@ -117,14 +187,28 @@ make_init_gems()
|
||||
|
||||
puts("");
|
||||
puts("#include \"mruby.h\"");
|
||||
puts("#include \"mruby/irep.h\"");
|
||||
puts("#include \"mruby/dump.h\"");
|
||||
puts("#include \"mruby/string.h\"");
|
||||
puts("#include \"mruby/proc.h\"");
|
||||
puts("");
|
||||
|
||||
dir_list("void mrb_", "_gem_init(mrb_state*);\n", "", "");
|
||||
for_each_gem("void mrb_", "_gem_init(mrb_state*);\n", "", "", "src");
|
||||
|
||||
puts("extern const char mrblib_gem_irep[];");
|
||||
puts("");
|
||||
|
||||
puts("void");
|
||||
puts("mrb_init_mrbgems(mrb_state *mrb)");
|
||||
puts("{");
|
||||
dir_list(" mrb_", "_gem_init(mrb);\n", "", "");
|
||||
puts("mrb_init_mrbgems(mrb_state *mrb) {");
|
||||
|
||||
for_each_gem(" mrb_", "_gem_init(mrb);\n", "", "", "src");
|
||||
|
||||
puts(" int n = mrb_read_irep(mrb, mrblib_gem_irep);");
|
||||
puts(" mrb_run(mrb, mrb_proc_new(mrb, mrb->irep[n]), mrb_top_self(mrb));");
|
||||
puts(" if (mrb->exc) {");
|
||||
puts(" mrb_p(mrb, mrb_obj_value(mrb->exc));");
|
||||
puts(" exit(0);");
|
||||
puts(" }");
|
||||
puts("}");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user