project('forts-clone', 'cpp', version: '0.1.0', license: 'GPL-3.0-or-later', default_options: [ 'cpp_std=c++20', 'warning_level=3', 'buildtype=debugoptimized', 'default_library=static', ], meson_version: '>=1.4.0', ) cpp = meson.get_compiler('cpp') # ============================================================================= # Dependencies (pre-built in /usr/local by Containerfile) # ============================================================================= fs = import('fs') # A source-built /usr/local (what the container ships) provides the heavier # libraries. On a stock system these paths are absent, so everything below falls # back to system packages. include_directories() errors on a missing directory, # hence the guard. # # NOTE: add /usr/local/include as a whole, never /usr/local/include/bx etc. # individually. sys/types.h includes , which collides with bx's # endian.h if -I.../include/bx is on the path. local_incs = [] if fs.is_dir('/usr/local/include') local_incs += include_directories('/usr/local/include') endif usr_local_libdirs = ['/usr/local/lib64', '/usr/local/lib', '/usr/local/lib/static'] # --- Libraries the code actually compiles against --------------------------- # SDL3 -- windowing + input. System pkg-config on every target. sdl3_dep = dependency('sdl3', required: true) # glm -- header-only math. pkg-config where available, else rely on the include # path (headers in /usr/include or the guarded /usr/local/include). glm_dep = dependency('glm', required: false) if not glm_dep.found() glm_dep = declare_dependency() endif # sol2 -- header-only Lua bindings. Headers resolve via the include path # (/usr/include/sol system/AUR, or /usr/local/include/sol in the container). sol2_dep = declare_dependency() # Lua 5.4. Container: a STATIC liblua.a in /usr/local/lib, so the binary carries # Lua and runs on any host regardless of its liblua soname. Native build: the # system Lua 5.4 (dynamic linking is fine when built and run on the same box). lua_static = cpp.find_library('lua', dirs: ['/usr/local/lib'], static: true, required: false) if lua_static.found() m_dep = cpp.find_library('m', required: false) dl_dep = cpp.find_library('dl', required: false) lua_dep = declare_dependency(dependencies: [lua_static, m_dep, dl_dep]) else lua_dep = dependency('lua5.4', 'lua54', 'lua-5.4', required: false) if not lua_dep.found() lua_dep = dependency('lua', required: true) endif endif # Box2D v3 -- physics. Idle for now, but physics.cpp compiles against its header. # Try /usr/local (container), then pkg-config/cmake, then a plain system lib. box2d_dep = cpp.find_library('box2d', dirs: usr_local_libdirs, required: false) if not box2d_dep.found() box2d_dep = dependency('box2d', required: false) endif if not box2d_dep.found() box2d_dep = cpp.find_library('box2d', required: true) endif # --- Declared but not yet wired up ------------------------------------------ # bgfx/SoLoud/ENet/EnTT belong to the planned stack, but no source file # #includes them yet (the live renderer is SDL_Renderer; physics/audio/net are # idle). Link them only if a source build has provided them; a stock system # build simply skips them. Promote each to a real dependency when it is wired up. optional_deps = [] foreach libname : ['bgfx', 'bimg', 'bx', 'soloud', 'enet'] found = cpp.find_library(libname, dirs: usr_local_libdirs, required: false) if found.found() optional_deps += found endif endforeach # ImGui -- skipped for M0, added when debug UI is needed # ============================================================================= # Engine library and executable # ============================================================================= engine_inc = include_directories('src') stb_inc = include_directories('third_party/stb') # Dear ImGui (dev UI) — built as its own lib with relaxed warnings. imgui_inc = include_directories('third_party/imgui', 'third_party/imgui/backends') imgui_lib = static_library('imgui', [ 'third_party/imgui/imgui.cpp', 'third_party/imgui/imgui_draw.cpp', 'third_party/imgui/imgui_tables.cpp', 'third_party/imgui/imgui_widgets.cpp', 'third_party/imgui/backends/imgui_impl_sdl3.cpp', 'third_party/imgui/backends/imgui_impl_sdlrenderer3.cpp', ], include_directories: imgui_inc, dependencies: sdl3_dep, override_options: ['warning_level=0', 'werror=false'], ) imgui_dep = declare_dependency(link_with: imgui_lib, include_directories: imgui_inc) engine_src = [ 'src/engine/app.cpp', 'src/engine/renderer.cpp', 'src/engine/input.cpp', 'src/engine/camera.cpp', 'src/engine/physics.cpp', 'src/engine/script.cpp', 'src/engine/stb_impl.cpp', 'src/game/build_graph.cpp', 'src/game/data.cpp', ] engine_deps = [ sdl3_dep, box2d_dep, lua_dep, glm_dep, sol2_dep, imgui_dep, ] + optional_deps extra_inc = local_incs + [stb_inc] # Required by bx/bgfx (normally set by cmake targets; we need them manually # since we link raw .a files). # GCC 14+ on glibc: __BEGIN_DECLS from sys/types.h wraps bx endian.inl # templates in extern "C". -fpermissive downgrades to warnings. buildtype = get_option('buildtype') bx_debug = buildtype.startswith('debug') ? '1' : '0' extra_cpp_args = [ '-msse4.2', '-DBX_CONFIG_DEBUG=@0@'.format(bx_debug), '-DBGFX_CONFIG_DEBUG_ANNOTATION=@0@'.format(bx_debug), '-DBGFX_CONFIG_MULTITHREADED=1', '-DBGFX_CONFIG_VIDEO=1', '-D__STDC_LIMIT_MACROS', '-D__STDC_FORMAT_MACROS', '-D__STDC_CONSTANT_MACROS', ] engine_lib = static_library('engine', engine_src, include_directories: [engine_inc] + extra_inc, dependencies: engine_deps, cpp_args: extra_cpp_args, ) executable('forts-clone', 'src/main.cpp', link_with: engine_lib, include_directories: [engine_inc] + extra_inc, dependencies: engine_deps, cpp_args: extra_cpp_args, )