Skip to content

Replace suboptimal cfgs #229

@apljungquist

Description

@apljungquist

Until #228 #[cfg(any(target_arch = "x86_64", target_os = "macos"))] would always work in the dev container (which is our tier 1 development environment) because it was always linux/amd64. I initially thought more workflows would break and started working on this. Now that I know the impact is relatively low, I will shift my focus to other things I need to do that are more urgent. But I won't leave this without documenting the results of my Claude assisted archeology to boost future me or anyone else who wants to pick this up.

I think part of a future solution will be to have a bindings feature for the sys-crates and check automatically that the tracked bindings are up to date. Maybe have acap or acapx_y features in other to enable things that only work on targets with the ACAP framework. Maybe also have a no-acap feature because, if I remember correctly, we cannot enable conditional dependencies based on a feature not being enabled.


What the cfg statements achieve

All 36 occurrences of any(target_arch = "x86_64", target_os = "macos") express the same semantic: "is this a host build?" They exist because the ACAP SDK's C libraries and device services are only available when cross-compiling for Axis cameras (ARM Linux), but developers need host-side tooling (cargo check, cargo doc, IDE completions, cargo test) to work without the SDK installed.

The pattern is a heuristic that assumes host = x86_64 or macOS, target = everything else. It is acknowledged as imperfect — an ARM Linux desktop would be misclassified 1 — and multiple locations carry // TODO: Find a more robust configuration.


Group 1: Binding source selection (27 occurrences)

9 -sys crates × 3 locations each (src/lib.rs × 2 cfg branches + build.rs × 1 env var check)

axevent-sys, axoverlay-sys, axparameter-sys, axstorage-sys, bbox-sys, larod-sys, licensekey-sys, mdb-sys, vdo-sys

Why it's needed: Bindgen requires the SDK's C headers, which are only present in the cross-compilation sysroot. Without a fallback, cargo check on host fails immediately because build.rs can't find the headers. The pre-generated bindings.rs files were checked into the repo specifically to enable host-side cargo doc and cargo package 2. The cfg was then added to select between the two sources 3.

The build.rs files use CARGO_CFG_TARGET_ARCH / CARGO_CFG_TARGET_OS environment variables (the build-script equivalent of #[cfg]).


Group 2: Device-only test modules (6 occurrences)

  • apps/bounding_box_example/src/main.rs:130
  • apps/embedded_web_page/src/main.rs:11
  • apps/inspect_env/src/main.rs:22
  • apps/using_a_build_script/src/main.rs:12
  • apps/vapix_access/src/main.rs:31
  • crates/licensekey/src/flex.rs:176

Why it's needed: These tests exercise device-specific behavior: ACAP file layout, D-Bus services, VAPIX APIs, and FFI calls to device-only shared libraries. The original commit considered using conditional compilation everywhere but rejected it as too noisy for example apps where readability matters 3.

Five of the six would merely fail at runtime on host (wrong paths, missing services). The licensekey tests are the exception — they call FFI functions (licensekey_verify, etc.) that would cause a linker error on host because no liblicensekey.so exists.

The Makefile separately excludes these from check_tests via --exclude flags 3 4, so the cfg gates are a second layer of defense rather than the only one.


Group 3: Host/device behavior switching (2 occurrences)

  • crates/acap-vapix/src/lib.rs:85 — runtime cfg!() macro
  • apps/reverse_proxy/src/main.rs:100 — compile-time #[cfg] attribute

Why it's needed: These enable running apps on the developer's machine for faster iteration 5 6. On host, VAPIX credentials come from environment variables instead of D-Bus; the reverse proxy serves static files from a local directory instead of relying on the Axis web server.

The acap-vapix location deliberately uses the runtime cfg!() macro so both branches compile everywhere, avoiding conditional imports 5. The reverse_proxy location uses a compile-time #[cfg] because it gates a dependency (tower_http::services::ServeDir).


Group 4: Custom test runner (1 occurrence)

  • .cargo/config.toml:1

Why it's needed: remote-test.sh copies test binaries to a camera via SSH and executes them there 1. It must not activate for host targets (where tests run locally) or for Miri (which sets its own runner) 7. This is Cargo TOML cfg syntax, not Rust.


References

Footnotes

  1. d9f6537 — noted the x86_64 assumption is "an unnecessary restriction" 2

  2. ff4eb34 — checked pre-generated bindings into the repo

  3. 3697564 — introduced the cfg pattern and Makefile --exclude 2 3

  4. f513ffc — collapsed explicit exclude lists into glob patterns

  5. 6b5dd98 — runtime behavior switching 2

  6. de16e5f — host-side static file serving

  7. 96daef9 — Miri exclusion in config.toml

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions