From 3eb4a40c39758399d2bae8887b4919d2f498c599 Mon Sep 17 00:00:00 2001 From: mmcomando Date: Mon, 1 Mar 2021 21:29:40 +0100 Subject: [PATCH 1/4] Support compiling demos in wasm build --- .gitignore | 1 + demos/external/sources/mmutils/thread_pool.d | 6 +- demos/meson.build | 65 ++++++++++++++----- meson.build | 10 ++- meson_crosscompile_base.ini | 3 + meson_crosscompile_wasm.ini | 28 ++++++++ subprojects/bindbc-loader.wrap | 5 +- subprojects/bindbc-sdl.wrap | 5 +- .../packagefiles/bindbc-loader/meson.build | 7 +- subprojects/packagefiles/cimgui/meson.build | 25 ++++--- tests/meson.build | 27 +++++--- 11 files changed, 139 insertions(+), 43 deletions(-) create mode 100644 meson_crosscompile_base.ini create mode 100644 meson_crosscompile_wasm.ini diff --git a/.gitignore b/.gitignore index f2e30a3..e726799 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ !skeleton.html !**/meson.build !**/*.wrap +!**/*.ini !meson_options.txt !compile_wasm.py !compile_android.py \ No newline at end of file diff --git a/demos/external/sources/mmutils/thread_pool.d b/demos/external/sources/mmutils/thread_pool.d index bd05fe5..83c5b4d 100644 --- a/demos/external/sources/mmutils/thread_pool.d +++ b/demos/external/sources/mmutils/thread_pool.d @@ -17,10 +17,8 @@ version (Posix)version = MM_USE_POSIX_THREADS; version (WebAssembly) { version = MM_NO_LOGS; - extern(C) struct FILE - { - - } + version = MM_USE_POSIX_THREADS; + struct FILE; } else { diff --git a/demos/meson.build b/demos/meson.build index 20df64c..0d9df2a 100644 --- a/demos/meson.build +++ b/demos/meson.build @@ -8,28 +8,61 @@ demos_inc = include_directories('source/') external_inc = include_directories('external/sources/') # Argumesnts +not_wasm = host_machine.cpu_family() != 'wasm32' versions = ['BindSDL_Image','SDL_208', 'BindBC_Static', 'BindSDL_Static'] # Dependencies bindbc_loader_dep = dependency('bindbc-loader') bindbc_sdl_dep = dependency('bindbc-sdl') cimgui_dep = dependency('cimgui') -sdl2_dep = dependency('SDL2') -sdl2_image_dep = dependency('SDL2_image') +sdl2_dep = dependency('SDL2', required: not_wasm) # On wasm delivered by Emscripten +sdl2_image_dep = dependency('SDL2_image', required: not_wasm) subdir('utils') # Utils library -executable('decs-demos', [demos_src, external_src], - include_directories : [demos_inc, external_inc], - d_module_versions : versions, - link_with : [ecs_lib, ecs_utils_lib], - dependencies : [ - bindbc_loader_dep, - bindbc_sdl_dep, - cimgui_dep, - decs_dep, - ecs_utils_dep, - sdl2_dep, - sdl2_image_dep, - ], -) \ No newline at end of file +deps = [ + bindbc_loader_dep, + bindbc_sdl_dep, + cimgui_dep, + decs_dep, + ecs_utils_dep, + sdl2_dep, + sdl2_image_dep, +] + +if not_wasm + exe = executable('decs-demos', [demos_src, external_src], + include_directories : [demos_inc, external_inc], + d_module_versions : versions, + link_with : [ecs_lib, ecs_utils_lib], + dependencies : deps, + ) + + test('basic-tests', exe) +else + decs_demos_lib = library('decs-demos', [demos_src, external_src], + include_directories : [demos_inc, external_inc], + d_module_versions : versions, + dependencies : deps, + ) + cimgui_lib = subproject('cimgui').get_variable('lib') + sdl2_lib = subproject('bindbc-sdl').get_variable('lib') + file_packager = find_program('file_packager') + + # Pack assets + assets_path = meson.source_root() / 'demos/assets@assets' + packed_assets = custom_target('packed-assets-web', + command: [file_packager, 'demos/assets.data', '--preload', assets_path, '--js-output=@OUTPUT@'], + output: ['assets.js'], + build_by_default: true, + ) + + wasm_web = custom_target('decs-demos-wasm-web', + command: [emcc, args_wasm, '--pre-js', packed_assets, '-o', '@OUTPUT@', '@INPUT@'], + input: [sdl2_lib, ecs_lib, decs_demos_lib, ecs_utils_lib, cimgui_lib], + output: ['game.html'], + build_by_default: true, + ) + summary('decs-demoswasm-index', wasm_web.full_path()) +endif + diff --git a/meson.build b/meson.build index d5cb683..279bbb6 100644 --- a/meson.build +++ b/meson.build @@ -50,11 +50,17 @@ endif add_global_arguments(args, language : 'd') add_global_link_arguments(link_args, language : 'd') +if host_machine.cpu_family() == 'wasm32' + add_global_arguments('--output-bc', language : 'd') # Adding it in cross files breaks linker detection + emcc = find_program('emcc') + args_wasm = ['-s', 'FORCE_FILESYSTEM=1','-s', 'USE_PTHREADS=1', '-s', 'USE_SDL=2', '-s', 'ALLOW_MEMORY_GROWTH=1', '-s', 'WASM_MEM_MAX=1024MB', '-s', 'MALLOC=dlmalloc', '-s', 'WASM=1'] +endif + + # Dependencies threads_dep = dependency('threads') -ecs_lib = library('decs', - src, +ecs_lib = library('decs', src, include_directories : [inc], ) diff --git a/meson_crosscompile_base.ini b/meson_crosscompile_base.ini new file mode 100644 index 0000000..698876f --- /dev/null +++ b/meson_crosscompile_base.ini @@ -0,0 +1,3 @@ +[constants] +emscripten_path = '/emsdk/upstream/emscripten' +ldc_path = '/ldc-1.25.0/bin' \ No newline at end of file diff --git a/meson_crosscompile_wasm.ini b/meson_crosscompile_wasm.ini new file mode 100644 index 0000000..9571392 --- /dev/null +++ b/meson_crosscompile_wasm.ini @@ -0,0 +1,28 @@ +; Ex. build: +; meson setup b_wasm -DbetterC=true -DBuildDemos=true --cross-file=meson_crosscompile_base.ini --cross-file=meson_crosscompile_wasm.ini +; ninja -C b_wasm +; emrun --browser chromium-browser ./b_wasm/demos/game.h + +[binaries] +emcc = emscripten_path / 'emcc' +file_packager = [ 'python3', emscripten_path / 'tools/file_packager.py'] +c = emscripten_path / 'emcc' +cpp = emscripten_path / 'em++' +ar = emscripten_path / 'emar' +d = ldc_path / 'ldc2' +; exe_wrapper = emscripten_path / 'emrun' + +[properties] +needs_exe_wrapper = true + +[built-in options] +d_args = ['-mtriple=wasm32-unknown-unknown-wasm', '--d-version=ECSEmscripten'] +c_args = ['-s', 'FORCE_FILESYSTEM=1','-s', 'USE_PTHREADS=1', '-s', 'USE_SDL=2', '-s', 'ALLOW_MEMORY_GROWTH=1', '-s', 'WASM_MEM_MAX=1024MB', '-s', 'MALLOC=dlmalloc', '-s', 'WASM=1'] +cpp_args = ['-s', 'FORCE_FILESYSTEM=1','-s', 'USE_PTHREADS=1', '-s', 'USE_SDL=2', '-s', 'ALLOW_MEMORY_GROWTH=1', '-s', 'WASM_MEM_MAX=1024MB', '-s', 'MALLOC=dlmalloc', '-s', 'WASM=1'] +default_library = 'static' + +[host_machine] +system = 'Emscripten' +cpu_family = 'wasm32' +cpu = 'wasm32' +endian = 'little' \ No newline at end of file diff --git a/subprojects/bindbc-loader.wrap b/subprojects/bindbc-loader.wrap index b99f744..88d2488 100644 --- a/subprojects/bindbc-loader.wrap +++ b/subprojects/bindbc-loader.wrap @@ -1,6 +1,7 @@ [wrap-git] -url = https://github.com/BindBC/bindbc-loader.git -revision = 9a51af991acce3c67e51695c07bf3fa6419ef938 +url = https://github.com/mmcomando/bindbc-loader.git +push-url = https://github.com/BindBC/bindbc-loader.git +revision = wasm patch_directory = bindbc-loader [provide] diff --git a/subprojects/bindbc-sdl.wrap b/subprojects/bindbc-sdl.wrap index 3b159a0..170cc8f 100644 --- a/subprojects/bindbc-sdl.wrap +++ b/subprojects/bindbc-sdl.wrap @@ -1,6 +1,7 @@ [wrap-git] -url = https://github.com/BindBC/bindbc-sdl.git -revision = 5c936064b7226630f5080f4b12b77ee39c8ac64b +url = https://github.com/mmcomando/bindbc-sdl.git +push-url = https://github.com/BindBC/bindbc-sdl.git +revision = wasm patch_directory = bindbc-sdl [provide] diff --git a/subprojects/packagefiles/bindbc-loader/meson.build b/subprojects/packagefiles/bindbc-loader/meson.build index ce3bdf0..1d0aaab 100644 --- a/subprojects/packagefiles/bindbc-loader/meson.build +++ b/subprojects/packagefiles/bindbc-loader/meson.build @@ -3,12 +3,17 @@ project('bindbc-loader', 'd', version : '0.3.2', default_options: ['default_libr # Files src = files( 'source/bindbc/loader/package.d', - 'source/bindbc/loader/sharedlib.d', + # 'source/bindbc/loader/sharedlib.d', # Not implemented for wasm 'source/bindbc/loader/system.d', ) inc = include_directories('source') +if host_machine.cpu_family() != 'wasm32' + src = files( + 'source/bindbc/loader/sharedlib.d', + ) +endif # Dependencies lib = library('bindbc-loader', src, include_directories : [inc], diff --git a/subprojects/packagefiles/cimgui/meson.build b/subprojects/packagefiles/cimgui/meson.build index e4c1a41..d161540 100644 --- a/subprojects/packagefiles/cimgui/meson.build +++ b/subprojects/packagefiles/cimgui/meson.build @@ -1,24 +1,33 @@ -project('cimgui', 'cpp', version : '1.73.0', default_options: ['default_library=shared', 'warning_level=1']) +project('cimgui', 'cpp', version : '1.73.0', default_options: ['default_library=static', 'warning_level=1']) # Files -src = [ +src = files( 'cimgui.cpp', 'imgui/imgui.cpp', 'imgui/imgui_draw.cpp', 'imgui/imgui_demo.cpp', 'imgui/imgui_widgets.cpp', -] +) inc = [ '.' ] +inc +='imgui/examples/' pub_inc = [ 'imgui' ] -# Dependencies -# bindbc_loader_dep = dependency('bindbc-loader') +if host_machine.cpu_family() == 'wasm32' + # For wasm we use C++ events/image handling implementation + src += files( + 'imgui/examples/imgui_impl_opengl3.cpp', + 'imgui/examples/imgui_impl_sdl.cpp', + ) +endif -lib = shared_library('cimgui', src, - # dependencies : bindbc_loader_dep, + +add_project_arguments('-DIMGUI_IMPL_API=extern "C" ', language : 'cpp') + +# Dependencies +lib = library('cimgui', src, include_directories : [inc, pub_inc], - # pic : true, + pic : true, ) cimgui_dep = declare_dependency( diff --git a/tests/meson.build b/tests/meson.build index dae8536..21cdde8 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -2,12 +2,23 @@ tests_src = files( 'tests.d', ) -exe = executable('decs-tests', - tests_src, - include_directories : [inc], - d_args : args, - link_args : link_args, - dependencies : decs_dep, -) -test('basic-tests', exe) +if host_machine.cpu_family() != 'wasm32' + exe = executable('decs-tests', tests_src, + include_directories : [inc], + dependencies : decs_dep, + ) + + test('basic-tests', exe) +else + tests_lib = library('decs-tests', tests_src, + include_directories : [inc], + ) + wasm_web = custom_target('wasm-web', + command: [emcc, args_wasm, '-o', '@OUTPUT@', '@INPUT@'], + input: [ecs_lib, tests_lib], + output: ['index.html'], + build_by_default: true, + ) + summary('wasm-index', wasm_web.full_path()) +endif -- 2.47.2 From 55bd698541229d7f2ccf46a31966201b8c386e60 Mon Sep 17 00:00:00 2001 From: mmcomando Date: Sat, 13 Mar 2021 13:23:19 +0000 Subject: [PATCH 2/4] Update thread_pool.d --- demos/external/sources/mmutils/thread_pool.d | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/demos/external/sources/mmutils/thread_pool.d b/demos/external/sources/mmutils/thread_pool.d index 093cb6d..7139a97 100644 --- a/demos/external/sources/mmutils/thread_pool.d +++ b/demos/external/sources/mmutils/thread_pool.d @@ -1,4 +1,4 @@ -module mmutils.thread_pool; +module mmutils.thread_pool; import std.algorithm : map; @@ -9,7 +9,9 @@ version (WebAssembly) { version = MM_NO_LOGS; version = MM_USE_POSIX_THREADS; - struct FILE; + extern(C) struct FILE + { + } } else { @@ -1825,4 +1827,4 @@ else // -fsanitize=address // rdmd -g -of=thread_pool src/mmutils/thread_pool.d && ./thread_pool // ldmd2 -release -inline -checkaction=C -g -of=thread_pool src/mmutils/thread_pool.d && ./thread_pool -// ldmd2 -checkaction=C -g -of=thread_pool src/mmutils/thread_pool.d && ./thread_pool \ No newline at end of file +// ldmd2 -checkaction=C -g -of=thread_pool src/mmutils/thread_pool.d && ./thread_pool -- 2.47.2 From 1254a990f1c6a71bcfac175e935b019b38d6988b Mon Sep 17 00:00:00 2001 From: Mergul Date: Sat, 13 Mar 2021 15:04:42 +0100 Subject: [PATCH 3/4] -added compilation for multithreaded and singlethreaded code -fixed problem with assets loading --- demos/meson.build | 11 +++++++++-- meson.build | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/demos/meson.build b/demos/meson.build index 0d9df2a..7cc6383 100644 --- a/demos/meson.build +++ b/demos/meson.build @@ -9,7 +9,7 @@ external_inc = include_directories('external/sources/') # Argumesnts not_wasm = host_machine.cpu_family() != 'wasm32' -versions = ['BindSDL_Image','SDL_208', 'BindBC_Static', 'BindSDL_Static'] +versions = ['BindSDL_Image','SDL_209', 'BindBC_Static', 'BindSDL_Static', 'MM_USE_POSIX_THREADS', 'ECSEmscripten'] # Dependencies bindbc_loader_dep = dependency('bindbc-loader') @@ -60,7 +60,14 @@ else wasm_web = custom_target('decs-demos-wasm-web', command: [emcc, args_wasm, '--pre-js', packed_assets, '-o', '@OUTPUT@', '@INPUT@'], input: [sdl2_lib, ecs_lib, decs_demos_lib, ecs_utils_lib, cimgui_lib], - output: ['game.html'], + output: ['ecs_demo.html'], + build_by_default: true, + ) + + wasm_web_mt = custom_target('decs-demos-wasm-web-mt', + command: [emcc, args_wasm, '-s', 'USE_PTHREADS=1', '--pre-js', packed_assets, '-o', '@OUTPUT@', '@INPUT@'], + input: [sdl2_lib, ecs_lib, decs_demos_lib, ecs_utils_lib, cimgui_lib], + output: ['ecs_demo_mt.js'], build_by_default: true, ) summary('decs-demoswasm-index', wasm_web.full_path()) diff --git a/meson.build b/meson.build index 279bbb6..28f2458 100644 --- a/meson.build +++ b/meson.build @@ -53,7 +53,7 @@ add_global_link_arguments(link_args, language : 'd') if host_machine.cpu_family() == 'wasm32' add_global_arguments('--output-bc', language : 'd') # Adding it in cross files breaks linker detection emcc = find_program('emcc') - args_wasm = ['-s', 'FORCE_FILESYSTEM=1','-s', 'USE_PTHREADS=1', '-s', 'USE_SDL=2', '-s', 'ALLOW_MEMORY_GROWTH=1', '-s', 'WASM_MEM_MAX=1024MB', '-s', 'MALLOC=dlmalloc', '-s', 'WASM=1'] + args_wasm = ['-O3', '-s', 'FORCE_FILESYSTEM=1', '-s', 'USE_SDL=2', '-s', 'USE_SDL_IMAGE=2', '-s', 'SDL2_IMAGE_FORMATS=["png"]', '-s', 'ERROR_ON_UNDEFINED_SYMBOLS=0', '-s', 'ALLOW_MEMORY_GROWTH=1', '-s', 'WASM_MEM_MAX=1024MB', '-s', 'MALLOC=dlmalloc', '-s', 'WASM=1', '--shell-file', '../demos/emscripten_multi_shell.html', '-s', 'DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR=1'] endif -- 2.47.2 From 3e0ab40977eac8d1299cbf7254d080f23e6ceee9 Mon Sep 17 00:00:00 2001 From: Mergul Date: Sat, 13 Mar 2021 20:28:06 +0100 Subject: [PATCH 4/4] -cleaned Meson build files and added some comments --- demos/meson.build | 7 ++++++- meson.build | 4 ++++ tests/meson.build | 1 + 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/demos/meson.build b/demos/meson.build index 7cc6383..8fb051b 100644 --- a/demos/meson.build +++ b/demos/meson.build @@ -9,7 +9,7 @@ external_inc = include_directories('external/sources/') # Argumesnts not_wasm = host_machine.cpu_family() != 'wasm32' -versions = ['BindSDL_Image','SDL_209', 'BindBC_Static', 'BindSDL_Static', 'MM_USE_POSIX_THREADS', 'ECSEmscripten'] +versions = ['BindSDL_Image','SDL_208', 'BindBC_Static', 'BindSDL_Static'] # Dependencies bindbc_loader_dep = dependency('bindbc-loader') @@ -40,6 +40,8 @@ if not_wasm test('basic-tests', exe) else + versions += ['MM_USE_POSIX_THREADS', 'ECSEmscripten'] + decs_demos_lib = library('decs-demos', [demos_src, external_src], include_directories : [demos_inc, external_inc], d_module_versions : versions, @@ -57,6 +59,7 @@ else build_by_default: true, ) + # build single-threaded demos with HTML output wasm_web = custom_target('decs-demos-wasm-web', command: [emcc, args_wasm, '--pre-js', packed_assets, '-o', '@OUTPUT@', '@INPUT@'], input: [sdl2_lib, ecs_lib, decs_demos_lib, ecs_utils_lib, cimgui_lib], @@ -64,12 +67,14 @@ else build_by_default: true, ) + # build multi-threded demos with JS output. Custom shellfile detects if web browser threads are enabled and select proper JS and WASM. wasm_web_mt = custom_target('decs-demos-wasm-web-mt', command: [emcc, args_wasm, '-s', 'USE_PTHREADS=1', '--pre-js', packed_assets, '-o', '@OUTPUT@', '@INPUT@'], input: [sdl2_lib, ecs_lib, decs_demos_lib, ecs_utils_lib, cimgui_lib], output: ['ecs_demo_mt.js'], build_by_default: true, ) + summary('decs-demoswasm-index', wasm_web.full_path()) endif diff --git a/meson.build b/meson.build index 9d83e58..f4de9a3 100644 --- a/meson.build +++ b/meson.build @@ -52,10 +52,13 @@ endif add_global_arguments(args, language : 'd') add_global_link_arguments(link_args, language : 'd') +versions = [] + if host_machine.cpu_family() == 'wasm32' add_global_arguments('--output-bc', language : 'd') # Adding it in cross files breaks linker detection emcc = find_program('emcc') args_wasm = ['-O3', '-s', 'FORCE_FILESYSTEM=1', '-s', 'USE_SDL=2', '-s', 'USE_SDL_IMAGE=2', '-s', 'SDL2_IMAGE_FORMATS=["png"]', '-s', 'ERROR_ON_UNDEFINED_SYMBOLS=0', '-s', 'ALLOW_MEMORY_GROWTH=1', '-s', 'WASM_MEM_MAX=1024MB', '-s', 'MALLOC=dlmalloc', '-s', 'WASM=1', '--shell-file', '../demos/emscripten_multi_shell.html', '-s', 'DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR=1'] + versions = ['ECSEmscripten'] endif @@ -64,6 +67,7 @@ threads_dep = dependency('threads') ecs_lib = library('decs', src, include_directories : [inc], + d_module_versions : versions ) decs_dep = declare_dependency( diff --git a/tests/meson.build b/tests/meson.build index 45c0ea1..dbf051d 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -20,6 +20,7 @@ if host_machine.cpu_family() != 'wasm32' else tests_lib = library('decs-tests', tests_src, include_directories : [inc], + d_module_versions : ['ECSEmscripten'], ) wasm_web = custom_target('wasm-web', command: [emcc, args_wasm, '-o', '@OUTPUT@', '@INPUT@'], -- 2.47.2