According to the Emscripten Docs
Make generates linked LLVM bitcode. It does not automatically generate JavaScript during linking because all the files must be compiled using the same optimizations and compiler options — and it makes sense to do this in the final conversion from bitcode to JavaScript.
Which is great and what I want to do. However, running Emscripten to compile the openjpeg .jp2 library generates 4 uncompressed (-O0
) .js files in the 5-6mb range, and three identical bytecode .so
files of 514kb, which don't seem to contain the code I need. When I run them through emcc
they come out as 141kb, without a _main
function or anything recognizable, and don't behave the same as the other .js
files.
What do I need to change to generate correct bytecode with the emmake
command rather than .js files?
emcmake cmake
completes ok and then emmake make
works, but I don't have the option to try various optimizations or any of the options emcc
would normally give.
I'm attempting this compilation on Lubuntu 15.04 in a vbox under Win 8. This is my first emscripten project other than the tutorials. I'm also not very familiar with c or c++ or compilation in general (though I can compile this project into Linux applications with no problems).
I'm aware of j2k.js, but I'm looking for obj_compress, not obj_decompress.
I am not sure about the usage of emcmake or emmake directly but worked on a CMAKE based C++ project, a main executable, that used be compiled to an x86_64 executable on linux, and that I converted to emscriptem in order to deploy it on an Nginx server.
openjpeg.jp2 project is a CMAKE C/C++ program.
Here you are trying to cross compile a C/C++ lib or executable from your host linux x86 with GCC for instance, could also be Windows + Visual C++ compiler.
You need a CMAKE toolchain file that's gonna tell CMAKE how to use emscriptem tools including the emscriptem compiler, and linker that produce JS or WebAssembly.
example of compiler flags: https://github.com/uclouvain/openjpeg/blob/172c8ae5cf230ff74b5814daf29e5b577aa30a9b/CMakeLists.txt#L200
Again I do not know the specifics of emmake/emcmake but if your project is CMAKE based, the toolchain file should tell CMAKE all that it needs to know to compile your program.
CMakelists.txt that specifies emscriptem linker flags and selects either JS or WebAssembly as an output based on the JS_ONLY option:
cmake_minimum_required(VERSION 3.6)
message( "Current dir: ${CMAKE_CURRENT_LIST_DIR}" )
#make sure it is all static
SET(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
SET(BUILD_SHARED_LIBRARIES OFF)
option(JS_ONLY "Compiles to native JS (No WASM)" OFF)
add_executable( myProgram main.cpp)
target_link_libraries( myProgram ${API_LIB})
target_compile_features(myProgram PRIVATE cxx_std_14)
if(JS_ONLY)
message(STATUS "Setting compilation target to native JavaScript")
set(CMAKE_EXECUTABLE_SUFFIX ".js")
set_target_properties(myProgram PROPERTIES LINK_FLAGS "--emrun -s EXPORTED_FUNCTIONS='[_main]'")
else(JS_ONLY)
message(STATUS "Setting compilation target to WASM")
set(CMAKE_EXECUTABLE_SUFFIX ".wasm.js")
set_target_properties(myProgram PROPERTIES LINK_FLAGS "--emrun -s WASM=1 -s BINARYEN_METHOD='native-wasm' -s EXPORTED_FUNCTIONS='[_main]' -s NO_EXIT_RUNTIME=1 -s EXTRA_EXPORTED_RUNTIME_METHODS=['ccall']")
endif(JS_ONLY)
#- Compiling to emscriptem/js output: PROPERTIES LINK_FLAGS set to --emrun -s
#- Compiling to emscriptem/WASM => webAssembly output: PROPERTIES LINK_FLAGS set to --emrun -s WASM=1 -s BINARYEN_METHOD='native-wasm'
Note WebAssembly is the lowest output level you will get with EmscriptEm, should be a more compact that JS in theory.
On this specific project, reuse the example CMakeLists.txt i gave above and customise it:
set_target_properties(... PROPERTIES LINK_FLAGS "--emrun -s <emscript em link flags as described above>)
set(CMAKE_C_FLAGS_DEBUG "-O0 -ggdb -Wall -Wunused-variable -Wno-unused-parameter -fno-inline ... etc ...etc ...")
set(CMAKE_C_FLAGS_RELEASE "-O2 -Wno-format-security -Wno-format-nonliteral -Wall -Wunused-variable -Wno-unused-parameter")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} [+ optional extra flags for both here...]"
Now is the time to use the toolchain file:
cmake -DCMAKE_BUILD_TYPE:string="Release" -DCMAKE_TOOLCHAIN_FILE=Toolchain-Emscripten.cmake src/"
Replace the src/ by the source directory.
I have not tried running this on the openjpeg project but I think this should put your on the right track. Iterate on this until it work. I have a working lib and exec using exactly this, no more ;-)
Again this is a CMAKE based project it looks nicely designed and looks modular, therefore I would stick with using CMAKE + cross compilation toolchain file and leave the details of make/emmake to ... CMAKE, unless you really have no other choice.
Hope this helps!
Romain
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With