Tüm eğitimler
TEKNİK REHBER GÖMÜLÜ LİNUX BUILD SİSTEMİ 2026

Meson
Modern Gömülü Proje Build Sistemi

Hızlı, okunabilir ve cross-compile dostu build sistemi — CMake/Autotools karşılaştırması, sysroot entegrasyonu, Yocto ve Buildroot uyumu.

00 Neden Meson

CMake karmaşık sözdizimi, Autotools ise yavaş yapılandırma süreci ile bilinir. Meson her ikisinin sorunlarını çözerek gömülü Linux projelerinde modern bir deneyim sunar.

Üç sistemin karşılaştırması

ÖzellikMesonCMakeAutotools
SözdizimiPython benzeri, temiz DSLTuhaf prosedürel dilM4 makro karmaşası
Yapılandırma hızıÇok hızlı (Ninja backend)OrtaYavaş (./configure uzun sürer)
Build hızıNinja ile paralel, en hızlıMake veya Ninja seçilebilirMake, rekabetçi değil
Cross-compilecross-file ile yerleşik destekToolchain dosyası, karmaşık--host flag, genellikle kırılır
Bağımlılık yönetimipkg-config + wrap sistemifind_package, tutarsızpkg-config elle yazılır
Test entegrasyonuYerleşik test(), benchmark()CTest ayrı araçmake check, elle yazılır
Yocto desteğimeson.bbclass — resmicmake.bbclass — resmiautotools.bbclass — eski
compile_commands.jsonOtomatik üretilirFlag gerekirbear ile elle üretilir
Öğrenme eğrisiDüz — 1 günde öğrenilebilirDik — CMake 3 ile daha iyiÇok dik — aylar alır

Meson'ın gömülü avantajları

Native + cross aynı andaHost'ta çalışan araçlar (kod üreteci) ile hedef binary'leri aynı build ağacında yönetir
pkg-config sysroot farkındalığıPKG_CONFIG_SYSROOT_DIR otomatik ayarlanır; cross-sysroot'taki kütüphaneleri bulur
Tekrar üretilebilir buildYapılandırma seçenekleri builddir/meson-info/ altında JSON olarak saklanır; CI'da izlenebilir
Minimal bağımlılıkPython 3.7+ ve Ninja yeterli; host'ta ayrı araç kurmak gerekmez

Meson kurulumu

# pip ile güncel sürüm (önerilen)
pip3 install --user meson ninja

# Debian/Ubuntu paket yöneticisi (eski sürüm olabilir)
sudo apt-get install meson ninja-build

# Sürüm kontrolü
meson --version   # 1.3.0+
ninja --version   # 1.11+

01 meson.build temelleri

Her Meson projesi kök dizinde bir meson.build dosyasıyla başlar. Bu dosya hedefleri, bağımlılıkları ve derleme seçeneklerini tanımlar.

Proje tanımı

project('my-daemon', 'c',
  version : '1.2.0',
  license : 'GPL-2.0-only',
  default_options : [
    'c_std=c11',
    'warning_level=2',
    'werror=false',
    'buildtype=debugoptimized',
    'strip=false',
  ]
)

Executable hedefi

sources = files(
  'src/main.c',
  'src/config.c',
  'src/sensor.c',
  'src/network.c',
)

executable('my-daemon',
  sources,
  include_directories : include_directories('include'),
  install : true,
  install_dir : get_option('sbindir'),
)

Kütüphane hedefleri

# Paylaşımlı kütüphane
libmyutil = shared_library('myutil',
  files('lib/util.c', 'lib/crc.c'),
  version : '1.0.0',
  soversion : '1',
  install : true,
)

# Statik kütüphane
libmyutil_static = static_library('myutil',
  files('lib/util.c', 'lib/crc.c'),
  pic : true,   # cross ile shared olarak da link edilebilsin
)

# Hem shared hem static üreten kısayol
both_libraries('myutil',
  files('lib/util.c', 'lib/crc.c'),
  install : true,
)

