Skip to content

Commit

Permalink
Rework libcubeb vendoring. (#111)
Browse files Browse the repository at this point in the history
cubeb-rs releases are now to be performed using `cargo xtask release`.

This is a hack to allow us to ship a vendored copy of libcubeb *including*
libcubeb's Rust crates.  `cargo publish` excludes all subdirectories that
contain a `Cargo.toml`, preventing a complete vendoring of libcubeb.

The release xtask recursively renames `Cargo.toml` -> `Cargo.toml.in` before
running `cargo release` and `cargo publish`, then renames them back.

build.rs now always builds using $OUT_DIR/libcubeb, copying and renaming
`Cargo.toml.in` as necessary.
  • Loading branch information
kinetiknz authored Dec 10, 2024
1 parent a40d2f4 commit 21a8086
Show file tree
Hide file tree
Showing 11 changed files with 195 additions and 31 deletions.
3 changes: 3 additions & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[alias]
xtask = "run --package xtask --"

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
[workspace]
resolver = "2"
members = [
"cubeb-core",
"cubeb-api",
"cubeb-backend",
"cubeb-sys",
"systest"
"systest",
"xtask",
]
exclude = [
"cubeb-sys/libcubeb/src/cubeb-coreaudio-rs",
Expand Down
4 changes: 2 additions & 2 deletions cubeb-api/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "cubeb"
version = "0.18.0"
version = "0.20.0"
authors = ["Dan Glastonbury <[email protected]>"]
license = "ISC"
readme = "README.md"
Expand All @@ -19,4 +19,4 @@ circle-ci = { repository = "mozilla/cubeb-rs" }
gecko-in-tree = ["cubeb-core/gecko-in-tree"]

[dependencies]
cubeb-core = { path = "../cubeb-core", version = "0.18.0" }
cubeb-core = { path = "../cubeb-core", version = "0.20.0" }
4 changes: 2 additions & 2 deletions cubeb-backend/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "cubeb-backend"
version = "0.18.0"
version = "0.20.0"
authors = ["Dan Glastonbury <[email protected]>"]
license = "ISC"
keywords = ["cubeb"]
Expand All @@ -18,4 +18,4 @@ circle-ci = { repository = "mozilla/cubeb-rs" }
gecko-in-tree = ["cubeb-core/gecko-in-tree"]

[dependencies]
cubeb-core = { path = "../cubeb-core", version = "0.18.0" }
cubeb-core = { path = "../cubeb-core", version = "0.20.0" }
2 changes: 1 addition & 1 deletion cubeb-backend/tests/test_capi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// This program is made available under an ISC-style license. See the
// accompanying file LICENSE for details

#![cfg_attr(feature = "cargo-clippy", allow(clippy::float_cmp))]
#![allow(clippy::float_cmp)]

#[macro_use]
extern crate cubeb_backend;
Expand Down
4 changes: 2 additions & 2 deletions cubeb-core/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "cubeb-core"
version = "0.18.0"
version = "0.20.0"
authors = ["Dan Glastonbury <[email protected]>"]
license = "ISC"
keywords = ["cubeb"]
Expand All @@ -19,7 +19,7 @@ gecko-in-tree = ["cubeb-sys/gecko-in-tree"]

[dependencies]
bitflags = "1.2.0"
cubeb-sys = { path = "../cubeb-sys", version = "0.18" }
cubeb-sys = { path = "../cubeb-sys", version = "0.20" }

[build-dependencies]
cc = "1.1.30"
4 changes: 2 additions & 2 deletions cubeb-sys/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
[package]
name = "cubeb-sys"
version = "0.18.0"
version = "0.20.0"
authors = ["Dan Glastonbury <[email protected]>"]
repository = "https://github.com/mozilla/cubeb-rs"
license = "ISC"
description = "Native bindings to the cubeb library"
exclude = ["libcubeb/"]
exclude = ["libcubeb/googletest"]

links = "cubeb"
build = "build.rs"
Expand Down
59 changes: 38 additions & 21 deletions cubeb-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,33 +33,50 @@ fn main() {
return;
}

if env::var("DOCS_RS").is_ok() {
// Use stubs, not libcubeb, for docs.rs.
return;
}

let _ = fs::remove_dir_all(env::var("OUT_DIR").unwrap());
t!(fs::create_dir_all(env::var("OUT_DIR").unwrap()));

env::remove_var("DESTDIR");

if env::var("DOCS_RS").is_ok() {
// Use stubs, not libcubeb, for docs.rs.
return;
// Copy libcubeb to the output directory.
let libcubeb_path = format!("{}/libcubeb", env::var("OUT_DIR").unwrap());
t!(Command::new("cp")
.args(["-r", "libcubeb", &env::var("OUT_DIR").unwrap(),])
.status());

fn visit_dirs(dir: &Path, cb: &dyn Fn(&fs::DirEntry)) -> std::io::Result<()> {
if dir.is_dir() {
for entry in fs::read_dir(dir)? {
let entry = entry?;
let path = entry.path();
if path.is_dir() {
visit_dirs(&path, cb)?;
} else {
cb(&entry);
}
}
}
Ok(())
}

// If the libcubeb submodule is present, use that.
let libcubeb_path = if Path::new("libcubeb").exists() {
"libcubeb".to_owned()
} else {
// If the submodule is not present, we're building in a packaged environment
// so we expected a vendored copy of the source to be available.
// Vendored copy generated with:
// "tar -c -f libcubeb_vendored.tar --exclude libcubeb/googletest libcubeb"
t!(Command::new("tar")
.args([
"xvfC",
"libcubeb_vendored.tar",
&env::var("OUT_DIR").unwrap(),
])
.status());
env::var("OUT_DIR").unwrap() + "/libcubeb"
};
// For packaged build: rename libcubeb Cargo.toml.in files to Cargo.toml.
t!(visit_dirs(Path::new(&libcubeb_path), &|entry| {
let path = entry.path();
if path
.file_name()
.unwrap()
.to_str()
.unwrap()
.ends_with("Cargo.toml.in")
{
let new_path = path.with_file_name("Cargo.toml");
fs::rename(&path, &new_path).unwrap();
}
}));

let target = env::var("TARGET").unwrap();
let windows = target.contains("windows");
Expand Down
Binary file removed cubeb-sys/libcubeb_vendored.tar
Binary file not shown.
8 changes: 8 additions & 0 deletions xtask/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[package]
name = "xtask"
version = "0.3.0"
edition = "2021"
publish = false
release = false

[dependencies]
134 changes: 134 additions & 0 deletions xtask/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
use std::{
env, fs,
path::{Path, PathBuf},
process::Command,
};

type DynError = Box<dyn std::error::Error>;

fn main() {
if let Err(e) = try_main() {
eprintln!("{}", e);
std::process::exit(-1);
}
}

fn try_main() -> Result<(), DynError> {
let task = env::args().nth(1);
match task.as_deref() {
Some("release") => release()?,
_ => print_help(),
}
Ok(())
}

fn print_help() {
eprintln!(
"Tasks:
release runs 'cargo release' after preparing the source directory
"
)
}

fn visit_dirs(dir: &Path, cb: &dyn Fn(&fs::DirEntry)) -> std::io::Result<()> {
if dir.is_dir() {
for entry in fs::read_dir(dir)? {
let entry = entry?;
let path = entry.path();
if path.is_dir() {
visit_dirs(&path, cb)?;
} else {
cb(&entry);
}
}
}
Ok(())
}

fn release() -> Result<(), DynError> {
let cargo = env::var("CARGO").unwrap_or_else(|_| "cargo".to_string());

let status = Command::new(&cargo)
.current_dir(project_root())
.args(["release", "--workspace", "minor", "-x", "--no-publish"])
.status()?;

if !status.success() {
Err("cargo release failed")?;
}

// For packaged build: rename libcubeb Cargo.toml files to Cargo.toml.in.
visit_dirs(Path::new("cubeb-sys/libcubeb"), &|entry| {
let path = entry.path();
if path
.file_name()
.unwrap()
.to_str()
.unwrap()
.ends_with("Cargo.toml")
{
let new_path = path.with_file_name("Cargo.toml.in");
fs::rename(&path, &new_path).unwrap();
}
})
.unwrap();

let status = Command::new(&cargo)
.current_dir(project_root())
.args(["publish", "--package", "cubeb-sys", "--allow-dirty"])
.status()?;
if !status.success() {
Err("cargo publish failed")?;
}

// Rename libcubeb Cargo.toml.in files back to Cargo.toml.
visit_dirs(Path::new("cubeb-sys/libcubeb"), &|entry| {
let path = entry.path();
if path
.file_name()
.unwrap()
.to_str()
.unwrap()
.ends_with("Cargo.toml.in")
{
let new_path = path.with_file_name("Cargo.toml");
fs::rename(&path, &new_path).unwrap();
}
})
.unwrap();

let status = Command::new(&cargo)
.current_dir(project_root())
.args(["publish", "--package", "cubeb-core"])
.status()?;
if !status.success() {
Err("cargo publish failed")?;
}

let status = Command::new(&cargo)
.current_dir(project_root())
.args(["publish", "--package", "cubeb-backend"])
.status()?;
if !status.success() {
Err("cargo publish failed")?;
}

let status = Command::new(&cargo)
.current_dir(project_root())
.args(["publish", "--package", "cubeb"])
.status()?;
if !status.success() {
Err("cargo publish failed")?;
}

Ok(())
}

fn project_root() -> PathBuf {
Path::new(&env!("CARGO_MANIFEST_DIR"))
.ancestors()
.nth(1)
.unwrap()
.to_path_buf()
}

0 comments on commit 21a8086

Please sign in to comment.