emscripten-core / emscripten

Emscripten: An LLVM-to-WebAssembly Compiler
Other
25.63k stars 3.28k forks source link

Interaction of CMake and emscripten seems broken #22454

Closed StormLord07 closed 2 weeks ago

StormLord07 commented 2 weeks ago

Version of emscripten/emsdk: emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.64 (a1fe3902bf73a3802eae0357d273d0e37ea79898) clang version 19.0.0git (https:/github.com/llvm/llvm-project 4d8e42ea6a89c73f90941fd1b6e899912e31dd34) Target: wasm32-unknown-emscripten Thread model: posix InstalledDir: C:\libs\emsdk\upstream\bin

Cmake Generator: Ninja

Failing command line in full: 2 almost identical cmake files

set(ASSET_DIR "res")

# Include SDL2, SDL2_mixer, SDL2_image, SDL2_ttf using Emscripten flags
set(USE_FLAGS "-s USE_LIBPNG=1 -sUSE_SDL=2 -s USE_SDL_MIXER=2 -s USE_SDL_IMAGE=2 -s USE_SDL_TTF=2 -s SDL2_IMAGE_FORMATS=[\"bmp\",\"png\"]")
set(LINK_FLAGS "-s ASSERTIONS=0 --preload-file ${ASSET_DIR}@/res")

# Set compiler flags
set(CMAKE_CXX_FLAGS_RELEASE "-Wall -Wextra -O3 ${USE_FLAGS}")
set(CMAKE_CXX_FLAGS_DEBUG "-Wall -Wextra -O0 ${USE_FLAGS}")

# Define the executable name
set(EXECUTABLE_NAME "pong-game") 
set(CMAKE_EXECUTABLE_SUFFIX ".html")

# Add executable target
add_executable(${EXECUTABLE_NAME} ${SOURCES})

target_link_options(${EXECUTABLE_NAME} PRIVATE ${LINK_FLAGS})

# Link SDL2 libraries
target_link_libraries(${EXECUTABLE_NAME} ${USE_FLAGS})

and

set(ASSET_DIR "res")

# Include SDL2, SDL2_mixer, SDL2_image, SDL2_ttf using Emscripten flags
set(USE_FLAGS "-s USE_LIBPNG=1 -sUSE_SDL=2 -s USE_SDL_MIXER=2 -s USE_SDL_IMAGE=2 -s USE_SDL_TTF=2 -s SDL2_IMAGE_FORMATS=[\"bmp\",\"png\"]  --preload-file ${ASSET_DIR}@/res")
set(LINK_FLAGS "-s ASSERTIONS=0")

# Set compiler flags
set(CMAKE_CXX_FLAGS_RELEASE "-Wall -Wextra -O3 ${USE_FLAGS}")
set(CMAKE_CXX_FLAGS_DEBUG "-Wall -Wextra -O0 ${USE_FLAGS}")

# Define the executable name
set(EXECUTABLE_NAME "pong-game")
set(CMAKE_EXECUTABLE_SUFFIX ".html")

# Add executable target
add_executable(${EXECUTABLE_NAME} ${SOURCES})

target_link_options(${EXECUTABLE_NAME} PRIVATE ${LINK_FLAGS})

# Link SDL2 libraries
target_link_libraries(${EXECUTABLE_NAME} ${USE_FLAGS})

Full link command and output with -v appended: CMake №1 link command

cmd.exe /C "cd . && C:\libs\emsdk\upstream\emscripten\em++.bat -Wall -Wextra -O3 -s USE_LIBPNG=1 -sUSE_SDL=2 -s USE_SDL_MIXER=2 -s USE_SDL_IMAGE=2 -s USE_SDL_TTF=2 -s SDL2_IMAGE_FORMATS=["bmp","png"] "-s ASSERTIONS=0 --preload-file res@/res -v" CMakeFiles/pong-game.dir/src/audio.cpp.o CMakeFiles/pong-game.dir/src/ball.cpp.o CMakeFiles/pong-game.dir/src/font.cpp.o CMakeFiles/pong-game.dir/src/font_manager.cpp.o CMakeFiles/pong-game.dir/src/game.cpp.o CMakeFiles/pong-game.dir/src/image.cpp.o CMakeFiles/pong-game.dir/src/main.cpp.o CMakeFiles/pong-game.dir/src/paddle.cpp.o CMakeFiles/pong-game.dir/src/random.cpp.o CMakeFiles/pong-game.dir/src/texture.cpp.o CMakeFiles/pong-game.dir/src/vector2d.cpp.o CMakeFiles/pong-game.dir/src/window.cpp.o -o release-build\pong-game.html  -s USE_LIBPNG=1 -sUSE_SDL=2 -s USE_SDL_MIXER=2 -s USE_SDL_IMAGE=2 -s USE_SDL_TTF=2 -s SDL2_IMAGE_FORMATS=["bmp","png"] && cd ."

