From 797958082ce64b33b1ab4cf62fe5e0a60c8e2f21 Mon Sep 17 00:00:00 2001 From: Meghan Denny Date: Mon, 11 Nov 2024 19:23:58 -0800 Subject: [PATCH] musl patches [v4] (#15066) --- cmake/targets/BuildBun.cmake | 5 ++++ cmake/tools/SetupWebKit.cmake | 2 +- src/bun.js/module_loader.zig | 2 +- src/compile_target.zig | 2 +- src/js/thirdparty/detect-libc.musl.js | 38 +++++++++++++++++++++++++++ test/harness.ts | 18 +++++++++++++ test/js/bun/spawn/spawn.test.ts | 10 +++---- test/js/node/process/call-raise.js | 4 +-- test/mkfifo.ts | 4 +-- 9 files changed, 73 insertions(+), 12 deletions(-) create mode 100644 src/js/thirdparty/detect-libc.musl.js diff --git a/cmake/targets/BuildBun.cmake b/cmake/targets/BuildBun.cmake index 9976d8dae339af..68e462447d37b0 100644 --- a/cmake/targets/BuildBun.cmake +++ b/cmake/targets/BuildBun.cmake @@ -879,6 +879,7 @@ else() set(LLD_NAME lld-${LLVM_VERSION_MAJOR}) endif() + if (NOT IS_MUSL) if (IS_ARM64) set(ARCH_WRAP_FLAGS -Wl,--wrap=fcntl64 @@ -901,6 +902,10 @@ else() -Wl,--wrap=statx ) endif() + else() + set(ARCH_WRAP_FLAGS + ) + endif() if (NOT IS_MUSL) set(ABI_WRAP_FLAGS diff --git a/cmake/tools/SetupWebKit.cmake b/cmake/tools/SetupWebKit.cmake index 677c8c0ad392b3..b71eff33e101b3 100644 --- a/cmake/tools/SetupWebKit.cmake +++ b/cmake/tools/SetupWebKit.cmake @@ -2,7 +2,7 @@ option(WEBKIT_VERSION "The version of WebKit to use") option(WEBKIT_LOCAL "If a local version of WebKit should be used instead of downloading") if(NOT WEBKIT_VERSION) - set(WEBKIT_VERSION 73b551e25d97e463e8e2c86cb819b8639fcbda06) + set(WEBKIT_VERSION 3bc4abf2d5875baf500b4687ef869987f6d19e00) endif() if(WEBKIT_LOCAL) diff --git a/src/bun.js/module_loader.zig b/src/bun.js/module_loader.zig index ded396631b953a..b3a0b91da9e4ae 100644 --- a/src/bun.js/module_loader.zig +++ b/src/bun.js/module_loader.zig @@ -2472,7 +2472,7 @@ pub const ModuleLoader = struct { return jsSyntheticModule(.@"bun:sql", specifier); }, .@"bun:sqlite" => return jsSyntheticModule(.@"bun:sqlite", specifier), - .@"detect-libc" => return jsSyntheticModule(if (Environment.isLinux) .@"detect-libc/linux" else .@"detect-libc", specifier), + .@"detect-libc" => return jsSyntheticModule(if (!Environment.isLinux) .@"detect-libc" else if (!Environment.isMusl) .@"detect-libc/linux" else .@"detect-libc/musl", specifier), .@"node:assert" => return jsSyntheticModule(.@"node:assert", specifier), .@"node:assert/strict" => return jsSyntheticModule(.@"node:assert/strict", specifier), .@"node:async_hooks" => return jsSyntheticModule(.@"node:async_hooks", specifier), diff --git a/src/compile_target.zig b/src/compile_target.zig index 242a36c09e0935..cf0f0acc202f5f 100644 --- a/src/compile_target.zig +++ b/src/compile_target.zig @@ -19,7 +19,7 @@ version: bun.Semver.Version = .{ .minor = @truncate(Environment.version.minor), .patch = @truncate(Environment.version.patch), }, -libc: Libc = .default, +libc: Libc = if (!Environment.isMusl) .default else .musl, const Libc = enum { /// The default libc for the target diff --git a/src/js/thirdparty/detect-libc.musl.js b/src/js/thirdparty/detect-libc.musl.js new file mode 100644 index 00000000000000..7ab932c53935ef --- /dev/null +++ b/src/js/thirdparty/detect-libc.musl.js @@ -0,0 +1,38 @@ +// Hardcoded module "detect-libc" for linux +function family() { + return Promise.resolve(familySync()); +} + +function familySync() { + return MUSL; +} + +const GLIBC = "glibc"; +const MUSL = "musl"; + +function version() { + return Promise.resolve(versionSync()); +} + +function versionSync() { + return "1.2.5"; +} + +function isNonGlibcLinuxSync() { + return true; +} + +function isNonGlibcLinux() { + return Promise.resolve(isNonGlibcLinuxSync()); +} + +export default { + GLIBC, + MUSL, + family, + familySync, + isNonGlibcLinux, + isNonGlibcLinuxSync, + version, + versionSync, +}; diff --git a/test/harness.ts b/test/harness.ts index 652d99b1f91324..82d3231b6fc914 100644 --- a/test/harness.ts +++ b/test/harness.ts @@ -5,6 +5,7 @@ import { readFile, readlink, writeFile } from "fs/promises"; import fs, { closeSync, openSync } from "node:fs"; import os from "node:os"; import { dirname, isAbsolute, join } from "path"; +import detect_libc from "detect-libc"; type Awaitable = T | Promise; @@ -18,6 +19,7 @@ export const isIntelMacOS = isMacOS && process.arch === "x64"; export const isDebug = Bun.version.includes("debug"); export const isCI = process.env.CI !== undefined; export const isBuildKite = process.env.BUILDKITE === "true"; +export const libc_family = detect_libc.familySync(); // Use these to mark a test as flaky or broken. // This will help us keep track of these tests. @@ -1365,3 +1367,19 @@ export function waitForFileToExist(path: string, interval: number) { sleepSync(interval); } } + +export function libcPathForDlopen() { + switch (process.platform) { + case "linux": + switch (libc_family) { + case "glibc": + return "libc.so.6"; + case "musl": + return "/usr/lib/libc.so"; + } + case "darwin": + return "libc.dylib"; + default: + throw new Error("TODO"); + } +} diff --git a/test/js/bun/spawn/spawn.test.ts b/test/js/bun/spawn/spawn.test.ts index 345e458e22f669..4f2adf20356932 100644 --- a/test/js/bun/spawn/spawn.test.ts +++ b/test/js/bun/spawn/spawn.test.ts @@ -152,7 +152,7 @@ for (let [gcTick, label] of [ it("nothing to stdout and sleeping doesn't keep process open 4ever", async () => { const proc = spawn({ - cmd: [shellExe(), "-c", "sleep", "0.1"], + cmd: [shellExe(), "-c", "sleep 0.1"], }); gcTick(); for await (const _ of proc.stdout) { @@ -366,7 +366,7 @@ for (let [gcTick, label] of [ it("kill(SIGKILL) works", async () => { const process = spawn({ - cmd: [shellExe(), "-c", "sleep", "1000"], + cmd: [shellExe(), "-c", "sleep 1000"], stdout: "pipe", }); gcTick(); @@ -377,7 +377,7 @@ for (let [gcTick, label] of [ it("kill() works", async () => { const process = spawn({ - cmd: [shellExe(), "-c", "sleep", "1000"], + cmd: [shellExe(), "-c", "sleep 1000"], stdout: "pipe", }); gcTick(); @@ -551,7 +551,7 @@ if (!process.env.BUN_FEATURE_FLAG_FORCE_WAITER_THREAD && isPosix && !isMacOS) { } describe("spawn unref and kill should not hang", () => { - const cmd = [shellExe(), "-c", "sleep", "0.001"]; + const cmd = [shellExe(), "-c", "sleep 0.001"]; it("kill and await exited", async () => { const promises = new Array(10); @@ -635,7 +635,7 @@ async function runTest(sleep: string, order = ["sleep", "kill", "unref", "exited console.log("running", order.join(","), "x 100"); for (let i = 0; i < (isWindows ? 10 : 100); i++) { const proc = spawn({ - cmd: [shellExe(), "-c", "sleep", sleep], + cmd: [shellExe(), "-c", `sleep ${sleep}`], stdout: "ignore", stderr: "ignore", stdin: "ignore", diff --git a/test/js/node/process/call-raise.js b/test/js/node/process/call-raise.js index 898906759e87d9..5b95f9ec44f05b 100644 --- a/test/js/node/process/call-raise.js +++ b/test/js/node/process/call-raise.js @@ -1,10 +1,10 @@ import { dlopen } from "bun:ffi"; +import { libcPathForDlopen } from "harness"; var lazyRaise; export function raise(signal) { if (!lazyRaise) { - const suffix = process.platform === "darwin" ? "dylib" : "so.6"; - lazyRaise = dlopen(`libc.${suffix}`, { + lazyRaise = dlopen(libcPathForDlopen(), { raise: { args: ["int"], returns: "int", diff --git a/test/mkfifo.ts b/test/mkfifo.ts index 1fd04572399c09..18956e845c12b8 100644 --- a/test/mkfifo.ts +++ b/test/mkfifo.ts @@ -1,10 +1,10 @@ import { dlopen, ptr } from "bun:ffi"; +import { libcPathForDlopen } from "harness"; var lazyMkfifo: any; export function mkfifo(path: string, permissions: number = 0o666): void { if (!lazyMkfifo) { - const suffix = process.platform === "darwin" ? "dylib" : "so.6"; - lazyMkfifo = dlopen(`libc.${suffix}`, { + lazyMkfifo = dlopen(libcPathForDlopen(), { mkfifo: { args: ["ptr", "i32"], returns: "i32",