Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions .github/workflows/build-reusable.yml
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,59 @@ jobs:
name: ${{matrix.label}}
path: ${{runner.temp}}/bun-webkit.tar.gz

freebsd:
name: FreeBSD
# Cross-compiled from a Linux host via clang --target + base.txz sysroot,
# so all FreeBSD targets build on x64 regardless of target arch.
runs-on: linux-x64-gh
strategy:
matrix:
include:
- label: bun-webkit-freebsd-amd64
freebsd_arch: x86_64
package_json_arch: "x64"
CMAKE_BUILD_TYPE: "Release"
- label: bun-webkit-freebsd-amd64-debug
freebsd_arch: x86_64
package_json_arch: "x64"
CMAKE_BUILD_TYPE: "Debug"
- label: bun-webkit-freebsd-arm64
freebsd_arch: aarch64
package_json_arch: "arm64"
CMAKE_BUILD_TYPE: "Release"
- label: bun-webkit-freebsd-arm64-debug
freebsd_arch: aarch64
package_json_arch: "arm64"
CMAKE_BUILD_TYPE: "Debug"
timeout-minutes: 90
steps:
- uses: actions/checkout@v4
with:
ref: ${{ inputs.build_ref }}
sparse-checkout-cone-mode: false
sparse-checkout: |
/*
!LayoutTests/
!JSTests/
- uses: docker/setup-buildx-action@v2
id: buildx
with:
install: true
Comment on lines +459 to +462

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# Check if the file exists and read lines around 459-462
if [ -f ".github/workflows/build-reusable.yml" ]; then
  echo "=== Lines 455-465 of build-reusable.yml ==="
  sed -n '455,465p' ".github/workflows/build-reusable.yml" | cat -n
else
  echo "File not found, listing workflow files:"
  find .github/workflows -name "*.yml" -o -name "*.yaml" | head -20
fi

Repository: oven-sh/WebKit

Length of output: 485


🌐 Web query:

docker/setup-buildx-action v2 v3 deprecation supported versions

💡 Result:

The docker/setup-buildx-action GitHub Action has versions v2, v3, and v4. v2 is outdated and should be upgraded (examples show migration from v2 to v3). In v3.12.0 (Dec 2025), the 'install' input was deprecated due to upstream docker/buildx changes. v4.0.0 (Mar 2026, current latest as of Apr 2026) fully removes deprecated inputs/outputs including 'install', 'config', 'config-inline', and some outputs like 'endpoint', 'status', 'flags'. Use v4 with recent GitHub Actions runners (v2.327.1+ for Node 24 runtime). Official README examples use docker/setup-buildx-action@v4. v2 and v3 remain functional but lack latest features and fixes; migrate to v4 for support.

Citations:


Upgrade to docker/setup-buildx-action@v4 and remove the deprecated install parameter.

Line 459 uses docker/setup-buildx-action@v2, which is outdated. The current version is v4 (as of Mar 2026). When upgrading, remove the install: true parameter, which was deprecated in v3.12.0 and removed in v4.0.0.

Proposed fix
-      - uses: docker/setup-buildx-action@v2
+      - uses: docker/setup-buildx-action@v4
         id: buildx
-        with:
-          install: true
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- uses: docker/setup-buildx-action@v2
id: buildx
with:
install: true
- uses: docker/setup-buildx-action@v4
id: buildx
🧰 Tools
🪛 actionlint (1.7.12)

[error] 459-459: the runner of "docker/setup-buildx-action@v2" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/build-reusable.yml around lines 459 - 462, Update the
GitHub Actions step that uses docker/setup-buildx-action@v2 by changing the
action version to docker/setup-buildx-action@v4 and remove the deprecated
install: true input; locate the step with id: buildx (currently referencing
docker/setup-buildx-action@v2) and replace the version tag and delete the
install parameter so the step conforms to v4 usage.

- name: Run
run: |
rm -rf ${{runner.temp}}/bun-webkit ${{runner.temp}}/bun-webkit.tar.gz
FREEBSD_ARCH="${{matrix.freebsd_arch}}" WEBKIT_RELEASE_TYPE="${{matrix.CMAKE_BUILD_TYPE}}" temp=${{runner.temp}} bash freebsd-release.sh
cd ${{runner.temp}}
echo "#define BUN_WEBKIT_VERSION \"${{ inputs.build_ref }}\"" >> bun-webkit/include/cmakeconfig.h
echo '{ "name": "${{matrix.label}}", "version": "0.0.1-${{ inputs.build_ref }}", "os": ["freebsd"], "cpu": ["${{matrix.package_json_arch}}"], "repository": "https://github.com/${{github.repository}}" }' > bun-webkit/package.json
rm -rf bun-webkit/lib/*.so bun-webkit/lib/*.so.*
tar -czf bun-webkit.tar.gz bun-webkit
rm -rf bun-webkit
- uses: actions/upload-artifact@v4
with:
name: ${{matrix.label}}
path: ${{runner.temp}}/bun-webkit.tar.gz

linux-android:
name: Linux Android
# NDK only ships linux-x86_64 prebuilts, so all Android targets
Expand Down Expand Up @@ -487,6 +540,7 @@ jobs:
- windows
- linux-musl
- linux-android
- freebsd
outputs:
tag: ${{ steps.release_info.outputs.tag }}
steps:
Expand Down Expand Up @@ -640,6 +694,22 @@ jobs:
with:
name: bun-webkit-linux-amd64-android-debug
path: ${{runner.temp}}/bun-webkit-linux-amd64-android-debug
- uses: actions/download-artifact@v4
with:
name: bun-webkit-freebsd-amd64
path: ${{runner.temp}}/bun-webkit-freebsd-amd64
- uses: actions/download-artifact@v4
with:
name: bun-webkit-freebsd-amd64-debug
path: ${{runner.temp}}/bun-webkit-freebsd-amd64-debug
- uses: actions/download-artifact@v4
with:
name: bun-webkit-freebsd-arm64
path: ${{runner.temp}}/bun-webkit-freebsd-arm64
- uses: actions/download-artifact@v4
with:
name: bun-webkit-freebsd-arm64-debug
path: ${{runner.temp}}/bun-webkit-freebsd-arm64-debug

- name: Rename files
run: |
Expand Down Expand Up @@ -679,6 +749,10 @@ jobs:
mv ${{runner.temp}}/bun-webkit-linux-arm64-android-debug/bun-webkit.tar.gz ./out/bun-webkit-linux-arm64-android-debug.tar.gz
mv ${{runner.temp}}/bun-webkit-linux-amd64-android/bun-webkit.tar.gz ./out/bun-webkit-linux-amd64-android.tar.gz
mv ${{runner.temp}}/bun-webkit-linux-amd64-android-debug/bun-webkit.tar.gz ./out/bun-webkit-linux-amd64-android-debug.tar.gz
mv ${{runner.temp}}/bun-webkit-freebsd-amd64/bun-webkit.tar.gz ./out/bun-webkit-freebsd-amd64.tar.gz
mv ${{runner.temp}}/bun-webkit-freebsd-amd64-debug/bun-webkit.tar.gz ./out/bun-webkit-freebsd-amd64-debug.tar.gz
mv ${{runner.temp}}/bun-webkit-freebsd-arm64/bun-webkit.tar.gz ./out/bun-webkit-freebsd-arm64.tar.gz
mv ${{runner.temp}}/bun-webkit-freebsd-arm64-debug/bun-webkit.tar.gz ./out/bun-webkit-freebsd-arm64-debug.tar.gz

- name: Set release info
id: release_info
Expand Down Expand Up @@ -731,6 +805,15 @@ jobs:
./out/bun-webkit-linux-amd64-android.tar.gz
./out/bun-webkit-linux-amd64-android-debug.tar.gz

- uses: softprops/action-gh-release@v1
with:
tag_name: ${{ inputs.release_tag }}
files: |
./out/bun-webkit-freebsd-amd64.tar.gz
./out/bun-webkit-freebsd-amd64-debug.tar.gz
./out/bun-webkit-freebsd-arm64.tar.gz
./out/bun-webkit-freebsd-arm64-debug.tar.gz
Comment on lines +808 to +815

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, let's read the workflow file around the specified lines
wc -l .github/workflows/build-reusable.yml

Repository: oven-sh/WebKit

Length of output: 99


🏁 Script executed:

# Read the context around lines 808-815
sed -n '800,820p' .github/workflows/build-reusable.yml

Repository: oven-sh/WebKit

Length of output: 835


🏁 Script executed:

# Search for all uses of softprops/action-gh-release in the workflow file
rg "softprops/action-gh-release" .github/workflows/build-reusable.yml -n -A 10

Repository: oven-sh/WebKit

Length of output: 3083


🏁 Script executed:

# Search for actionlint config or mentions in the repo
fd actionlint

Repository: oven-sh/WebKit

Length of output: 40


🏁 Script executed:

# Check for any linting configuration files
fd -e yaml -e yml | rg -i "actionlint|action" | head -20

Repository: oven-sh/WebKit

Length of output: 360


🏁 Script executed:

# Look for GitHub Actions documentation or version constraints
rg "action-gh-release" . --type yaml -B 2 -A 10 | head -50

Repository: oven-sh/WebKit

Length of output: 40


🏁 Script executed:

# Check if there's any actionlint configuration in common locations
ls -la .github/ | grep -i action

Repository: oven-sh/WebKit

Length of output: 40


🏁 Script executed:

# Look for any workflow linting or CI configuration
find .github -type f -name "*.yml" -o -name "*.yaml" | xargs grep -l "actionlint" 2>/dev/null

Repository: oven-sh/WebKit

Length of output: 42


🌐 Web query:

softprops/action-gh-release v1 vs v2 differences deprecated

💡 Result:

softprops/action-gh-release v1 and v2 are major versions of this GitHub Action for creating GitHub Releases. v1 was originally implemented as a Docker container, limiting it to Linux runners only, and required a 'docker://' prefix in some usages. v2 (starting around 2024 with v2.0.0) rewrote it as a JavaScript/TypeScript action for cross-platform support (Linux, Windows, macOS), removed the Docker dependency (no more 'docker://' prefix needed), upgraded the Node runtime (e.g., to node16 then node20), fixed deprecations like set-output warnings, added/improved inputs like make_latest, previous_tag, working_directory, discussion_category_name, append_body, and enhanced features like better asset handling, error recovery, generate_release_notes support, and numerous bug fixes (e.g., concurrent uploads, prerelease behavior). v1 is effectively legacy/outdated; upgrade to v2 (latest v2.6.2 as of 2026-04) or v3 (Node 24). No explicit deprecation notice for v1, but Dependabot auto-upgrades from v1 to v2, and docs/examples use v2/v3.

Citations:


Use @v2 for softprops/action-gh-release and update all existing instances in this workflow.

The FreeBSD release step at lines 808-815 (and all other uses of softprops/action-gh-release@v1 in this file) should be upgraded to @v2. Version 1 is a legacy Docker-based implementation; v2 provides cross-platform support via JavaScript/TypeScript, improved Node runtime, and better feature support. Lines 763, 769, 786, 799, 808, 817, and 828 all need this update for consistency and to avoid maintenance issues.

Proposed fix for FreeBSD section
-      - uses: softprops/action-gh-release@v1
+      - uses: softprops/action-gh-release@v2
         with:
           tag_name: ${{ inputs.release_tag }}
           files: |
             ./out/bun-webkit-freebsd-amd64.tar.gz
             ./out/bun-webkit-freebsd-amd64-debug.tar.gz
             ./out/bun-webkit-freebsd-arm64.tar.gz
             ./out/bun-webkit-freebsd-arm64-debug.tar.gz
🧰 Tools
🪛 actionlint (1.7.12)

[error] 808-808: the runner of "softprops/action-gh-release@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/build-reusable.yml around lines 808 - 815, Replace every
usage of the GitHub Action softprops/action-gh-release@v1 with
softprops/action-gh-release@v2 across this workflow file; specifically update
the FreeBSD release step that currently lists files like
./out/bun-webkit-freebsd-*.tar.gz (and all other occurrences of
softprops/action-gh-release@v1) to use `@v2` so the workflow benefits from the
JS/TS cross-platform implementation and consistent behavior.


- uses: softprops/action-gh-release@v1
with:
tag_name: ${{ inputs.release_tag }}
Expand Down
177 changes: 177 additions & 0 deletions Dockerfile.freebsd
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
ARG MARCH_FLAG="-march=haswell"
ARG WEBKIT_RELEASE_TYPE=Release
ARG LTO_FLAG=""
ARG LLVM_VERSION="21"
ARG FREEBSD_VERSION="14.3"
ARG FREEBSD_ARCH="x86_64"
Comment on lines +1 to +6

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Default MARCH_FLAG is incompatible with aarch64 builds.

-march=haswell is an x86_64 instruction set flag and will cause clang to error when targeting aarch64-unknown-freebsd*. While freebsd-release.sh overrides this, invoking the Dockerfile directly with FREEBSD_ARCH=aarch64 without also overriding MARCH_FLAG will fail.

Consider adding validation or using an empty default:

🔧 Suggested fix
-ARG MARCH_FLAG="-march=haswell"
+ARG MARCH_FLAG=""

Alternatively, add a build-time check similar to line 50's architecture validation.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
ARG MARCH_FLAG="-march=haswell"
ARG WEBKIT_RELEASE_TYPE=Release
ARG LTO_FLAG=""
ARG LLVM_VERSION="21"
ARG FREEBSD_VERSION="14.3"
ARG FREEBSD_ARCH="x86_64"
ARG MARCH_FLAG=""
ARG WEBKIT_RELEASE_TYPE=Release
ARG LTO_FLAG=""
ARG LLVM_VERSION="21"
ARG FREEBSD_VERSION="14.3"
ARG FREEBSD_ARCH="x86_64"
🧰 Tools
🪛 Checkov (3.2.524)

[low] 1-183: Ensure that HEALTHCHECK instructions have been added to container images

(CKV_DOCKER_2)


[low] 1-183: Ensure that a user for the container has been created

(CKV_DOCKER_3)

🪛 Trivy (0.69.3)

[error] 1-1: Image user should not be 'root'

Specify at least 1 USER command in Dockerfile with non-root user as argument

Rule: DS-0002

Learn more

(IaC/Dockerfile)


[info] 1-1: No HEALTHCHECK defined

Add HEALTHCHECK instruction in your Dockerfile

Rule: DS-0026

Learn more

(IaC/Dockerfile)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfile.freebsd` around lines 1 - 6, The ARG MARCH_FLAG default
"-march=haswell" is x86_64-specific and will break aarch64 builds; update
Dockerfile.freebsd to either make MARCH_FLAG empty by default (ARG
MARCH_FLAG="") or add a build-time validation that inspects FREEBSD_ARCH and
fails with a clear message if FREEBSD_ARCH="aarch64" while MARCH_FLAG contains
an x86-only flag (mirror the architecture validation logic used elsewhere in the
file). Target the ARG names MARCH_FLAG and FREEBSD_ARCH when implementing the
change so callers can override MARCH_FLAG for x86_64 builds or get a helpful
error for mismatched arch/flags.

ARG DEFAULT_CFLAGS="-mno-omit-leaf-frame-pointer -g -fno-omit-frame-pointer -ffunction-sections -fdata-sections -faddrsig -fno-unwind-tables -fno-asynchronous-unwind-tables -DU_STATIC_IMPLEMENTATION=1 "
ARG ICU_VERSION="75_1"
ARG ICU_RELEASE_TAG="release-75-1"
ARG ICU_SHA256="cb968df3e4d2e87e8b11c49a5d01c787bd13b9545280fc6642f826527618caef"

FROM ubuntu:24.04 AS base
SHELL ["/bin/bash", "-o", "pipefail", "-c"]

ARG LLVM_VERSION
ARG FREEBSD_VERSION
ARG FREEBSD_ARCH

RUN apt-get update && apt-get install -y --no-install-recommends \
wget unzip xz-utils ca-certificates \
cmake ninja-build make git \
ruby ruby-getoptlong perl python3 rsync file cpio \
lsb-release software-properties-common gnupg \
&& rm -rf /var/lib/apt/lists/*

# Host clang (same version Bun uses) — we cross-compile via --target/--sysroot.
# apt.llvm.org installs version-suffixed names only, so add unversioned links
# for -fuse-ld=lld.
RUN wget -qO- https://apt.llvm.org/llvm.sh | bash -s -- ${LLVM_VERSION} && \
for t in clang clang++ ld.lld lld llvm-ar llvm-ranlib; do \
ln -sf /usr/bin/${t}-${LLVM_VERSION} /usr/local/bin/${t}; \
done
Comment on lines +33 to +36

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

What is the recommended apt.llvm.org installation flow that avoids piping llvm.shtobash, and where are the official checksum/signature files for FreeBSD 14.3 RELEASE base.txz published?

💡 Result:

The recommended apt.llvm.org installation flow that avoids piping llvm.sh to bash is: wget https://apt.llvm.org/llvm.sh chmod +x llvm.sh sudo ./llvm.sh [version] To install all packages: sudo ./llvm.sh [version] all (or sudo ./llvm.sh all for latest stable). No official checksum or signature files are published for llvm.sh itself on apt.llvm.org; verification relies on HTTPS/TLS and the repo GPG key at https://apt.llvm.org/llvm-snapshot.gpg.key (fingerprint: 6084 F3CF 814B 57C1 CF12 EFD5 15CF 4D18 AF4F 7421). Source packages in the repos use sigstore/rekor for verification. Official checksum/signature files for FreeBSD 14.3-RELEASE base.txz (and other install sets) are published at https://www.freebsd.org/releases/14.3R/signatures/ as PGP-signed SHA512 and SHA256 checksum files per architecture (e.g., SHA512 for amd64 base.txz, etc.).

Citations:


Verify downloaded toolchain and sysroot using published checksums before using them in release builds.

Lines 29–32 pipe a network-fetched script directly into bash as root. The recommended approach is to download, inspect, and execute locally:

RUN wget https://apt.llvm.org/llvm.sh && chmod +x llvm.sh && ./llvm.sh ${LLVM_VERSION}

Lines 42–50 extract base.txz without integrity verification. FreeBSD publishes PGP-signed SHA512/SHA256 checksums at https://www.freebsd.org/releases/14.3R/signatures/. Validate the downloaded archive against the official checksum before extraction.

This stage produces published prebuilts; unverified inputs introduce supply-chain risk.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfile.freebsd` around lines 29 - 32, The Dockerfile currently pipes the
remote llvm.sh into bash and extracts FreeBSD base.txz without integrity checks;
change the llvm install step (the RUN line invoking wget -qO-
https://apt.llvm.org/llvm.sh | bash -s -- ${LLVM_VERSION}) to instead download
the script to disk (preserve ${LLVM_VERSION} usage), set executable bit, and run
it locally after verifying its integrity/signature, and for the FreeBSD stage
download base.txz and its published checksum/signature from the FreeBSD
signatures URL and verify the archive with the published SHA512/SHA256 or PGP
signature before extraction (fail the build on mismatch); ensure the Dockerfile
aborts on verification failure and does not use network-piped shell execution or
unverified archives.

ENV CC=clang-${LLVM_VERSION}
ENV CXX=clang++-${LLVM_VERSION}
ENV AR=llvm-ar-${LLVM_VERSION}
ENV RANLIB=llvm-ranlib-${LLVM_VERSION}
ENV LD=lld-${LLVM_VERSION}

# FreeBSD sysroot — extract base.txz (libc, libc++, headers, crt files,
# compiler-rt). FreeBSD ships its own libc++ in base, so /usr/include/c++/v1
# and /usr/lib/libc++.* come from here.
RUN set -eux; \
case "${FREEBSD_ARCH}" in \
x86_64) FBSD_DL_ARCH="amd64" ;; \
aarch64) FBSD_DL_ARCH="arm64" ;; \
*) echo "unsupported FREEBSD_ARCH ${FREEBSD_ARCH}" >&2; exit 1 ;; \
esac; \
mkdir -p /opt/freebsd-sysroot; \
wget -q "https://download.freebsd.org/releases/${FBSD_DL_ARCH}/${FREEBSD_VERSION}-RELEASE/base.txz" -O /tmp/base.txz; \
tar -C /opt/freebsd-sysroot -xJf /tmp/base.txz ./usr/include ./usr/lib ./lib; \
rm /tmp/base.txz
ENV FREEBSD_SYSROOT=/opt/freebsd-sysroot

# Sanity check. FreeBSD's base ships builtins as /usr/lib/libgcc.a (it IS
# compiler-rt, renamed for ABI compat) and clang's freebsd driver finds it
# via --sysroot, so no resource-dir symlinking is needed (unlike Android).
RUN echo 'int main(){return 0;}' | $CC --target=${FREEBSD_ARCH}-unknown-freebsd${FREEBSD_VERSION} --sysroot=$FREEBSD_SYSROOT -fuse-ld=lld -xc - -o /tmp/t && file /tmp/t | grep -q FreeBSD

RUN mkdir -p /output/lib /output/include /output/include/JavaScriptCore /output/include/wtf /output/include/bmalloc /output/include/unicode

# ───────────────────────────────────────────────────────────────────────────
# ICU — cross-compiled. Same two-stage host/target build as Android: host
# tools first, then --with-cross-build.
# ───────────────────────────────────────────────────────────────────────────
FROM base AS build_icu

ARG MARCH_FLAG
ARG LTO_FLAG
ARG DEFAULT_CFLAGS
ARG FREEBSD_VERSION
ARG FREEBSD_ARCH

ARG ICU_VERSION
ARG ICU_RELEASE_TAG
ARG ICU_SHA256
ADD --checksum=sha256:${ICU_SHA256} https://github.com/unicode-org/icu/releases/download/${ICU_RELEASE_TAG}/icu4c-${ICU_VERSION}-src.tgz /icu.tgz

# Host build (tools only — no LTO, fast).
RUN mkdir -p /icu-host && cd /icu-host \
&& tar -xf /icu.tgz --strip-components=1 \
&& cd source \
&& CC=$CC CXX=$CXX CFLAGS="-Os" CXXFLAGS="-Os" \
./configure --disable-shared --enable-static --disable-samples --disable-tests \
&& make -j$(nproc)

# Target build.
RUN --mount=type=tmpfs,target=/icu \
export TARGET_TRIPLE="${FREEBSD_ARCH}-unknown-freebsd${FREEBSD_VERSION}" && \
export CROSS_FLAGS="--target=${TARGET_TRIPLE} --sysroot=${FREEBSD_SYSROOT}" && \
export CFLAGS="${CROSS_FLAGS} ${DEFAULT_CFLAGS} ${MARCH_FLAG} -Os -std=c17 ${LTO_FLAG}" && \
export CXXFLAGS="${CROSS_FLAGS} ${DEFAULT_CFLAGS} ${MARCH_FLAG} -Os -std=c++20 -fno-exceptions ${LTO_FLAG} -fno-c++-static-destructors" && \
export LDFLAGS="${CROSS_FLAGS} -fuse-ld=lld" && \
cd /icu && tar -xf /icu.tgz --strip-components=1 && rm /icu.tgz && cd source && \
{ ./configure --host=${FREEBSD_ARCH}-unknown-freebsd${FREEBSD_VERSION} \
--with-cross-build=/icu-host/source \
--enable-static --disable-shared --with-data-packaging=static \
--disable-samples --disable-tests --disable-debug \
|| { cat config.log; exit 1; }; } && \
make -j$(nproc) && \
cp lib/*.a /output/lib && \
cp -r i18n/unicode/* common/unicode/* /output/include/unicode

# ───────────────────────────────────────────────────────────────────────────
# WebKit (JSCOnly) — cross-compiled. CMAKE_SYSTEM_NAME=FreeBSD is already
# handled in Source/WTF/wtf/PlatformJSCOnly.cmake (selects
# generic/MemoryFootprintGeneric.cpp + unix/MemoryPressureHandlerUnix.cpp),
# and __FreeBSD__ is defined by --target=*-freebsd*.
# ───────────────────────────────────────────────────────────────────────────
FROM base AS build_webkit

ARG MARCH_FLAG
ARG WEBKIT_RELEASE_TYPE
ARG LTO_FLAG
ARG DEFAULT_CFLAGS
ARG FREEBSD_VERSION
ARG FREEBSD_ARCH

COPY . /webkit
WORKDIR /webkit
COPY --from=build_icu /output /icu

ENV WEBKIT_OUT_DIR=/webkitbuild

RUN --mount=type=tmpfs,target=/webkitbuild \
export TARGET_TRIPLE="${FREEBSD_ARCH}-unknown-freebsd${FREEBSD_VERSION}" && \
export CROSS="--target=${TARGET_TRIPLE} --sysroot=${FREEBSD_SYSROOT}" && \
export CFLAGS="${CROSS} ${DEFAULT_CFLAGS} ${MARCH_FLAG} ${LTO_FLAG} -isystem /icu/include -ffile-prefix-map=/webkit/Source=vendor/WebKit/Source -ffile-prefix-map=/webkitbuild/=." && \
export CXXFLAGS="${CROSS} -isystem ${FREEBSD_SYSROOT}/usr/include/c++/v1 ${DEFAULT_CFLAGS} ${MARCH_FLAG} ${LTO_FLAG} -isystem /icu/include -fno-c++-static-destructors -ffile-prefix-map=/webkit/Source=vendor/WebKit/Source -ffile-prefix-map=/webkitbuild/=." && \
cd /webkitbuild && \
cmake \
-DCMAKE_SYSTEM_NAME=FreeBSD \
-DCMAKE_SYSTEM_PROCESSOR=${FREEBSD_ARCH} \
-DCMAKE_SYSROOT=${FREEBSD_SYSROOT} \
-DCMAKE_C_COMPILER=$(which $CC) \
-DCMAKE_CXX_COMPILER=$(which $CXX) \
-DCMAKE_AR=$(which $AR) \
-DCMAKE_RANLIB=$(which $RANLIB) \
-DPORT=JSCOnly \
-DENABLE_STATIC_JSC=ON \
-DENABLE_BUN_SKIP_FAILING_ASSERTIONS=ON \
-DCMAKE_BUILD_TYPE=${WEBKIT_RELEASE_TYPE} \
-DUSE_THIN_ARCHIVES=OFF \
-DUSE_BUN_JSC_ADDITIONS=ON \
-DUSE_BUN_EVENT_LOOP=ON \
-DENABLE_FTL_JIT=ON \
-DENABLE_API_TESTS=OFF \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
-DALLOW_LINE_AND_COLUMN_NUMBER_IN_BUILTINS=ON \
-DENABLE_REMOTE_INSPECTOR=ON \
-DCMAKE_EXE_LINKER_FLAGS="${CROSS} -fuse-ld=lld" \
-DCMAKE_C_FLAGS="$CFLAGS" \
-DCMAKE_CXX_FLAGS="$CXXFLAGS" \
-DICU_ROOT=/icu \
-DICU_INCLUDE_DIR=/icu/include \
-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=BOTH \
-DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=BOTH \
-DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=BOTH \
Comment on lines +161 to +163

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

For a CMake cross-compilation that sets CMAKE_SYSROOT, when should CMAKE_FIND_ROOT_PATH_MODE_PACKAGE/LIBRARY/INCLUDEbeONLYinstead ofBOTH, and what host-contamination risks does BOTH introduce?

💡 Result:

Use ONLY mode for CMAKE_FIND_ROOT_PATH_MODE_PACKAGE, CMAKE_FIND_ROOT_PATH_MODE_LIBRARY, and CMAKE_FIND_ROOT_PATH_MODE_INCLUDE when cross-compiling with CMAKE_SYSROOT set, to ensure CMake's find_* commands (find_package, find_library, find_path) search exclusively in the sysroot and CMAKE_FIND_ROOT_PATH directories for target libraries, headers, and packages. Use ONLY in strict cross-compilation scenarios where the sysroot contains all required target dependencies. This is the recommended best practice in toolchain files, as shown in official CMake documentation examples. It forces isolation from the host system, preventing CMake from finding incompatible target artifacts on the host. BOTH mode searches both sysroot paths first, then host system paths. Host-contamination risks include: - Linking against host libraries of wrong architecture, causing linker errors or runtime failures (e.g., x86_64 host lib vs ARM target). - Including host headers with mismatched APIs/versions/ABIs, leading to subtle bugs, compilation failures, or binaries depending on unavailable host-specific symbols on target. - Silent failures where builds succeed but produce broken binaries (e.g., wrong glibc versions, versioned symbols). - Particularly dangerous with package managers like Conan that may override to BOTH, allowing fallback to /usr/lib on host. Set in toolchain file example: set(CMAKE_SYSROOT /path/to/target/sysroot) set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) # host tools set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

Citations:


Restrict CMake package/library/header discovery to the FreeBSD sysroot.

Using CMAKE_FIND_ROOT_PATH_MODE_{PACKAGE,LIBRARY,INCLUDE}=BOTH allows CMake to fall back to Ubuntu host artifacts during cross-compilation, risking mixed host/target inputs and broken FreeBSD binaries. Change these to ONLY to enforce sysroot-only discovery.

🔧 Suggested change
-    -DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=BOTH \
-    -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=BOTH \
-    -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=BOTH \
+    -DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ONLY \
+    -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY \
+    -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY \

If dependencies are discovered through pkg-config, also set PKG_CONFIG_SYSROOT_DIR and PKG_CONFIG_LIBDIR to the FreeBSD sysroot.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=BOTH \
-DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=BOTH \
-DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=BOTH \
-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ONLY \
-DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY \
-DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY \
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfile.freebsd` around lines 155 - 157, The CMake find root modes are
currently set to BOTH which allows fallback to host artifacts; change
CMAKE_FIND_ROOT_PATH_MODE_PACKAGE, CMAKE_FIND_ROOT_PATH_MODE_LIBRARY, and
CMAKE_FIND_ROOT_PATH_MODE_INCLUDE from BOTH to ONLY so CMake only searches the
FreeBSD sysroot, and also export PKG_CONFIG_SYSROOT_DIR and PKG_CONFIG_LIBDIR
pointing at the FreeBSD sysroot so pkg-config resolves target libs/headers from
the sysroot rather than the host environment.

-G Ninja \
/webkit && \
cmake --build /webkitbuild --config ${WEBKIT_RELEASE_TYPE} --target jsc && \
cp -r $WEBKIT_OUT_DIR/lib/*.a /output/lib && \
cp $WEBKIT_OUT_DIR/*.h /output/include && \
cp $WEBKIT_OUT_DIR/*.json /output && \
find $WEBKIT_OUT_DIR/JavaScriptCore/DerivedSources/ -name "*.h" -exec sh -c 'cp "$1" "/output/include/JavaScriptCore/$(basename "$1")"' sh {} \; && \
find $WEBKIT_OUT_DIR/JavaScriptCore/DerivedSources/ -name "*.json" -exec sh -c 'cp "$1" "/output/$(basename "$1")"' sh {} \; && \
find $WEBKIT_OUT_DIR/JavaScriptCore/Headers/JavaScriptCore/ -name "*.h" -exec cp {} /output/include/JavaScriptCore/ \; && \
find $WEBKIT_OUT_DIR/JavaScriptCore/PrivateHeaders/JavaScriptCore/ -name "*.h" -exec cp {} /output/include/JavaScriptCore/ \; && \
cp -r $WEBKIT_OUT_DIR/WTF/Headers/wtf/ /output/include && \
cp -r $WEBKIT_OUT_DIR/bmalloc/Headers/bmalloc/ /output/include && \
mkdir -p /output/Source/JavaScriptCore && \
cp -r /webkit/Source/JavaScriptCore/Scripts /output/Source/JavaScriptCore && \
cp /webkit/Source/JavaScriptCore/create_hash_table /output/Source/JavaScriptCore

FROM scratch AS artifact

COPY --from=build_icu /output /
COPY --from=build_webkit /output /
2 changes: 2 additions & 0 deletions Source/JavaScriptCore/assembler/ARM64Assembler.h
Original file line number Diff line number Diff line change
Expand Up @@ -4025,6 +4025,8 @@ class ARM64Assembler {
linuxPageFlush(current, end);
#elif OS(WINDOWS)
FlushInstructionCache(GetCurrentProcess(), code, size);
#elif OS(FREEBSD)
__builtin___clear_cache(reinterpret_cast<char*>(code), reinterpret_cast<char*>(code) + size);
#else
#error "The cacheFlush support is missing on this platform."
#endif
Expand Down
2 changes: 1 addition & 1 deletion Source/JavaScriptCore/assembler/ARM64Registers.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
// beyond what you would save by the platform-agnostic "preserve return address" and "restore
// return address" operations in CCallHelpers.

#if OS(LINUX)
#if OS(LINUX) || OS(FREEBSD)
#define FOR_EACH_GP_REGISTER(macro) \
/* Parameter/result registers. */ \
macro(x0, "x0"_s, 0, 0) \
Expand Down
4 changes: 2 additions & 2 deletions Source/JavaScriptCore/offlineasm/arm64.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1458,8 +1458,8 @@ def lowerARM64
$asm.puts "ldr #{operands[1].arm64Operand(:quad)}, [#{operands[1].arm64Operand(:quad)}, #{operands[0].asmLabel}@GOTPAGEOFF]"
$asm.putStr("#endif")