compile command

C:\libs\emsdk\upstream\emscripten\em++.bat   -Wall -Wextra -O3 -s USE_LIBPNG=1 -sUSE_SDL=2 -s USE_SDL_MIXER=2 -s USE_SDL_IMAGE=2 -s USE_SDL_TTF=2 -s SDL2_IMAGE_FORMATS=["bmp","png"] -std=gnu++11 -MD -MT CMakeFiles/pong-game.dir/src/audio.cpp.o -MF CMakeFiles\pong-game.dir\src\audio.cpp.o.d -o CMakeFiles/pong-game.dir/src/audio.cpp.o -c C:/Users/pasha/Desktop/pong-game/src/audio.cpp

CMake №2 link command

cmd.exe /C "cd . && C:\libs\emsdk\upstream\emscripten\em++.bat -Wall -Wextra -O3 -s USE_LIBPNG=1 -sUSE_SDL=2 -s USE_SDL_MIXER=2 -s USE_SDL_IMAGE=2 -s USE_SDL_TTF=2 -s SDL2_IMAGE_FORMATS=["bmp","png"] --preload-file res@/res "-s ASSERTIONS=0" CMakeFiles/pong-game.dir/src/audio.cpp.o CMakeFiles/pong-game.dir/src/ball.cpp.o CMakeFiles/pong-game.dir/src/font.cpp.o CMakeFiles/pong-game.dir/src/font_manager.cpp.o CMakeFiles/pong-game.dir/src/game.cpp.o CMakeFiles/pong-game.dir/src/image.cpp.o CMakeFiles/pong-game.dir/src/main.cpp.o CMakeFiles/pong-game.dir/src/paddle.cpp.o CMakeFiles/pong-game.dir/src/random.cpp.o CMakeFiles/pong-game.dir/src/texture.cpp.o CMakeFiles/pong-game.dir/src/vector2d.cpp.o CMakeFiles/pong-game.dir/src/window.cpp.o -o release-build\pong-game.html  -s USE_LIBPNG=1 -sUSE_SDL=2 -s USE_SDL_MIXER=2 -s USE_SDL_IMAGE=2 -s USE_SDL_TTF=2 -s SDL2_IMAGE_FORMATS=["bmp","png"] --preload-file res@/res && cd ."

compile command

 C:\libs\emsdk\upstream\emscripten\em++.bat   -Wall -Wextra -O3 -s USE_LIBPNG=1 -sUSE_SDL=2 -s USE_SDL_MIXER=2 -s USE_SDL_IMAGE=2 -s USE_SDL_TTF=2 -s SDL2_IMAGE_FORMATS=["bmp","png"] --preload-file res@/res -std=gnu++11 -MD -MT CMakeFiles/pong-game.dir/src/audio.cpp.o -MF CMakeFiles\pong-game.dir\src\audio.cpp.o.d -o CMakeFiles/pong-game.dir/src/audio.cpp.o -c C:/Users/pasha/Desktop/pong-game/src/audio.cpp
em++: warning: linker flag ignored during compilation: '--preload-file' [-Wunused-command-line-argument]

Error desciption

1st cmake builds with no warnings however no file can be loaded on frontend

2nd cmake warns out every file -Wunused-command-line-argument however only then files can be loaded on frontend

StormLord07 commented 2 weeks ago

Either the issue with linker/compiler or how CMake concatenates vars, unfortunately CMake is the only way how I can interact with compilers and generators provided by MSVC without having to butcher my $PATH, so I can't check which, never before I encountered this error.

StormLord07 commented 2 weeks ago

A little more experimenting it seems to be a problem with how arguments are handled, spaces don't work well with both cmake and emcc, em++ changing LINK_FLAGS to set(LINK_FLAGS "-s" "ASSERTIONS=0" "--preload-file" "${ASSET_DIR}@/res") "fixes" the issue

sbc100 commented 2 weeks ago

I recommend using -sASSERTIONS=0 (without the space), and --preload-file=${ASSET_DIR}@/res (again without a space), especially when using cmake.

sbc100 commented 2 weeks ago

Also, with linker flags such as -sASSERTIONS=0 and --preload-file you don't really want to add them to CMAKE_CXX_FLAGS_RELEASE or CMAKE_CXX_FLAGS_DEBUG since those used for compiler sources. When adding link flags you should use CMAKE_EXE_LINKER_FLAGS or target_link_options (https://cmake.org/cmake/help/latest/command/target_link_options.html)