diff --git a/.github/workflows/ci-main.yml b/.github/workflows/ci-main.yml index ab2da32f..e3ee9057 100644 --- a/.github/workflows/ci-main.yml +++ b/.github/workflows/ci-main.yml @@ -137,6 +137,20 @@ jobs: continue-on-error: true run: scripts/ci/check-text-size.sh builddir/libwirelog.so + - name: Path A example compile-check + if: runner.os == 'Linux' && matrix.compiler == 'gcc' + continue-on-error: true + run: | + meson install -C builddir --destdir="$PWD/staging" + staging_prefix="$PWD/staging/usr/local" + multiarch="$(dpkg-architecture -qDEB_HOST_MULTIARCH 2>/dev/null || true)" + PKG_CONFIG_SYSROOT_DIR="$PWD/staging" \ + PKG_CONFIG_PATH="$staging_prefix/lib/${multiarch:+$multiarch/}pkgconfig:$staging_prefix/lib/pkgconfig" \ + meson setup builddir-path-a examples/path_a_pcap_skeleton + meson compile -C builddir-path-a + LD_LIBRARY_PATH="$staging_prefix/lib/${multiarch:+$multiarch:}$staging_prefix/lib" \ + ./builddir-path-a/pcap_skeleton + - name: Publish results if: always() shell: bash diff --git a/.github/workflows/ci-pr.yml b/.github/workflows/ci-pr.yml index b0a07912..9e52819e 100644 --- a/.github/workflows/ci-pr.yml +++ b/.github/workflows/ci-pr.yml @@ -125,6 +125,24 @@ jobs: if: runner.os == 'Linux' && matrix.compiler == 'gcc' run: scripts/ci/check-text-size.sh builddir/libwirelog.so + # ======================================================================= + # Path A example compile-check (Issue #462) + # Install wirelog to a staging dir, then build the example as a + # separate project to catch header-install regressions (#449). + # ======================================================================= + - name: Path A example compile-check + if: runner.os == 'Linux' && matrix.compiler == 'gcc' + run: | + meson install -C builddir --destdir="$PWD/staging" + staging_prefix="$PWD/staging/usr/local" + multiarch="$(dpkg-architecture -qDEB_HOST_MULTIARCH 2>/dev/null || true)" + PKG_CONFIG_SYSROOT_DIR="$PWD/staging" \ + PKG_CONFIG_PATH="$staging_prefix/lib/${multiarch:+$multiarch/}pkgconfig:$staging_prefix/lib/pkgconfig" \ + meson setup builddir-path-a examples/path_a_pcap_skeleton + meson compile -C builddir-path-a + LD_LIBRARY_PATH="$staging_prefix/lib/${multiarch:+$multiarch:}$staging_prefix/lib" \ + ./builddir-path-a/pcap_skeleton + # ======================================================================= # Phase 3: Sanitizers (ASan + UBSan) — runs on same platform after build # Linux: GCC + Clang; macOS: Clang (Windows: skipped) diff --git a/examples/path_a_pcap_skeleton/main.c b/examples/path_a_pcap_skeleton/main.c new file mode 100644 index 00000000..70b6c183 --- /dev/null +++ b/examples/path_a_pcap_skeleton/main.c @@ -0,0 +1,87 @@ +/* + * Path A pcap skeleton — standalone I/O adapter example + * + * Demonstrates how a user registers a custom I/O adapter with libwirelog + * WITHOUT rebuilding the library. The user compiles only this file and + * links against the installed libwirelog. + * + * Build (after `meson install`): + * cc -o pcap_skeleton main.c $(pkg-config --cflags --libs wirelog) + * + * This is a compile-check skeleton; the read callback returns an empty + * result set. A real adapter would parse pcap data here. + * + * See also: Issue #446 (Option C design), Issue #462 (CI compile gate). + */ + +#include + +#include +#include + +/* ---------- adapter callbacks ---------- */ + +static int +pcap_validate(wl_io_ctx_t *ctx, char *errbuf, size_t errbuf_len, + void *user_data) +{ + (void)user_data; + + const char *filename = wl_io_ctx_param(ctx, "filename"); + if (!filename) { + snprintf(errbuf, errbuf_len, "missing required param 'filename'"); + return -1; + } + return 0; +} + +static int +pcap_read(wl_io_ctx_t *ctx, int64_t **out_data, uint32_t *out_nrows, + void *user_data) +{ + (void)ctx; + (void)user_data; + + /* + * Skeleton: return an empty result set. + * A real adapter would open the pcap file, parse packets, + * and fill a row-major int64_t buffer here. + */ + *out_data = NULL; + *out_nrows = 0; + return 0; +} + +/* ---------- adapter definition ---------- */ + +static const wl_io_adapter_t pcap_adapter = { + .abi_version = WL_IO_ABI_VERSION, + .scheme = "pcap", + .description = "libpcap file reader (skeleton)", + .read = pcap_read, + .validate = pcap_validate, + .user_data = NULL, +}; + +/* ---------- main ---------- */ + +int +main(void) +{ + if (wl_io_register_adapter(&pcap_adapter) != 0) { + fprintf(stderr, "register failed: %s\n", wl_io_last_error()); + return 1; + } + + const wl_io_adapter_t *found = wl_io_find_adapter("pcap"); + if (!found) { + fprintf(stderr, "adapter lookup failed\n"); + return 1; + } + + printf("registered adapter: scheme=%s desc=\"%s\"\n", + found->scheme, found->description); + + wl_io_unregister_adapter("pcap"); + return 0; +} diff --git a/examples/path_a_pcap_skeleton/meson.build b/examples/path_a_pcap_skeleton/meson.build new file mode 100644 index 00000000..bf03a918 --- /dev/null +++ b/examples/path_a_pcap_skeleton/meson.build @@ -0,0 +1,27 @@ +# examples/path_a_pcap_skeleton/meson.build +# +# Standalone meson project that builds against *installed* libwirelog. +# This is NOT a subdirectory of the main wirelog build — it is compiled +# as a separate project in CI to catch header-install regressions (#449). +# +# CI usage (see ci-pr.yml): +# meson install -C builddir --destdir=$PWD/staging +# PKG_CONFIG_PATH=staging/.../pkgconfig meson setup ... path_a_pcap_skeleton +# meson compile -C builddir-path-a + +project( + 'path_a_pcap_skeleton', + 'c', + version: '0.1.0', + meson_version: '>=0.62.0', + default_options: ['warning_level=3', 'c_std=c11'], +) + +wirelog_dep = dependency('wirelog', required: true) + +executable( + 'pcap_skeleton', + files('main.c'), + dependencies: [wirelog_dep], + install: false, +)