# On Linux, use ELF GOT relocation specifiers.
$asm.putStr("#elif OS(LINUX)")
# On Linux/FreeBSD, use ELF GOT relocation specifiers.
$asm.putStr("#elif OS(LINUX) || OS(FREEBSD)")

$asm.puts "adrp #{operands[1].arm64Operand(:quad)}, :got:#{operands[0].asmLabel}"
$asm.putStr("#if CPU(ADDRESS32)")
Expand Down
9 changes: 5 additions & 4 deletions Source/WTF/wtf/AvailableMemory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
#import <mach/mach.h>
#import <math.h>
#elif OS(UNIX)
#if OS(FREEBSD) || OS(LINUX)
#if OS(LINUX)
#include <sys/sysinfo.h>
#endif
#if OS(LINUX)
Expand Down Expand Up @@ -161,9 +161,10 @@ static size_t computeAvailableMemory()
}
return availableMemoryGuess;
#elif OS(FREEBSD)
struct sysinfo info;
if (!sysinfo(&info))
return info.totalram * info.mem_unit;
uint64_t physmem = 0;
size_t len = sizeof(physmem);
if (!sysctlbyname("hw.physmem", &physmem, &len, nullptr, 0))
return physmem;
return availableMemoryGuess;
#elif OS(UNIX) || OS(HAIKU)
long pages = sysconf(_SC_PHYS_PAGES);
Expand Down
1 change: 1 addition & 0 deletions Source/WTF/wtf/PlatformJSCOnly.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ elseif (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")

unix/MemoryPressureHandlerUnix.cpp
)
list(APPEND WTF_LIBRARIES execinfo)
else ()
list(APPEND WTF_SOURCES
generic/MemoryFootprintGeneric.cpp
Expand Down
2 changes: 1 addition & 1 deletion Source/WTF/wtf/RAMSize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

#if OS(WINDOWS)
#include <windows.h>
#elif OS(LINUX) || OS(FREEBSD)
#elif OS(LINUX)
#include <sys/sysinfo.h>
#elif OS(UNIX) || OS(HAIKU)
#endif
Expand Down
2 changes: 1 addition & 1 deletion Source/bmalloc/bmalloc/BPlatform.h
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@

/* BENABLE(LIBPAS) is enabling libpas build. But this does not mean we use libpas for bmalloc replacement. */
#if !defined(BENABLE_LIBPAS)
#if (!BUSE(MIMALLOC) && !BUSE(SYSTEM_MALLOC)) && BCPU(ADDRESS64) && (BOS(DARWIN) || BOS(WINDOWS) || (BOS(LINUX) && (BCPU(X86_64) || BCPU(ARM64))) || BPLATFORM(PLAYSTATION))
#if (!BUSE(MIMALLOC) && !BUSE(SYSTEM_MALLOC)) && BCPU(ADDRESS64) && (BOS(DARWIN) || BOS(WINDOWS) || ((BOS(LINUX) || BOS(FREEBSD)) && (BCPU(X86_64) || BCPU(ARM64))) || BPLATFORM(PLAYSTATION))
#define BENABLE_LIBPAS 1
#ifndef PAS_BMALLOC
#define PAS_BMALLOC 1
Expand Down
9 changes: 9 additions & 0 deletions Source/bmalloc/libpas/src/libpas/pas_monotonic_time.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,15 @@ uint64_t pas_get_current_monotonic_time_nanoseconds(void)
return ts.tv_sec * 1.0e9 + ts.tv_nsec;
}

