project( 'hsdbg', ['c', 'cpp'], version : '0.1.0', meson_version : '>= 1.1.0', default_options : [ 'c_std=c11', 'cpp_std=c++23', # the vendored dependencies keep their own warnings off; hsdbg opts back # in explicitly below so the flag set matches what premake used 'warning_level=0', 'default_library=static', ], ) cc = meson.get_compiler('c') cpp = meson.get_compiler('cpp') system = host_machine.system() is_macos = system == 'darwin' is_linux = system == 'linux' is_windows = system == 'windows' msvc = cpp.get_argument_syntax() == 'msvc' python = find_program('python3', 'python') # glfw cocoa is Objective-C; only pull in that toolchain where it is needed if is_macos add_languages('objc', required : true, native : false) endif # tools/find_llvm.py carries the search logic (env, vendored ext/llvm, # llvm-config, platform defaults) and prints KEY=value lines we parse here. llvm_query = run_command( python, files('tools/find_llvm.py'), get_option('llvm_prefix'), check : false, ) if llvm_query.returncode() != 0 error( 'no llvm with lldb headers found. install one and pass ' + '-Dllvm_prefix= (or set $LLVM_PREFIX), or run ' + '`python3 tools/fetch_llvm.py` to download the pinned release, ' + 'then reconfigure.' ) endif llvm_prefix = '' lldb_incdir = '' lldb_libdir = '' lldb_lib = '' lldb_dlls = [] foreach line : llvm_query.stdout().strip().split('\n') if line.contains('=') pair = line.split('=') key = pair[0] value = pair[1] if key == 'prefix' llvm_prefix = value elif key == 'incdir' lldb_incdir = value elif key == 'libdir' lldb_libdir = value elif key == 'lib' lldb_lib = value elif key == 'dll' lldb_dlls += value endif endif endforeach message('using llvm/lldb at ' + llvm_prefix) # lldb lives outside the source tree, so feed its include path through the # compiler as a system dir (quiets its headers under our strict warnings) and # link the resolved library by full path, exactly as premake did if msvc lldb_inc_args = ['/I' + lldb_incdir] else lldb_inc_args = ['-isystem', lldb_incdir] endif lldb_dep = declare_dependency( compile_args : lldb_inc_args, link_args : [lldb_lib], ) glfw_inc = include_directories('ext/glfw/include') glad_inc = include_directories('ext/glad/include') imgui_inc = include_directories('ext/imgui', 'ext/imgui/backends') # glfw glfw_src = files( 'ext/glfw/src/context.c', 'ext/glfw/src/init.c', 'ext/glfw/src/input.c', 'ext/glfw/src/monitor.c', 'ext/glfw/src/platform.c', 'ext/glfw/src/vulkan.c', 'ext/glfw/src/window.c', 'ext/glfw/src/null_init.c', 'ext/glfw/src/null_joystick.c', 'ext/glfw/src/null_monitor.c', 'ext/glfw/src/null_window.c', ) if is_linux glfw_defines = ['-D_GLFW_X11'] glfw_src += files( 'ext/glfw/src/x11_init.c', 'ext/glfw/src/x11_monitor.c', 'ext/glfw/src/x11_window.c', 'ext/glfw/src/xkb_unicode.c', 'ext/glfw/src/wl_init.c', 'ext/glfw/src/wl_monitor.c', 'ext/glfw/src/wl_window.c', 'ext/glfw/src/posix_module.c', 'ext/glfw/src/posix_time.c', 'ext/glfw/src/posix_thread.c', 'ext/glfw/src/posix_poll.c', 'ext/glfw/src/glx_context.c', 'ext/glfw/src/egl_context.c', 'ext/glfw/src/osmesa_context.c', 'ext/glfw/src/linux_joystick.c', ) elif is_macos glfw_defines = ['-D_GLFW_COCOA'] glfw_src += files( 'ext/glfw/src/cocoa_init.m', 'ext/glfw/src/cocoa_joystick.m', 'ext/glfw/src/cocoa_monitor.m', 'ext/glfw/src/macos_time.c', 'ext/glfw/src/cocoa_window.m', 'ext/glfw/src/nsgl_context.m', 'ext/glfw/src/egl_context.c', 'ext/glfw/src/osmesa_context.c', 'ext/glfw/src/posix_module.c', 'ext/glfw/src/posix_thread.c', ) elif is_windows glfw_defines = ['-D_GLFW_WIN32', '-D_CRT_SECURE_NO_WARNINGS'] glfw_src += files( 'ext/glfw/src/win32_init.c', 'ext/glfw/src/win32_joystick.c', 'ext/glfw/src/win32_module.c', 'ext/glfw/src/win32_monitor.c', 'ext/glfw/src/win32_thread.c', 'ext/glfw/src/win32_time.c', 'ext/glfw/src/win32_window.c', 'ext/glfw/src/wgl_context.c', 'ext/glfw/src/egl_context.c', 'ext/glfw/src/osmesa_context.c', ) else glfw_defines = [] endif glfw = static_library( 'glfw', glfw_src, c_args : glfw_defines, objc_args : is_macos ? glfw_defines : [], include_directories : glfw_inc, override_options : ['warning_level=0'], ) glfw_dep = declare_dependency( link_with : glfw, include_directories : glfw_inc, ) # glad glad = static_library( 'glad', files('ext/glad/src/gl.c'), include_directories : glad_inc, override_options : ['warning_level=0'], ) glad_dep = declare_dependency( link_with : glad, include_directories : glad_inc, ) # imgui (+ glfw / opengl3 backends) imgui_args = ['-DGLFW_INCLUDE_NONE'] if is_macos imgui_args += '-DGL_SILENCE_DEPRECATION' elif is_windows imgui_args += '-D_CRT_SECURE_NO_WARNINGS' endif imgui = static_library( 'imgui', files( 'ext/imgui/imgui.cpp', 'ext/imgui/imgui_draw.cpp', 'ext/imgui/imgui_tables.cpp', 'ext/imgui/imgui_widgets.cpp', 'ext/imgui/imgui_demo.cpp', 'ext/imgui/misc/cpp/imgui_stdlib.cpp', 'ext/imgui/backends/imgui_impl_glfw.cpp', 'ext/imgui/backends/imgui_impl_opengl3.cpp', ), cpp_args : imgui_args, include_directories : [imgui_inc, glfw_inc], override_options : ['warning_level=0'], ) imgui_dep = declare_dependency( link_with : imgui, include_directories : imgui_inc, ) hsdbg_src = files( 'src/main.cpp', 'src/ui/ui.cpp', 'src/ui/ui_preferences.cpp', 'src/ui/profiler.cpp', 'src/ui/preferences.cpp', 'src/ui/theme.cpp', 'src/ui/image_renderer.cpp', 'src/ui/macro_expander.cpp', 'src/ui/widgets.cpp', 'src/ui/source_view.cpp', 'src/ui/animated_image.cpp', 'src/core/log.cpp', 'src/core/window.cpp', 'src/core/window_manager.cpp', 'src/core/application.cpp', 'src/debugger/debugger.cpp', ) asset_dir = meson.project_source_root().replace('\\', '/') + '/assets' hsdbg_defines = [ '-DGLFW_INCLUDE_NONE', '-D_CRT_SECURE_NO_WARNINGS', '-DHSDBG_LLVM_PREFIX="' + llvm_prefix + '"', '-DHSDBG_ASSET_DIR="' + asset_dir + '"', '-DHSDBG_VERSION="' + meson.project_version() + '"', ] if is_windows hsdbg_defines += '-DHSDBG_WINDOWS' elif is_linux hsdbg_defines += '-DHSDBG_LINUX' elif is_macos hsdbg_defines += '-DHSDBG_MACOS' endif # dist is a stripped release build; premake keyed its HSDBG_DIST off that # configuration, so tie it to disabled asserts (-Db_ndebug=true) ndebug = get_option('b_ndebug') is_dist = ndebug == 'true' or ( ndebug == 'if-release' and get_option('buildtype') in ['release', 'plain'] ) if is_dist hsdbg_defines += '-DHSDBG_DIST' endif hsdbg_warnings = [] if not msvc hsdbg_warnings = [ '-Wall', '-Wextra', '-Wpedantic', '-Wconversion', '-Wsign-conversion', '-Wshadow', ] endif # match premake's frame-pointer preservation whenever a sanitizer is active if get_option('b_sanitize') != 'none' hsdbg_warnings += '-fno-omit-frame-pointer' endif hsdbg_deps = [lldb_dep, glfw_dep, glad_dep, imgui_dep] if is_macos hsdbg_deps += dependency( 'appleframeworks', modules : [ 'Cocoa', 'IOKit', 'CoreFoundation', 'CoreVideo', 'OpenGL', 'QuartzCore', ], ) elif is_linux hsdbg_deps += dependency('gl') hsdbg_deps += dependency('threads') hsdbg_deps += cc.find_library('dl') hsdbg_deps += cc.find_library('m') elif is_windows hsdbg_deps += cc.find_library('opengl32') endif # on unix the loader needs to find liblldb at runtime; on windows we stage the # runtime dlls next to the executable instead (below) hsdbg_rpath = is_windows ? '' : lldb_libdir hsdbg = executable( 'hsdbg', hsdbg_src, include_directories : include_directories('src', 'ext/stb'), cpp_args : hsdbg_defines + hsdbg_warnings, dependencies : hsdbg_deps, build_rpath : hsdbg_rpath, ) if is_windows and lldb_dlls.length() > 0 # stage the lldb / python runtime dlls beside hsdbg.exe (top-level targets # land in the build root), mirroring premake's postbuild copies custom_target( 'llvm-runtime', command : [ python, files('tools/copy_files.py'), '@OUTPUT@', meson.project_build_root(), ] + lldb_dlls, output : 'llvm-runtime.stamp', build_by_default : true, ) endif run_target('fetch-llvm', command : [python, files('tools/fetch_llvm.py')]) cppcheck = find_program('cppcheck', required : false) if cppcheck.found() # meson emits compile_commands.json into the build dir, so no bear needed; # analyse the configured build type (use a release/dist build dir to mirror # premake, which checked the dist configuration) run_target( 'cppcheck', command : [ cppcheck, '--project=' + meson.project_build_root() / 'compile_commands.json', '-i', meson.project_source_root() / 'ext', '--suppress=*:*/ext/*', '--inline-suppr', '--enable=warning,style,performance,portability', '--error-exitcode=1', ], ) endif