Skip to content

Commit 1ae8a07

Browse files
committed
fix(go-runner): detect missing C compiler before building instrument hooks
1 parent 3f94c58 commit 1ae8a07

1 file changed

Lines changed: 43 additions & 2 deletions

File tree

go-runner/src/runner/mod.rs

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,53 @@ use tempfile::TempDir;
88

99
mod overlay;
1010

11+
fn check_c_compiler(go_binary: &Path) -> anyhow::Result<()> {
12+
let output = Command::new(go_binary)
13+
.args(["env", "CC"])
14+
.output()
15+
.context("Failed to run `go env CC`")?;
16+
17+
let cc = String::from_utf8_lossy(&output.stdout).trim().to_string();
18+
if cc.is_empty() {
19+
bail!(
20+
"No C compiler found. The CodSpeed Go runner requires a C compiler (gcc/cc) \
21+
to build the instrumentation hooks. Install `build-essential` on Ubuntu/Debian \
22+
or the equivalent for your platform."
23+
);
24+
}
25+
26+
let found = Command::new("sh")
27+
.args(["-c", &format!("command -v {}", cc)])
28+
.output()
29+
.map(|o| o.status.success())
30+
.unwrap_or(false);
31+
32+
if !found {
33+
bail!(
34+
"C compiler '{}' not found in PATH. The CodSpeed Go runner requires a C compiler \
35+
to build the instrumentation hooks. Install `build-essential` on Ubuntu/Debian \
36+
or the equivalent for your platform.",
37+
cc
38+
);
39+
}
40+
41+
Ok(())
42+
}
43+
1144
fn run_cmd<P: AsRef<Path>>(
1245
profile_dir: P,
1346
dir: P,
1447
cli: &Cli,
1548
) -> anyhow::Result<(TempDir, Command)> {
16-
let (_dir, overlay_file) = overlay::get_overlay_file(profile_dir.as_ref())?;
17-
1849
// Execute the `go test` command using the go binary, rather than the one in the PATH
1950
// to avoid running into infinite loops with the runner which tries to intercept `go test`.
2051
let go_binary = find_go_binary()?;
2152

53+
// Check early, before downloading instrument-hooks and generating the overlay.
54+
check_c_compiler(&go_binary)?;
55+
56+
let (_dir, overlay_file) = overlay::get_overlay_file(profile_dir.as_ref())?;
57+
2258
// Convert the CLI struct into a command:
2359
let mut cmd = Command::new(go_binary);
2460
cmd.args([
@@ -44,6 +80,11 @@ fn run_cmd<P: AsRef<Path>>(
4480
cmd.env("GOCACHE", _dir.path().join("gocache"));
4581
cmd.env("GOMODCACHE", _dir.path().join("gomodcache"));
4682

83+
// The overlay includes instrument-hooks.go which uses cgo (`import "C"`).
84+
// If CGO_ENABLED=0 (e.g. no C compiler on a bare metal runner), Go silently
85+
// excludes the file, causing "undefined: InstrumentHooks" build errors.
86+
cmd.env("CGO_ENABLED", "1");
87+
4788
Ok((_dir, cmd))
4889
}
4990

0 commit comments

Comments
 (0)