diff options
| -rw-r--r-- | .gitignore | 3 | ||||
| -rw-r--r-- | Makefile | 3 | ||||
| -rw-r--r-- | mrbgems/Makefile | 53 | ||||
| -rw-r--r-- | mrbgems/Makefile4gem | 37 | ||||
| -rw-r--r-- | mrbgems/g/hello_world/Makefile | 12 | ||||
| -rw-r--r-- | mrbgems/g/hello_world/README.md | 4 | ||||
| -rw-r--r-- | mrbgems/g/hello_world/src/hello_world.c | 17 | ||||
| -rw-r--r-- | mrbgems/g/hello_world/test/hello_world.rb | 3 | ||||
| -rw-r--r-- | mrbgems/gem_helper.c | 131 | ||||
| -rw-r--r-- | mrblib/Makefile | 3 | ||||
| -rw-r--r-- | src/init.c | 2 | ||||
| -rw-r--r-- | tools/mrbc/mrbc.c | 5 |
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 @@ -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) +{ +} |
