Compare commits

...

15 Commits

Author SHA1 Message Date
Ashcon Partovi
237a15851b Changes [no ci] 2024-12-11 18:48:10 -08:00
Ashcon Partovi
387800fe70 Changes [no ci] 2024-12-11 16:36:17 -08:00
Ashcon Partovi
d109a9eabe Changes [no ci] 2024-12-11 15:14:21 -08:00
Ashcon Partovi
83f430482c Changes [no ci] 2024-12-11 14:55:59 -08:00
Ashcon Partovi
b7959cc1e2 Changes [no ci] 2024-12-11 14:45:20 -08:00
Ashcon Partovi
ef092602c1 Changes [no ci] 2024-12-11 12:49:26 -08:00
Ashcon Partovi
38d55fface Changes [no ci] 2024-12-11 11:49:32 -08:00
Ashcon Partovi
06f9ea853e Changes [no ci] 2024-12-11 11:23:44 -08:00
Ashcon Partovi
da9e842014 Changes [no ci] 2024-12-11 11:08:02 -08:00
Ashcon Partovi
0f9f993d5e aarch64 [no ci] 2024-12-11 10:54:40 -08:00
Ashcon Partovi
1b9041d1ab Bump macos sdk [no ci] 2024-12-10 19:46:05 -08:00
Ashcon Partovi
23afa08cb0 Bump macos sdk [no ci] 2024-12-10 19:16:06 -08:00
Ashcon Partovi
90beb5350d Add toolchain 2024-12-10 18:57:09 -08:00
Ashcon Partovi
b0dd79e0a7 WIP 2024-12-10 18:42:20 -08:00
Ashcon Partovi
90a60c2c11 WIP 2024-12-10 17:38:11 -08:00
8 changed files with 552 additions and 238 deletions

View File

