diff --git a/.buildkite/ci.mjs b/.buildkite/ci.mjs index d7d704a40c..575e62f10d 100644 --- a/.buildkite/ci.mjs +++ b/.buildkite/ci.mjs @@ -169,8 +169,14 @@ function getPipeline(buildId) { */ const getKey = platform => { - const { os, arch, baseline } = platform; + const { os, arch, abi, baseline } = platform; + if (abi) { + if (baseline) { + return `${os}-${arch}-${abi}-baseline`; + } + return `${os}-${arch}-${abi}`; + } if (baseline) { return `${os}-${arch}-baseline`; } @@ -179,8 +185,11 @@ function getPipeline(buildId) { }; const getLabel = platform => { - const { os, arch, baseline, release } = platform; + const { os, arch, abi, baseline, release } = platform; let label = release ? `:${os}: ${release} ${arch}` : `:${os}: ${arch}`; + if (abi) { + label += `-${abi}`; + } if (baseline) { label += `-baseline`; } @@ -218,15 +227,16 @@ function getPipeline(buildId) { */ const getBuildVendorStep = platform => { - const { os, arch, baseline } = platform; + const { os, arch, abi, baseline } = platform; return { key: `${getKey(platform)}-build-vendor`, - label: `${getLabel(platform)} - build-vendor`, + label: `build-vendor`, agents: { os, arch, - queue: `build-${os}`, + abi, + queue: abi ? `build-${os}-${abi}` : `build-${os}`, }, retry: getRetry(), cancel_on_build_failing: isMergeQueue(), @@ -238,15 +248,16 @@ function getPipeline(buildId) { }; const getBuildCppStep = platform => { - const { os, arch, baseline } = platform; + const { os, arch, abi, baseline } = platform; return { key: `${getKey(platform)}-build-cpp`, - label: `${getLabel(platform)} - build-cpp`, + label: `build-cpp`, agents: { os, arch, - queue: `build-${os}`, + abi, + queue: abi ? `build-${os}-${abi}` : `build-${os}`, }, retry: getRetry(), cancel_on_build_failing: isMergeQueue(), @@ -259,12 +270,12 @@ function getPipeline(buildId) { }; const getBuildZigStep = platform => { - const { os, arch, baseline } = platform; - const toolchain = baseline ? `${os}-${arch}-baseline` : `${os}-${arch}`; + const { os, arch, abi, baseline } = platform; + const toolchain = getKey(platform); return { key: `${getKey(platform)}-build-zig`, - label: `${getLabel(platform)} - build-zig`, + label: `build-zig`, agents: { queue: "build-zig", }, @@ -278,11 +289,11 @@ function getPipeline(buildId) { }; const getBuildBunStep = platform => { - const { os, arch, baseline } = platform; + const { os, arch, abi, baseline } = platform; return { key: `${getKey(platform)}-build-bun`, - label: `${getLabel(platform)} - build-bun`, + label: `build-bun`, depends_on: [ `${getKey(platform)}-build-vendor`, `${getKey(platform)}-build-cpp`, @@ -291,6 +302,7 @@ function getPipeline(buildId) { agents: { os, arch, + abi, queue: `build-${os}`, }, retry: getRetry(), @@ -304,7 +316,7 @@ function getPipeline(buildId) { }; const getTestBunStep = platform => { - const { os, arch, distro, release } = platform; + const { os, arch, abi, distro, release } = platform; let name; if (os === "darwin" || os === "windows") { @@ -315,11 +327,11 @@ function getPipeline(buildId) { let agents; if (os === "darwin") { - agents = { os, arch, queue: `test-darwin` }; + agents = { os, arch, abi, queue: `test-darwin` }; } else if (os === "windows") { - agents = { os, arch, robobun: true }; + agents = { os, arch, abi, robobun: true }; } else { - agents = { os, arch, distro, release, robobun: true }; + agents = { os, arch, abi, distro, release, robobun: true }; } let command; @@ -375,8 +387,10 @@ function getPipeline(buildId) { { os: "darwin", arch: "aarch64" }, { os: "darwin", arch: "x64" }, { os: "linux", arch: "aarch64" }, + // { os: "linux", arch: "aarch64", abi: "musl" }, // TODO: { os: "linux", arch: "x64" }, { os: "linux", arch: "x64", baseline: true }, + // { os: "linux", arch: "x64", abi: "musl" }, // TODO: { os: "windows", arch: "x64" }, { os: "windows", arch: "x64", baseline: true }, ]; @@ -389,12 +403,14 @@ function getPipeline(buildId) { { os: "linux", arch: "aarch64", distro: "debian", release: "12" }, { os: "linux", arch: "aarch64", distro: "ubuntu", release: "22.04" }, { os: "linux", arch: "aarch64", distro: "ubuntu", release: "20.04" }, + // { os: "linux", arch: "aarch64", abi: "musl", distro: "alpine", release: "edge" }, // TODO: { os: "linux", arch: "x64", distro: "debian", release: "12" }, { os: "linux", arch: "x64", distro: "ubuntu", release: "22.04" }, { os: "linux", arch: "x64", distro: "ubuntu", release: "20.04" }, { os: "linux", arch: "x64", distro: "debian", release: "12", baseline: true }, { os: "linux", arch: "x64", distro: "ubuntu", release: "22.04", baseline: true }, { os: "linux", arch: "x64", distro: "ubuntu", release: "20.04", baseline: true }, + // { os: "linux", arch: "x64", abi: "musl", distro: "alpine", release: "edge" }, // TODO: { os: "windows", arch: "x64", distro: "server", release: "2019" }, { os: "windows", arch: "x64", distro: "server", release: "2019", baseline: true }, ]; diff --git a/build.zig b/build.zig index f65a9bd231..aef591190a 100644 --- a/build.zig +++ b/build.zig @@ -165,7 +165,7 @@ pub fn build(b: *Build) !void { var target_query = b.standardTargetOptionsQueryOnly(.{}); const optimize = b.standardOptimizeOption(.{}); - const os, const arch = brk: { + const os, const arch, const abi = brk: { // resolve the target query to pick up what operating system and cpu // architecture that is desired. this information is used to slightly // refine the query. @@ -179,7 +179,8 @@ pub fn build(b: *Build) !void { .windows => .windows, else => |t| std.debug.panic("Unsupported OS tag {}", .{t}), }; - break :brk .{ os, arch }; + const abi = temp_resolved.result.abi; + break :brk .{ os, arch, abi }; }; // target must be refined to support older but very popular devices on @@ -191,7 +192,7 @@ pub fn build(b: *Build) !void { } target_query.os_version_min = getOSVersionMin(os); - target_query.glibc_version = getOSGlibCVersion(os); + target_query.glibc_version = if (abi.isGnu()) getOSGlibCVersion(os) else null; const target = b.resolveTargetQuery(target_query); @@ -313,6 +314,8 @@ pub fn build(b: *Build) !void { .{ .os = .mac, .arch = .aarch64 }, .{ .os = .linux, .arch = .x86_64 }, .{ .os = .linux, .arch = .aarch64 }, + .{ .os = .linux, .arch = .x86_64, .musl = true }, + .{ .os = .linux, .arch = .aarch64, .musl = true }, }); } @@ -325,20 +328,20 @@ pub fn build(b: *Build) !void { } } -pub inline fn addMultiCheck( +pub fn addMultiCheck( b: *Build, parent_step: *Step, root_build_options: BunBuildOptions, - to_check: []const struct { os: OperatingSystem, arch: Arch }, + to_check: []const struct { os: OperatingSystem, arch: Arch, musl: bool = false }, ) void { - inline for (to_check) |check| { - inline for (.{ .Debug, .ReleaseFast }) |mode| { + for (to_check) |check| { + for ([_]std.builtin.Mode{ .Debug, .ReleaseFast }) |mode| { const check_target = b.resolveTargetQuery(.{ .os_tag = OperatingSystem.stdOSTag(check.os), .cpu_arch = check.arch, .cpu_model = getCpuModel(check.os, check.arch) orelse .determined_by_cpu_arch, .os_version_min = getOSVersionMin(check.os), - .glibc_version = getOSGlibCVersion(check.os), + .glibc_version = if (check.musl) null else getOSGlibCVersion(check.os), }); var options: BunBuildOptions = .{ diff --git a/cmake/Globals.cmake b/cmake/Globals.cmake index b987dfc201..9760101274 100644 --- a/cmake/Globals.cmake +++ b/cmake/Globals.cmake @@ -105,6 +105,14 @@ else() unsupported(CMAKE_HOST_SYSTEM_NAME) endif() +if(EXISTS "/lib/ld-musl-aarch64.so.1") + set(IS_MUSL ON) +elseif(EXISTS "/lib/ld-musl-x86_64.so.1") + set(IS_MUSL ON) +else() + set(IS_MUSL OFF) +endif() + if(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "arm64|ARM64|aarch64|AARCH64") set(HOST_OS "aarch64") elseif(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "x86_64|X86_64|x64|X64|amd64|AMD64") @@ -369,7 +377,7 @@ function(register_command) if(CMD_ENVIRONMENT) set(CMD_COMMAND ${CMAKE_COMMAND} -E env ${CMD_ENVIRONMENT} ${CMD_COMMAND}) endif() - + if(NOT CMD_COMMENT) string(JOIN " " CMD_COMMENT ${CMD_COMMAND}) endif() @@ -519,7 +527,7 @@ function(parse_package_json) set(NPM_NODE_MODULES) set(NPM_NODE_MODULES_PATH ${NPM_CWD}/node_modules) set(NPM_NODE_MODULES_PROPERTIES "devDependencies" "dependencies") - + foreach(property ${NPM_NODE_MODULES_PROPERTIES}) string(JSON NPM_${property} ERROR_VARIABLE error GET "${NPM_PACKAGE_JSON}" "${property}") if(error MATCHES "not found") @@ -875,7 +883,7 @@ function(register_compiler_flags) if(NOT COMPILER_TARGETS) add_compile_options($<$:${flag}>) endif() - + foreach(target ${COMPILER_TARGETS}) get_target_property(type ${target} TYPE) if(type MATCHES "EXECUTABLE|LIBRARY") @@ -887,7 +895,7 @@ function(register_compiler_flags) endfunction() function(register_compiler_definitions) - + endfunction() # register_linker_flags() diff --git a/cmake/targets/BuildBun.cmake b/cmake/targets/BuildBun.cmake index c247d1e16c..c62888ff82 100644 --- a/cmake/targets/BuildBun.cmake +++ b/cmake/targets/BuildBun.cmake @@ -686,6 +686,14 @@ target_include_directories(${bun} PRIVATE ${NODEJS_HEADERS_PATH}/include ) +if(LINUX) + include(CheckIncludeFiles) + check_include_files("sys/queue.h" HAVE_SYS_QUEUE_H) + if(NOT HAVE_SYS_QUEUE_H) + target_include_directories(${bun} PRIVATE vendor/lshpack/compat/queue) + endif() +endif() + # --- C/C++ Definitions --- if(ENABLE_ASSERTIONS) @@ -746,6 +754,29 @@ if(NOT WIN32) -faddrsig ) if(DEBUG) + # TODO: this shouldn't be necessary long term + if (NOT IS_MUSL) + set(ABI_PUBLIC_FLAGS + -fsanitize=null + -fsanitize-recover=all + -fsanitize=bounds + -fsanitize=return + -fsanitize=nullability-arg + -fsanitize=nullability-assign + -fsanitize=nullability-return + -fsanitize=returns-nonnull-attribute + -fsanitize=unreachable + ) + set(ABI_PRIVATE_FLAGS + -fsanitize=null + ) + else() + set(ABI_PUBLIC_FLAGS + ) + set(ABI_PRIVATE_FLAGS + ) + endif() + target_compile_options(${bun} PUBLIC -Werror=return-type -Werror=return-stack-address @@ -761,17 +792,11 @@ if(NOT WIN32) -Wno-unused-function -Wno-nullability-completeness -Werror - -fsanitize=null - -fsanitize-recover=all - -fsanitize=bounds - -fsanitize=return - -fsanitize=nullability-arg - -fsanitize=nullability-assign - -fsanitize=nullability-return - -fsanitize=returns-nonnull-attribute - -fsanitize=unreachable + ${ABI_PUBLIC_FLAGS} + ) + target_link_libraries(${bun} PRIVATE + ${ABI_PRIVATE_FLAGS} ) - target_link_libraries(${bun} PRIVATE -fsanitize=null) else() # Leave -Werror=unused off in release builds so we avoid errors from being used in ASSERT target_compile_options(${bun} PUBLIC ${LTO_FLAG} @@ -816,7 +841,7 @@ if(WIN32) ) endif() elseif(APPLE) - target_link_options(${bun} PUBLIC + target_link_options(${bun} PUBLIC -dead_strip -dead_strip_dylibs -Wl,-stack_size,0x1200000 @@ -872,6 +897,29 @@ else() ) endif() + if (NOT IS_MUSL) + set(ABI_WRAP_FLAGS + -Wl,--wrap=cosf + -Wl,--wrap=exp + -Wl,--wrap=expf + -Wl,--wrap=fmod + -Wl,--wrap=fmodf + -Wl,--wrap=log + -Wl,--wrap=log10f + -Wl,--wrap=log2 + -Wl,--wrap=log2f + -Wl,--wrap=logf + -Wl,--wrap=pow + -Wl,--wrap=powf + -Wl,--wrap=sincosf + -Wl,--wrap=sinf + -Wl,--wrap=tanf + ) + else() + set(ABI_WRAP_FLAGS + ) + endif() + target_link_options(${bun} PUBLIC -fuse-ld=${LLD_NAME} -fno-pic @@ -883,21 +931,7 @@ else() -Wl,--gc-sections -Wl,-z,stack-size=12800000 ${ARCH_WRAP_FLAGS} - -Wl,--wrap=cosf - -Wl,--wrap=exp - -Wl,--wrap=expf - -Wl,--wrap=fmod - -Wl,--wrap=fmodf - -Wl,--wrap=log - -Wl,--wrap=log10f - -Wl,--wrap=log2 - -Wl,--wrap=log2f - -Wl,--wrap=logf - -Wl,--wrap=pow - -Wl,--wrap=powf - -Wl,--wrap=sincosf - -Wl,--wrap=sinf - -Wl,--wrap=tanf + ${ABI_WRAP_FLAGS} -Wl,--compress-debug-sections=zlib -Wl,-z,lazy -Wl,-z,norelro diff --git a/cmake/tools/SetupLLVM.cmake b/cmake/tools/SetupLLVM.cmake index 53d74cacc9..a7046d996f 100644 --- a/cmake/tools/SetupLLVM.cmake +++ b/cmake/tools/SetupLLVM.cmake @@ -4,7 +4,7 @@ if(NOT ENABLE_LLVM) return() endif() -if(CMAKE_HOST_WIN32 OR CMAKE_HOST_APPLE) +if(CMAKE_HOST_WIN32 OR CMAKE_HOST_APPLE OR IS_MUSL) set(DEFAULT_LLVM_VERSION "18.1.8") else() set(DEFAULT_LLVM_VERSION "16.0.6") diff --git a/cmake/tools/SetupWebKit.cmake b/cmake/tools/SetupWebKit.cmake index 6767ccdabc..54188ec973 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 9b84f43643eff64ab46daec9b860de262c80f5e2) + set(WEBKIT_VERSION 4f92f334956b250a6bc4ecc1529945bacd22d96c) endif() if(WEBKIT_LOCAL) @@ -63,12 +63,16 @@ else() message(FATAL_ERROR "Unsupported architecture: ${CMAKE_SYSTEM_PROCESSOR}") endif() +if(IS_MUSL) + set(WEBKIT_SUFFIX "-musl") +endif() + if(DEBUG) - set(WEBKIT_SUFFIX "-debug") + set(WEBKIT_SUFFIX "${WEBKIT_SUFFIX}-debug") elseif(ENABLE_LTO AND NOT WIN32) - set(WEBKIT_SUFFIX "-lto") + set(WEBKIT_SUFFIX "${WEBKIT_SUFFIX}-lto") else() - set(WEBKIT_SUFFIX "") + set(WEBKIT_SUFFIX "${WEBKIT_SUFFIX}") endif() set(WEBKIT_NAME bun-webkit-${WEBKIT_OS}-${WEBKIT_ARCH}${WEBKIT_SUFFIX}) diff --git a/cmake/tools/SetupZig.cmake b/cmake/tools/SetupZig.cmake index e679423861..d34c4b53ff 100644 --- a/cmake/tools/SetupZig.cmake +++ b/cmake/tools/SetupZig.cmake @@ -11,7 +11,11 @@ if(APPLE) elseif(WIN32) set(DEFAULT_ZIG_TARGET ${DEFAULT_ZIG_ARCH}-windows-msvc) elseif(LINUX) - set(DEFAULT_ZIG_TARGET ${DEFAULT_ZIG_ARCH}-linux-gnu) + if(IS_MUSL) + set(DEFAULT_ZIG_TARGET ${DEFAULT_ZIG_ARCH}-linux-musl) + else() + set(DEFAULT_ZIG_TARGET ${DEFAULT_ZIG_ARCH}-linux-gnu) + endif() else() unsupported(CMAKE_SYSTEM_NAME) endif() diff --git a/scripts/bootstrap.sh b/scripts/bootstrap.sh index f809e4d734..fabc9fc1e7 100755 --- a/scripts/bootstrap.sh +++ b/scripts/bootstrap.sh @@ -170,6 +170,12 @@ check_system() { fi if [ -n "$VERSION_ID" ]; then release="$VERSION_ID" + + if [ "$distro" = "alpine" ]; then + if [ "$(echo $release | grep -c '_')" = "1" ]; then + release="edge" + fi + fi fi fi @@ -195,20 +201,28 @@ check_system() { apt="$(which apt-get)" if [ -f "$apt" ]; then pm="apt" + else dnf="$(which dnf)" if [ -f "$dnf" ]; then pm="dnf" + else yum="$(which yum)" if [ -f "$yum" ]; then pm="yum" + + else + apk="$(which apk)" + if [ -f "$apk" ]; then + pm="apk" + fi fi fi fi if [ -z "$pm" ]; then - error "No package manager found. (apt, dnf, yum)" + error "No package manager found. (apt, dnf, yum, apk)" fi fi @@ -261,18 +275,19 @@ package_manager() { dnf) execute dnf "$@" ;; yum) execute "$yum" "$@" ;; brew) - if ! [ -f "$(which brew)" ]; then + if ! [ -f "$brew" ]; then install_brew fi - execute_non_root brew "$@" + execute_non_root "$brew" "$@" ;; + apk) execute "$apk" "$@" ;; *) error "Unsupported package manager: $pm" ;; esac } update_packages() { case "$pm" in - apt) + apt | apk) package_manager update ;; esac @@ -307,6 +322,9 @@ install_packages() { package_manager install --force --formula "$@" package_manager link --force --overwrite "$@" ;; + apk) + package_manager add "$@" + ;; *) error "Unsupported package manager: $pm" ;; @@ -316,7 +334,7 @@ install_packages() { get_version() { command="$1" path="$(which "$command")" - + if [ -f "$path" ]; then case "$command" in go | zig) "$path" version ;; @@ -403,6 +421,13 @@ install_nodejs() { } install_bun() { + if [ "$os" = "linux" ] && [ "$distro" = "alpine" ] && [ "$arch" = "aarch64" ]; then + mkdir -p "$HOME/.bun/bin" + wget -O "$HOME/.bun/bin/bun" https://pub-61e0d0e2da4146a099e4545a59a9f0f7.r2.dev/bun-musl-arm64 + chmod +x "$HOME/.bun/bin/bun" + append_to_path "$HOME/.bun/bin" + return + fi bash="$(require bash)" script=$(download_file "https://bun.sh/install") @@ -433,30 +458,27 @@ install_rosetta() { install_build_essentials() { case "$pm" in - apt) install_packages \ - build-essential \ - ninja-build \ - xz-utils + apt) + install_packages build-essential ninja-build xz-utils pkg-config golang ;; - dnf | yum) install_packages \ - ninja-build \ - gcc-c++ \ - xz + dnf | yum) + install_packages ninja-build gcc-c++ xz pkg-config golang ;; - brew) install_packages \ - ninja + brew) + install_packages ninja pkg-config golang + ;; + apk) + install_packages ninja xz ;; esac install_packages \ make \ cmake \ - pkg-config \ python3 \ libtool \ ruby \ - perl \ - golang + perl install_llvm install_ccache @@ -465,6 +487,10 @@ install_build_essentials() { } llvm_version_exact() { + if [ "$os" = "linux" ] && [ "$distro" = "alpine" ]; then + print "18.1.8" + return + fi case "$os" in linux) print "16.0.6" @@ -488,6 +514,9 @@ install_llvm() { ;; brew) install_packages "llvm@$(llvm_version)" + ;; + apk) + install_packages "llvm$(llvm_version)-dev" "clang$(llvm_version)-dev" "lld$(llvm_version)-dev" ;; esac } @@ -501,6 +530,10 @@ install_ccache() { } install_rust() { + if [ "$os" = "linux" ] && [ "$distro" = "alpine" ]; then + install_packages rust + return + fi sh="$(require sh)" script=$(download_file "https://sh.rustup.rs") execute "$sh" "$script" -y @@ -699,6 +732,9 @@ install_chrome_dependencies() { xorg-x11-fonts-Type1 \ xorg-x11-utils ;; + apk) + echo # TODO: + ;; esac } diff --git a/src/bun.js/bindings/BunProcess.cpp b/src/bun.js/bindings/BunProcess.cpp index ce076e0fe5..d204592e49 100644 --- a/src/bun.js/bindings/BunProcess.cpp +++ b/src/bun.js/bindings/BunProcess.cpp @@ -58,8 +58,11 @@ typedef int mode_t; #include "ProcessBindingNatives.h" #if OS(LINUX) +#include +#ifdef __GNU_LIBRARY__ #include #endif +#endif #pragma mark - Node.js Process @@ -1573,8 +1576,11 @@ static JSValue constructReportObjectComplete(VM& vm, Zig::GlobalObject* globalOb } #if OS(LINUX) +#ifdef __GNU_LIBRARY__ header->putDirect(vm, JSC::Identifier::fromString(vm, "glibcVersionCompiler"_s), JSC::jsString(vm, makeString(__GLIBC__, '.', __GLIBC_MINOR__)), 0); header->putDirect(vm, JSC::Identifier::fromString(vm, "glibcVersionRuntime"_s), JSC::jsString(vm, String::fromUTF8(gnu_get_libc_version()), 0)); +#else +#endif #endif header->putDirect(vm, Identifier::fromString(vm, "cpus"_s), JSC::constructEmptyArray(globalObject, nullptr), 0); diff --git a/src/bun.js/bindings/bun-spawn.cpp b/src/bun.js/bindings/bun-spawn.cpp index a9aa921dc1..4a81d79850 100644 --- a/src/bun.js/bindings/bun-spawn.cpp +++ b/src/bun.js/bindings/bun-spawn.cpp @@ -8,8 +8,8 @@ #include #include #include -#include -#include +#include +#include #include #include diff --git a/src/bun.js/bindings/c-bindings.cpp b/src/bun.js/bindings/c-bindings.cpp index c0fbebfbdd..0d229cc0df 100644 --- a/src/bun.js/bindings/c-bindings.cpp +++ b/src/bun.js/bindings/c-bindings.cpp @@ -4,15 +4,15 @@ #if !OS(WINDOWS) #include -#include +#include #include -#include +#include #include #include #include #include #include -#include +#include #include #include #else diff --git a/src/bun.js/bindings/workaround-missing-symbols.cpp b/src/bun.js/bindings/workaround-missing-symbols.cpp index f53174c4f8..b09a388efb 100644 --- a/src/bun.js/bindings/workaround-missing-symbols.cpp +++ b/src/bun.js/bindings/workaround-missing-symbols.cpp @@ -53,6 +53,8 @@ extern "C" int kill(int pid, int sig) // if linux #if defined(__linux__) +#include +#ifdef __GNU_LIBRARY__ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -298,21 +300,24 @@ extern "C" int __wrap_fstatat64(int dirfd, const char* path, struct stat64* stat return __fxstatat64(_STAT_VER, dirfd, path, stat, flags); } -extern "C" int __xmknod(int ver, const char* path, __mode_t mode, __dev_t dev); -extern "C" int __wrap_mknod(const char* path, __mode_t mode, __dev_t dev) +extern "C" int __xmknod(int ver, const char* path, mode_t mode, dev_t dev); +extern "C" int __wrap_mknod(const char* path, mode_t mode, dev_t dev) { return __xmknod(_MKNOD_VER, path, mode, dev); } -extern "C" int __xmknodat(int ver, int dirfd, const char* path, __mode_t mode, __dev_t dev); -extern "C" int __wrap_mknodat(int dirfd, const char* path, __mode_t mode, __dev_t dev) +extern "C" int __xmknodat(int ver, int dirfd, const char* path, mode_t mode, dev_t dev); +extern "C" int __wrap_mknodat(int dirfd, const char* path, mode_t mode, dev_t dev) { return __xmknodat(_MKNOD_VER, dirfd, path, mode, dev); } #endif -double __wrap_exp(double x) { return exp(x); } +double __wrap_exp(double x) +{ + return exp(x); +} double __wrap_fmod(double x, double y) { return fmod(x, y); } double __wrap_log(double x) { return log(x); } double __wrap_log2(double x) { return log2(x); } @@ -340,7 +345,11 @@ extern "C" int __wrap_statx(int fd, const char* path, int flags, return -1; } -#endif +#endif // glibc + +// musl + +#endif // linux // macOS #if defined(__APPLE__) diff --git a/src/c.zig b/src/c.zig index ff9226a660..1579667ab9 100644 --- a/src/c.zig +++ b/src/c.zig @@ -31,12 +31,6 @@ pub extern "c" fn fchmodat(c_int, [*c]const u8, mode_t, c_int) c_int; pub extern "c" fn fchown(std.c.fd_t, std.c.uid_t, std.c.gid_t) c_int; pub extern "c" fn lchown(path: [*:0]const u8, std.c.uid_t, std.c.gid_t) c_int; pub extern "c" fn chown(path: [*:0]const u8, std.c.uid_t, std.c.gid_t) c_int; -// TODO: this is wrong on Windows -pub extern "c" fn lstat64([*c]const u8, [*c]libc_stat) c_int; -// TODO: this is wrong on Windows -pub extern "c" fn fstat64([*c]const u8, [*c]libc_stat) c_int; -// TODO: this is wrong on Windows -pub extern "c" fn stat64([*c]const u8, [*c]libc_stat) c_int; pub extern "c" fn lchmod(path: [*:0]const u8, mode: mode_t) c_int; pub extern "c" fn truncate([*:0]const u8, i64) c_int; // note: truncate64 is not a thing @@ -46,19 +40,31 @@ pub extern "c" fn mkdtemp(template: [*c]u8) ?[*:0]u8; pub extern "c" fn memcmp(s1: [*c]const u8, s2: [*c]const u8, n: usize) c_int; pub extern "c" fn memchr(s: [*]const u8, c: u8, n: usize) ?[*]const u8; -pub const lstat = lstat64; -pub const fstat = fstat64; -pub const stat = stat64; - pub extern "c" fn strchr(str: [*]const u8, char: u8) ?[*]const u8; +pub const lstat = blk: { + const T = *const fn ([*c]const u8, [*c]libc_stat) callconv(.C) c_int; // TODO: this is wrong on Windows + if (bun.Environment.isMusl) break :blk @extern(T, .{ .library_name = "c", .name = "lstat" }); + break :blk @extern(T, .{ .name = "lstat64" }); +}; +pub const fstat = blk: { + const T = *const fn (c_int, [*c]libc_stat) callconv(.C) c_int; // TODO: this is wrong on Windows + if (bun.Environment.isMusl) break :blk @extern(T, .{ .library_name = "c", .name = "fstat" }); + break :blk @extern(T, .{ .name = "fstat64" }); +}; +pub const stat = blk: { + const T = *const fn ([*c]const u8, [*c]libc_stat) callconv(.C) c_int; // TODO: this is wrong on Windows + if (bun.Environment.isMusl) break :blk @extern(T, .{ .library_name = "c", .name = "stat" }); + break :blk @extern(T, .{ .name = "stat64" }); +}; + pub fn lstat_absolute(path: [:0]const u8) !Stat { if (builtin.os.tag == .windows) { @compileError("Not implemented yet, conside using bun.sys.lstat()"); } var st = zeroes(libc_stat); - switch (errno(lstat64(path.ptr, &st))) { + switch (errno(lstat(path.ptr, &st))) { .SUCCESS => {}, .NOENT => return error.FileNotFound, // .EINVAL => unreachable, diff --git a/src/crash_handler.zig b/src/crash_handler.zig index 4f806ab6dc..34ba5eb182 100644 --- a/src/crash_handler.zig +++ b/src/crash_handler.zig @@ -840,8 +840,7 @@ pub fn printMetadata(writer: anytype) !void { { const platform = bun.Analytics.GenerateHeader.GeneratePlatform.forOS(); const cpu_features = CPUFeatures.get(); - if (bun.Environment.isLinux) { - // TODO: musl + if (bun.Environment.isLinux and !bun.Environment.isMusl) { const version = gnu_get_libc_version() orelse ""; const kernel_version = bun.Analytics.GenerateHeader.GeneratePlatform.kernelVersion(); if (platform.os == .wsl) { @@ -849,6 +848,9 @@ pub fn printMetadata(writer: anytype) !void { } else { try writer.print("Linux Kernel v{d}.{d}.{d} | glibc v{s}\n", .{ kernel_version.major, kernel_version.minor, kernel_version.patch, bun.sliceTo(version, 0) }); } + } else if (bun.Environment.isLinux and bun.Environment.isMusl) { + const kernel_version = bun.Analytics.GenerateHeader.GeneratePlatform.kernelVersion(); + try writer.print("Linux Kernel v{d}.{d}.{d} | musl\n", .{ kernel_version.major, kernel_version.minor, kernel_version.patch }); } else if (bun.Environment.isMac) { try writer.print("macOS v{s}\n", .{platform.version}); } else if (bun.Environment.isWindows) { diff --git a/src/env.zig b/src/env.zig index 3ced38ab31..bbc36aba6f 100644 --- a/src/env.zig +++ b/src/env.zig @@ -25,6 +25,7 @@ pub const isLinux = @import("builtin").target.os.tag == .linux; pub const isAarch64 = @import("builtin").target.cpu.arch.isAARCH64(); pub const isX86 = @import("builtin").target.cpu.arch.isX86(); pub const isX64 = @import("builtin").target.cpu.arch == .x86_64; +pub const isMusl = builtin.target.abi.isMusl(); pub const allow_assert = isDebug or isTest or std.builtin.Mode.ReleaseSafe == @import("builtin").mode; pub const build_options = @import("build_options"); diff --git a/src/sys.zig b/src/sys.zig index e2ea08f83a..e6d9eec837 100644 --- a/src/sys.zig +++ b/src/sys.zig @@ -594,7 +594,7 @@ pub fn lstat(path: [:0]const u8) Maybe(bun.Stat) { return sys_uv.lstat(path); } else { var stat_ = mem.zeroes(bun.Stat); - if (Maybe(bun.Stat).errnoSys(C.lstat64(path, &stat_), .lstat)) |err| return err; + if (Maybe(bun.Stat).errnoSys(C.lstat(path, &stat_), .lstat)) |err| return err; return Maybe(bun.Stat){ .result = stat_ }; } } @@ -1579,7 +1579,7 @@ else if (builtin.os.tag.isDarwin()) else system.writev; -const pread_sym = if (builtin.os.tag == .linux and builtin.link_libc) +const pread_sym = if (builtin.os.tag == .linux and builtin.link_libc and !bun.Environment.isMusl) sys.pread64 else if (builtin.os.tag.isDarwin()) system.@"pread$NOCANCEL" @@ -1608,7 +1608,7 @@ pub fn pread(fd: bun.FileDescriptor, buf: []u8, offset: i64) Maybe(usize) { } } -const pwrite_sym = if (builtin.os.tag == .linux and builtin.link_libc) +const pwrite_sym = if (builtin.os.tag == .linux and builtin.link_libc and !bun.Environment.isMusl) sys.pwrite64 else sys.pwrite;