cmake_minimum_required(VERSION 3.24) project(smack_a_brother LANGUAGES C CXX) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # The simulation must run identically on every platform (desktop and web play together), so floating point is kept # strict: no fusing multiplies and adds (GCC and arm64 Clang do by default), no fast-math reordering. The math # library's transcendentals are replaced by src/dmath.h. if(MSVC) add_compile_options(/fp:precise /fp:contract-) else() add_compile_options(-ffp-contract=off -fno-fast-math) endif() if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE RelWithDebInfo) endif() # SDL: static, with only the video (OpenGL), audio and gamepad pieces the game uses. set(SDL_SHARED OFF CACHE BOOL "" FORCE) set(SDL_STATIC ON CACHE BOOL "" FORCE) set(SDL_OPENGL ON CACHE BOOL "" FORCE) set(SDL_JOYSTICK ON CACHE BOOL "" FORCE) set(SDL_HIDAPI ON CACHE BOOL "" FORCE) set(SDL_VIRTUAL_JOYSTICK ON CACHE BOOL "" FORCE) set(SDL_TEST_LIBRARY OFF CACHE BOOL "" FORCE) set(SDL_EXAMPLES OFF CACHE BOOL "" FORCE) foreach(OPTION RENDER GPU VULKAN CAMERA HAPTIC HIDAPI_LIBUSB POWER SENSOR DIALOG TRAY OPENGLES OFFSCREEN DUMMYVIDEO DISKAUDIO DUMMYAUDIO OSS JACK SNDIO KMSDRM IBUS LIBURING) set(SDL_${OPTION} OFF CACHE BOOL "" FORCE) endforeach() add_subdirectory(external/sdl EXCLUDE_FROM_ALL) # simdjson: its single-file build, static, without exceptions. add_library(simdjson STATIC external/simdjson/singleheader/simdjson.cpp) target_include_directories(simdjson SYSTEM PUBLIC external/simdjson/singleheader) target_compile_definitions(simdjson PUBLIC SIMDJSON_EXCEPTIONS=0) include(src/sim.cmake) # Networking: WebRTC data channels between players and a WebSocket to the server. On desktop it's # libdatachannel (static, data channels only, no media); in the browser, datachannel-wasm gives the same API over the # browser's own WebRTC. if(EMSCRIPTEN) add_subdirectory(external/datachannel-wasm EXCLUDE_FROM_ALL) set(NETWORK_LIBRARY datachannel-wasm) else() set(NO_MEDIA ON CACHE BOOL "" FORCE) set(NO_EXAMPLES ON CACHE BOOL "" FORCE) set(NO_TESTS ON CACHE BOOL "" FORCE) add_subdirectory(external/libdatachannel EXCLUDE_FROM_ALL) set(NETWORK_LIBRARY LibDataChannel::LibDataChannelStatic) # The server, which can also be built on its own (see server/CMakeLists.txt). add_subdirectory(server) endif() file(GLOB SOURCES CONFIGURE_DEPENDS src/*.cpp) list(REMOVE_ITEM SOURCES ${SIM_SOURCES}) add_executable(smack_a_brother ${SOURCES}) target_include_directories(smack_a_brother SYSTEM PRIVATE external/stb) target_link_libraries(smack_a_brother PRIVATE sim SDL3::SDL3-static simdjson ${NETWORK_LIBRARY}) set_target_properties(smack_a_brother PROPERTIES OUTPUT_NAME smack-a-brother) file(CREATE_LINK ${CMAKE_SOURCE_DIR}/resources ${CMAKE_BINARY_DIR}/resources SYMBOLIC) # Emscripten: RPG_NODE builds a headless copy for node (balance runs and the determinism check), with the resources # embedded. if(EMSCRIPTEN) option(RPG_NODE "Build for node, headless" OFF) target_link_options(smack_a_brother PRIVATE -sALLOW_MEMORY_GROWTH=1 -sSTACK_SIZE=1048576) if(NOT RPG_NODE) # The browser build: WebGL2, the resources preloaded, the prefs folder kept in browser storage, and a page # whose canvas fills the window. set_target_properties(smack_a_brother PROPERTIES SUFFIX ".html") target_link_options(smack_a_brother PRIVATE -sMIN_WEBGL_VERSION=2 -sMAX_WEBGL_VERSION=2 -lidbfs.js "--preload-file=${CMAKE_SOURCE_DIR}/resources/gfx@/resources/gfx" "--preload-file=${CMAKE_SOURCE_DIR}/resources/font@/resources/font" "--preload-file=${CMAKE_SOURCE_DIR}/resources/sfx@/resources/sfx" "--shell-file=${CMAKE_SOURCE_DIR}/web/web_shell.html" "--pre-js=${CMAKE_SOURCE_DIR}/web/web_pre.js") endif() if(RPG_NODE) target_link_options(smack_a_brother PRIVATE -sENVIRONMENT=node -sEXIT_RUNTIME=1 "--pre-js=${CMAKE_SOURCE_DIR}/web/node_pre.js" "--embed-file=${CMAKE_SOURCE_DIR}/resources/gfx@/resources/gfx" "--embed-file=${CMAKE_SOURCE_DIR}/resources/font@/resources/font") endif() endif()