Skip to content

Commit 6cc5efa

Browse files
committed
Add CARGO_HOME/lib support for cargo install workflows
Updates binary_finder to check $CARGO_HOME/lib/{package}/ directories before falling back to system PATH. This enables packages that depend on fastga-rs (like sweepga) to install FastGA helper binaries to a library directory after cargo install, ensuring they work from any directory. Search order now: 1. Same directory as executable (cargo install) 2. $CARGO_HOME/lib/{package}/ for sweepga, fastga-rs, fastga 3. OUT_DIR (build-time only) 4. Cargo build directories (development) 5. System PATH All tests pass.
1 parent e33ea5b commit 6cc5efa

File tree

1 file changed

+54
-10
lines changed

1 file changed

+54
-10
lines changed

src/binary_finder.rs

Lines changed: 54 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@ use std::path::PathBuf;
1010
///
1111
/// Search order:
1212
/// 1. Same directory as current executable (cargo install)
13-
/// 2. OUT_DIR from build.rs (development only)
14-
/// 3. Cargo build directories (development)
15-
/// 4. System PATH
13+
/// 2. $CARGO_HOME/lib/{parent_package}/ (for dependent packages after cargo install)
14+
/// 3. OUT_DIR from build.rs (development only)
15+
/// 4. Cargo build directories (development)
16+
/// 5. System PATH
1617
pub fn find_binary(name: &str) -> Result<PathBuf> {
1718
// 1. Try same directory as the current executable (for cargo install)
1819
if let Ok(exe_path) = std::env::current_exe() {
@@ -24,15 +25,37 @@ pub fn find_binary(name: &str) -> Result<PathBuf> {
2425
}
2526
}
2627

27-
// 2. Try OUT_DIR (compile-time env var, only works during build)
28+
// 2. Try $CARGO_HOME/lib/{parent_package}/ for packages that depend on fastga-rs
29+
// This allows dependent packages to install FastGA binaries to a known location
30+
let cargo_home = std::env::var("CARGO_HOME")
31+
.ok()
32+
.map(PathBuf::from)
33+
.or_else(|| {
34+
std::env::var("HOME")
35+
.ok()
36+
.map(|h| PathBuf::from(h).join(".cargo"))
37+
});
38+
39+
if let Some(cargo_home) = cargo_home {
40+
let lib_dir = cargo_home.join("lib");
41+
// Check common package names that might use fastga-rs
42+
for package in &["sweepga", "fastga-rs", "fastga"] {
43+
let binary = lib_dir.join(package).join(name);
44+
if binary.exists() {
45+
return Ok(binary);
46+
}
47+
}
48+
}
49+
50+
// 3. Try OUT_DIR (compile-time env var, only works during build)
2851
if let Ok(out_dir) = std::env::var("OUT_DIR") {
2952
let path = PathBuf::from(out_dir).join(name);
3053
if path.exists() {
3154
return Ok(path);
3255
}
3356
}
3457

35-
// 3. Try current exe's build directory (development in target/)
58+
// 4. Try current exe's build directory (development in target/)
3659
if let Ok(exe_path) = std::env::current_exe() {
3760
if let Some(exe_dir) = exe_path.parent() {
3861
let build_dir = exe_dir.join("build");
@@ -53,7 +76,7 @@ pub fn find_binary(name: &str) -> Result<PathBuf> {
5376
}
5477
}
5578

56-
// 4. Try target directories (running from project root)
79+
// 5. Try target directories (running from project root)
5780
for profile in &["debug", "release"] {
5881
let build_dir = PathBuf::from(format!("target/{profile}/build"));
5982
if let Ok(entries) = std::fs::read_dir(&build_dir) {
@@ -72,7 +95,7 @@ pub fn find_binary(name: &str) -> Result<PathBuf> {
7295
}
7396
}
7497

75-
// 5. Fall back to PATH (system-installed FastGA)
98+
// 6. Fall back to PATH (system-installed FastGA)
7699
if let Ok(path) = which::which(name) {
77100
return Ok(path);
78101
}
@@ -98,7 +121,28 @@ pub fn get_binary_dir() -> Result<PathBuf> {
98121
}
99122
}
100123

101-
// 2. Try OUT_DIR
124+
// 2. Try $CARGO_HOME/lib/{parent_package}/
125+
let cargo_home = std::env::var("CARGO_HOME")
126+
.ok()
127+
.map(PathBuf::from)
128+
.or_else(|| {
129+
std::env::var("HOME")
130+
.ok()
131+
.map(|h| PathBuf::from(h).join(".cargo"))
132+
});
133+
134+
if let Some(cargo_home) = cargo_home {
135+
let lib_dir = cargo_home.join("lib");
136+
for package in &["sweepga", "fastga-rs", "fastga"] {
137+
let package_lib = lib_dir.join(package);
138+
let test_binary = package_lib.join("FastGA");
139+
if test_binary.exists() {
140+
return Ok(package_lib);
141+
}
142+
}
143+
}
144+
145+
// 3. Try OUT_DIR
102146
if let Ok(out_dir) = std::env::var("OUT_DIR") {
103147
let path = PathBuf::from(&out_dir);
104148
let test_binary = path.join("FastGA");
@@ -107,7 +151,7 @@ pub fn get_binary_dir() -> Result<PathBuf> {
107151
}
108152
}
109153

110-
// 3. Try current exe's build directory
154+
// 4. Try current exe's build directory
111155
if let Ok(exe_path) = std::env::current_exe() {
112156
if let Some(exe_dir) = exe_path.parent() {
113157
let build_dir = exe_dir.join("build");
@@ -129,7 +173,7 @@ pub fn get_binary_dir() -> Result<PathBuf> {
129173
}
130174
}
131175

132-
// 4. Try target directories
176+
// 5. Try target directories
133177
for profile in &["debug", "release"] {
134178
let build_dir = PathBuf::from(format!("target/{profile}/build"));
135179
if let Ok(entries) = std::fs::read_dir(&build_dir) {

0 commit comments

Comments
 (0)