| 1 | # Sniffly - Pure Fortran GUI Disk Analyzer |
| 2 | # Build configuration using Meson |
| 3 | |
| 4 | project('sniffly', ['fortran', 'c', 'objc'], |
| 5 | version: '0.4.0', # Also maintained in VERSION file |
| 6 | license: 'MIT', |
| 7 | default_options: [ |
| 8 | 'warning_level=3', |
| 9 | 'buildtype=debugoptimized', |
| 10 | ]) |
| 11 | |
| 12 | # Minimum Meson version |
| 13 | meson_version_required = '>=0.60.0' |
| 14 | |
| 15 | # Project information |
| 16 | project_description = 'Pure Fortran GUI disk analyzer inspired by SpaceSniffer' |
| 17 | project_url = 'https://github.com/FortranGoingOnForty/sniffly' |
| 18 | |
| 19 | # Print build configuration |
| 20 | message('===========================================') |
| 21 | message('Configuring Sniffly v' + meson.project_version()) |
| 22 | message('Build type: ' + get_option('buildtype')) |
| 23 | message('===========================================') |
| 24 | |
| 25 | # Check for dependencies |
| 26 | message('Checking dependencies...') |
| 27 | |
| 28 | # GTK4 via gtk-fortran (required) |
| 29 | gtk4_dep = dependency('gtk-4-fortran', |
| 30 | version: '>=4.0', |
| 31 | required: true, |
| 32 | fallback: ['gtk-fortran', 'gtk4_dep']) |
| 33 | |
| 34 | # Cairo (required for drawing) |
| 35 | cairo_dep = dependency('cairo', |
| 36 | version: '>=1.16', |
| 37 | required: true) |
| 38 | |
| 39 | # Optional: threads for background scanning |
| 40 | thread_dep = dependency('threads', required: false) |
| 41 | |
| 42 | # Collect all dependencies |
| 43 | dependencies = [ |
| 44 | gtk4_dep, |
| 45 | cairo_dep, |
| 46 | ] |
| 47 | |
| 48 | if thread_dep.found() |
| 49 | dependencies += thread_dep |
| 50 | message('Threading support: enabled') |
| 51 | else |
| 52 | message('Threading support: disabled (will use single-threaded scanning)') |
| 53 | endif |
| 54 | |
| 55 | # Print dependency versions |
| 56 | message('GTK4-Fortran version: ' + gtk4_dep.version()) |
| 57 | message('Cairo version: ' + cairo_dep.version()) |
| 58 | |
| 59 | # Generate version module from template |
| 60 | version_data = configuration_data() |
| 61 | version_data.set('VERSION', meson.project_version()) |
| 62 | version_f90 = configure_file( |
| 63 | input: 'src/version.f90.in', |
| 64 | output: 'version.f90', |
| 65 | configuration: version_data, |
| 66 | ) |
| 67 | |
| 68 | # Source files |
| 69 | # Note: Order matters for Fortran modules (dependencies must come first) |
| 70 | |
| 71 | # C helper sources (for file system operations) |
| 72 | c_sources = [ |
| 73 | 'src/core/dir_helpers.c', |
| 74 | 'src/core/macos_file_picker.m', |
| 75 | ] |
| 76 | |
| 77 | # Fortran source files |
| 78 | core_sources = [ |
| 79 | version_f90, # Generated version module (no dependencies) |
| 80 | 'src/core/types.f90', # Must be first (no dependencies) |
| 81 | 'src/core/file_system.f90', # Depends on types |
| 82 | 'src/core/disk_scanner.f90', # Depends on types, file_system |
| 83 | 'src/core/progressive_scanner.f90', # Depends on types, file_system |
| 84 | ] |
| 85 | |
| 86 | layout_sources = [ |
| 87 | # Layout algorithms |
| 88 | 'src/layout/squarified.f90', # Depends on types |
| 89 | # 'src/layout/cushioned.f90', |
| 90 | # 'src/layout/layout_manager.f90', |
| 91 | ] |
| 92 | |
| 93 | gui_sources = [ |
| 94 | # GTK4 interface |
| 95 | 'src/gui/tab_manager.f90', # Tab state management (only depends on types) |
| 96 | 'src/gui/tab_widget.f90', # Tab bar UI (depends on tab_manager) |
| 97 | 'src/gui/cairo_tab_bar.f90', # Cairo-rendered filing cabinet tabs |
| 98 | 'src/gui/treemap_widget.f90', # Must come before gtk_app (dependency) |
| 99 | 'src/gui/breadcrumb_widget.f90', # Must come before gtk_app (dependency) |
| 100 | 'src/gui/gtk_app.f90', |
| 101 | # 'src/gui/main_window.f90', |
| 102 | # 'src/gui/toolbar.f90', |
| 103 | # 'src/gui/statusbar.f90', |
| 104 | # 'src/gui/dialogs.f90', |
| 105 | # 'src/gui/menus.f90', |
| 106 | ] |
| 107 | |
| 108 | rendering_sources = [ |
| 109 | # Cairo rendering |
| 110 | 'src/rendering/treemap_renderer.f90', # Depends on types, disk_scanner, squarified_layout, cairo |
| 111 | # 'src/rendering/colors.f90', |
| 112 | # 'src/rendering/text_layout.f90', |
| 113 | # 'src/rendering/effects.f90', |
| 114 | ] |
| 115 | |
| 116 | state_sources = [ |
| 117 | # Application state (will add later) |
| 118 | # 'src/state/app_state.f90', |
| 119 | # 'src/state/selection.f90', |
| 120 | # 'src/state/config.f90', |
| 121 | # 'src/state/scan_manager.f90', |
| 122 | ] |
| 123 | |
| 124 | app_sources = [ |
| 125 | 'app/main.f90', |
| 126 | ] |
| 127 | |
| 128 | # Combine all sources (C first, then Fortran in dependency order) |
| 129 | all_sources = c_sources + core_sources + layout_sources + gui_sources + rendering_sources + state_sources + app_sources |
| 130 | |
| 131 | # Compiler flags |
| 132 | fortran = meson.get_compiler('fortran') |
| 133 | fortran_args = [] |
| 134 | |
| 135 | # Warning flags |
| 136 | if fortran.get_id() == 'gcc' |
| 137 | fortran_args += [ |
| 138 | '-Wall', |
| 139 | '-Wextra', |
| 140 | '-Wimplicit-interface', |
| 141 | '-fcheck=all', # Runtime checks in debug mode |
| 142 | '-fbacktrace', # Backtrace on error |
| 143 | ] |
| 144 | endif |
| 145 | |
| 146 | # Linker flags for macOS app bundling |
| 147 | # -headerpad_max_install_names reserves space for dylibbundler to rewrite library paths |
| 148 | link_args = [] |
| 149 | if host_machine.system() == 'darwin' |
| 150 | link_args += ['-Wl,-headerpad_max_install_names', '-framework', 'Cocoa'] |
| 151 | endif |
| 152 | |
| 153 | # Build executable |
| 154 | executable('sniffly', |
| 155 | sources: all_sources, |
| 156 | dependencies: dependencies, |
| 157 | fortran_args: fortran_args, |
| 158 | link_args: link_args, |
| 159 | install: true, |
| 160 | install_dir: get_option('bindir')) |
| 161 | |
| 162 | # Tests (to be added) |
| 163 | # subdir('test') |
| 164 | |
| 165 | # Installation |
| 166 | # install_man('docs/sniffly.1') # Man page (when created) |
| 167 | |
| 168 | # Configuration summary |
| 169 | summary({ |
| 170 | 'Version': meson.project_version(), |
| 171 | 'Build type': get_option('buildtype'), |
| 172 | 'Install prefix': get_option('prefix'), |
| 173 | 'GTK4-Fortran': gtk4_dep.version(), |
| 174 | 'Cairo': cairo_dep.version(), |
| 175 | 'Threading': thread_dep.found() ? 'yes' : 'no', |
| 176 | }, section: 'Configuration') |
| 177 | |
| 178 | message('===========================================') |
| 179 | message('Sniffly configuration complete!') |
| 180 | message('Next steps:') |
| 181 | message(' 1. Add source files to src/ directories') |
| 182 | message(' 2. Uncomment source lists in meson.build') |
| 183 | message(' 3. Uncomment executable() to build') |
| 184 | message(' 4. Run: meson compile -C build') |
| 185 | message('===========================================') |
| 186 |