project('cell', ['c', 'cpp'], version: '0.9.3', meson_version: '>=1.4', default_options : [ 'cpp_std=c++11', 'default_library=static']) libtype = get_option('default_library') link = [] src = [] fs = import('fs') add_project_arguments('-Wno-gnu-label-as-value', language: ['c']) git_tag_cmd = run_command('git', 'describe', '--tags', '--abbrev=0', check: false) cell_version = 'unknown' if git_tag_cmd.returncode() == 0 cell_version = git_tag_cmd.stdout().strip() endif git_commit_cmd = run_command('git', 'rev-parse', '--short', 'HEAD', check: false) cell_commit = 'unknown' if git_commit_cmd.returncode() == 0 cell_commit = git_commit_cmd.stdout().strip() endif # Important: pass the definitions without double-escaping quotes add_project_arguments( '-DCELL_VERSION="' + cell_version + '"', '-DCELL_COMMIT="' + cell_commit + '"', language : 'c' ) add_project_arguments('-Wno-incompatible-pointer-types', language: 'c') add_project_arguments('-Wno-narrowing', language: 'cpp') add_project_arguments('-Wno-missing-braces', language:'c') add_project_arguments('-Wno-strict-prototypes', language:'c') add_project_arguments('-Wno-unused-command-line-argument', language: 'c') add_project_arguments('-Wno-unused-command-line-argument', language: 'cpp') deps = [] if host_machine.system() == 'darwin' add_project_arguments('-x', 'objective-c', language: 'c') fworks = [ 'foundation', 'metal', 'audiotoolbox', 'metalkit', 'avfoundation', 'quartzcore', 'cocoa', 'coreaudio', 'coremedia', 'gamecontroller', 'forcefeedback', 'iokit', 'corefoundation', 'corehaptics', 'carbon', 'uniformtypeidentifiers' ] foreach fkit : fworks deps += dependency('appleframeworks', modules: fkit) endforeach endif cmake = import('cmake') sdl3_opts = cmake.subproject_options() sdl3_opts.add_cmake_defines({ 'SDL_STATIC': 'ON', 'SDL_SHARED': 'OFF', 'SDL_TEST': 'OFF', 'CMAKE_BUILD_TYPE': 'Release', 'SDL_THREADS': 'ON', 'SDL_PIPEWIRE': 'ON', 'SDL_PULSEAUDIO': 'ON', }) cc = meson.get_compiler('c') if host_machine.system() == 'darwin' # deps += dependency('appleframeworks', modules: 'accelerate') # add_project_arguments('-DACCELERATE_NEW_LAPACK=1', language:'c') # add_project_arguments('-DACCELERATE_LAPACK_ILP64=1', language:'c') endif if host_machine.system() == 'linux' deps += cc.find_library('asound', required:true) deps += [dependency('x11'), dependency('xi'), dependency('xcursor'), dependency('egl'), dependency('gl')] # deps += cc.find_library('blas', required:true) # deps += cc.find_library('lapacke', required:true) endif if host_machine.system() == 'windows' deps += cc.find_library('d3d11') deps += cc.find_library('ws2_32', required:true) # For Windows, you may need to install OpenBLAS or Intel MKL # and adjust these library names accordingly # deps += cc.find_library('openblas', required:false) # if not cc.find_library('openblas', required:false).found() # deps += cc.find_library('blas', required:false) # deps += cc.find_library('lapacke', required:false) # endif deps += cc.find_library('dbghelp') deps += cc.find_library('winmm') deps += cc.find_library('setupapi') deps += cc.find_library('imm32') deps += cc.find_library('version') deps += cc.find_library('cfgmgr32') deps += cc.find_library('bcrypt') sdl3_opts.add_cmake_defines({'HAVE_ISINF': '1'}) # Hack for MSYS2 sdl3_opts.add_cmake_defines({'HAVE_ISNAN': '1'}) link += ['-static', '-static-libgcc', '-static-libstdc++'] add_project_link_arguments('-static-libgcc', '-static-libstdc++', language: ['c', 'cpp']) endif if host_machine.system() == 'emscripten' message('⚙ Building SDL3 subproject for Emscripten...') sdl3_opts.append_compile_args( 'c', '-pthread', '-sUSE_PTHREADS=1', ) sdl3_opts.append_compile_args( 'cpp', '-pthread', '-sUSE_PTHREADS=1', ) # 3. And into every link step sdl3_opts.append_link_args( '-pthread', '-sUSE_PTHREADS=1', '-sPTHREAD_POOL_SIZE=4', ) sdl3_proj = cmake.subproject('sdl3', options: sdl3_opts) deps += sdl3_proj.dependency('SDL3-static') add_project_arguments('-DPATH_MAX=4096', language: 'c') add_project_arguments( '-pthread', '-sUSE_PTHREADS=1', '-sPTHREAD_POOL_SIZE=4', language: ['c', 'cpp']) add_project_link_arguments( '--use-port=emdawnwebgpu', '-sUSE_PTHREADS=1', '-pthread', '-sPTHREAD_POOL_SIZE=4', '-sMALLOC=mimalloc', language: ['c','cpp']) else # Try to find system-installed SDL3 first sdl3_dep = dependency('sdl3', static: true, required: false) if not sdl3_dep.found() message('⚙ System SDL3 not found, building subproject...') sdl3_proj = cmake.subproject('sdl3', options : sdl3_opts) deps += sdl3_proj.dependency('SDL3-static') else deps += sdl3_dep endif endif miniz_dep = dependency('miniz', static: true, required: false) if not miniz_dep.found() message('⚙ System miniz not found, building subproject...') deps += dependency('miniz', static:true) else deps += miniz_dep endif deps += dependency('threads') # Try to find system-installed chipmunk first chipmunk_dep = dependency('chipmunk', static: true, required: false) if not chipmunk_dep.found() message('⚙ System chipmunk not found, building subproject...') deps += dependency('chipmunk', static:true) else deps += chipmunk_dep endif # Try to find system-installed curl first curl_dep = dependency('libcurl', static: true, required: false) if not curl_dep.found() message('⚙ System curl not found, building subproject...') deps += dependency('libcurl', static:true) else deps += curl_dep endif if host_machine.system() != 'emscripten' # Try to find system-installed enet first enet_dep = dependency('enet', static: true, required: false) if not enet_dep.found() message('⚙ System enet not found, building subproject...') deps += dependency('enet', static:true) else deps += enet_dep endif src += 'qjs_enet.c' mimalloc_enabled = get_option('mimalloc') if mimalloc_enabled message('⚙ Using mimalloc subproject for static linking...') deps += dependency('mimalloc', static:true) add_project_arguments('-DHAVE_MIMALLOC', language: ['c', 'cpp']) else message('⚙ Mimalloc support disabled') endif tracy_enabled = get_option('tracy') if tracy_enabled message('⚙ Tracy profiling enabled') tracy_opts = ['fibers=true', 'no_exit=true', 'on_demand=true'] add_project_arguments('-DTRACY_ENABLE', language:['c','cpp']) # Try to find system-installed tracy first tracy_dep = dependency('tracy', static: true, required: false) if not tracy_dep.found() message('⚙ System tracy not found, building subproject...') deps += dependency('tracy', static:true, default_options:tracy_opts) else deps += tracy_dep endif else message('⚙ Tracy profiling disabled') endif src += 'qjs_dmon.c' endif # Try to find system-installed soloud first soloud_dep = dependency('soloud', static: true, required: false) if not soloud_dep.found() message('⚙ System soloud not found, building subproject...') deps += dependency('soloud', static:true) else deps += soloud_dep endif link_args = link sources = [] src += [ 'qjs_http.c', 'qjs_blob.c', 'qjs_nota.c', 'monocypher.c', 'qjs_crypto.c', 'qjs_time.c', 'qjs_js.c', 'qjs_debug.c', 'qjs_miniz.c', 'timer.c', 'qjs_socket.c', 'qjs_kim.c', 'qjs_utf8.c', 'qjs_fit.c', 'qjs_text.c', 'jsffi.c', 'cell.c', 'wildmatch.c', 'qjs_wildstar.c', 'qjs_fd.c', 'qjs_qop.c', 'qjs_os.c', 'qjs_actor.c', 'qjs_wota.c', ] src += [ 'anim.c', 'config.c', 'datastream.c', 'font.c', 'HandmadeMath.c', 'model.c', 'render.c', 'simplex.c', 'spline.c', 'transform.c', 'sprite.c', 'qjs_soloud.c', 'qjs_sdl.c', 'qjs_sdl_input.c', 'qjs_sdl_video.c', 'qjs_sdl_surface.c', 'qjs_sdl_gpu.c', 'qjs_math.c', 'qjs_geometry.c', 'qjs_transform.c', 'qjs_sprite.c', 'qjs_spline.c', 'qjs_layout.c', 'qjs_staef.c', 'cell_qoi.c' ] # quirc src src += [ 'thirdparty/quirc/quirc.c', 'thirdparty/quirc/decode.c', 'thirdparty/quirc/identify.c', 'thirdparty/quirc/version_db.c' ] # quickjs src src += ['quickjs.c', 'libregexp.c', 'libunicode.c', 'cutils.c', 'dtoa.c'] imsrc = [ 'GraphEditor.cpp','ImCurveEdit.cpp','ImGradient.cpp','imgui_draw.cpp', 'imgui_tables.cpp','imgui_widgets.cpp','imgui.cpp','ImGuizmo.cpp','backends/imgui_impl_sdl3.cpp', 'backends/imgui_impl_sdlrenderer3.cpp', 'backends/imgui_impl_sdlgpu3.cpp' ] foreach file : imsrc sources += 'source/thirdparty/imgui' / file sources += 'source/qjs_imgui.cpp' endforeach srceng = 'source' tp = srceng / 'thirdparty' includes = [ srceng, tp / 'cgltf', tp / 'imgui', tp / 'imgui/backends', tp / 'par', tp / 'stb', tp, tp / 'pl_mpeg/include', tp / 'quirc' ] foreach file : src full_path = join_paths('source', file) sources += files(full_path) endforeach includers = [] foreach inc : includes includers += include_directories(inc) endforeach if host_machine.system() == 'windows' exe_ext = '.exe' else exe_ext = '' endif strip_enabled = ['release', 'minsize'].contains(get_option('buildtype')) if strip_enabled add_project_link_arguments('-s', language: ['c', 'cpp']) endif cell_bin = executable('cell_bin', sources, dependencies: deps, include_directories: includers, link_args: link, build_rpath: '$ORIGIN', install: false ) cell_dep = declare_dependency( link_with: cell_bin ) # Create core.zip from scripts folder qop_target = custom_target('core.qop', output: 'core.qop', command: ['sh', '-c', ' mkdir -p .cell && cell qopconv -d ' + meson.project_source_root() / 'scripts . core.qop'], build_by_default: true, build_always_stale: true ) # Create final cell executable by appending core.zip to cell_bin cell = custom_target('cell', input: [cell_bin, qop_target], output: 'cell' + exe_ext, command: [ 'sh', '-c', 'cp "$1" "$3" && cat "$2" >> "$3" && chmod +x "$3"', 'cell-cat', '@INPUT0@', '@INPUT1@', '@OUTPUT@' ], build_by_default: true, install: true, install_dir: get_option('bindir') ) tests = [ 'spawn_actor', 'empty', 'nota', 'wota', 'portalspawner', 'overling', 'send', 'delay' ] foreach file : tests test(file, cell, args:['tests/' + file]) endforeach