# frontend/apiserver — Go REST API server with CGO backend integration. # # CGO is required for two reasons: # 1. pam_linux.go: dlopen/dlsym for PAM (handled by -ldl in the source file) # 2. backend/clib.go: libxce C client library for IPC with the controller # # Include/link flags for libxce and its transitive deps are gathered from # pkg-config and injected into CGO_CFLAGS/CGO_LDFLAGS so the go_build script # can substitute path placeholders before invoking go build. cgo_cflags = '' cgo_ldflags = '' if with_debug cgo_cflags += '-fsanitize=address -g -DWITH_DEBUG=1 ' cgo_ldflags += '-fsanitize=address -g ' endif # Deps whose cflags/ldflags must be passed into CGO (transitive libxce deps). apiserver_cgo_deps = [ librtti_dep, c_capnproto_dep, ssl_dep, tinylog_dep, math_dep, rt_dep, ] foreach dep : apiserver_cgo_deps cf = run_command(pkgconfig, '--cflags', dep.name(), check: false) if cf.returncode() == 0 cgo_cflags += ' ' + cf.stdout().strip() endif lf = run_command(pkgconfig, '--libs', dep.name(), check: false) if lf.returncode() == 0 cgo_ldflags += ' ' + lf.stdout().strip() endif endforeach # Add the source and build-directory include paths with meson placeholders. # The go_build script resolves @CURRENT_SOURCE_DIR@ and @BUILD_ROOT@ at build time. cgo_cflags += ' -I@CURRENT_SOURCE_DIR@/../../include -I@BUILD_ROOT@/lib' cgo_ldflags += ' -L@BUILD_ROOT@/lib -lxce' go_env = environment() go_env.set('CGO_CFLAGS', cgo_cflags) go_env.set('CGO_LDFLAGS', cgo_ldflags) go_env.set('BUILDTYPE', get_option('buildtype')) go_env.set('FIX_ENVARS', 'CGO_CFLAGS CGO_LDFLAGS') go_env.set('ENVARS', 'CURRENT_SOURCE_DIR BUILD_ROOT') go_env.set('DEPENDENCIES','thread math') custom_target('apiserver', input: 'cmd/main.go', output: 'xce_apiserver', command: [env_program, 'CURRENT_SOURCE_DIR="@CURRENT_SOURCE_DIR@"', 'BUILD_ROOT="@BUILD_ROOT@"', 'XCE_GIT_COMMIT=' + get_option('commit_id'), 'XCE_BUILD_TIME=' + get_option('build_time'), 'XCE_DIRTY_FINGERPRINT=' + get_option('dirty_fingerprint'), go_build_program, '@INPUT@', '@OUTPUT@'], env: go_env, depends: [libxce], install: true, install_dir: get_option('prefix') / 'bin') # CGO-backed backend test suite, run directly via `go test` under Meson's # test runner (not through tools/go_build, which only knows how to invoke # `go build` once for a single output). This reuses apiserver_cgo_deps's # already-computed cgo_cflags/cgo_ldflags (the same values the custom_target # above uses) rather than deriving CGO flags a second time. # # cgo_cflags/cgo_ldflags still contain the literal @CURRENT_SOURCE_DIR@/ # @BUILD_ROOT@ placeholder tokens appended above -- normally resolved by # go_build's own fix_env/fix_input_envs sed machinery at build time. Since # this target bypasses go_build entirely, resolve those tokens ourselves at # Meson-configure time via Meson's own string .replace(). resolved_cgo_cflags = cgo_cflags.replace('@CURRENT_SOURCE_DIR@', meson.current_source_dir()).replace('@BUILD_ROOT@', meson.project_build_root()) resolved_cgo_ldflags = cgo_ldflags.replace('@CURRENT_SOURCE_DIR@', meson.current_source_dir()).replace('@BUILD_ROOT@', meson.project_build_root()) test('apiserver backend', go_compiler, args: ['test', './backend/...', '-count=1'], workdir: meson.current_source_dir(), env: {'CGO_ENABLED': '1', 'CGO_CFLAGS': resolved_cgo_cflags, 'CGO_LDFLAGS': resolved_cgo_ldflags, 'GOFLAGS': '-mod=vendor', 'GOPROXY': 'off', 'GOCACHE': meson.current_build_dir() / 'go-cache', 'GOPATH': meson.current_build_dir() / 'go-path'}, suite: 'apiserver', # A cold GOCACHE/GOPATH (the normal case: both are freshly created # under this build dir, see above) makes `go test` compile the whole # CGO+ASAN dependency graph from scratch -- measured ~34s, already over # Meson's 30s test() default. Matches the timeout the existing # 'controller test' registration uses for the same reason (see # controller/meson.build / steering build-deployment.md). timeout: 300, depends: [libxce])