project( 'zinnia', license: 'ISC', version: '0.1.0', meson_version: '>=1.5.0', default_options: [ 'c_std=gnu23', 'werror=true', 'warning_level=2', 'strip=true', ], ) if get_option('headers_only') install_subdir('include/uapi', install_dir: get_option('includedir')) pkg = import('pkgconfig') pkg.generate(name: 'zinnia', description: 'Zinnia user API') subdir_done() endif add_languages('c', native: false, required: true) # Check if we're using a sane compiler. c_compiler = meson.get_compiler('c') # We require a compiler that supports the GNU C dialect. assert(c_compiler.has_define('__GNUC__')) if get_option('tools_only') subdir('tools') subdir_done() endif add_project_arguments( '-Wno-unused', '-Wno-unused-parameter', language: 'c', ) common_c_args = [ '-fno-stack-protector', '-fno-omit-frame-pointer', '-ffunction-sections', '-fdata-sections', '-ffreestanding', '-nostdinc', ] common_link_args = [ '-ffreestanding', '-nostdlib', '-Wl,-z,noexecstack', '-Wl,--gc-sections', '-Wl,--build-id=none', ] common_includes = [ include_directories('include'), include_directories('arch' / target_machine.cpu_family() / 'include'), ] cfg = configuration_data() cfg.set_quoted('ZINNIA_VERSION', meson.project_version()) cfg.set_quoted('ZINNIA_ARCH', target_machine.cpu_family()) cfg.set_quoted('ZINNIA_COMPILER_ID', c_compiler.get_id() + ' ' + c_compiler.version()) cfg.set_quoted('ZINNIA_LINKER_ID', c_compiler.get_linker_id()) # Parse kernel config kv = import('keyval') kconfig = kv.load(get_option('config_path')) foreach k, v : kconfig if v == 'y' cfg.set10(k, true) elif v == 'n' cfg.set10(k, false) else cfg.set(k, v) endif endforeach kernel_c_args = ['-D__IN_KERNEL'] kernel_lds = meson.current_source_dir() / 'boot' / 'kernel.ld' kernel_link_args = [ '-T' + kernel_lds, '-shared', '-Wl,-Bsymbolic', '-Wl,-soname,zinnia', ] kernel_includes = [] kernel_sources = [] modules = {} # These dirs go first so we can add arch-specific flags to drivers. subdir('arch' / target_machine.cpu_family()) subdir('boot') subdir('core') subdir('syscalls') # Device and file system drivers. subdir('dev') subdir('fs') configure_file( configuration: cfg, output: 'config.h', ) zinnia_datadir = get_option('datadir') / 'zinnia' mod_summary = {} modular_modules = {} builtin_libs = [] foreach name, v : modules foreach dep : v.get('depends', []) assert( dep in modules, 'Module "' + name + '" depends on unknown module "' + dep + '"', ) assert( not modules[dep].get('modular', false), 'Module "' + name + '" can\'t depend on modular module "' + dep + '"', ) endforeach if v.get('modular', false) modular_modules += {name: v} mod_summary += {name: 'module'} continue endif mod_c_args = v.get('c_args', []) mod_includes = v.get('include_directories', []) builtin_libs += static_library( name, sources: v.get('sources'), c_args: [ common_c_args, kernel_c_args, mod_c_args, '-D__MODULE_NAME="' + name + '"', ], include_directories: [common_includes, kernel_includes, mod_includes], pic: true, ) kernel_c_args += mod_c_args kernel_includes += mod_includes kernel_link_args += v.get('link_args', []) mod_summary += {name: 'builtin'} endforeach # Kernel kernel = executable( 'zinnia', include_directories: [ common_includes, kernel_includes, ], c_args: [common_c_args, kernel_c_args], link_args: [common_link_args, kernel_link_args], link_depends: kernel_lds, sources: kernel_sources, link_whole: builtin_libs, pie: true, install: true, install_dir: zinnia_datadir, ) foreach name, v : modular_modules shared_library( name, sources: v.get('sources'), c_args: [ common_c_args, '-fPIC', '-D__IN_MODULE', '-D__MODULE_NAME="' + name + '"', v.get('c_args', []), ], link_args: [ common_link_args, '-T' + module_lds, kernel.full_path(), v.get('link_args', []), ], link_depends: [module_lds, kernel], include_directories: [ common_includes, kernel_includes, # We want this, actually v.get('include_directories', []), ], name_prefix: '', name_suffix: 'kso', link_with: v.get('link_with', []), install_dir: zinnia_datadir / 'modules', ) endforeach # Print a summary summary(mod_summary, section: 'Driver configuration') summary(kconfig, bool_yn: true, section: 'Kernel configuration')