emscripten-core / emsdk

Emscripten SDK
http://emscripten.org
Other
2.92k stars 662 forks source link

Build scenario for Emscripten #1319

Closed vault-thirteen closed 7 months ago

vault-thirteen commented 7 months ago

I am having trouble with building a project with Emscripten.

I have a working scenario for MinGW in MSYS2 MINGW64 on Windows O.S. The following code is working and producing a DLL file in Windows O.S.

cd /D/Temp/2
cmake . -B "_BUILD_" -G "MinGW Makefiles"
cmake --build _BUILD_

Note that all this happens inside the MSYS2 MINGW64 terminal, so usual Windows slashes in path are changed to MSYS2-styled Unix slashes.

When I try to convert this scenario into Emscripten, I see errors.

What do I do.

  1. I start the MSYS2 MINGW64 terminal, cd to the folder with Emscripten's SDK, and run a script which sets environment variables:

    cd /D/Temp/1emsdk
    source ./emsdk_env.sh
    echo $PATH

    I see the new value of PATH variable. Check.

  2. Then I cd to a project source code directory and do the emconfigure ./configure from the manual located here: https://emscripten.org/docs/compiling/Building-Projects.html It says to use another command, so I change it accordingly. emcmake cmake . -B "_BUILD_" -G "MinGW Makefiles"

    
    configure: cmake . -B _BUILD_ -G "MinGW Makefiles" -DCMAKE_TOOLCHAIN_FILE=D:\Temp\1\emsdk\upstream\emscripten\cmake\Modules\Plat
    form\Emscripten.cmake -DCMAKE_CROSSCOMPILING_EMULATOR=D:/Temp/1/emsdk/node/16.20.0_64bit/bin/node.exe
    Product Name: Argon2 library
    Project Version: 0.1.0.0.
    Product Version: 0,1,0,0.
    File Version: 0,1,0,0.
    Source Files: src/argon2.c;src/bench.c;src/core.c;src/encoding.c;src/thread.c;src/blake2/blake2b.c;src/ref.c.
    Public Header Files: include/argon2.h.
    AVX: no.
    Version.rc: no.
    CMake Warning (dev) at CMakeLists.txt:84 (add_library):
    ADD_LIBRARY called with SHARED option but the target platform does not
    support dynamic linking.  Building a STATIC library instead.  This may lead
    to problems.
    This warning is for project developers.  Use -Wno-dev to suppress it.

-- Configuring done (0.7s) -- Generating done (0.0s) -- Build files have been written to: D:/Temp/2/BUILD

AFAIK, Emscripten changes the shared library to a static one in WASM, so it is OK to see this warning, I guess.

What do I do next ?

If I try to `emcmake cmake --build _BUILD_`, it does not like it.

configure: cmake --build BUILD -DCMAKE_TOOLCHAIN_FILE=D:\Temp\1\emsdk\upstream\emscripten\cmake\Modules\Platform\Emscripten.cm ake -DCMAKE_CROSSCOMPILING_EMULATOR=D:/Temp/1/emsdk/node/16.20.0_64bit/bin/node.exe -G "MinGW Makefiles" Unknown argument -DCMAKE_TOOLCHAIN_FILE=D:\Temp\1\emsdk\upstream\emscripten\cmake\Modules\Platform\Emscripten.cmake Usage: cmake --build

[options] [-- [native-options]] cmake --build --preset [options] [-- [native-options]] Options:

= Project binary directory to be built. --preset , --preset= = Specify a build preset. --list-presets[=] = List available build presets. --parallel [], -j [] = Build in parallel using the given number of jobs. If is omitted the native build tool's default number is used. The CMAKE_BUILD_PARALLEL_LEVEL environment variable specifies a default parallel level when this option is not given. -t ..., --target ... = Build instead of default targets. --config = For multi-configuration tools, choose . --clean-first = Build target 'clean' first, then build. (To clean only, use --target 'clean'.) --resolve-package-references={on|only|off} = Restore/resolve package references during build. -v, --verbose = Enable verbose output - if supported - including the build commands to be executed. -- = Pass remaining options to the native tool. emcmake: error: 'cmake --build _BUILD_ -DCMAKE_TOOLCHAIN_FILE=D:\Temp\1\emsdk\upstream\emscripten\cmake\Modules\Platform\Emscrip ten.cmake -DCMAKE_CROSSCOMPILING_EMULATOR=D:/Temp/1/emsdk/node/16.20.0_64bit/bin/node.exe -G "MinGW Makefiles"' failed (returned 1) ``` If I try to ` emmake cmake --build _BUILD_` it does not like it too. ``` make: cmake --build _BUILD_ [ 12%] Building C object CMakeFiles/argon2.dir/src/argon2.c.o [ 25%] Building C object CMakeFiles/argon2.dir/src/bench.c.o D:\Temp\2\src\bench.c:42:2: error: "Not implemented!" 42 | #error "Not implemented!" | ^ 1 error generated. emcc: error: 'D:/Temp/1/emsdk/upstream/bin\clang.exe -target wasm32-unknown-emscripten -fignore-exceptions -fvisibility=default -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr --sysroot=D:\Temp\1\emsdk\upstre am\emscripten\cache\sysroot -DEMSCRIPTEN -Werror=implicit-function-declaration -Xclang -iwithsysroot/include\fakesdl -Xclang -iw ithsysroot/include\compat -ID:/Temp/2/include -ID:/Temp/2/src -std=gnu23 -MD -MT CMakeFiles/argon2.dir/src/bench.c.o -MF CMakeFi les\argon2.dir\src\bench.c.o.d -c D:\Temp\2\src\bench.c -o CMakeFiles\argon2.dir\src\bench.c.o' failed (returned 1) mingw32-make[2]: *** [CMakeFiles\argon2.dir\build.make:91: CMakeFiles/argon2.dir/src/bench.c.o] Error 1 mingw32-make[1]: *** [CMakeFiles\Makefile2:82: CMakeFiles/argon2.dir/all] Error 2 mingw32-make: *** [Makefile:135: all] Error 2 emmake: error: 'cmake --build _BUILD_' failed (returned 2) ``` Thank you.
vault-thirteen commented 7 months ago

Well, it looks like the author of the library decided to throw an error in the preprocessing stage at that line 42. https://github.com/vault-thirteen/argon2/blob/main/src/bench.c#L42

For some reason, CMake started via Emscripten thinks that the CPU is neither Intel x86 nor AMD64. How can it be ? I am using an Intel x86-64 CPU. And a normal CMake produced a DLL for it.

sbc100 commented 7 months ago

Emscripten is a cross compiler that targets WebAsssembly, which is a virtual ISA and is neither x86 nor AMD64. Any code that is architecture-specific would need to be modified to build for WebAssembly.

The function in question looks like it trying to access a high frequency timer. On the web and with emscripten the closest thing you have to do would be something like the emscripten_get_now function. But remember this will be a lot more expensive than single assembly instruction since it has to call out the JavaScript to get this number.

vault-thirteen commented 7 months ago

@sbc100 thank you very much ! WASM is a separate universe for me.