Bağımlılık yönetimi

# pkg-config ile sistem bağımlılıkları
libgpiod_dep = dependency('libgpiod', version : '>=2.0')
libudev_dep  = dependency('libudev')
libdbus_dep  = dependency('dbus-1', required : false)

# Koşullu bağımlılık
if libdbus_dep.found()
  sources += files('src/dbus_iface.c')
endif

# Dahili include
inc = include_directories('include', 'third_party/jsmn')

executable('my-daemon',
  sources,
  dependencies : [libgpiod_dep, libudev_dep, libdbus_dep],
  include_directories : inc,
  install : true,
)

Compiler flag'leri ve feature check

cc = meson.get_compiler('c')

# Özellik tespiti
has_epoll = cc.has_function('epoll_create1',
  prefix : '#include <sys/epoll.h>')

has_timerfd = cc.has_header('sys/timerfd.h')

# Koşullu derleme
conf = configuration_data()
conf.set('HAVE_EPOLL',    has_epoll    ? 1 : 0)
conf.set('HAVE_TIMERFD',  has_timerfd  ? 1 : 0)
conf.set_quoted('VERSION', meson.project_version())

configure_file(
  input  : 'config.h.in',
  output : 'config.h',
  configuration : conf,
)

# Ekstra flag ekle
extra_flags = cc.get_supported_arguments([
  '-fstack-protector-strong',
  '-D_FORTIFY_SOURCE=2',
  '-Wformat-security',
])
add_project_arguments(extra_flags, language : 'c')

02 Cross-compilation

Meson, cross-compilation için ayrı bir "cross file" mekanizması kullanır. Bu dosya toolchain, sysroot ve hedef sisteme ait ayarları tanımlar.

Cross file yapısı

# aarch64-linux-gnu.ini
[binaries]
c       = 'aarch64-linux-gnu-gcc'
cpp     = 'aarch64-linux-gnu-g++'
ar      = 'aarch64-linux-gnu-ar'
strip   = 'aarch64-linux-gnu-strip'
objcopy = 'aarch64-linux-gnu-objcopy'
pkg-config = 'aarch64-linux-gnu-pkg-config'

[built-in options]
c_args   = ['-march=armv8-a', '-mtune=cortex-a53']
c_link_args = ['-Wl,--hash-style=gnu']

[properties]
sys_root          = '/opt/sysroot-aarch64'
pkg_config_libdir = '/opt/sysroot-aarch64/usr/lib/pkgconfig'

[host_machine]
system     = 'linux'
cpu_family = 'aarch64'
cpu        = 'cortex-a53'
endian     = 'little'

Cross file ile yapılandırma

# Cross build dizini oluştur
meson setup builddir-aarch64 \
  --cross-file aarch64-linux-gnu.ini \
  --buildtype release \
  -Dprefix=/usr

# Derleme
ninja -C builddir-aarch64 -j$(nproc)

# Kurulum (DESTDIR ile sysroot'a)
DESTDIR=/opt/sysroot-aarch64 ninja -C builddir-aarch64 install

Sysroot ve pkg-config entegrasyonu

# Cross sysroot pkg-config wrapper scripti
cat > /usr/local/bin/aarch64-linux-gnu-pkg-config << 'EOF'
#!/bin/sh
SYSROOT=/opt/sysroot-aarch64
export PKG_CONFIG_DIR=
export PKG_CONFIG_LIBDIR=${SYSROOT}/usr/lib/pkgconfig:${SYSROOT}/usr/share/pkgconfig
export PKG_CONFIG_SYSROOT_DIR=${SYSROOT}
exec pkg-config "$@"
EOF
chmod +x /usr/local/bin/aarch64-linux-gnu-pkg-config

Native ve cross hedeflerin birlikte yönetimi

># meson.build — kod üreteci host'ta çalışır, output hedef için derlenir
gen_tool = executable('gen-headers',
  'tools/gen_headers.c',
  native : true,   # host makinede derle
)

