myxce/src/meson.build
Rongsong Shen 6dd70f1091
feat(build): no fork in multi-threaded XCE processes, enforced by check-no-fork
Design constraint (tech.md "Process Creation"): the controller, scheduler,
xcecd and anything that starts libxce threads never call fork, vfork,
forkpty, daemon, system, popen or uv_spawn; children start with posix_spawn()
or a systemd unit. A process proven single-threaded may fork, marked
/* xce-fork-ok: <why> */. Tests, harness, autoscaler (not finalized; bug-1969)
and the Go frontend are out of scope.

- scripts/check-no-fork.py scans src/{controller,scheduler,lib,worker}
  (comment/string/#if 0 aware); runs as meson test "no-fork rule" in the
  lib/controller/scheduler/worker suites and in the pre-commit hook.
- worker: drop xcecd's unused fork-based worker start paths
  (process_manager_start_process, process_manager_start_worker; xcecd
  starts xcecd_worker over D-Bus) and a dead #if 0 daemonize fork.
- xcecd_worker's fork/uv_spawn/system calls are marked: its call graph
  from main(), callbacks included, reaches no pthread_create or libuv
  thread-pool call.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-10 13:35:52 +00:00

100 lines
3 KiB
Meson

project('xce',
['c'],
version: '0.0.1',
meson_version: '>=1.5',
default_options: [
'c_std=gnu17'])
component = get_option('component')
with_debug = false
if get_option('buildtype') == 'debug'
# add -DWITH_DEBUG=1
add_project_arguments(['-DWITH_DEBUG=1',
'-DDEBUG',
'-O0',
'-fno-lto',
'-Wno-cpp',
'-fno-inline',
'-fno-omit-frame-pointer',
'-ggdb',
'-gdwarf-4',
'-g3',
'-fvar-tracking',
'-fvar-tracking-assignments',
], language: ['c', 'cpp'])
add_project_link_arguments('-fno-lto', language: ['c', 'cpp'])
with_debug = true
endif
add_project_arguments(['-DVERSION_COMMIT_ID='+get_option('commit_id'),
'-DVERSION_BUILD_TIME='+get_option('build_time'),
'-DVERSION_DIRTY_FINGERPRINT='+get_option('dirty_fingerprint')], language: 'c')
# Programs needed by all components
go_compiler = find_program('go')
go_build = files('tools/go_build')
go_build_program = find_program('go_build', go_build)
env_program = find_program('env')
if component != 'xcecli'
c_compiler_id = meson.get_compiler('c').get_id()
if c_compiler_id == 'gcc' or c_compiler_id == 'clang'
wrap_link_args = ['-Wl,--wrap=printf', '-Wl,--wrap=perror']
else
wrap_link_args = []
endif
pkgconfig = find_program('pkg-config')
include_dir = include_directories('include', 'include/xce')
cc = meson.get_compiler('c')
math_dep = cc.find_library('m', required: false)
rt_dep = cc.find_library('rt', required: false)
struct2json_dep = dependency('struct2json')
libcyaml_dep = dependency('libcyaml')
libyaml_dep = dependency('yaml-0.1')
libtirpc_dep = dependency('libtirpc')
librtti_dep = dependency('librtti')
yaml_deps = [
libcyaml_dep,
libyaml_dep
]
subdir('lib')
subdir('harness')
subdir('controller')
subdir('worker')
subdir('autoscaler')
subdir('scheduler')
subdir('frontend/apiserver')
subdir('xceadmin')
# No-fork rule (.kiro/steering/tech.md, "Process creation"): fails if a
# covered component's C code calls fork()/system()/popen()/uv_spawn()
# outside a call marked xce-fork-ok. In each covered suite, so
# `xce-build.sh <component>` runs it too.
test('no-fork rule',
find_program('python3'),
args: [meson.project_source_root() / '..' / 'scripts' / 'check-no-fork.py',
meson.project_source_root() / '..'],
suite: ['lib', 'controller', 'scheduler', 'worker'])
configure_file(
input: 'tools/appimage/entry.sh',
output: 'xce',
copy: true,
install: true,
install_dir: 'bin',
install_mode: 'rwxr-xr-x'
)
install_data('docs/xce.md',
install_dir: 'share/docs')
endif
if component != 'xcecore'
subdir('frontend/xcecli')
endif