Force-link all PCM sink crates with their ffi features enabled
dlopen kept failing with "cannot locate symbol pcm_airplay_connect" then
"pcm_squeezelite_start" etc. Two issues stacked:
1. The PCM sink crates (rockbox-airplay, rockbox-slim, rockbox-chromecast,
rockbox-upnp) gate their #[no_mangle] pub extern "C" exports behind
a `ffi` cargo feature (so desktop dev builds without the firmware
don't pay for them). Enable `ffi` per crate in the embedded-daemon
feature group.
2. rustc's #[used] on the empty `_link_<name>()` helper isn't enough —
it keeps that one fn alive but the unrelated pcm_<sink>_* exports
still get dead-code-stripped. Take addresses of actual C-ABI fns
(pcm_airplay_set_host, pcm_squeezelite_set_slim_port,
pcm::pcm_chromecast_set_device_host, pcm_upnp_set_http_port) so
rustc pulls each crate's full export set into the cdylib.
Result: librockbox_expo.so is now 45.1 MB with every PCM sink's
pcm_* C-ABI exports T (defined) instead of U (undefined). The phone
can now stream out via FIFO/Snapcast/AirPlay/Squeezelite/Chromecast/UPnP
in addition to local AAudio playback.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>