Skip to content

vozduxan CMake Build

vozduxan is a C++ static library (libvozduxan.a) that wraps libtorrent-rasterbar. It lives in the vozduxan/ Git submodule and is built by the Rust build.rs via the cmake crate.

Sources: vozduxan/CMakeLists.txt, src-tauri/build.rs


CMakeLists.txt structure

project(vozduxan VERSION 1.0.8 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15")  # macOS minimum

libtorrent discovery: three-tier strategy

1. find_package(LibtorrentRasterbar CONFIG)     # CMake installed package
   └─ not found ──▶
2. pkg_check_modules(LIBTORRENT libtorrent-rasterbar)  # pkg-config
   └─ not found ──▶
3. FetchContent: github.com/arvidn/libtorrent v2.0.10  # build from source
   BUILD_SHARED_LIBS = OFF
   OPENSSL_USE_STATIC_LIBS = ON
   install(TARGETS torrent-rasterbar ARCHIVE DESTINATION lib)

The install() call in the FetchContent path is critical: it places libtorrent-rasterbar.a in <cmake_dst>/lib/ where build.rs can find it via cargo:rustc-link-search.

vozduxan library target

add_library(vozduxan STATIC
    src/session.cpp
    src/api.cpp
)
target_link_libraries(vozduxan PRIVATE ${LT_TARGET})
install(TARGETS vozduxan ARCHIVE DESTINATION lib)
install(DIRECTORY include/ DESTINATION include)

The library is installed to <cmake_dst>/lib/libvozduxan.a. The build.rs links it as cargo:rustc-link-lib=static=vozduxan.


build.rs integration

fn build_vozduxan() {
    let vozduxan_dir = manifest_dir.parent().unwrap().join("vozduxan");

    let dst = cmake::Config::new(&vozduxan_dir)
        .profile("Release")
        .define("CMAKE_BUILD_TYPE", "Release")
        .define("CMAKE_POSITION_INDEPENDENT_CODE", "ON")
        .define("OPENSSL_USE_STATIC_LIBS", "ON")  // macOS only
        .build();

    println!("cargo:rustc-link-search=native={}", dst.join("lib").display());
    println!("cargo:rustc-link-lib=static=vozduxan");
    // ...
}

cmake::Config::build() runs CMake configure + build + install in a build-script-managed directory under target/. The resulting <dst>/lib/ is added to the linker search path.

Platform-specific linking

After libvozduxan.a, build.rs links its dependencies:

macOS:

cargo:rustc-link-lib=static=torrent-rasterbar      (FetchContent static)
  OR
cargo:rustc-link-lib=static=torrent-rasterbar      (Homebrew /opt/homebrew/lib)
  OR
cargo:rustc-link-lib=dylib=torrent-rasterbar        (Homebrew dynamic, fallback)

cargo:rustc-link-lib=static=ssl
cargo:rustc-link-lib=static=crypto    ← Homebrew OpenSSL (prefers static .a)

cargo:rustc-link-lib=framework=SystemConfiguration
cargo:rustc-link-lib=framework=CoreFoundation
cargo:rustc-link-lib=framework=IOKit

OpenSSL is preferrred as static .a to avoid Library not loaded: .../libssl.dylib errors on machines without Homebrew or with different OpenSSL paths.

Linux:

cargo:rustc-link-lib=dylib=torrent-rasterbar  (or via pkg-config)
cargo:rustc-link-lib=dylib=ssl
cargo:rustc-link-lib=dylib=crypto
cargo:rustc-link-lib=dylib=pthread

Windows:

cargo:rustc-link-lib=static=torrent-rasterbar
cargo:rustc-link-lib=dylib=ws2_32
cargo:rustc-link-lib=dylib=iphlpapi

C++ standard library (link_cxx_stdlib) is linked before libtorrent so the linker resolves C++ symbols from libvozduxan.a before processing libtorrent's symbols.

rerun-if-changed — macOS directory mtime bug

Cargo's rerun-if-changed on a directory only reacts when the directory mtime changes. macOS (APFS) does not update the parent directory mtime when a file inside it is modified. So a change to vozduxan/src/session.cpp would not trigger a rebuild.

build.rs enumerates individual C++ files instead:

for entry in std::fs::read_dir(vozduxan_dir.join("src")).flatten().flatten() {
    println!("cargo:rerun-if-changed={}", entry.path().display());
}
for entry in std::fs::read_dir(vozduxan_dir.join("include")).flatten().flatten() {
    println!("cargo:rerun-if-changed={}", entry.path().display());
}
println!("cargo:rerun-if-changed={}", vozduxan_dir.join("CMakeLists.txt").display());

This ensures cargo tauri dev (watch mode) detects C++ source changes correctly on macOS.


C++ standard library

fn link_cxx_stdlib() {
    #[cfg(target_os = "macos")]
    println!("cargo:rustc-link-lib=dylib=c++");    // libc++ (system)
    #[cfg(target_os = "linux")]
    println!("cargo:rustc-link-lib=dylib=stdc++");  // libstdc++
    // Windows: MSVC CRT is linked automatically
}

Must appear before libtorrent in the link order.