@@ -140,7 +140,11 @@ const testPlatforms = [
{ os: "linux", arch: "aarch64", abi: "musl", distro: "alpine", release: "3.20", tier: "latest" },
{ os: "linux", arch: "x64", abi: "musl", distro: "alpine", release: "3.20", tier: "latest" },
{ os: "linux", arch: "x64", abi: "musl", baseline: true, distro: "alpine", release: "3.20", tier: "latest" },
{ os: "windows", arch: "x64", release: "2025", tier: "latest" },
{ os: "windows", arch: "x64", release: "2022", tier: "previous" },
{ os: "windows", arch: "x64", release: "2019", tier: "oldest" },
{ os: "windows", arch: "x64", release: "2025", baseline: true, tier: "latest" },
{ os: "windows", arch: "x64", release: "2022", baseline: true, tier: "previous" },
{ os: "windows", arch: "x64", release: "2019", baseline: true, tier: "oldest" },
];
@@ -1050,19 +1054,17 @@ async function getPipeline(options = {}) {
);
}
if (!isMainBranch()) {
const { skipTests, forceTests, unifiedTests, testFiles } = options;
if (!skipTests || forceTests) {
steps.push(
...testPlatforms
.flatMap(platform => buildProfiles.map(profile => ({ ...platform, profile })))
.map(target => ({
key: getTargetKey(target),
group: getTargetLabel(target),
steps: [getTestBunStep(target, { unifiedTests, testFiles, buildId })],
})),
);
}
const { skipTests, forceTests, unifiedTests, testFiles } = options;
if (!skipTests || forceTests) {
steps.push(
...testPlatforms
.flatMap(platform => buildProfiles.map(profile => ({ ...platform, profile })))
.map(target => ({
key: getTargetKey(target),
group: getTargetLabel(target),
steps: [getTestBunStep(target, { unifiedTests, testFiles, buildId })],
})),
);
}
if (isMainBranch()) {

View File

@@ -743,6 +743,10 @@ function(register_cmake_command)
list(APPEND MAKE_EFFECTIVE_ARGS --fresh)
endif()
if(CMAKE_TOOLCHAIN_FILE)
list(APPEND MAKE_EFFECTIVE_ARGS --toolchain=${CMAKE_TOOLCHAIN_FILE})
endif()
register_command(
COMMENT "Configuring ${MAKE_TARGET}"
TARGET configure-${MAKE_TARGET}

View File

@@ -26,11 +26,31 @@ if(RELEASE)
list(APPEND LOLHTML_BUILD_ARGS --release)
endif()
if(CMAKE_CROSSCOMPILING)
if(ARCH STREQUAL "x64")
set(RUST_ARCH x86_64)
elseif(ARCH STREQUAL "arm64")
set(RUST_ARCH aarch64)
else()
unsupported(ARCH)
endif()
if(APPLE)
set(RUST_TARGET ${RUST_ARCH}-apple-darwin)
elseif(LINUX)
set(RUST_TARGET ${RUST_ARCH}-unknown-linux-gnu)
elseif(WIN32)
set(RUST_TARGET ${RUST_ARCH}-pc-windows-msvc)
else()
unsupported(CMAKE_SYSTEM_NAME)
endif()
list(APPEND LOLHTML_BUILD_ARGS --target=${RUST_TARGET})
endif()
# Windows requires unwind tables, apparently.
if (NOT WIN32)
# The encoded escape sequences are intentional. They're how you delimit multiple arguments in a single environment variable.
# Also add rust optimization flag for smaller binary size, but not huge speed penalty.
set(RUSTFLAGS "-Cpanic=abort-Cdebuginfo=0-Cforce-unwind-tables=no-Copt-level=s")
if(NOT WIN32)
set(RUST_FLAGS "-Cpanic=abort -Cdebuginfo=0 -Cforce-unwind-tables=no -Copt-level=s")
endif()
register_command(
@@ -48,12 +68,23 @@ register_command(
CARGO_TERM_COLOR=always
CARGO_TERM_VERBOSE=true
CARGO_TERM_DIAGNOSTIC=true
CARGO_ENCODED_RUSTFLAGS=${RUSTFLAGS}
CARGO_HOME=${CARGO_HOME}
RUSTUP_HOME=${RUSTUP_HOME}
CC=${CMAKE_C_COMPILER}
CFLAGS=${CMAKE_C_FLAGS}
CXX=${CMAKE_CXX_COMPILER}
CXXFLAGS=${CMAKE_CXX_FLAGS}
AR=${CMAKE_AR}
RUSTFLAGS=${RUST_FLAGS}
)
target_link_libraries(${bun} PRIVATE ${LOLHTML_LIBRARY})
if(BUN_LINK_ONLY)
target_sources(${bun} PRIVATE ${LOLHTML_LIBRARY})
endif()
# Notes for OSXCross, which doesn't work yet:
# CFLAGS += --sysroot=${CMAKE_OSX_SYSROOT}
# CXXFLAGS += --sysroot=${CMAKE_OSX_SYSROOT}
# LDFLAGS += -F${CMAKE_OSX_SYSROOT}/System/Library/Frameworks
# RUSTFLAGS += -C linker=${CMAKE_LINKER} -C link-arg=-F${CMAKE_OSX_SYSROOT}/System/Library/Frameworks -C link-arg=-L${CMAKE_OSX_SYSROOT}/usr/lib

View File

@@ -0,0 +1,28 @@
set(CMAKE_SYSTEM_NAME Darwin)
set(CMAKE_SYSTEM_PROCESSOR aarch64)
set(CMAKE_C_COMPILER_WORKS ON)
set(CMAKE_CXX_COMPILER_WORKS ON)
set(OSXCROSS_TARGET_DIR "/opt/osxcross")
set(OSXCROSS_SDK "${OSXCROSS_TARGET_DIR}/SDK/MacOSX14.5.sdk")
set(OSXCROSS_HOST "aarch64-apple-darwin23.5")
set(CMAKE_C_COMPILER "${OSXCROSS_TARGET_DIR}/bin/${OSXCROSS_HOST}-clang" CACHE FILEPATH "clang")
set(CMAKE_CXX_COMPILER "${OSXCROSS_TARGET_DIR}/bin/${OSXCROSS_HOST}-clang++" CACHE FILEPATH "clang++")
set(CMAKE_LINKER "${OSXCROSS_TARGET_DIR}/bin/${OSXCROSS_HOST}-ld" CACHE FILEPATH "ld")
set(CMAKE_AR "${OSXCROSS_TARGET_DIR}/bin/${OSXCROSS_HOST}-ar" CACHE FILEPATH "ar")
set(CMAKE_STRIP "${OSXCROSS_TARGET_DIR}/bin/${OSXCROSS_HOST}-strip" CACHE FILEPATH "strip")
set(CMAKE_RANLIB "${OSXCROSS_TARGET_DIR}/bin/${OSXCROSS_HOST}-ranlib" CACHE FILEPATH "ranlib")
set(CMAKE_NM "${OSXCROSS_TARGET_DIR}/bin/${OSXCROSS_HOST}-nm" CACHE FILEPATH "nm")
set(CMAKE_DSYMUTIL "${OSXCROSS_TARGET_DIR}/bin/${OSXCROSS_HOST}-dsymutil" CACHE FILEPATH "dsymutil")
set(CMAKE_INSTALL_NAME_TOOL "${OSXCROSS_TARGET_DIR}/bin/${OSXCROSS_HOST}-install_name_tool" CACHE FILEPATH "install_name_tool")
set(CMAKE_FIND_ROOT_PATH "${CMAKE_FIND_ROOT_PATH}" "${OSXCROSS_SDK}" "${OSXCROSS_TARGET_DIR}/macports/pkgs/opt/local")
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
set(ENV{PKG_CONFIG_LIBDIR} "${OSXCROSS_TARGET_DIR}/macports/pkgs/opt/local/lib/pkgconfig")
set(ENV{PKG_CONFIG_SYSROOT_DIR} "${OSXCROSS_TARGET_DIR}/macports/pkgs")

View File

@@ -0,0 +1,37 @@
set(CMAKE_SYSTEM_NAME Darwin)
set(CMAKE_SYSTEM_PROCESSOR x64)
set(CMAKE_OSX_ARCHITECTURES x86_64)
set(CMAKE_OSX_SDK_VERSION 14.5)
set(CMAKE_OSX_KERNEL_VERSION 23.5)
set(CMAKE_OSX_DEPLOYMENT_TARGET 13.0)
set(CMAKE_C_COMPILER_WORKS ON)
set(CMAKE_CXX_COMPILER_WORKS ON)
set(OSXCROSS_TARGET_DIR "/opt/osxcross")
set(OSXCROSS_SDK "${OSXCROSS_TARGET_DIR}/SDK/MacOSX${CMAKE_OSX_SDK_VERSION}.sdk")
set(OSXCROSS_HOST "x86_64-apple-darwin${CMAKE_OSX_KERNEL_VERSION}")
set(CMAKE_C_COMPILER "${OSXCROSS_TARGET_DIR}/bin/${OSXCROSS_HOST}-clang" CACHE FILEPATH "clang")
set(CMAKE_CXX_COMPILER "${OSXCROSS_TARGET_DIR}/bin/${OSXCROSS_HOST}-clang++" CACHE FILEPATH "clang++")
set(CMAKE_LINKER "${OSXCROSS_TARGET_DIR}/bin/${OSXCROSS_HOST}-ld" CACHE FILEPATH "ld")
set(CMAKE_AR "${OSXCROSS_TARGET_DIR}/bin/${OSXCROSS_HOST}-ar" CACHE FILEPATH "ar")
set(CMAKE_STRIP "${OSXCROSS_TARGET_DIR}/bin/${OSXCROSS_HOST}-strip" CACHE FILEPATH "strip")
set(CMAKE_RANLIB "${OSXCROSS_TARGET_DIR}/bin/${OSXCROSS_HOST}-ranlib" CACHE FILEPATH "ranlib")
set(CMAKE_NM "${OSXCROSS_TARGET_DIR}/bin/${OSXCROSS_HOST}-nm" CACHE FILEPATH "nm")
set(CMAKE_DSYMUTIL "${OSXCROSS_TARGET_DIR}/bin/${OSXCROSS_HOST}-dsymutil" CACHE FILEPATH "dsymutil")
set(CMAKE_INSTALL_NAME_TOOL "${OSXCROSS_TARGET_DIR}/bin/${OSXCROSS_HOST}-install_name_tool" CACHE FILEPATH "install_name_tool")
set(CMAKE_SYSROOT "${OSXCROSS_SDK}")
set(CMAKE_OSX_SYSROOT "${OSXCROSS_SDK}")
set(CMAKE_FIND_ROOT_PATH "${CMAKE_FIND_ROOT_PATH}" "${OSXCROSS_SDK}" "${OSXCROSS_TARGET_DIR}/macports/pkgs/opt/local")
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
# This fixes an issue where pthreads is not found with c-ares
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
set(ENV{PKG_CONFIG_LIBDIR} "${OSXCROSS_TARGET_DIR}/macports/pkgs/opt/local/lib/pkgconfig")
set(ENV{PKG_CONFIG_SYSROOT_DIR} "${OSXCROSS_TARGET_DIR}/macports/pkgs")

View File

@@ -29,7 +29,6 @@ endif()
if(CMAKE_C_COMPILER_ID MATCHES "GNU")
add_compile_options(
-fheinous-gnu-extensions
-Wno-string-plus-int
-Wno-deprecated-declarations
)
@@ -57,81 +56,100 @@ if(WIN32)
)
endif()
file(READ ${CMAKE_CURRENT_SOURCE_DIR}/VERSION TCC_VERSION)
option(BUILD_C2STR "Build the c2str utility" ON)
option(BUILD_TCC "Build the tcc compiler" ON)
add_compile_definitions(TCC_VERSION=\"${TCC_VERSION}\")
if(BUILD_C2STR)
if(CMAKE_CROSSCOMPILING)
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/c2str)
add_custom_target(c2str.exe
COMMAND
${CMAKE_COMMAND}
-S ${CMAKE_CURRENT_SOURCE_DIR}
-B ${CMAKE_CURRENT_BINARY_DIR}/c2str
-G${CMAKE_GENERATOR}
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
-DBUILD_TCC=OFF
COMMAND
${CMAKE_COMMAND}
--build ${CMAKE_CURRENT_BINARY_DIR}/c2str
--target c2str.exe
WORKING_DIRECTORY
${CMAKE_CURRENT_BINARY_DIR}/c2str
)
else()
add_executable(c2str.exe conftest.c)
target_compile_options(c2str.exe PRIVATE -DC2STR)
execute_process(
COMMAND git rev-parse --short HEAD
OUTPUT_VARIABLE TCC_GITHASH
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
)
if(TCC_GITHASH)
add_compile_definitions(TCC_GITHASH=\"${TCC_GITHASH}\")
add_custom_command(
TARGET
c2str.exe POST_BUILD
COMMAND
c2str.exe include/tccdefs.h tccdefs_.h
WORKING_DIRECTORY
${CMAKE_CURRENT_SOURCE_DIR}
)
endif()
endif()
set(TCC_SOURCES
libtcc.c
tccpp.c
tccgen.c
tccdbg.c
tccelf.c
tccasm.c
tccrun.c
)
if(BUILD_TCC)
file(READ ${CMAKE_CURRENT_SOURCE_DIR}/VERSION TCC_VERSION)
if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm64|aarch64|ARM64")
list(APPEND TCC_SOURCES
arm64-gen.c
arm64-link.c
arm64-asm.c
add_compile_definitions(TCC_VERSION=\"${TCC_VERSION}\")
execute_process(
COMMAND git rev-parse --short HEAD
OUTPUT_VARIABLE TCC_GITHASH
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|x64|amd64|AMD64")
list(APPEND TCC_SOURCES
x86_64-gen.c
x86_64-link.c
i386-asm.c
if(TCC_GITHASH)
add_compile_definitions(TCC_GITHASH=\"${TCC_GITHASH}\")
endif()
set(TCC_SOURCES
libtcc.c
tccpp.c
tccgen.c
tccdbg.c
tccelf.c
tccasm.c
tccrun.c
)
else()
message(FATAL_ERROR "Unsupported architecture: ${CMAKE_SYSTEM_PROCESSOR}")
endif()
if(APPLE)
list(APPEND TCC_SOURCES tccmacho.c)
endif()
if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm64|aarch64|ARM64")
list(APPEND TCC_SOURCES
arm64-gen.c
arm64-link.c
arm64-asm.c
)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|x64|amd64|AMD64")
list(APPEND TCC_SOURCES
x86_64-gen.c
x86_64-link.c
i386-asm.c
)
else()
message(FATAL_ERROR "Unsupported architecture: ${CMAKE_SYSTEM_PROCESSOR}")
endif()
if(WIN32)
list(APPEND TCC_SOURCES tccpe.c)
endif()
if(APPLE)
list(APPEND TCC_SOURCES tccmacho.c)
endif()
add_executable(c2str.exe conftest.c)
target_compile_options(c2str.exe PRIVATE -DC2STR)
if(WIN32)
list(APPEND TCC_SOURCES tccpe.c)
endif()
add_custom_command(
TARGET
c2str.exe POST_BUILD
COMMAND
c2str.exe include/tccdefs.h tccdefs_.h
WORKING_DIRECTORY
add_library(tcc STATIC ${TCC_SOURCES})
if(BUILD_C2STR)
add_dependencies(tcc c2str.exe)
endif()
target_include_directories(tcc PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
)
add_library(tcc STATIC ${TCC_SOURCES})
add_custom_command(
TARGET
tcc PRE_BUILD
COMMAND
${CMAKE_COMMAND} -E touch config.h
WORKING_DIRECTORY
${CMAKE_CURRENT_SOURCE_DIR}
)
add_dependencies(tcc c2str.exe)
target_include_directories(tcc PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/include
)
${CMAKE_CURRENT_SOURCE_DIR}/include
)
endif()

View File

@@ -1,5 +1,5 @@
#!/bin/sh
# Version: 7
# Version: 9
# A script that installs the dependencies needed to build and test Bun.
# This should work on macOS and Linux with a POSIX shell.
@@ -11,15 +11,17 @@
# increment the version comment to indicate that a new image should be built.
# Otherwise, the existing image will be retroactively updated.
pid=$$
pid="$$"
print() {
echo "$@"
}
error() {
echo "error: $@" >&2
kill -s TERM "$pid"
print "error: $@" >&2
if ! [ "$$" = "$pid" ]; then
kill -s TERM "$pid"
fi
exit 1
}
@@ -39,24 +41,44 @@ execute_sudo() {
}
execute_as_user() {
sh="$(require sh)"
if [ "$sudo" = "1" ] || [ "$can_sudo" = "1" ]; then
if [ -f "$(which sudo)" ]; then
execute sudo -n -u "$user" /bin/sh -c "$*"
execute sudo -n -u "$user" "$sh" -c "$*"
elif [ -f "$(which doas)" ]; then
execute doas -u "$user" /bin/sh -c "$*"
execute doas -u "$user" "$sh" -c "$*"
elif [ -f "$(which su)" ]; then
execute su -s /bin/sh "$user" -c "$*"
execute su -s "$sh" "$user" -c "$*"
else
execute /bin/sh -c "$*"
execute "$sh" -c "$*"
fi
else
execute /bin/sh -c "$*"
execute "$sh" -c "$*"
fi
}
grant_to_user() {
path="$1"
execute_sudo chown -R "$user:$group" "$path"
if ! [ -f "$path" ] && ! [ -d "$path" ]; then
error "Could not find file or directory: \"$path\""
fi
chown="$(require chown)"
execute_sudo "$chown" -R "$user:$group" "$path"
if ! [ "$user" = "$current_user" ] || ! [ "$group" = "$current_group" ]; then
execute_sudo "$chown" -R "$current_user:$current_group" "$path"
fi
}
grant_to_everyone() {
path="$1"
if ! [ -f "$path" ] && ! [ -d "$path" ]; then
error "Could not find file or directory: \"$path\""
fi
chmod="$(require chmod)"
execute_sudo "$chmod" 777 "$path"
}
which() {
@@ -68,15 +90,15 @@ require() {
if ! [ -f "$path" ]; then
error "Command \"$1\" is required, but is not installed."
fi
echo "$path"
print "$path"
}
fetch() {
curl=$(which curl)
curl="$(which curl)"
if [ -f "$curl" ]; then
execute "$curl" -fsSL "$1"
else
wget=$(which wget)
wget="$(which wget)"
if [ -f "$wget" ]; then
execute "$wget" -qO- "$1"
else
@@ -85,78 +107,115 @@ fetch() {
fi
}
download_file() {
url="$1"
filename="${2:-$(basename "$url")}"
tmp="$(execute mktemp -d)"
execute chmod 755 "$tmp"
compare_version() {
if [ "$1" = "$2" ]; then
print "0"
elif [ "$1" = "$(echo -e "$1\n$2" | sort -V | head -n1)" ]; then
print "-1"
else
print "1"
fi
}
path="$tmp/$filename"
fetch "$url" >"$path"
execute chmod 644 "$path"
create_directory() {
path="$1"
path_dir="$path"
while ! [ -d "$path_dir" ]; do
path_dir="$(dirname "$path_dir")"
done
path_needs_sudo="0"
if ! [ -r "$path_dir" ] || ! [ -w "$path_dir" ]; then
path_needs_sudo="1"
fi
mkdir="$(require mkdir)"
if [ "$path_needs_sudo" = "1" ]; then
execute_sudo "$mkdir" -p "$path"
else
execute "$mkdir" -p "$path"
fi
grant_to_user "$path"
}
create_tmp_directory() {
mktemp="$(require mktemp)"
path="$(execute "$mktemp" -d)"
grant_to_everyone "$path"
print "$path"
}
compare_version() {
if [ "$1" = "$2" ]; then
echo "0"
elif [ "$1" = "$(echo -e "$1\n$2" | sort -V | head -n1)" ]; then
echo "-1"
else
echo "1"
create_file() {
path="$1"
path_dir="$(dirname "$path")"
if ! [ -d "$path_dir" ]; then
create_directory "$path_dir"
fi
path_needs_sudo="0"
if ! [ -r "$path" ] || ! [ -w "$path" ]; then
path_needs_sudo="1"
fi
if [ "$path_needs_sudo" = "1" ]; then
execute_sudo touch "$path"
else
execute touch "$path"
fi
content="$2"
if [ -n "$content" ]; then
append_file "$path" "$content"
fi
grant_to_user "$path"
}
append_to_file() {
file="$1"
content="$2"
file_needs_sudo="0"
if [ -f "$file" ]; then
if ! [ -r "$file" ] || ! [ -w "$file" ]; then
file_needs_sudo="1"
fi
else
execute_as_user mkdir -p "$(dirname "$file")"
execute_as_user touch "$file"
append_file() {
path="$1"
if ! [ -f "$path" ]; then
create_file "$path"
fi
echo "$content" | while read -r line; do
if ! grep -q "$line" "$file"; then
if [ "$file_needs_sudo" = "1" ]; then
execute_sudo sh -c "echo '$line' >> '$file'"
path_needs_sudo="0"
if ! [ -r "$path" ] || ! [ -w "$path" ]; then
path_needs_sudo="1"
fi
content="$2"
print "$content" | while read -r line; do
if ! grep -q "$line" "$path"; then
sh="$(require sh)"
if [ "$path_needs_sudo" = "1" ]; then
execute_sudo "$sh" -c "echo '$line' >> '$path'"
else
echo "$line" >>"$file"
execute "$sh" -c "echo '$line' >> '$path'"
fi
fi
done
}
append_to_file_sudo() {
file="$1"
content="$2"
download_file() {
file_url="$1"
file_tmp_dir="$(create_tmp_directory)"
file_tmp_path="$file_tmp_dir/$(basename "$file_url")"
if ! [ -f "$file" ]; then
execute_sudo mkdir -p "$(dirname "$file")"
execute_sudo touch "$file"
fi
echo "$content" | while read -r line; do
if ! grep -q "$line" "$file"; then
echo "$line" | execute_sudo tee "$file" >/dev/null
fi
done
fetch "$file_url" >"$file_tmp_path"
grant_to_everyone "$file_tmp_path"
print "$file_tmp_path"
}
append_to_profile() {
content="$1"
profiles=".profile .zprofile .bash_profile .bashrc .zshrc"
for profile in $profiles; do
file="$home/$profile"
if [ "$ci" = "1" ] || [ -f "$file" ]; then
append_to_file "$file" "$content"
fi
for profile_path in "$current_home/$profile" "$home/$profile"; do
if [ "$ci" = "1" ] || [ -f "$profile_path" ]; then
append_file "$profile_path" "$content"
fi
done
done
}
@@ -167,7 +226,7 @@ append_to_path() {
fi
append_to_profile "export PATH=\"$path:\$PATH\""
export PATH="$path:$PATH"
# export PATH="$path:$PATH"
}
move_to_bin() {
@@ -190,19 +249,22 @@ move_to_bin() {
check_features() {
print "Checking features..."
case "$CI" in
true | 1)
ci=1
print "CI: enabled"
;;
esac
case "$@" in
*--ci*)
ci=1
print "CI: enabled"
;;
esac
for arg in "$@"; do
case "$arg" in
*--ci*)
ci=1
print "CI: enabled"
;;
*--osxcross*)
osxcross=1
print "Cross-compiling to macOS: enabled"
;;
*--gcc-13*)
gcc_version="13"
print "GCC 13: enabled"
;;
esac
done
}
check_operating_system() {
@@ -211,17 +273,29 @@ check_operating_system() {
os="$("$uname" -s)"
case "$os" in
Linux*) os="linux" ;;
Darwin*) os="darwin" ;;
*) error "Unsupported operating system: $os" ;;
Linux*)
os="linux"
;;
Darwin*)
os="darwin"
;;
*)
error "Unsupported operating system: $os"
;;
esac
print "Operating System: $os"
arch="$("$uname" -m)"
case "$arch" in
x86_64 | x64 | amd64) arch="x64" ;;
aarch64 | arm64) arch="aarch64" ;;
*) error "Unsupported architecture: $arch" ;;
x86_64 | x64 | amd64)
arch="x64"
;;
aarch64 | arm64)
arch="aarch64"
;;
*)
error "Unsupported architecture: $arch"
;;
esac
print "Architecture: $arch"
@@ -235,7 +309,7 @@ check_operating_system() {
abi="musl"
alpine="$(cat /etc/alpine-release)"
if [ "$alpine" ~ "_" ]; then
release="$(echo "$alpine" | cut -d_ -f1)-edge"
release="$(print "$alpine" | cut -d_ -f1)-edge"
else
release="$alpine"
fi
@@ -255,6 +329,7 @@ check_operating_system() {
distro="$("$sw_vers" -productName)"
release="$("$sw_vers" -productVersion)"
fi
case "$arch" in
x64)
sysctl="$(which sysctl)"
@@ -277,7 +352,7 @@ check_operating_system() {
ldd="$(which ldd)"
if [ -f "$ldd" ]; then
ldd_version="$($ldd --version 2>&1)"
abi_version="$(echo "$ldd_version" | grep -o -E '[0-9]+\.[0-9]+(\.[0-9]+)?' | head -n 1)"
abi_version="$(print "$ldd_version" | grep -o -E '[0-9]+\.[0-9]+(\.[0-9]+)?' | head -n 1)"
case "$ldd_version" in
*musl*)
abi="musl"
@@ -394,6 +469,10 @@ check_user() {
can_sudo=1
print "Sudo: can be used"
fi
current_user="$user"
current_group="$group"
current_home="$home"
}
check_ulimit() {
@@ -405,15 +484,12 @@ check_ulimit() {
systemd_conf="/etc/systemd/system.conf"
if [ -f "$systemd_conf" ]; then
limits_conf="/etc/security/limits.d/99-unlimited.conf"
if ! [ -f "$limits_conf" ]; then
execute_sudo mkdir -p "$(dirname "$limits_conf")"
execute_sudo touch "$limits_conf"
fi
create_file "$limits_conf"
fi
limits="core data fsize memlock nofile rss stack cpu nproc as locks sigpending msgqueue"
for limit in $limits; do
limit_upper="$(echo "$limit" | tr '[:lower:]' '[:upper:]')"
limit_upper="$(print "$limit" | tr '[:lower:]' '[:upper:]')"
limit_value="unlimited"
case "$limit" in
@@ -425,13 +501,13 @@ check_ulimit() {
if [ -f "$limits_conf" ]; then
limit_users="root *"
for limit_user in $limit_users; do
append_to_file "$limits_conf" "$limit_user soft $limit $limit_value"
append_to_file "$limits_conf" "$limit_user hard $limit $limit_value"
append_file "$limits_conf" "$limit_user soft $limit $limit_value"
append_file "$limits_conf" "$limit_user hard $limit $limit_value"
done
fi
if [ -f "$systemd_conf" ]; then
append_to_file "$systemd_conf" "DefaultLimit$limit_upper=$limit_value"
append_file "$systemd_conf" "DefaultLimit$limit_upper=$limit_value"
fi
done
@@ -448,13 +524,13 @@ check_ulimit() {
esac
rc_ulimit="$rc_ulimit -$limit_flag $limit_value"
done
append_to_file "$rc_conf" "rc_ulimit=\"$rc_ulimit\""
append_file "$rc_conf" "rc_ulimit=\"$rc_ulimit\""
fi
pam_confs="/etc/pam.d/common-session /etc/pam.d/common-session-noninteractive"
for pam_conf in $pam_confs; do
if [ -f "$pam_conf" ]; then
append_to_file "$pam_conf" "session optional pam_limits.so"
append_file "$pam_conf" "session optional pam_limits.so"
fi
done
@@ -557,7 +633,7 @@ install_brew() {
bash="$(require bash)"
script=$(download_file "https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh")
NONINTERACTIVE=1 execute_as_user "$bash" "$script"
execute_as_user "$bash" -c "NONINTERACTIVE=1 $script"
case "$arch" in
x64)
@@ -638,7 +714,7 @@ nodejs_version_exact() {
}
nodejs_version() {
echo "$(nodejs_version_exact)" | cut -d. -f1
print "$(nodejs_version_exact)" | cut -d. -f1
}
install_nodejs() {
@@ -674,14 +750,21 @@ install_nodejs() {
}
install_nodejs_headers() {
headers_tar="$(download_file "https://nodejs.org/download/release/v$(nodejs_version_exact)/node-v$(nodejs_version_exact)-headers.tar.gz")"
headers_dir="$(dirname "$headers_tar")"
execute tar -xzf "$headers_tar" -C "$headers_dir"
headers_include="$headers_dir/node-v$(nodejs_version_exact)/include"
execute_sudo cp -R "$headers_include/" "/usr"
nodejs_headers_tar="$(download_file "https://nodejs.org/download/release/v$(nodejs_version_exact)/node-v$(nodejs_version_exact)-headers.tar.gz")"
nodejs_headers_dir="$(dirname "$nodejs_headers_tar")"
execute tar -xzf "$nodejs_headers_tar" -C "$nodejs_headers_dir"
nodejs_headers_include="$nodejs_headers_dir/node-v$(nodejs_version_exact)/include"
execute_sudo cp -R "$nodejs_headers_include/" "/usr"
}
bun_version_exact() {
print "1.1.38"
}
install_bun() {
install_packages unzip
case "$pm" in
apk)
install_packages \
@@ -690,23 +773,28 @@ install_bun() {
;;
esac
bash="$(require bash)"
script=$(download_file "https://bun.sh/install")
version="${1:-"latest"}"
case "$version" in
latest)
execute_as_user "$bash" "$script"
case "$abi" in
musl)
bun_triplet="bun-$os-$arch-$abi"
;;
*)
execute_as_user "$bash" "$script" -s "$version"
bun_triplet="bun-$os-$arch"
;;
esac
move_to_bin "$home/.bun/bin/bun"
bun_path="$(which bun)"
bunx_path="$(dirname "$bun_path")/bunx"
execute_sudo ln -sf "$bun_path" "$bunx_path"
unzip="$(require unzip)"
bun_download_url="https://pub-5e11e972747a44bf9aaf9394f185a982.r2.dev/releases/bun-v$(bun_version_exact)/$bun_triplet.zip"
bun_zip="$(download_file "$bun_download_url")"
bun_tmpdir="$(dirname "$bun_zip")"
execute "$unzip" -o "$bun_zip" -d "$bun_tmpdir"
bun_path="/opt/bun"
create_directory "$bun_path/bin"
execute mv "$bun_tmpdir/$bun_triplet/bun" "$bun_path/bin/bun"
execute ln -sf "$bun_path/bin/bun" "$bun_path/bin/bunx"
append_to_path "$bun_path/bin"
append_to_profile "export BUN_INSTALL=$bun_path"
}
install_cmake() {
@@ -799,24 +887,19 @@ install_build_essentials() {
install_cmake
install_llvm
install_osxcross
install_gcc
install_ccache
install_rust
install_docker
}
llvm_version_exact() {
case "$os-$abi" in
darwin-* | windows-* | linux-musl)
print "18.1.8"
;;
linux-*)
print "16.0.6"
;;
esac
print "18.1.8"
}
llvm_version() {
echo "$(llvm_version_exact)" | cut -d. -f1
print "$(llvm_version_exact)" | cut -d. -f1
}
install_llvm() {
@@ -824,14 +907,7 @@ install_llvm() {
apt)
bash="$(require bash)"
llvm_script="$(download_file "https://apt.llvm.org/llvm.sh")"
case "$distro-$release" in
ubuntu-24*)
execute_sudo "$bash" "$llvm_script" "$(llvm_version)" all -njammy
;;
*)
execute_sudo "$bash" "$llvm_script" "$(llvm_version)" all
;;
esac
execute_sudo "$bash" "$llvm_script" "$(llvm_version)" all
;;
brew)
install_packages "llvm@$(llvm_version)"
@@ -849,6 +925,55 @@ install_llvm() {
esac
}
install_gcc() {
if ! [ "$os" = "linux" ] || ! [ "$distro" = "ubuntu" ] || [ -z "$gcc_version" ]; then
return
fi
# Taken from WebKit's Dockerfile.
# https://github.com/oven-sh/WebKit/blob/816a3c02e0f8b53f8eec06b5ed911192589b51e2/Dockerfile
execute_sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y
execute_sudo apt update -y
install_packages \
"gcc-$gcc_version" \
"g++-$gcc_version" \
"libgcc-$gcc_version-dev" \
"libstdc++-$gcc_version-dev" \
libasan6 \
libubsan1 \
libatomic1 \
libtsan0 \
liblsan0 \
libgfortran5 \
libc6-dev
execute_sudo update-alternatives \
--install /usr/bin/gcc gcc "/usr/bin/gcc-$gcc_version" 130 \
--slave /usr/bin/g++ g++ "/usr/bin/g++-$gcc_version" \
--slave /usr/bin/gcc-ar gcc-ar "/usr/bin/gcc-ar-$gcc_version" \
--slave /usr/bin/gcc-nm gcc-nm "/usr/bin/gcc-nm-$gcc_version" \
--slave /usr/bin/gcc-ranlib gcc-ranlib "/usr/bin/gcc-ranlib-$gcc_version"
case "$arch" in
x64)
arch_path="x86_64-linux-gnu"
;;
aarch64)
arch_path="aarch64-linux-gnu"
;;
esac
gcc_path="/usr/lib/gcc/$arch_path/$gcc_version"
create_directory "$gcc_path"
execute_sudo ln -sf /usr/lib/$arch_path/libstdc++.so.6 "$gcc_path/libstdc++.so.6"
ld_conf_path="/etc/ld.so.conf.d/gcc-$gcc_version.conf"
append_file "$ld_conf_path" "$gcc_path"
append_file "$ld_conf_path" "/usr/lib/$arch_path"
execute_sudo ldconfig
}
install_ccache() {
case "$pm" in
apt | apk | brew)
@@ -865,9 +990,23 @@ install_rust() {
cargo
;;
*)
rust_home="/opt/rust"
create_directory "$rust_home"
append_to_profile "export RUSTUP_HOME=$rust_home"
append_to_profile "export CARGO_HOME=$rust_home"
sh="$(require sh)"
script=$(download_file "https://sh.rustup.rs")
execute_as_user "$sh" "$script" -y
rustup_script=$(download_file "https://sh.rustup.rs")
execute "$sh" -c "RUSTUP_HOME=$rust_home CARGO_HOME=$rust_home $rustup_script -y --no-modify-path"
append_to_path "$rust_home/bin"
;;
esac
case "$osxcross" in
1)
rustup="$(require rustup)"
execute_as_user "$rustup" target add aarch64-apple-darwin
execute_as_user "$rustup" target add x86_64-apple-darwin
;;
esac
}
@@ -910,6 +1049,46 @@ install_docker() {
fi
}
macos_sdk_version() {
# https://github.com/alexey-lysiuk/macos-sdk/releases
print "14.5"
}
install_osxcross() {
if ! [ "$os" = "linux" ] || ! [ "$osxcross" = "1" ]; then
return
fi
install_packages \
libssl-dev \
lzma-dev \
libxml2-dev \
zlib1g-dev \
bzip2 \
cpio
osxcross_path="/opt/osxcross"
create_directory "$osxcross_path"
osxcross_commit="29fe6dd35522073c9df5800f8cd1feb4b9a993a8"
osxcross_tar="$(download_file "https://github.com/tpoechtrager/osxcross/archive/$osxcross_commit.tar.gz")"
execute tar -xzf "$osxcross_tar" -C "$osxcross_path"
osxcross_build_path="$osxcross_path/build"
execute mv "$osxcross_path/osxcross-$osxcross_commit" "$osxcross_build_path"
osxcross_sdk_tar="$(download_file "https://github.com/alexey-lysiuk/macos-sdk/releases/download/$(macos_sdk_version)/MacOSX$(macos_sdk_version).tar.xz")"
execute mv "$osxcross_sdk_tar" "$osxcross_build_path/tarballs/MacOSX$(macos_sdk_version).sdk.tar.xz"
bash="$(require bash)"
execute_sudo ln -sf "$(which clang-$(llvm_version))" /usr/bin/clang
execute_sudo ln -sf "$(which clang++-$(llvm_version))" /usr/bin/clang++
execute_sudo "$bash" -c "UNATTENDED=1 TARGET_DIR='$osxcross_path' $osxcross_build_path/build.sh"
execute_sudo rm -rf "$osxcross_build_path"
grant_to_user "$osxcross_path"
}
install_tailscale() {
if [ "$docker" = "1" ]; then
return
@@ -975,14 +1154,12 @@ create_buildkite_user() {
buildkite_paths="$home /var/cache/buildkite-agent /var/log/buildkite-agent /var/run/buildkite-agent /var/run/buildkite-agent/buildkite-agent.sock"
for path in $buildkite_paths; do
execute_sudo mkdir -p "$path"
execute_sudo chown -R "$user:$group" "$path"
create_directory "$path"
done
buildkite_files="/var/run/buildkite-agent/buildkite-agent.pid"
for file in $buildkite_files; do
execute_sudo touch "$file"
execute_sudo chown "$user:$group" "$file"
create_file "$file"
done
}
@@ -992,27 +1169,22 @@ install_buildkite() {
fi
buildkite_version="3.87.0"
case "$os-$arch" in
linux-aarch64)
buildkite_filename="buildkite-agent-linux-arm64-$buildkite_version.tar.gz"
case "$arch" in
aarch64)
buildkite_arch="arm64"
;;
linux-x64)
buildkite_filename="buildkite-agent-linux-amd64-$buildkite_version.tar.gz"
;;
darwin-aarch64)
buildkite_filename="buildkite-agent-darwin-arm64-$buildkite_version.tar.gz"
;;
darwin-x64)
buildkite_filename="buildkite-agent-darwin-amd64-$buildkite_version.tar.gz"
x64)
buildkite_arch="amd64"
;;
esac
buildkite_url="https://github.com/buildkite/agent/releases/download/v$buildkite_version/$buildkite_filename"
buildkite_filepath="$(download_file "$buildkite_url" "$buildkite_filename")"
buildkite_tmpdir="$(dirname "$buildkite_filepath")"
execute tar -xzf "$buildkite_filepath" -C "$buildkite_tmpdir"
buildkite_filename="buildkite-agent-$os-$buildkite_arch-$buildkite_version.tar.gz"
buildkite_url="https://github.com/buildkite/agent/releases/download/v$buildkite_version/$buildkite_filename"
buildkite_tar="$(download_file "$buildkite_url")"
buildkite_tmpdir="$(dirname "$buildkite_tar")"
execute tar -xzf "$buildkite_tar" -C "$buildkite_tmpdir"
move_to_bin "$buildkite_tmpdir/buildkite-agent"
execute rm -rf "$buildkite_tmpdir"
}
install_chromium() {
@@ -1103,6 +1275,19 @@ install_chromium() {
esac
}
clean_system() {
if ! [ "$ci" = "1" ]; then
return
fi
print "Cleaning system..."
tmp_paths="/tmp /var/tmp"
for path in $tmp_paths; do
execute_sudo rm -rf "$path"/*
done
}
main() {
check_features "$@"
check_operating_system
@@ -1114,6 +1299,7 @@ main() {
install_common_software
install_build_essentials
install_chromium
clean_system
}
main "$@"

View File

@@ -2374,6 +2374,7 @@ function getCloud(name) {
* @typedef {"linux" | "darwin" | "windows"} Os
* @typedef {"aarch64" | "x64"} Arch
* @typedef {"macos" | "windowsserver" | "debian" | "ubuntu" | "alpine" | "amazonlinux"} Distro
* @typedef {"osxcross" | "gcc-13"} Feature
*/
/**
@@ -2383,6 +2384,7 @@ function getCloud(name) {
* @property {Distro} distro
* @property {string} release
* @property {string} [eol]
* @property {Feature[]} [features]
*/
/**
@@ -2416,6 +2418,7 @@ function getCloud(name) {
* @property {Arch} arch
* @property {Distro} distro
* @property {string} [release]
* @property {Feature[]} [features]
* @property {string} [name]
* @property {string} [instanceType]
* @property {string} [imageId]
@@ -2464,6 +2467,7 @@ async function main() {
"detached": { type: "boolean" },
"tag": { type: "string", multiple: true },
"ci": { type: "boolean" },
"feature": { type: "string", multiple: true },
"rdp": { type: "boolean" },
"vnc": { type: "boolean" },
"authorized-user": { type: "string", multiple: true },
@@ -2501,6 +2505,7 @@ async function main() {
arch: parseArch(args["arch"]),
distro: args["distro"],
release: args["release"],
features: args["feature"],
name: args["name"],
instanceType: args["instance-type"],
imageId: args["image-id"],
@@ -2517,7 +2522,7 @@ async function main() {
sshKeys,
};
const { detached, bootstrap, ci, os, arch, distro, release } = options;
const { detached, bootstrap, ci, os, arch, distro, release, features } = options;
const name = distro ? `${os}-${arch}-${distro}-${release}` : `${os}-${arch}-${release}`;
let bootstrapPath, agentPath;
@@ -2627,6 +2632,9 @@ async function main() {
} else {
const remotePath = "/tmp/bootstrap.sh";
const args = ci ? ["--ci"] : [];
for (const feature of features || []) {
args.push(`--${feature}`);
}
await startGroup("Running bootstrap...", async () => {
await machine.upload(bootstrapPath, remotePath);
await machine.spawnSafe(["sh", remotePath, ...args], { stdio: "inherit" });