#elif PAS_OS(FREEBSD)

uint64_t pas_get_current_monotonic_time_nanoseconds(void)
{
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC_FAST, &ts);
return (uint64_t)ts.tv_sec * 1000ull * 1000ull * 1000ull + (uint64_t)ts.tv_nsec;
}
Comment on lines +91 to +98

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

find . -path "*libpas/pas_monotonic_time.c" -type f

Repository: oven-sh/WebKit

Length of output: 114


🏁 Script executed:

cat -n ./Source/bmalloc/libpas/src/libpas/pas_monotonic_time.c

Repository: oven-sh/WebKit

Length of output: 4580


🏁 Script executed:

cat -n ./Source/bmalloc/libpas/src/libpas/pas_monotonic_time.h

Repository: oven-sh/WebKit

Length of output: 1883


🏁 Script executed:

head -100 ./Source/bmalloc/libpas/src/libpas/pas_config.h

Repository: oven-sh/WebKit

Length of output: 3386


🏁 Script executed:

head -150 ./Source/bmalloc/libpas/src/libpas/pas_utils.h | grep -A 5 -B 5 "include"

Repository: oven-sh/WebKit

Length of output: 1415


Add explicit <time.h> coverage for the FreeBSD branch.

The FreeBSD implementation at lines 95-96 uses struct timespec and clock_gettime(), both defined in <time.h>. Currently, the <time.h> include guard (lines 39-41) covers only Linux and PlayStation, leaving FreeBSD to rely on transitive includes. Extend the include guard to explicitly include <time.h> for FreeBSD, matching the pattern used for other platforms.

Proposed diff
-#if PAS_OS(LINUX) || PAS_PLATFORM(PLAYSTATION)
+#if PAS_OS(LINUX) || PAS_OS(FREEBSD) || PAS_PLATFORM(PLAYSTATION)
 `#include` <time.h>
 `#endif`
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Source/bmalloc/libpas/src/libpas/pas_monotonic_time.c` around lines 91 - 98,
The FreeBSD branch uses struct timespec and clock_gettime in
pas_get_current_monotonic_time_nanoseconds but doesn't explicitly include
<time.h>; update the platform include guard that currently adds <time.h> for
Linux/PlayStation to also cover PAS_OS(FREEBSD) so the FreeBSD branch explicitly
includes <time.h> (ensure the change is made alongside the existing
include-guard pattern used for other platforms to keep consistency).


#elif PAS_PLATFORM(PLAYSTATION)

uint64_t pas_get_current_monotonic_time_nanoseconds(void)
Expand Down
Loading
Loading