RC Day 6 - Building by the C
Today was my sixth day and the start of my second week at the Recurse Center as a participant in this year’s Summer 2 batch!
Writing
I had some really good discussions this morning about how to make the most of our time in-batch. A few of us1 also discussed how to capture a large volume of ideas and new discoveries so we don’t forget them. A common thread seems to be that writing first for oneself and then for an audience is a good way to first get ideas onto the page and then structure thoughts and solidify one’s understanding of a topic.
Lately, I’ve been using Logseq as a tool to capture thoughts and ideas throughout the day. I don’t worry too much about structuring them as I capture things - I just create a new bullet point whenever I want to add something. If I’m taking notes on a meeting or specific topic I’ll nest bullet points under that topic, but otherwise I don’t worry too much about where things go. This lack of pressure to provide any polish or structure up front has greatly increased the volume of ideas I write down, which has in turn made it easier to keep writing and share ideas on Zulip and on this blog. I’ve also given myself permission to make these daily blog posts as short or as long as they need to be. If at some point I only have one sentence to write about a given day, that would be OK.
Linking to a Rust library from C
Later in the day I spent some time pairing with Rhea on my project to link to a Rust library from ffmpeg.
With a few hacks, we were able to get ffmpeg to build and link against our toy Rust library today!
At some point I plan to write up what was needed to make that work.
On second thought, in the spirit of capturing discoveries before they’re forgotten, here’s the gist of what we’ve done so far:
- Created a new library crate (
cargo new --lib ffout
) - Added no-op stubs for some functions in
src/lib.rs
that I think we’ll need:write_header
write_packet
write_trailer
- Added the
ffmpeg-sys-next
crate to our dependencies inCargo.toml
use
‘d the necessary types insrc/lib.rs
to provide appropriate function signatures — namely:use ffmpeg_sys_next::{AVFormatContext, AVPacket}
use std::os::raw::c_int;
- Made the functions all
pub extern "C"
and marked them#[no_mangle]
so the correct symbols get exported - Set
crate-type
inCargo.toml
to["cdylib", "staticlib"]
to build C-compatible dynamic and static libraries - Figured out that this only seems to work when building
--release
targets for some reason - Realized we needed to produce a header file for these libraries
- Found
cbindgen
and added it to ourbuild.rs
to create a header file attarget/release/ffout.h
- Figured out how to configure
cbindgen
to produce C header files instead of C++ header files (cbindgen.toml
) - Determined we’ll also want to produce a
pkg-config
file (libffout.pc
) - Borrowed heavily from other patches to produce a changeset for
ffmpeg
itself to optionally build with support for our library- (Note: this part is almost certainly not correct yet, but it’s close enough to test basic linking at least)
- Learned about
cargo-c
and its slightly more opinionated approach to building C ABI libraries like this - Decided to keep doing things by hand a bit more before adopting
cargo-c
- Added some code to
build.rs
to write a statically definedtarget/release/libffout.pc
- Added a Makefile to “install” and “uninstall” our library from
/usr/local
for testing - Spent a good portion of the afternoon just making names and paths match up correctly
- Fun fact I knew: linking C libaries by convention drops any leading
lib
prefix from the library name in the linker flags (e.g.-lffout
to link againstlibffout.a
) - Fact I had forgotten: by convention, header files also drop the
lib
portion of the library’s full name (e.g.libffout/ffout.h
)
- Fun fact I knew: linking C libaries by convention drops any leading
- One last hack: since Homebrew doesn’t seem to link
ffmpeg
’s libraries or headers into/usr/local
, we put the path of my local ffmpeg git checkout direclty into ourlibffout.pc
configuration’s include flags so that ffmpeg could find its own headers which define theAVFormatContext
andAVPacket
structs our functions accept
In the end we were able to get our patched ffmpeg
’s ./configure
script to run without error, and make
even worked!
My repos for work this are public on GitHub, but they’re not really in a tutorial or walkthrough state of cleanliness so I’m not linking directly to them here for now. If you’re curious about any of this though, feel free to poke around my GitHub profile and/or ping me on Hachyderm, Bluesky, Discord, or even Twitter or wherever else you can find me.
Media over QUIC (MoQ) and CDNs
After that I spent some time catching up with non-RC collaborators and other folks interested in MoQ and talked about things like what “CDN support” means for a protocol like this as compared to something like WebRTC.
Tomorrow, I’ll take the day off of RC to spend with family.
-
Erika, Rachael, and Aditya ↩