gen_headers = custom_target('generated-headers',
  input   : ['defs/registers.json'],
  output  : ['registers.h'],
  command : [gen_tool, '@INPUT@', '@OUTPUT@'],
)

executable('firmware-util',
  ['src/main.c', gen_headers],  # cross-compile hedef
  install : true,
)

RISC-V 32-bit cross file örneği

# riscv32-unknown-linux-gnu.ini
[binaries]
c          = 'riscv32-unknown-linux-gnu-gcc'
cpp        = 'riscv32-unknown-linux-gnu-g++'
ar         = 'riscv32-unknown-linux-gnu-ar'
pkg-config = 'pkg-config'

[built-in options]
c_args = ['-march=rv32imac', '-mabi=ilp32']

[properties]
sys_root          = '/opt/riscv32-sysroot'
pkg_config_libdir = '/opt/riscv32-sysroot/usr/lib/pkgconfig'

[host_machine]
system     = 'linux'
cpu_family = 'riscv32'
cpu        = 'riscv32'
endian     = 'little'

03 Subproject ve wrap

Meson'ın wrap sistemi, harici bağımlılıkları proje ağacına dahil etmenin standart yoludur. Sistem kütüphanesi bulunamazsa otomatik olarak kaynak kodundan derler.

wrap dosyası formatı

# subprojects/libsodium.wrap
[wrap-file]
directory = libsodium-1.0.19
source_url = https://download.libsodium.org/libsodium/releases/libsodium-1.0.19.tar.gz
source_hash = 018d79fe0a045cca07331d37bd0cb57b91bbc7fd85952a6d84c0ae382e898e98

patch_url = https://wrapdb.mesonbuild.com/v2/libsodium_1.0.19-1/get_patch
patch_hash = abc123...

[provide]
libsodium = libsodium_dep

wrapdb'den bağımlılık kurma

># Mevcut wrap paketlerini listele
meson wrap list

# Belirli paketi indir
meson wrap install zlib
meson wrap install libuuid
meson wrap install nlohmann_json

# subprojects/ dizini oluşturulur
ls subprojects/
# zlib.wrap  libuuid.wrap  nlohmann_json.wrap

meson.build'e fallback bağımlılık

# Sistem kütüphanesi yoksa subproject kullan
zlib_dep = dependency('zlib',
  required  : true,
  fallback  : ['zlib', 'zlib_dep'],
)

# Gömülü ortamda her zaman subproject kullan
libjpeg_dep = dependency('libjpeg',
  required : false,
  fallback : ['libjpeg-turbo', 'libjpeg_dep'],
)
if not libjpeg_dep.found()
  error('libjpeg-turbo bulunamadi')
endif

Git submodule olarak subproject

># subprojects/mylib/ dizinine git submodule ekle
git submodule add https://github.com/example/mylib.git subprojects/mylib

# subprojects/mylib.wrap (git tabanlı)
[wrap-git]
url      = https://github.com/example/mylib.git
revision = v2.1.0
depth    = 1

[provide]
mylib = mylib_dep

Subproject'te override

># subprojects/mynewlib/meson.build
project('mynewlib', 'c')

mynewlib_lib = static_library('mynewlib',
  'src/mynewlib.c',
)

# Ana projeye dışa aktar
mynewlib_dep = declare_dependency(
  include_directories : include_directories('include'),
  link_with           : mynewlib_lib,
)

# Ana proje meson.build'de
subproject('mynewlib')
mynewlib_dep = dependency('mynewlib')

04 Testler ve benchmark

Meson'ın yerleşik test çerçevesi, birim testlerini ve performans benchmark'larını aynı yapılandırma içinde yönetir.

Test tanımı

# Birim test oluştur
test_sensor = executable('test-sensor',
  'tests/test_sensor.c',
  include_directories : inc,
  link_with : libmyutil,
  dependencies : [cmocka_dep],
)

test('sensor birim testi',
  test_sensor,
  args    : ['--verbose'],
  timeout : 30,
  env     : ['SENSOR_MOCK=1'],
)

# Parametrik test
foreach driver : ['spi', 'i2c', 'uart']
  test('driver test @0@'.format(driver),
    test_sensor,
    args : ['--driver', driver],
  )
endforeach

Test çalıştırma

># Tüm testleri çalıştır
meson test -C builddir

# Belirli test
meson test -C builddir 'sensor birim testi'

# Paralel çalıştır, verbose
meson test -C builddir --num-processes 4 -v

# Başarısız testleri tekrar çalıştır
meson test -C builddir --rerun-failing

# JUnit XML çıktısı (CI için)
meson test -C builddir --logbase testresults
# builddir/meson-logs/testresults.junit.xml üretilir

cmocka entegrasyonu

># subprojects/cmocka.wrap kurulu
cmocka_dep = dependency('cmocka',
  required : true,
  fallback : ['cmocka', 'cmocka_dep'],
)

test_config = executable('test-config',
  'tests/test_config.c',
  'src/config.c',
  include_directories : inc,
  dependencies : cmocka_dep,
)

test('config modulu',
  test_config,
  protocol : 'tap',   # TAP protokolu ciktisi
)

Benchmark tanımı

bench_crc = executable('bench-crc',
  'benchmarks/bench_crc.c',
  link_with : libmyutil,
)

benchmark('CRC hesaplama',
  bench_crc,
  args    : ['--iterations', '100000'],
  timeout : 120,
)

# Benchmark çalıştır
meson test -C builddir --benchmark --logbase benchresults

QEMU üzerinde cross-test çalıştırma

># cross file'a ekle
[properties]
exe_wrapper = ['qemu-aarch64', '-L', '/opt/sysroot-aarch64']

# Artık meson test cross binary'leri QEMU üzerinde çalıştırır
meson test -C builddir-aarch64

05 Install hedefleri

Meson'ın install sistemi, binary'leri, kütüphaneleri, başlık dosyalarını, systemd servislerini ve veri dosyalarını doğru dizinlere yerleştirir.

Temel install yapılandırması

># meson setup ile prefix belirle
meson setup builddir \
  --prefix /usr \
  --libdir /usr/lib \
  --sysconfdir /etc \
  --localstatedir /var

# DESTDIR ile staging area'ya kur
DESTDIR=/tmp/staging ninja -C builddir install

# Kurulacak dosyaları listele
ninja -C builddir install 2>&1 | grep "Installing"

Farklı hedef türlerini kurma

# Binary
executable('my-daemon', sources,
  install     : true,
  install_dir : get_option('sbindir'),  # /usr/sbin
)

# Kütüphane
shared_library('mylib', lib_sources,
  install : true,
  # otomatik olarak libdir'e gider: /usr/lib
)

# Başlık dosyaları
install_headers(
  'include/mylib.h',
  'include/mylib_types.h',
  subdir : 'mylib',  # /usr/include/mylib/
)

# Veri dosyaları
install_data(
  'data/default.conf',
  install_dir : get_option('sysconfdir') / 'my-daemon',
)

# Man sayfaları
install_man('docs/my-daemon.8')

# Dizin oluştur
install_emptydir('/var/lib/my-daemon')

systemd servis dosyası kurulumu

># systemd birim dosyasını yapılandır ve kur
systemd = dependency('systemd', required : false)

if systemd.found()
  systemd_system_unit_dir = systemd.get_variable(
    pkgconfig : 'systemdsystemunitdir'
  )
  install_data(
    'init/my-daemon.service',
    install_dir : systemd_system_unit_dir,
  )
endif

meson.options — kullanıcı seçenekleri

># meson.options (eski: meson_options.txt)
option('enable-dbus',
  type        : 'boolean',
  value       : true,
  description : 'D-Bus arabirimi derle',
)

option('log-level',
  type    : 'combo',
  choices : ['debug', 'info', 'warning', 'error'],
  value   : 'info',
  description : 'Varsayılan log seviyesi',
)

option('max-sensors',
  type        : 'integer',
  min         : 1,
  max         : 64,
  value       : 16,
  description : 'Maksimum sensör sayısı',
)
># Seçenekleri meson.build'de oku
if get_option('enable-dbus')
  sources += files('src/dbus_iface.c')
  deps += libdbus_dep
endif

conf.set('LOG_LEVEL_DEFAULT', '"' + get_option('log-level') + '"')
conf.set('MAX_SENSORS', get_option('max-sensors'))

# Yapılandırma zamanı override
meson setup builddir -Denable-dbus=false -Dlog-level=debug

06 Yocto ve Buildroot entegrasyonu

Meson projeleri hem Yocto'nun meson.bbclass'ı hem de Buildroot'un meson.mk'ı ile sorunsuz entegre olur. Otomatik cross-file üretimi sayesinde ek yapılandırma gerekmez.

Yocto — meson.bbclass

># meta-myproject/recipes-app/my-daemon/my-daemon_1.2.0.bb
SUMMARY = "Gömülü sensör daemon"
LICENSE = "GPL-2.0-only"
LIC_FILES_CHKSUM = "file://COPYING;md5=..."

SRC_URI = "git://github.com/myorg/my-daemon.git;branch=main"
SRCREV  = "abc123def456..."

S = "${WORKDIR}/git"

inherit meson pkgconfig systemd

# Meson seçenekleri
EXTRA_OEMESON = " \
    -Denable-dbus=true \
    -Dlog-level=info \
    -Dmax-sensors=32 \
"

# Yocto meson.bbclass otomatik olarak şunları yapar:
# 1. MACHINE'e uygun cross-file üretir
# 2. PKG_CONFIG_SYSROOT_DIR ayarlar
# 3. do_configure: meson setup
# 4. do_compile:   ninja
# 5. do_install:   DESTDIR ile ninja install

SYSTEMD_SERVICE:${PN} = "my-daemon.service"

FILES:${PN} += "${sysconfdir}/my-daemon/"

meson.bbclass cross-file üretimi

Yocto, derleme zamanında hedef mimariye uygun bir cross-file otomatik oluşturur. Bu dosya ${WORKDIR}/meson.cross konumunda saklanır ve meson setup çağrısına otomatik eklenir.

># Yocto'nun ürettiği meson.cross örneği
[binaries]
c       = '/path/to/sysroots/x86_64/usr/bin/aarch64-poky-linux/aarch64-poky-linux-gcc'
cpp     = '/path/to/sysroots/x86_64/usr/bin/aarch64-poky-linux/aarch64-poky-linux-g++'
ar      = '/path/to/sysroots/x86_64/usr/bin/aarch64-poky-linux/aarch64-poky-linux-ar'
pkgconfig = '/path/to/sysroots/x86_64/usr/bin/pkg-config'

[properties]
sys_root = '/path/to/sysroots/cortexa53-poky-linux'
pkg_config_libdir = '/path/to/sysroots/cortexa53-poky-linux/usr/lib/pkgconfig'

[host_machine]
system     = 'linux'
cpu_family = 'aarch64'
cpu        = 'cortex-a53'
endian     = 'little'

Buildroot — package/my-daemon/

># package/my-daemon/Config.in
config BR2_PACKAGE_MY_DAEMON
    bool "my-daemon"
    depends on BR2_TOOLCHAIN_HAS_THREADS
    select BR2_PACKAGE_LIBGPIOD
    help
      Gomulu sensor daemon.
># package/my-daemon/my-daemon.mk
MY_DAEMON_VERSION = 1.2.0
MY_DAEMON_SITE    = https://github.com/myorg/my-daemon/archive
MY_DAEMON_SOURCE  = v$(MY_DAEMON_VERSION).tar.gz

MY_DAEMON_DEPENDENCIES = libgpiod host-pkgconf

MY_DAEMON_CONF_OPTS = \
    -Denable-dbus=false \
    -Dmax-sensors=16

$(eval $(meson-package))

Buildroot meson-package makrosu davranışı

Configuremeson setup --cross-file $(BR_MESON_CROSS_FILE) otomatik çağrılır
Buildninja -j$(PARALLEL_JOBS) komutu çalıştırılır
InstallDESTDIR=$(TARGET_DIR) ninja install; strip otomatik uygulanır
BR_MESON_CROSS_FILEBuildroot'un hedef mimariye göre ürettiği cross-file yolu

07 Introspection ve IDE desteği

Meson, build sistemi hakkında makine tarafından okunabilir JSON meta verisi üretir. Bu özellik clangd, VS Code ve diğer IDE'lerin cross-compile projelerini anlamasını sağlar.

compile_commands.json

># Meson her zaman otomatik üretir
meson setup builddir --cross-file aarch64.ini
ls builddir/compile_commands.json  # hemen mevcut

# İçerik örneği
# [
#   {
#     "directory": "/home/user/project/builddir",
#     "command": "aarch64-linux-gnu-gcc -I../include -march=armv8-a
#                  -c ../src/sensor.c -o src/sensor.c.o",
#     "file": "/home/user/project/src/sensor.c"
#   },
#   ...
# ]

meson introspect

># Tüm hedefleri listele
meson introspect --targets builddir

# Bağımlılıkları listele
meson introspect --dependencies builddir

# Build seçeneklerini listele
meson introspect --buildoptions builddir

# Kaynak dosyaları
meson introspect --scan-dependencies builddir

# JSON formatı, jq ile işlenebilir
meson introspect --targets builddir | jq '.[].name'

VS Code için compile_commands.json bağlantısı

># Proje kökünde sembolik link oluştur
ln -s builddir/compile_commands.json compile_commands.json

# .vscode/settings.json
{
  "clangd.arguments": [
    "--compile-commands-dir=${workspaceFolder}",
    "--background-index",
    "--clang-tidy"
  ]
}

Meson ile IDE projeleri

># VS Code görev entegrasyonu — .vscode/tasks.json
{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "meson: build (aarch64)",
      "type": "shell",
      "command": "ninja",
      "args": ["-C", "builddir-aarch64"],
      "group": "build"
    },
    {
      "label": "meson: test",
      "type": "shell",
      "command": "meson",
      "args": ["test", "-C", "builddir-aarch64", "-v"],
      "group": "test"
    }
  ]
}

meson rewrite — programatik düzenleme

># meson.build'i elle düzenlemeden kaynak ekle
meson rewrite target my-daemon add src/new_module.c

# Bağımlılık ekle
meson rewrite kwargs set target my-daemon dependencies libssl_dep

# Seçenek değiştir
meson configure builddir -Dlog-level=debug

08 Gerçek proje örneği — gömülü C daemon

Uçtan uca örnek: GPIO ve SPI ile çalışan, systemd ile entegre, D-Bus arabirimi olan gömülü bir sensör daemon'ı için eksiksiz Meson yapılandırması.

Proje dizin yapısı

sensor-daemon/
├── meson.build          # Kök yapılandırma
├── meson.options
├── include/
│   ├── sensor.h
│   └── config.h.in
├── src/
│   ├── main.c
│   ├── sensor_spi.c
│   ├── sensor_gpio.c
│   ├── config.c
│   └── dbus_iface.c
├── lib/
│   ├── meson.build      # Alt yapılandırma
│   ├── crc.c
│   └── ringbuf.c
├── tests/
│   ├── meson.build
│   ├── test_sensor.c
│   └── test_config.c
├── data/
│   └── sensor-daemon.conf
├── init/
│   └── sensor-daemon.service
└── subprojects/
    └── cmocka.wrap
    

Kök meson.build

project('sensor-daemon', 'c',
  version : '2.0.0',
  license : 'GPL-2.0-only',
  default_options : [
    'c_std=c11',
    'warning_level=2',
    'buildtype=debugoptimized',
  ]
)

