-
Notifications
You must be signed in to change notification settings - Fork 79
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Manual Build process for Emscripten and Mobile #69
Comments
I added some "build-system-agnostic" instructions to the readme a little while ago here (but I just noticed that I missed emscripten there): https://github.com/floooh/sokol-samples#how-to-build-without-a-build-system The only two reasons why this is a bit more tricky with the sokol-app samples are:
For Android the whole process of setting up the Android SDK/NDK and then actually building APKs without a build system is so broken by design that I'd rather skip any instructions (e.g. look at those two python scripts to get an idea what the instructions would need to cover):
I will add a section for building the emscripten samples (under https://github.com/floooh/sokol-samples/tree/master/html5) though, these will all be one-liners once the emscripten SDK has been installed. |
Cross platform is never as simple as it could be... It probably makes sense to to put up a YMMV notice on the mobile platforms and just pointing to the build scripts like you did for me is enough. Are there weird scripts for iOS as well? P.S. - There may be a more elegant way to do things for Android without the whole SDK/NDK. I was just reading this morning in a PR for Dear Imgui (PR:3446) using Gradle... It looked like a lot less gymnastics than using the full SDK/NDK. Seemed promising... |
Gradle is just the current "Android build system flavour of the month", this is exactly one of the fundamental problems of the whole Android development workflow: they change build system details all the time, so that nothing works for longer than half a year or so. Using only cmake and calling the underlying tools directly to build the final APK (this is the only part that Gradle actually simplifies) is actually more stable and easier to maintain. ...what the Android SDK would actually need is a compiler/linker wrapper like |
I'm new to Android development. Would love to see less build tools used in most projects I work on. I feel Like I spend more time debugging Python and Node than I do writing C sometimes. I wish there was a simple build system that just worked without external dependencies. I've read a few who claim to be. But the tooling is getting ridiculous these days! |
I'll echo this but specific for a |
@cshenton see: https://github.com/floooh/fips/blob/master/cmake-toolchains/emscripten.toolchain.cmake this seems to be where a lot of the magic config happens... |
fips is python + cmake |
@frink @cshenton the emscripten.toolchain.cmake is a bit overkill, the emscripten-specific samples under https://github.com/floooh/sokol-samples/tree/master/html5 can actually be built with one-liners, I just need to add a section to the README for this. For instance:
The only reasons that the cross-platform sokol_app.h samples under https://github.com/floooh/sokol-samples are a bit more complicated to build are
|
But the html5 samples also include things like ImGui? (e.g. html5/imgui-emsc.cc) So other than using sokol_app and sokol_imgui providing the scaffolding is there much other diffident between html5/imgui-emsc.cc and sapp/imgui-sapp.cc? The ImGui guts seem nearly identical... Right now I'm hacking on the samples project adding my own stuff. But I'd really like to remove everything else and have a template project without a hard fips dependencies. |
The platform-specific samples in the d3d11/html5/glfw/metal... directories are essentially tests and examples of using sokol_gfx.h without sokol_app.h. The application-wrapper code (e.g. here https://github.com/floooh/sokol-samples/blob/master/html5/emsc.h, or here https://github.com/floooh/sokol-samples/blob/master/d3d11/d3d11entry.c) is much more minimal and "hacky" than what's in sokol_app.h (or SDL / GLFW), but the actual sokol_gfx.h code is mostly identical to the samples in the sapp directory. |
Could you for example use:
In other words, is there any other craziness besides just mapping which files and headers get included? |
Yeah basically, in the case of the imgui samples this works because sokol_imgui.h comes with embedded shader code (e.g. sokol-shdc doesn't need to run). The 3D backend to use isn't autodetected in the source code and must be defined via Let's use the
Or split over several lines for better readability:
PS: compiling like this gives you emscripten's default "shell.html" file, it works but looks ugly. To get the WebGL canvas stretched over the entire browser window, add this command line option too:
|
Thanks for the explanation...
Assuming cimgui is more difficult because you need both cimgui and imgui sources to compile...?
I guess I should next ask about sokol-shdc. Maybe we can pick on an easy example like
Is that on the right track? |
Yes, cimgui is just a C wrapper around ImGui, so you need to add both the cimgui sources and the imgui sources to the compilation.
Yes. The exact arguments used for the sokol-samples are a bit different, but the above should also work. For reference: ...also see the documentation: https://github.com/floooh/sokol-tools/blob/master/docs/sokol-shdc.md |
Wow digging deeper into this it has problems because installing Emscripten itself is Royal Pain. I ended up adding it as a submodule. Really close to having a Makefile building an app. The wasm and html generated by my scripts are roughly the same size as the stuff gneerated by fips but my JS file is 121K whereas yours is only 32K from the same sapp file. (I've been modifying the |
Did you follow the emsdk installations instructions here? https://emscripten.org/docs/getting_started/downloads.html#installation-instructions I didn't have any trouble with emsdk for a long time, especially compared to "pre-emsdk" times.
Fips has a lot of tweaks in its emscripten-cmake toolchain file to balance size vs performance (like switching off the filesystem emulation layer, and using the small-but-slow emmalloc instead of the vanilla jemalloc): |
Found another issue in trying to work through this... For my test app, I basically combined the quad-sapp background with the cimgui-sapp code to get a nice background behind my ImGui App. But then I started themeing and realized that the fading background color might change so I call
I noticed buried in the CMake/fips stuff that you are actually using Is GLFW a dependency when running SOKOL_GLES3? Also wondering if there's a way to get a call stack to know where it's failing? |
Just to make sure it wasn't my code I tried copying the float vertices[] = {
// positions colors
-1.0f, 1.0f, 1.0f, 0.5f, 0.0f, 0.4f, 1.0f,
1.0f, 1.0f, 1.0f, 0.4f, 0.0f, 0.3f, 1.0f,
1.0f, -1.0f, 1.0f, 0.1f, 0.0f, 0.2f, 1.0f,
-1.0f, -1.0f, 1.0f, 0.2f, 0.0f, 0.1f, 1.0f,
};
sg_update_buffer(iapp_gconf.bind.vertex_buffers[0], vertices, sizeof(vertices)); Building with
Aren't these symbols from GLFW? If built with |
Okay so I found what the symbol problem was... When building Sadly this still doesn't help my assert problem yet. I also notice that the fips build uses the flag |
These seem like several unrelated problems:
It would be important to know what the assertion says to know what the error is. E.g. the update-data might be too big to fit into the buffer, or sg_update_buffer() might have been called more then once per frame on the same buffer.
No, GLFW is only needed for the samples that use GLFW instead of sokol_app.h for window management: https://github.com/floooh/sokol-samples/tree/master/glfw
This is really weird, those two things should not be related. In general, if you only need GLES2/WebGL functionality, you should compile with SOKOL_GLES2, and only use SOKOL_GLES3 if you need GLES3/WebGL2 features. For instance the emscripten-specific samples in here either use SOKOL_GLES2 or SOKOL_GLES3: https://github.com/floooh/sokol-samples/tree/master/html5
No, these are regular desktop-GL and GLES3 functions and called in the non-GLES2 code paths in sokol_gfx.h
If you compile with debug information (-g), then you'll get callstacks in the browser's Javascript console.
What does the assertion say on the Javascript console?
Ooops, yeah good find, this is sort-of deprecated, I should remove this from the build-config-files. I used this here in Oryol: ...this was because Oryol defauls to keeping assert even in release mode. But with sokol I have switched to using the standard assert() macros which are controlled by the NDEBUG define. |
Thanks for working with me in all this. Once I have this working good I'll contribute a PR on manually building with Emscripten to the README.md.
Agreed. I solved the GLES3 problem. Now working on the sg_update_buffer() problem. Will follow your suggestion bellow and get back to you.
I'll compile with this and see if I can get further down the road...
I answered my own question on this. You have to use two flags to get GLES working.
I wonder if we should add an #ifdef in the relevant headers on this to avoid ambiguity of the two flags. Seems like this will be a common gotcha. But then again when WebGPU becomes standard that may throw a wrench in stuff again. But the two flags is definitely unclear...
For now I'm trying to get binary consistency with the fips examples so I am purposely trying to use the exact same flags as fips to prove that I'm generating the same binary with either build system. This is the only way to prove that I'm doing a perfect manual build. Once I can get this level of consistency I will distill it all down and write a concise README section on building Emscripten manually. Like you said above, it would be good to include this... I'll send a PR with a good write up once I actually understand the process. |
Debug output from running with -g:
Here is my void frame(void) {
sg_begin_default_pass(&state.pass_action, sapp_width(), sapp_height());
float vertices[] = {
// positions colors
-1.0f, 1.0f, 1.0f, 0.5f, 0.0f, 0.4f, 1.0f,
1.0f, 1.0f, 1.0f, 0.4f, 0.0f, 0.3f, 1.0f,
1.0f, -1.0f, 1.0f, 0.1f, 0.0f, 0.2f, 1.0f,
-1.0f, -1.0f, 1.0f, 0.2f, 0.0f, 0.1f, 1.0f,
};
sg_update_buffer(state.bind.vertex_buffers[0], vertices, sizeof(vertices));
sg_apply_pipeline(state.pip);
sg_apply_bindings(&state.bind);
sg_draw(0, 6, 1);
__dbgui_draw();
sg_end_pass();
sg_commit();
} Judging from above stack trace it looks like maybe something got in-lined. I'm finding several calls to
I'm guessing the first but I don't know why it would work in your fips compiler and not in mine unless fips sets I tested building with |
Is there no way to get fips and CMake to show their full calls so I can just grab the compiler flags from there? (I'm running with fips UPDATE: For fips + ninja to show a verbose build you just use: |
Found it!!! I was missing I also found that these settings gave me a 32% file size reduction in the wasm file.
I'm now generating the same file sizes as fips. I've only got 34 flags passed to emcc. hehehe But it works! |
This thread is immensely helpful, thank you. In the end, after seemingly satisfying every dependency, the build was still failing, and I kept seeing these:
Turns out they disappear once you remove |
@lobotony I'm not sure where those symbols are coming from TBH, haven't seen those before, but I haven't used LLD_REPORT_UNDEFINED so far. There's this Emscripten-specific linker setting:
Also see here: And maybe this projects also helps, it's using a plain cmake file, but I tried to keep this as simple as possible: |
I'd like to be able to build without fips for Emscripten and the Mobile platforms. But fips is so tightly integrated that I'm finding it hard to do a basic Makefiles. Could you add this to the documentation please?
The text was updated successfully, but these errors were encountered: