Skip to content

Commit 7e2593f

Browse files
committed
more reliable implementation and tests
1 parent a386864 commit 7e2593f

15 files changed

+1434
-347
lines changed

Cargo.toml

+22-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1-
[package]
2-
name = "system-deps"
1+
[workspace]
2+
members = [ "meta" ]
3+
exclude = [ "target" ]
4+
5+
[workspace.package]
36
version = "7.0.3"
47
authors = [
58
"Guillaume Desmottes <[email protected]>",
@@ -17,10 +20,20 @@ keywords = [
1720
]
1821
edition = "2018"
1922
documentation = "https://docs.rs/system-deps/"
20-
readme = "README.md"
2123

22-
[build-dependencies]
23-
system-deps-meta = { path = "./meta", optional = true }
24+
[workspace.dependencies]
25+
system-deps-meta = { path = "./meta" }
26+
27+
[package]
28+
name = "system-deps"
29+
version.workspace = true
30+
authors.workspace = true
31+
license.workspace = true
32+
description.workspace = true
33+
keywords.workspace = true
34+
edition.workspace = true
35+
documentation.workspace = true
36+
readme = "README.md"
2437

2538
[dependencies]
2639
pkg-config = "0.3.25"
@@ -29,13 +42,15 @@ version-compare = "0.2"
2942
heck = "0.5"
3043
cfg-expr = { version = "0.17", features = ["targets"] }
3144

45+
[build-dependencies]
46+
system-deps-meta = { workspace = true, optional = true }
47+
3248
[dev-dependencies]
33-
lazy_static = "1"
3449
itertools = "0.13"
3550
assert_matches = "1.5"
3651

3752
[features]
38-
default = [ "binary" ]
53+
default = [ ]
3954
binary = [ "system-deps-meta/binary" ]
4055
gx = [ "system-deps-meta/gz" ]
4156
xz = [ "system-deps-meta/xz" ]

build.rs

+17-18
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,31 @@
11
pub fn main() {
22
#[cfg(feature = "binary")]
3-
binary::build();
3+
binary::build().unwrap_or_else(|e| panic!("{}", e));
44
}
55

66
#[cfg(feature = "binary")]
77
mod binary {
8-
use std::{collections::HashMap, fs, path::Path};
8+
use std::{collections::HashMap, convert::TryInto, fs, path::Path};
99

10-
use system_deps_meta::{read_metadata, Binary, BinaryPaths, BUILD_TARGET_DIR};
11-
12-
pub fn build() {
13-
// Add pkg-config paths to the overrides
14-
// TODO: This should probably follow some deterministic ordering to avoid issues
15-
16-
let dest_path = Path::new(BUILD_TARGET_DIR).join("binary_config.rs");
17-
println!("cargo:rustc-env=BINARY_CONFIG={}", dest_path.display());
10+
use system_deps_meta::{
11+
binary::{merge_binary, Binary, BinaryPaths},
12+
error::{BinaryError, Error},
13+
parse::{MetadataList, ValueExt},
14+
BUILD_MANIFEST, BUILD_TARGET_DIR,
15+
};
1816

17+
// Add pkg-config paths to the overrides
18+
pub fn build() -> Result<(), Error> {
1919
// Read metadata from the crate graph
20-
let metadata = read_metadata(system_deps_meta::BUILD_MANIFEST, "system-deps");
20+
let metadata = MetadataList::new(BUILD_MANIFEST, "system-deps")?;
2121

2222
// Download the binaries and get their pkg_config paths
23-
let mut binaries = metadata
24-
.get::<HashMap<String, Binary>>(|| true)
25-
.unwrap_or_default();
26-
println!("cargo:warning=BINARIES {:?}", binaries);
27-
let paths = BinaryPaths::from(binaries.drain());
28-
println!("cargo:warning=PATHS {:?}", paths);
23+
let list: HashMap<String, Binary> = metadata.build(merge_binary)?.to().unwrap_or_default();
24+
let paths: BinaryPaths = list.try_into()?;
2925

30-
fs::write(dest_path, paths.build()).expect("Error when writing binary config");
26+
// Write the binary paths to a file for later use
27+
let dest_path = Path::new(BUILD_TARGET_DIR).join("binary_config.rs");
28+
println!("cargo:rustc-env=BINARY_CONFIG={}", dest_path.display());
29+
fs::write(dest_path, paths.build()).map_err(|e| BinaryError::InvalidDirectory(e).into())
3130
}
3231
}

meta/Cargo.toml

+7-6
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,24 @@
11
[package]
22
name = "system-deps-meta"
3-
version = "0.1.0"
4-
edition = "2021"
3+
version.workspace = true
4+
authors.workspace = true
5+
license.workspace = true
6+
description.workspace = true
7+
keywords.workspace = true
8+
edition.workspace = true
9+
documentation.workspace = true
510

611
[dependencies]
712
cargo_metadata = "0.19"
8-
# Metadata
913
serde_json = "1.0"
1014
serde = "1.0"
1115
cfg-expr = { version = "0.17", features = ["targets"] }
12-
# Binary
1316
sha256 = { version = "1.5", optional = true }
1417
reqwest = { version = "0.12", features = ["blocking"], optional = true }
1518
flate2 = { version = "1.0", optional = true }
1619
xz = { version = "0.1", optional = true }
1720
tar = { version = "0.4", optional = true }
1821
zip = { version = "2.2", optional = true }
19-
apple-flat-package = { version = "0.20", optional = true }
2022

2123
[dev-dependencies]
2224
toml = "0.8"
@@ -27,4 +29,3 @@ binary = [ "dep:sha256", "dep:reqwest" ]
2729
gz = [ "dep:flate2", "dep:tar" ]
2830
xz = [ "dep:xz", "dep:tar" ]
2931
zip = [ "dep:zip" ]
30-
pkg = [ "dep:apple-flat-package" ]

meta/build.rs

+6-38
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::{
44
};
55

66
/// Environment variable to override the top level `Cargo.toml`.
7-
const MANIFEST_VAR: &str = "SYSTEM_DEPS_MANIFEST";
7+
const MANIFEST_VAR: &str = "SYSTEM_DEPS_BUILD_MANIFEST";
88

99
/// Environment variable to override the directory where `system-deps`
1010
/// will store build products such as binary outputs.
@@ -26,27 +26,6 @@ fn find_with_cargo(dir: &Path) -> Option<PathBuf> {
2626
Some(PathBuf::from(std::str::from_utf8(&out).ok()?.trim()))
2727
}
2828

29-
/// Try to find the project root finding the outmost Cargo.toml
30-
/// TODO: Check if this is ever called
31-
fn find_by_path(mut dir: PathBuf) -> Option<PathBuf> {
32-
let mut best_match = None;
33-
loop {
34-
let Ok(read) = dir.read_dir() else {
35-
break;
36-
};
37-
for entry in read {
38-
let Ok(entry) = entry else { continue };
39-
if entry.file_name() == "Cargo.toml" {
40-
best_match = Some(entry.path());
41-
}
42-
}
43-
if !dir.pop() {
44-
break;
45-
}
46-
}
47-
best_match
48-
}
49-
5029
/// Get the manifest from the project directory. This is **not** the directory
5130
/// where `system-deps` is cloned, it should point to the top level `Cargo.toml`
5231
/// file. This is needed to obtain metadata from all of dependencies, including
@@ -75,34 +54,23 @@ fn manifest() -> PathBuf {
7554
);
7655
dir.pop();
7756

78-
// Try to find the project first with cargo
79-
if let Some(dir) = find_with_cargo(&dir) {
80-
return dir;
81-
}
82-
83-
// If it doesn't work, try to find a Cargo.toml
84-
find_by_path(dir).expect(
57+
// Try to find the project with cargo
58+
find_with_cargo(&dir).expect(
8559
"Error determining the cargo root manifest.\n\
8660
Please set `SYSTEM_DEPS_MANIFEST` to the path of your project's Cargo.toml",
8761
)
8862
}
8963

90-
/// Directory where system-deps related build products will be stored.
91-
/// Notably, binary outputs are located here.
92-
fn target_dir() -> String {
93-
println!("cargo:rerun-if-env-changed={}", TARGET_VAR);
94-
env::var(TARGET_VAR).or(env::var("OUT_DIR")).unwrap()
95-
}
96-
97-
/// This will set compile time values for the manifest and target paths.
64+
/// Set compile time values for the manifest and target paths, and the compile target.
9865
/// Calculating this in a build script is necessary so that they are only calculated
9966
/// once and every invocation of `system-deps` references the same metadata.
10067
pub fn main() {
10168
let manifest = manifest();
10269
println!("cargo:rerun-if-changed={}", manifest.display());
10370
println!("cargo:rustc-env=BUILD_MANIFEST={}", manifest.display());
10471

105-
let target_dir = target_dir();
72+
let target_dir = env::var(TARGET_VAR).or(env::var("OUT_DIR")).unwrap();
73+
println!("cargo:rerun-if-env-changed={}", TARGET_VAR);
10674
println!("cargo:rustc-env=BUILD_TARGET_DIR={}", target_dir);
10775

10876
println!(

0 commit comments

Comments
 (0)