summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--Makefile3
-rw-r--r--mrbgems/Makefile53
-rw-r--r--mrbgems/Makefile4gem37
-rw-r--r--mrbgems/g/hello_world/Makefile12
-rw-r--r--mrbgems/g/hello_world/README.md4
-rw-r--r--mrbgems/g/hello_world/src/hello_world.c17
-rw-r--r--mrbgems/g/hello_world/test/hello_world.rb3
-rw-r--r--mrbgems/gem_helper.c131
-rw-r--r--mrblib/Makefile3
-rw-r--r--src/init.c2
-rw-r--r--tools/mrbc/mrbc.c5
12 files changed, 271 insertions, 2 deletions
diff --git a/.gitignore b/.gitignore
index 797f98917..02ffb598a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -24,3 +24,6 @@ cscope.out
/test/*.*tmp
CMakeFiles
CMakeCache.txt
+/mrbgems/gem_helper
+/mrbgems/init_gems.c
+/mrbgems/g/Makefile
diff --git a/Makefile b/Makefile
index 2df86c949..6866ec9e3 100644
--- a/Makefile
+++ b/Makefile
@@ -44,6 +44,7 @@ export CAT := cat
all :
@$(MAKE) -C src $(MAKE_FLAGS)
@$(MAKE) -C mrblib $(MAKE_FLAGS)
+ @$(MAKE) -C mrbgems $(MAKE_FLAGS)
@$(MAKE) -C tools/mruby $(MAKE_FLAGS)
@$(MAKE) -C tools/mirb $(MAKE_FLAGS)
@@ -51,11 +52,13 @@ all :
.PHONY : test
test : all
@$(MAKE) -C test $(MAKE_FLAGS)
+ @$(MAKE) test -C mrbgems $(MAKE_FLAGS)
# clean up
.PHONY : clean
clean :
@$(MAKE) clean -C src $(MAKE_FLAGS)
+ @$(MAKE) clean -C mrbgems $(MAKE_FLAGS)
@$(MAKE) clean -C tools/mruby $(MAKE_FLAGS)
@$(MAKE) clean -C tools/mirb $(MAKE_FLAGS)
@$(MAKE) clean -C test $(MAKE_FLAGS)
diff --git a/mrbgems/Makefile b/mrbgems/Makefile
new file mode 100644
index 000000000..6fde97128
--- /dev/null
+++ b/mrbgems/Makefile
@@ -0,0 +1,53 @@
+# makefile description.
+# add gems to the ruby library
+
+LIBR := ../lib/libmruby.a
+INIT := init_gems
+RM_F := rm -f
+CC_FLAGS := -Wall -Werror-implicit-function-declaration -g -O3 -MMD -I. -I./../include
+MMAKER := ./gem_helper
+MMAKER_BIN := $(MMAKER)
+export CC = gcc
+export LL = gcc
+export AR = ar
+
+##############################
+# generic build targets, rules
+
+.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) $<
+
+$(MMAKER).o : $(MMAKER).c
+ $(CC) $(CC_FLAGS) -MMD -c $< -o $@
+
+$(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 $@
+ $(AR) rs $(LIBR) $@
+
+g/Makefile :
+ @echo "Generate Gem Makefile"
+ $(MMAKER_BIN) makefile > $@
+
+all_gems : $(MMAKER_BIN) g/Makefile
+ @echo "Build all gems"
+ $(MAKE) -C g
+
+test :
+ $(MAKE) test -C g
+
+# clean driver and all gems
+.PHONY : clean
+clean : $(MMAKER_BIN)
+ @echo "Cleanup Gems"
+ $(MMAKER_BIN) makefile > g/Makefile
+ $(MAKE) clean -C g
+ -$(RM_F) $(INIT).c *.o *.d $(MMAKER_BIN) g/Makefile
diff --git a/mrbgems/Makefile4gem b/mrbgems/Makefile4gem
new file mode 100644
index 000000000..a4fa3f3c9
--- /dev/null
+++ b/mrbgems/Makefile4gem
@@ -0,0 +1,37 @@
+# This is the default Makefile integrated
+# by each Gem. It integrates important constants
+# for usage inside of a Gem.
+
+# mruby src root
+MRUBY_ROOT := ../../../
+
+# Tools
+CC := gcc
+RM := rm -f
+AR := ar
+
+SRC_DIR := src
+
+INCLUDES := -I$(SRC_DIR) -I$(MRUBY_ROOT)include -I$(MRUBY_ROOT)src -I.
+CFLAGS := $(INCLUDES) -O3 -g -Wall -Werror-implicit-function-declaration
+
+# LIBR can be manipulated with command line arguments
+ifeq ($(strip $(LIBR)),)
+ # default mruby library
+ LIBR := $(MRUBY_ROOT)lib/libmruby.a
+endif
+
+# Default rules which are calling the
+# gem specific gem-all and gem-clean
+# implementations of a gem
+
+.PHONY : all
+all : gem-info gem-all
+ @echo "Gem '$(GEM)' is done"
+
+gem-info:
+ @echo "Building Gem '$(GEM)'"
+
+.PHONY : clean
+clean : gem-clean
+ @echo "Gem '$(GEM)' is clean"
diff --git a/mrbgems/g/hello_world/Makefile b/mrbgems/g/hello_world/Makefile
new file mode 100644
index 000000000..c03910bf6
--- /dev/null
+++ b/mrbgems/g/hello_world/Makefile
@@ -0,0 +1,12 @@
+include ../../Makefile4gem
+
+GEM := hello_world
+
+GEM_C_FILES := $(wildcard $(SRC_DIR)/*.c)
+GEM_OBJECTS := $(patsubst %.c, %.o, $(GEM_C_FILES))
+
+gem-all : $(GEM_OBJECTS)
+ $(AR) rs $(LIBR) $<
+
+gem-clean :
+ -$(RM) $(GEM_OBJECTS)
diff --git a/mrbgems/g/hello_world/README.md b/mrbgems/g/hello_world/README.md
new file mode 100644
index 000000000..42792567f
--- /dev/null
+++ b/mrbgems/g/hello_world/README.md
@@ -0,0 +1,4 @@
+hello world
+=========
+
+This is an example gem which implements just one method +HW.say+ in a C extension.
diff --git a/mrbgems/g/hello_world/src/hello_world.c b/mrbgems/g/hello_world/src/hello_world.c
new file mode 100644
index 000000000..75d353542
--- /dev/null
+++ b/mrbgems/g/hello_world/src/hello_world.c
@@ -0,0 +1,17 @@
+#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());
+}
diff --git a/mrbgems/g/hello_world/test/hello_world.rb b/mrbgems/g/hello_world/test/hello_world.rb
new file mode 100644
index 000000000..2d8c335db
--- /dev/null
+++ b/mrbgems/g/hello_world/test/hello_world.rb
@@ -0,0 +1,3 @@
+assert('Hello World') do
+ HW.respond_to? :say
+end
diff --git a/mrbgems/gem_helper.c b/mrbgems/gem_helper.c
new file mode 100644
index 000000000..01daef364
--- /dev/null
+++ b/mrbgems/gem_helper.c
@@ -0,0 +1,131 @@
+#include <string.h>
+#include <stdio.h>
+#include <dirent.h>
+#include <sys/stat.h>
+
+static int
+one (const struct dirent *unused)
+{
+ return 1;
+}
+
+void
+dir_list (char before[1024], char after[1024], char start[1024], char end[1024])
+{
+ struct dirent **eps;
+ int n;
+ char gemname[1024] = "";
+ char gemname_path[4096] = "";
+ char complete_line[4096] = "";
+ struct stat attribut;
+
+ strcat(complete_line, start);
+
+ n = scandir("./g", &eps, one, alphasort);
+ if (n >= 0) {
+ int cnt;
+ for (cnt = 0; cnt < n; ++cnt) {
+ strcpy(gemname, eps[cnt]->d_name);
+ strcpy(gemname_path, "./g/");
+ strcat(gemname_path, gemname);
+
+ if (strcmp(gemname, ".") == 0)
+ continue;
+ if (strcmp(gemname, "..") == 0)
+ continue;
+
+ stat(gemname_path, &attribut);
+ if (S_ISDIR(attribut.st_mode) == 0)
+ continue;
+
+ strcat(complete_line, before);
+ strcat(complete_line, gemname);
+ strcat(complete_line, after);
+
+ }
+ }
+ else {
+ perror("Error while scanning the directory.");
+ }
+
+ strcat(complete_line, end);
+ puts(complete_line);
+}
+
+void
+make_gem_makefile()
+{
+ puts("CFLAGS := -I. -I../../include -I../../src");
+ puts("");
+ puts("ifeq ($(OS),Windows_NT)");
+ puts("MAKE_FLAGS = --no-print-directory CC=$(CC) LL=$(LL) ALL_CFLAGS='$(ALL_CFLAGS)'");
+ puts("else");
+ puts("MAKE_FLAGS = --no-print-directory CC='$(CC)' LL='$(LL)' ALL_CFLAGS='$(ALL_CFLAGS)'");
+ puts("endif");
+ puts("");
+
+ puts(".PHONY : all");
+ puts("all :");
+ dir_list("\t@$(MAKE) -C ", " $(MAKE_FLAGS)\n", "", "");
+
+ puts(".PHONY : test");
+ puts("test :");
+ dir_list("", "/test/*.rb ", "\tcat ../../test/assert.rb ", "> mrbtest.rbtmp");
+ puts("\t../../bin/mrbc -Bmrbtest_irep -omrbtest.ctmp mrbtest.rbtmp");
+ puts("\tcat ../../test/init_mrbtest.c mrbtest.ctmp > mrbtest.c");
+ puts("\t$(CC) -c ../../test/driver.c -o ./driver.o $(CFLAGS)");
+ puts("\t$(CC) -c ./mrbtest.c -o ./mrbtest.o $(CFLAGS)");
+ puts("\t$(CC) -o ./mrbtest ./mrbtest.o ../../lib/libmruby.a ./driver.o $(CFLAGS) -lm");
+ puts("\t./mrbtest");
+ puts("");
+
+ puts(".PHONY : clean");
+ puts("clean :");
+ puts("\t$(RM) *.c *.d *.rbtmp *.ctmp *.o mrbtest");
+ dir_list("\t@$(MAKE) clean -C ", " $(MAKE_FLAGS)\n", "", "");
+}
+
+void
+make_init_gems()
+{
+ puts("/*");
+ puts(" * This file contains a list of all");
+ puts(" * initializing methods which are");
+ puts(" * necessary to bootstrap all gems.");
+ puts(" *");
+ puts(" * IMPORTANT:");
+ puts(" * This file was generated!");
+ puts(" * All manual changes will get lost.");
+ puts(" */");
+
+ puts("");
+ puts("#include \"mruby.h\"");
+ puts("");
+
+ dir_list("void mrb_", "_gem_init(mrb_state*);\n", "", "");
+
+ puts("void");
+ puts("mrb_init_mrbgems(mrb_state *mrb)");
+ puts("{");
+ dir_list(" mrb_", "_gem_init(mrb);\n", "", "");
+ puts("}");
+}
+
+int
+main (int argc, char *argv[])
+{
+ if (argc == 2) {
+ if (strcmp(argv[1], "makefile") == 0)
+ make_gem_makefile();
+ else if (strcmp(argv[1], "init_gems") == 0)
+ make_init_gems();
+ else
+ return 1;
+ }
+ else {
+ puts("Argument missing! Options: 'makefile', 'init_gems'");
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/mrblib/Makefile b/mrblib/Makefile
index 6d7ac65f9..def24d497 100644
--- a/mrblib/Makefile
+++ b/mrblib/Makefile
@@ -52,10 +52,9 @@ endif
.PHONY : all
all : $(LIBR)
-# update libmruby.a
$(LIBR) : $(MLIB) $(LIBR0)
$(CP) $(LIBR0) $(LIBR)
- $(AR) r $(LIBR) $(MLIB)
+ $(AR) rs $(LIBR) $(MLIB)
# Compile mrblib source
$(MLIB) : $(CLIB)
diff --git a/src/init.c b/src/init.c
index 52fd9e118..1a7e72686 100644
--- a/src/init.c
+++ b/src/init.c
@@ -27,6 +27,7 @@ void mrb_init_print(mrb_state*);
void mrb_init_time(mrb_state*);
void mrb_init_math(mrb_state*);
void mrb_init_mrblib(mrb_state*);
+void mrb_init_mrbgems(mrb_state*);
void
@@ -66,6 +67,7 @@ mrb_init_core(mrb_state *mrb)
#endif
mrb_init_mrblib(mrb);
+ mrb_init_mrbgems(mrb);
mrb_gc_arena_restore(mrb, 0);
}
diff --git a/tools/mrbc/mrbc.c b/tools/mrbc/mrbc.c
index 5382b90a8..62bc34700 100644
--- a/tools/mrbc/mrbc.c
+++ b/tools/mrbc/mrbc.c
@@ -212,3 +212,8 @@ void
mrb_init_mrblib(mrb_state *mrb)
{
}
+
+void
+mrb_init_mrbgems(mrb_state *mrb)
+{
+}