cc = meson.get_compiler('c')

# Bağımlılıklar
libgpiod_dep  = dependency('libgpiod', version : '>=2.0')
libudev_dep   = dependency('libudev')
libsystemd_dep = dependency('libsystemd', required : false)
libdbus_dep   = dependency('dbus-1',
  required : get_option('enable-dbus'),
  fallback : [],
)

# Config header üretimi
conf = configuration_data()
conf.set_quoted('PACKAGE_VERSION',  meson.project_version())
conf.set('HAVE_SD_NOTIFY',   libsystemd_dep.found() ? 1 : 0)
conf.set('HAVE_DBUS',        libdbus_dep.found()     ? 1 : 0)
conf.set('MAX_SENSORS',      get_option('max-sensors'))
conf.set_quoted('LOG_LEVEL', get_option('log-level'))
conf.set_quoted('DEFAULT_CONFIG_PATH',
  get_option('sysconfdir') / 'sensor-daemon' / 'sensor-daemon.conf')

configure_file(
  input  : 'include/config.h.in',
  output : 'config.h',
  configuration : conf,
)

generated_inc = include_directories('.')

# Alt dizinler
subdir('lib')     # libsensorutil oluşturur
subdir('tests')   # testleri tanımlar

# Ana kaynak listesi
daemon_sources = files(
  'src/main.c',
  'src/sensor_spi.c',
  'src/sensor_gpio.c',
  'src/config.c',
)

daemon_deps = [libgpiod_dep, libudev_dep]

if libsystemd_dep.found()
  daemon_sources += files('src/sd_notify.c')
  daemon_deps += libsystemd_dep
endif

if libdbus_dep.found()
  daemon_sources += files('src/dbus_iface.c')
  daemon_deps += libdbus_dep
endif

executable('sensor-daemon',
  daemon_sources,
  include_directories : [
    include_directories('include'),
    generated_inc,
  ],
  link_with    : libsensorutil,
  dependencies : daemon_deps,
  install      : true,
  install_dir  : get_option('sbindir'),
)

install_data('data/sensor-daemon.conf',
  install_dir : get_option('sysconfdir') / 'sensor-daemon',
)

systemd = dependency('systemd', required : false)
if systemd.found()
  install_data('init/sensor-daemon.service',
    install_dir : systemd.get_variable(pkgconfig : 'systemdsystemunitdir'),
  )
endif

lib/meson.build

libsensorutil = static_library('sensorutil',
  files('crc.c', 'ringbuf.c'),
  include_directories : include_directories('../include'),
  pic : true,
)

tests/meson.build

cmocka_dep = dependency('cmocka',
  required : true,
  fallback : ['cmocka', 'cmocka_dep'],
)

test_env = environment()
test_env.set('SENSOR_MOCK_PATH', meson.project_source_root() / 'tests/fixtures')

foreach t : ['sensor', 'config']
  test_exe = executable('test-@0@'.format(t),
    'test_@0@.c'.format(t),
    include_directories : [
      include_directories('../include'),
      generated_inc,
    ],
    link_with    : libsensorutil,
    dependencies : cmocka_dep,
  )
  test('test @0@'.format(t),
    test_exe,
    env     : test_env,
    timeout : 60,
    protocol : 'tap',
  )
endforeach

Tam derleme ve kurulum

># Host derleme (geliştirme)
meson setup builddir
ninja -C builddir
meson test -C builddir -v

# ARM64 cross-compile + kurulum
meson setup builddir-aarch64 \
  --cross-file aarch64-linux-gnu.ini \
  --buildtype release \
  -Dprefix=/usr \
  -Denable-dbus=true \
  -Dmax-sensors=32
ninja -C builddir-aarch64 -j$(nproc)
DESTDIR=/tmp/rootfs-staging ninja -C builddir-aarch64 install

# Kurulan dosyaları listele
find /tmp/rootfs-staging -type f | sort