Skip to content

Commit 27aa01d

Browse files
Honaadamdotdevin
authored andcommitted
fix: baseline CPU detection (#13371)
1 parent fe4f2b1 commit 27aa01d

File tree

6 files changed

+127
-22
lines changed

6 files changed

+127
-22
lines changed

bun.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

install

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ else
130130
needs_baseline=false
131131
if [ "$arch" = "x64" ]; then
132132
if [ "$os" = "linux" ]; then
133-
if ! grep -qi avx2 /proc/cpuinfo 2>/dev/null; then
133+
if ! grep -qwi avx2 /proc/cpuinfo 2>/dev/null; then
134134
needs_baseline=true
135135
fi
136136
fi
@@ -141,6 +141,20 @@ else
141141
needs_baseline=true
142142
fi
143143
fi
144+
145+
if [ "$os" = "windows" ]; then
146+
ps="(Add-Type -MemberDefinition \"[DllImport(\"\"kernel32.dll\"\")] public static extern bool IsProcessorFeaturePresent(int ProcessorFeature);\" -Name Kernel32 -Namespace Win32 -PassThru)::IsProcessorFeaturePresent(40)"
147+
out=""
148+
if command -v powershell.exe >/dev/null 2>&1; then
149+
out=$(powershell.exe -NoProfile -NonInteractive -Command "$ps" 2>/dev/null || true)
150+
elif command -v pwsh >/dev/null 2>&1; then
151+
out=$(pwsh -NoProfile -NonInteractive -Command "$ps" 2>/dev/null || true)
152+
fi
153+
out=$(echo "$out" | tr -d '\r' | tr '[:upper:]' '[:lower:]' | tr -d '[:space:]')
154+
if [ "$out" != "true" ] && [ "$out" != "1" ]; then
155+
needs_baseline=true
156+
fi
157+
fi
144158
fi
145159

146160
target="$os-$arch"

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"description": "AI-powered development tool",
55
"private": true,
66
"type": "module",
7-
"packageManager": "bun@1.3.5",
7+
"packageManager": "bun@1.3.9",
88
"scripts": {
99
"dev": "bun run --cwd packages/opencode --conditions=browser src/index.ts",
1010
"dev:desktop": "bun --cwd packages/desktop tauri dev",
@@ -23,7 +23,7 @@
2323
"packages/slack"
2424
],
2525
"catalog": {
26-
"@types/bun": "1.3.5",
26+
"@types/bun": "1.3.9",
2727
"@octokit/rest": "22.0.0",
2828
"@hono/zod-validator": "0.4.2",
2929
"ulid": "3.0.1",

packages/desktop/scripts/predev.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ const sidecarConfig = getCurrentSidecar(RUST_TARGET)
88

99
const binaryPath = windowsify(`../opencode/dist/${sidecarConfig.ocBinary}/bin/opencode`)
1010

11-
await $`cd ../opencode && bun run build --single`
11+
await (sidecarConfig.ocBinary.includes("-baseline")
12+
? $`cd ../opencode && bun run build --single --baseline`
13+
: $`cd ../opencode && bun run build --single`)
1214

1315
await copyBinaryToSidecarFolder(binaryPath, RUST_TARGET)

packages/desktop/scripts/utils.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,17 @@ export const SIDECAR_BINARIES: Array<{ rustTarget: string; ocBinary: string; ass
88
},
99
{
1010
rustTarget: "x86_64-apple-darwin",
11-
ocBinary: "opencode-darwin-x64",
11+
ocBinary: "opencode-darwin-x64-baseline",
1212
assetExt: "zip",
1313
},
1414
{
1515
rustTarget: "x86_64-pc-windows-msvc",
16-
ocBinary: "opencode-windows-x64",
16+
ocBinary: "opencode-windows-x64-baseline",
1717
assetExt: "zip",
1818
},
1919
{
2020
rustTarget: "x86_64-unknown-linux-gnu",
21-
ocBinary: "opencode-linux-x64",
21+
ocBinary: "opencode-linux-x64-baseline",
2222
assetExt: "tar.gz",
2323
},
2424
{

packages/opencode/bin/opencode

Lines changed: 101 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -47,20 +47,109 @@ if (!arch) {
4747
const base = "opencode-" + platform + "-" + arch
4848
const binary = platform === "windows" ? "opencode.exe" : "opencode"
4949

50+
function supportsAvx2() {
51+
if (arch !== "x64") return false
52+
53+
if (platform === "linux") {
54+
try {
55+
return /(^|\s)avx2(\s|$)/i.test(fs.readFileSync("/proc/cpuinfo", "utf8"))
56+
} catch {
57+
return false
58+
}
59+
}
60+
61+
if (platform === "darwin") {
62+
try {
63+
const result = childProcess.spawnSync("sysctl", ["-n", "hw.optional.avx2_0"], {
64+
encoding: "utf8",
65+
timeout: 1500,
66+
})
67+
if (result.status !== 0) return false
68+
return (result.stdout || "").trim() === "1"
69+
} catch {
70+
return false
71+
}
72+
}
73+
74+
if (platform === "windows") {
75+
const cmd =
76+
'(Add-Type -MemberDefinition "[DllImport(""kernel32.dll"")] public static extern bool IsProcessorFeaturePresent(int ProcessorFeature);" -Name Kernel32 -Namespace Win32 -PassThru)::IsProcessorFeaturePresent(40)'
77+
78+
for (const exe of ["powershell.exe", "pwsh.exe", "pwsh", "powershell"]) {
79+
try {
80+
const result = childProcess.spawnSync(exe, ["-NoProfile", "-NonInteractive", "-Command", cmd], {
81+
encoding: "utf8",
82+
timeout: 3000,
83+
windowsHide: true,
84+
})
85+
if (result.status !== 0) continue
86+
const out = (result.stdout || "").trim().toLowerCase()
87+
if (out === "true" || out === "1") return true
88+
if (out === "false" || out === "0") return false
89+
} catch {
90+
continue
91+
}
92+
}
93+
94+
return false
95+
}
96+
97+
return false
98+
}
99+
100+
const names = (() => {
101+
const avx2 = supportsAvx2()
102+
const baseline = arch === "x64" && !avx2
103+
104+
if (platform === "linux") {
105+
const musl = (() => {
106+
try {
107+
if (fs.existsSync("/etc/alpine-release")) return true
108+
} catch {
109+
// ignore
110+
}
111+
112+
try {
113+
const result = childProcess.spawnSync("ldd", ["--version"], { encoding: "utf8" })
114+
const text = ((result.stdout || "") + (result.stderr || "")).toLowerCase()
115+
if (text.includes("musl")) return true
116+
} catch {
117+
// ignore
118+
}
119+
120+
return false
121+
})()
122+
123+
if (musl) {
124+
if (arch === "x64") {
125+
if (baseline) return [`${base}-baseline-musl`, `${base}-musl`, `${base}-baseline`, base]
126+
return [`${base}-musl`, `${base}-baseline-musl`, base, `${base}-baseline`]
127+
}
128+
return [`${base}-musl`, base]
129+
}
130+
131+
if (arch === "x64") {
132+
if (baseline) return [`${base}-baseline`, base, `${base}-baseline-musl`, `${base}-musl`]
133+
return [base, `${base}-baseline`, `${base}-musl`, `${base}-baseline-musl`]
134+
}
135+
return [base, `${base}-musl`]
136+
}
137+
138+
if (arch === "x64") {
139+
if (baseline) return [`${base}-baseline`, base]
140+
return [base, `${base}-baseline`]
141+
}
142+
return [base]
143+
})()
144+
50145
function findBinary(startDir) {
51146
let current = startDir
52147
for (;;) {
53148
const modules = path.join(current, "node_modules")
54149
if (fs.existsSync(modules)) {
55-
const entries = fs.readdirSync(modules)
56-
for (const entry of entries) {
57-
if (!entry.startsWith(base)) {
58-
continue
59-
}
60-
const candidate = path.join(modules, entry, "bin", binary)
61-
if (fs.existsSync(candidate)) {
62-
return candidate
63-
}
150+
for (const name of names) {
151+
const candidate = path.join(modules, name, "bin", binary)
152+
if (fs.existsSync(candidate)) return candidate
64153
}
65154
}
66155
const parent = path.dirname(current)
@@ -74,9 +163,9 @@ function findBinary(startDir) {
74163
const resolved = findBinary(scriptDir)
75164
if (!resolved) {
76165
console.error(
77-
'It seems that your package manager failed to install the right version of the opencode CLI for your platform. You can try manually installing the "' +
78-
base +
79-
'" package',
166+
"It seems that your package manager failed to install the right version of the opencode CLI for your platform. You can try manually installing " +
167+
names.map((n) => `\"${n}\"`).join(" or ") +
168+
" package",
80169
)
81170
process.exit(1)
82171
}

0 commit comments

Comments
 (0)