diff --git a/.gitignore b/.gitignore index 327cacb..a1f02ea 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ *.hl *.js *.bc +.vscode diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..ee202d8 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,16 @@ +{ + "configurations": [ + { + "name": "Linux", + "includePath": [ + "${workspaceFolder}/**" + ], + "defines": [], + "compilerPath": "/usr/bin/clang", + "cStandard": "c11", + "cppStandard": "c++17", + "intelliSenseMode": "clang-x64" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/sample/Makefile b/sample/Makefile deleted file mode 100644 index 9c4cb54..0000000 --- a/sample/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -all: - -libpoint.cpp: - haxe -lib webidl --macro "SampleModule.buildLibCpp()" - -libpoint.js: libpoint.cpp - haxe -lib webidl --macro "SampleModule.buildLibJS()" - -js: libpoint.js - haxe -js sample.js -lib webidl -main Sample -dce full - -# ---- HL PART - -ifndef HLPATH -HLPATH = /path/to/hl -endif - -libpoint.hdll: libpoint.cpp - $(CC) -o libpoint.hdll -shared -Wall -O3 -I . -I $(HLPATH) libpoint.cpp point.cpp -lstdc++ -lhl - -libpoint_win: libpoint.cpp - cl /olibpoint.hdll /LD /EHsc /I $(HLPATH) /DYNAMICBASE libhl.lib libpoint.cpp point.cpp - -hl: libpoint.hdll - haxe -hl sample.hl -lib webidl -main Sample - -.PHONY: libpoint.cpp libpoint.js - -.SUFFIXES : .cpp .o - -.cpp.o: - $CC \ No newline at end of file diff --git a/sample/SampleModule.hx b/sample/SampleModule.hx deleted file mode 100644 index da773b0..0000000 --- a/sample/SampleModule.hx +++ /dev/null @@ -1,29 +0,0 @@ -#if !macro -private typedef Import = haxe.macro.MacroType<[SampleModule.build()]>; -#else - -class SampleModule { - - static var config : webidl.Options = { - idlFile : "point.idl", - nativeLib : "libpoint", - includeCode : "#include \"point.h\"", - autoGC : false, - }; - - public static function build() { - return webidl.Module.build(config); - } - - public static function buildLibCpp() { - webidl.Generate.generateCpp(config); - } - - public static function buildLibJS() { - var sourceFiles = ["point.cpp"]; - webidl.Generate.generateJs(config, sourceFiles); - } - -} - -#end \ No newline at end of file diff --git a/sample/sample.html b/sample/sample.html deleted file mode 100644 index 0da1f6a..0000000 --- a/sample/sample.html +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/samples/simple/Makefile b/samples/simple/Makefile new file mode 100644 index 0000000..c64b633 --- /dev/null +++ b/samples/simple/Makefile @@ -0,0 +1,45 @@ +all: + +OUT = "./webRoot/" + +clean: + if [ -f $(OUT)lib_simple.bc ]; then rm $(OUT)lib_simple.bc; fi; + if [ -f $(OUT)lib_simple.cpp ]; then rm $(OUT)lib_simple.cpp; fi; + if [ -f $(OUT)lib_simple.js ]; then rm $(OUT)lib_simple.js; fi; + if [ -f $(OUT)lib_simple.wasm ]; then rm $(OUT)lib_simple.wasm; fi; + + if [ -f $(OUT)simple.js ]; then rm $(OUT)simple.js; fi; + + if [ -f $(OUT)point.bc ]; then rm $(OUT)point.bc; fi; + if [ -f $(OUT)context.bc ]; then rm $(OUT)context.bc; fi; + +lib_simple.cpp: + haxe -lib webidl --macro "SimpleModule.buildLibCpp()" + +lib_simple.js: lib_simple.cpp + haxe -lib webidl --macro "SimpleModule.buildLibJS()" + +js: lib_simple.js + haxe -js $(OUT)simple.js -lib webidl -main Simple -dce full + +# ---- HL PART + +ifndef HLPATH +HLPATH = /path/to/hl +endif + +lib_simple.hdll: lib_simple.cpp + $(CC) -o lib_simple.hdll -shared -Wall -O0 -I . -I $(HLPATH) lib_simple.cpp -lstdc++ -lhl + +lib_simple: lib_simple.cpp + cl /olib_simple.hdll /LD /EHsc /I $(HLPATH) /DYNAMICBASE libhl.lib lib_simple.cpp + +hl: lib_simple.hdll + haxe -hl simple.hl -lib webidl -main Simple + +.PHONY: lib_simple.cpp lib_simple.js + +.SUFFIXES : .cpp .o + +.cpp.o: + $CC \ No newline at end of file diff --git a/samples/simple/README.md b/samples/simple/README.md new file mode 100644 index 0000000..eb7e3e7 --- /dev/null +++ b/samples/simple/README.md @@ -0,0 +1 @@ +# Simple example \ No newline at end of file diff --git a/sample/Sample.hx b/samples/simple/Simple.hx similarity index 54% rename from sample/Sample.hx rename to samples/simple/Simple.hx index d772f67..a6dd911 100644 --- a/sample/Sample.hx +++ b/samples/simple/Simple.hx @@ -1,13 +1,15 @@ -import SampleModule.Point; -import SampleModule.Init as SampleModuleInit; +import SimpleModule.Point; +import SimpleModule.Context; +import SimpleModule.Init as SimpleModuleInit; -class Sample { +class Simple { public static function main() { - SampleModuleInit.init(startApp); + SimpleModuleInit.init(startApp); } public static function startApp() { + /** Point */ var p1 = new Point(); p1.x = 4; p1.y = 5; @@ -17,5 +19,9 @@ class Sample { p1.delete(); p2.delete(); p.delete(); + + /** Context */ + var context = new Context(); + context.test(); } -} +} \ No newline at end of file diff --git a/samples/simple/SimpleModule.hx b/samples/simple/SimpleModule.hx new file mode 100644 index 0000000..869bd49 --- /dev/null +++ b/samples/simple/SimpleModule.hx @@ -0,0 +1,28 @@ +#if !macro +private typedef Import = haxe.macro.MacroType<[SimpleModule.build()]>; +#else + +class SimpleModule { + + static var json = haxe.Json.parse(sys.io.File.getContent("./webidl.json")); + var cc = sys.io.File.getBytes("./webidl.json"); + var obj = haxe.Json.parse(cc.toString()); + obj; + } + + static var config: webidl.Options = json; + + public static function build() { + return webidl.Module.build(config); + } + + public static function buildLibCpp() { + webidl.Generate.generateCpp(config); + } + + public static function buildLibJS() { + webidl.Generate.generateJs(config); + } +} + +#end diff --git a/samples/simple/context.cpp b/samples/simple/context.cpp new file mode 100644 index 0000000..105632e --- /dev/null +++ b/samples/simple/context.cpp @@ -0,0 +1,6 @@ +#include "context.h" +#include "stdio.h" + +void Context::test(){ + printf("%s\n", "This is Context::test()"); +} \ No newline at end of file diff --git a/samples/simple/context.h b/samples/simple/context.h new file mode 100644 index 0000000..5744a86 --- /dev/null +++ b/samples/simple/context.h @@ -0,0 +1,13 @@ +#include "stdio.h" + +#include "emscripten.h" +#include +#include + +class Context { + public: + Context(){ + printf("%s\n", "Context Initialized"); + } + void test(); +}; \ No newline at end of file diff --git a/samples/simple/index.html b/samples/simple/index.html new file mode 100644 index 0000000..25369e3 --- /dev/null +++ b/samples/simple/index.html @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/sample/point.cpp b/samples/simple/point.cpp similarity index 100% rename from sample/point.cpp rename to samples/simple/point.cpp diff --git a/sample/point.h b/samples/simple/point.h similarity index 100% rename from sample/point.h rename to samples/simple/point.h diff --git a/sample/point.idl b/samples/simple/simple.idl similarity index 76% rename from sample/point.idl rename to samples/simple/simple.idl index 7dfbea3..264bc04 100644 --- a/sample/point.idl +++ b/samples/simple/simple.idl @@ -1,4 +1,3 @@ - interface Point { attribute long x; attribute long y; @@ -8,3 +7,7 @@ interface Point { double length(); }; +interface Context { + void Context(); + void test(); +}; \ No newline at end of file diff --git a/samples/simple/webRoot/favicon.ico b/samples/simple/webRoot/favicon.ico new file mode 100644 index 0000000..9ae83d3 Binary files /dev/null and b/samples/simple/webRoot/favicon.ico differ diff --git a/samples/simple/webRoot/index.html b/samples/simple/webRoot/index.html new file mode 100644 index 0000000..25369e3 --- /dev/null +++ b/samples/simple/webRoot/index.html @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/samples/simple/webidl.json b/samples/simple/webidl.json new file mode 100644 index 0000000..fc90333 --- /dev/null +++ b/samples/simple/webidl.json @@ -0,0 +1,7 @@ +{ + "idlFile": "simple.idl", + "nativeLib": "lib_simple", + "sourceFiles": ["point.cpp", "context.cpp"], + "autoGC": false, + "out": "./webRoot" +} \ No newline at end of file diff --git a/webidl/Generate.hx b/webidl/Generate.hx index 862caf8..e366fc1 100644 --- a/webidl/Generate.hx +++ b/webidl/Generate.hx @@ -2,77 +2,66 @@ package webidl; import webidl.Data; class Generate { - static var HEADER_EMSCRIPTEN = " - -#include -#define HL_PRIM -#define HL_NAME(n) EMSCRIPTEN_KEEPALIVE eb_##n -#define DEFINE_PRIM(ret, name, args) -#define _OPT(t) t* -#define _GET_OPT(value,t) *value - - -"; + #include + #define HL_PRIM + #define HL_NAME(n) EMSCRIPTEN_KEEPALIVE eb_##n + #define DEFINE_PRIM(ret, name, args) + #define _OPT(t) t* + #define _GET_OPT(value,t) *value + "; static var HEADER_HL = " - -#include -#define _IDL _BYTES -#define _OPT(t) vdynamic * -#define _GET_OPT(value,t) (value)->v.t - - -"; + #include + #define _IDL _BYTES + #define _OPT(t) vdynamic * + #define _GET_OPT(value,t) (value)->v.t + "; static var HEADER_NO_GC = " - -#define alloc_ref(r, _) r -#define alloc_ref_const(r,_) r -#define _ref(t) t -#define _unref(v) v -#define free_ref(v) delete (v) -#define HL_CONST const - + #define alloc_ref(r, _) r + #define alloc_ref_const(r,_) r + #define _ref(t) t + #define _unref(v) v + #define free_ref(v) delete (v) + #define HL_CONST const "; static var HEADER_GC = " + template struct pref { + void *finalize; + T *value; + }; + + #define _ref(t) pref + #define _unref(v) v->value + #define alloc_ref(r,t) _alloc_ref(r,finalize_##t) + #define alloc_ref_const(r, _) _alloc_const(r) + #define HL_CONST + + template void free_ref( pref *r ) { + if( !r->finalize ) return; + delete r->value; + r->value = NULL; + r->finalize = NULL; + } + + template pref *_alloc_ref( T *value, void (*finalize)( pref * ) ) { + pref *r = (pref*)hl_gc_alloc_finalizer(sizeof(r)); + r->finalize = finalize; + r->value = value; + return r; + } -template struct pref { - void *finalize; - T *value; -}; - -#define _ref(t) pref -#define _unref(v) v->value -#define alloc_ref(r,t) _alloc_ref(r,finalize_##t) -#define alloc_ref_const(r, _) _alloc_const(r) -#define HL_CONST - -template void free_ref( pref *r ) { - if( !r->finalize ) return; - delete r->value; - r->value = NULL; - r->finalize = NULL; -} - -template pref *_alloc_ref( T *value, void (*finalize)( pref * ) ) { - pref *r = (pref*)hl_gc_alloc_finalizer(sizeof(r)); - r->finalize = finalize; - r->value = value; - return r; -} - -template pref *_alloc_const( const T *value ) { - pref *r = (pref*)hl_gc_alloc_noptr(sizeof(r)); - r->finalize = NULL; - r->value = (T*)value; - return r; -} - -"; - - public static function generateCpp( opts : Options ) { + template pref *_alloc_const( const T *value ) { + pref *r = (pref*)hl_gc_alloc_noptr(sizeof(r)); + r->finalize = NULL; + r->value = (T*)value; + return r; + } + "; + + public static function generateCpp(opts : Options) { var file = opts.idlFile; var content = sys.io.File.getBytes(file); var parse = new webidl.Parser(); @@ -99,10 +88,19 @@ template pref *_alloc_const( const T *value ) { add(StringTools.trim(gc ? HEADER_GC : HEADER_NO_GC)); add(""); add("#endif"); - if( opts.includeCode != null ) { + + /* Handle Includes TODO@Wolfie -> Dedup? **/ + for(sFile in opts.sourceFiles){ add(""); - add(StringTools.trim(opts.includeCode)); + for(l in sys.io.File.getBytes(if(sys.FileSystem.exists(opts.out+ "/" + sFile)){ + opts.out + "/" + sFile; + } else { sFile; }).toString().split("\n")){ + if(StringTools.startsWith(l, "#include")){ + add(StringTools.trim(l)); + } + } } + add(""); add('extern "C" {'); add(""); @@ -381,7 +379,7 @@ template pref *_alloc_const( const T *value ) { add("}"); // extern C - sys.io.File.saveContent(opts.nativeLib+".cpp", output.toString()); + sys.io.File.saveContent(opts.out + "/" + opts.nativeLib+".cpp", output.toString()); } static function command( cmd, args : Array ) { @@ -390,7 +388,9 @@ template pref *_alloc_const( const T *value ) { if( ret != 0 ) throw "Command '" + cmd + "' has exit with error code " + ret; } - public static function generateJs( opts : Options, sources : Array, ?params : Array ) { + public static function generateJs(opts : Options, ?params : Array) { + var sources = opts.sourceFiles; + if( params == null ) params = []; @@ -399,7 +399,7 @@ template pref *_alloc_const( const T *value ) { if( p.substr(0, 2) == "-O" ) hasOpt = true; if( !hasOpt ) - params.push("-O2"); + params.push("-O0"); var lib = opts.nativeLib; @@ -412,18 +412,25 @@ template pref *_alloc_const( const T *value ) { var outFiles = []; sources.push(lib+".cpp"); for( cfile in sources ) { - var out = cfile.substr(0, -4) + ".bc"; - var args = params.concat(["-c", cfile, "-o", out]); + var sourcePath = if(sys.FileSystem.exists(opts.out+ "/" + cfile)){ + opts.out + "/" + cfile; + } else { cfile; } + + var out = opts.out + "/" + cfile.substr(0, -4) + ".bc"; + var args = params.concat(["-c", sourcePath, "-o", out, "-I" + Sys.getCwd()]); command( emcc, args); outFiles.push(out); } // link : because too many files, generate Makefile var tmp = "Makefile.tmp"; + var libPath = opts.out + "/" + lib; + var args = params.concat([ - "-s", 'EXPORT_NAME="\'$lib\'"', "-s", "MODULARIZE=1", + //"-s", 'EXPORT_NAME="\'$lib\'"', "-s", "MODULARIZE=1", "-O0", "-s", "USE_WEBGL2=1", "-s", "FULL_ES3=1", "-s", "NO_EXIT_RUNTIME=1", + "-s", 'EXPORT_NAME="\'$lib\'"', "-s", "MODULARIZE=1", "-O0", "-s", "NO_EXIT_RUNTIME=1", "--memory-init-file", "0", - "-o", '$lib.js' + "-o", '$libPath.js' ]); var output = "SOURCES = " + outFiles.join(" ") + "\n"; output += "all:\n"; @@ -431,7 +438,6 @@ template pref *_alloc_const( const T *value ) { sys.io.File.saveContent(tmp, output); command("make", ["-f", tmp]); sys.FileSystem.deleteFile(tmp); + sys.io.File.copy("index.html", opts.out+"/index.html"); } - - -} +} \ No newline at end of file diff --git a/webidl/Options.hx b/webidl/Options.hx index 26354da..7cf3d29 100644 --- a/webidl/Options.hx +++ b/webidl/Options.hx @@ -3,7 +3,8 @@ package webidl; typedef Options = { var idlFile : String; var nativeLib : String; - @:optional var includeCode : String; + var sourceFiles: Array; @:optional var chopPrefix : String; @:optional var autoGC : Bool; + @:optional var out: String; } \ No newline at end of file