Skip to content

Building WPEWebKit for 32‐bit Raspberry Pi 3 (Buildroot DRM config)

Justin Michaud edited this page Mar 12, 2026 · 15 revisions

This is an easy and reliable way to build a WPE image, but it does not have the graphics drivers that using Yocto gives.

image of rpi screen

This is on my Fedora laptop, set up as follows:

Host: /WebKit/buildroot: https://github.com/WebPlatformForEmbedded/buildroot wpe branch /WebKit/Yokto/OpenSource: https://github.com/WebPlatformForEmbedded/WPEWebKit wpe-2.38 branch

Ignore the Yokto name, this is not using Yokto.

Inside Ubuntu docker, these map to: /root/buildroot /root/Yokto/OpenSource/

Run on laptop running Fedora Workstation 40:

# SELinux stuff, Fedora only
chcon -Rt svirt_sandbox_file_t /WebKit/buildroot/
chcon -Rt svirt_sandbox_file_t /WebKit/Yokto/

# Change paths
docker run -ti --rm -v /WebKit/buildroot:/root/buildroot -v /WebKit/Yokto:/root/Yokto mcr.microsoft.com/devcontainers/base:ubuntu-22.04 /bin/bash

apt update && apt install -y file cpio bc libncurses-dev

git config --global user.email "no" && git config --global user.name "no"

cd ~/buildroot

make raspberrypi3_wpe_2_46_cog_defconfig
make menuconfig

Target packages → Libraries → Graphics -> select anything you neeed

ex: gdb, wpe extra options -> reftracker, Target packages > Hardware handling > Firmware > Override firmware version for pi 3b+

FORCE_UNSAFE_CONFIGURE=1 make -j 8

Make partitions on sd card (boot 512mb, root)

# Change mount paths
sudo cp -R output/images/rpi-firmware/* /media/jmichaud/BOOT/ && sudo cp output/images/zImage /media/jmichaud/BOOT/ && sudo cp output/images/bcm2710-rpi-3* /media/jmichaud/BOOT/ && sudo tar -xvpsf output/images/rootfs.tar -C /media/jmichaud/rootfs/
(or just to update after rebuilding:) sudo tar -xvpsf output/images/rootfs.tar -C /media/jmichaud/rootfs/ --overwrite-dir --recursive-unlink

See below to update via scp

sync
sudo umount /run/media/justin/*

ssh root@10.42.0.55 -o UserKnownHostsFile=/dev/null
(pw root)

On PI:

/etc/init.d/S90cog stop
cog  --enable-write-console-messages-to-stdout=1 https://example.com

# Alternatively
JSC_validateOptions=1 JSC_useDollarVM=1 JSC_enableStrongRefTracker=1 JSC_dumpHeapOnLowMemory=0 JSC_useSourceProviderCache=0 JSC_useCodeCache=0 WEBKIT_DISABLE_SANDBOX_THIS_IS_DANGEROUS=1 cog  --enable-write-console-messages-to-stdout=1 https://example.com

In another ssh session:

cogctl -y open google.com

Using a custom checkout

On Pi, in buildroot directory:

# cat ./local.mk
WPEWEBKIT_OVERRIDE_SRCDIR = /root/Yokto/OpenSource
rm -rf output/build/wpewebkit*
make wpewebkit-reconfigure
make wpewebkit-rebuild

WebKit development cycle:

make wpewebkit-rebuild
scp  -o UserKnownHostsFile=/dev/null -O output/target/usr/lib/libWPEWebKit* buildroot:/usr/lib

View memory usage

# Desktop
# In the url bar:
javascript: $vm.gc() | $vm.triggerMemoryPressure()
# In the terminal
ps -ao pid,comm,pmem

# PI:
cogctl -y open "javascript:\$vm.gc()|\$vm.triggerMemoryPressure()"
cat /proc/$(ps -ef | awk '$3=="/usr/libexec/wpe-webkit-1.1/WPEWebProcess" {print $1}')/status | grep "VmRSS"

Set up ethernet proxy if you don't have a router

Connect rpi to laptop, and set ehternet ipv4 to "shared to other computers" in NetworkManager

Set up dante:

systemctl stop firewalld.service
sudo gnome-text-editor /etc/sockd.conf

Text:

internal: 0.0.0.0 port = 1080
external: wlp0s20f3
logoutput: /var/log/sockd.log

socksmethod: username none #rfc931
clientmethod: none

user.privileged: root
user.unprivileged: nobody

client pass {
	from: 0.0.0.0/0 to: 0.0.0.0/0
	log: error connect disconnect
}

socks pass {
    	from: 0.0.0.0/0 to: 0.0.0.0/0
	log: error connect disconnect
}

pass {
    	from: 0.0.0.0/0 to: 0.0.0.0/0
	log: error connect disconnect
}
sudo systemctl start sockd
journalctl -xeu sockd.service
curl --socks5 localhost:1080 http://example.com
journalctl -b --since "10min ago" | grep sockd

On PI:

date -s '2024-08-01 12:34:56'

echo $'export http_proxy=\"socks5://10.42.0.1:1080\"\nexport https_proxy=\"socks5://10.42.0.1:1080\"' > ~/.profile
chmod +x ~/.profile

Making disk images

#!/bin/bash

set -x
set -e

# apt install fdisk kpartx dosfstools

rm -f output/disk.img
fallocate -l 4G output/disk.img
printf "n\np\n1\n\n+512M\na\nt\nc\nn\np\n2\n\n\nw\n" | /usr/sbin/fdisk output/disk.img
map=$(sudo kpartx -v -a output/disk.img)
boot=/dev/mapper/$(echo "$map" | grep p1 | cut -d " " -f 3)
root=/dev/mapper/$(echo "$map" | grep p2 | cut -d " " -f 3)
sudo mkfs.fat -F 32 -n "BOOT" $boot
sudo mkfs.ext4 $root
sudo mkdir -p /mnt/{boot,root}
sudo mount $boot /mnt/boot/
sudo mount $root /mnt/root
sudo cp -R output/images/rpi-firmware/* /mnt/boot/
sudo cp output/images/zImage /mnt/boot/
sudo cp output/images/bcm2710-rpi-3* /mnt/boot/
sudo tar -xpsf output/images/rootfs.tar -C /mnt/root/
sudo umount /mnt/root/
sudo umount /mnt/boot
sudo kpartx -d -v output/disk.img
file output/disk.img

Debug builds

Select Libraries -> Graphics -> WPE -> Build options in menuconfig

Running benchmarks on pi

WPE_BCMRPI_CURSOR=1 cog https://browserbench.org/Speedometer3.0/?startAutomatically=1

https://browserbench.org/Speedometer3.0/InteractiveRunner.html?suites=React-Stockcharts-SVG&startAutomatically=1 https://browserbench.org/JetStream/?report=true

Pi WebInspector

    export WEBKIT_INSPECTOR_HTTP_SERVER=0.0.0.0:9999
    cog https://browserbench.org/MotionMark

open http://rpi-ip:9999/ on desktop

Pi wifi

Target packages -> Networking applications -> wpa_supplicant (Enable wpa_supplicant and wpa_cli) Target packages -> Networking applications -> wireless-tools

rfkill???

wpa_passphrase "Ducky0183" "PW" | sudo tee /media/jmichaud/rootfs/etc/wpa_supplicant.conf

wpa_supplicant -D nl80211 -i wlan0 -c /etc/wpa_supplicant.conf -B

Core dumps

mkdir -p /tmp/core_files
chmod a+rwx /tmp/core_files # Ensure correct permissions
sysctl -w kernel.core_pattern="/tmp/core_files/core.%e.%p.%h.%t"
ulimit -c unlimited

cogctl -y open "https://browserbench.org/JetStream/?report=true"

Running pi image on Desktop (not working)

tar -xvpsf ~/Development/64/Development/buildroot/output/images/rootfs.tar -C ~/Development/32/wperoot

# outside a container
export CHROOT_DIR=/home/jmichaud/wperoot
sudo mount -o bind /dev $CHROOT_DIR/dev
sudo mount -o bind /dev/pts $CHROOT_DIR/dev/pts
sudo mount -o bind /proc $CHROOT_DIR/proc
sudo mount -o bind /sys $CHROOT_DIR/sys
sudo setarch linux32 chroot wperoot /bin/bash

---

sudo umount $CHROOT_DIR/*
sudo lsof +D $CHROOT_DIR/dev

Building 238 32-bit in container sdk for desktop

In 32-bit container sdk:

git checkout wpe-2.38
rm -rf /home/jmichaud/Development/ReleaseVersion/OpenSource/Tools/Scripts/libraries
rm -rf WebKitBuild
git checkout .
sudo apt install software-properties-common
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt update
sudo apt install python3.11 python3.11-venv python3.11-dev
cd $HOME && python3.11 -m venv myenv && source myenv/bin/activate
source init-release
export PKG_CONFIG_PATH=$PWD/WebKitBuild/Release:$PKG_CONFIG_PATH
clear; linux32 Tools/Scripts/build-webkit --wpe --release --no-fatal-warnings --cmakeargs="-DENABLE_INTROSPECTION=OFF -DENABLE_ACCELERATED_2D_CANVAS=OFF"

Make sure nvidia drivers are not installed.

jmichaud@wkdev32:~$ cat ~/.profile 
export XDG_SESSION_TYPE=x11
export GDK_BACKEND=x11
export QT_QPA_PLATFORM=xcb
export LIBGL_ALWAYS_SOFTWARE=1
export QT_XCB_FORCE_SOFTWARE_OPENGL=1
Tools/Scripts/run-minibrowser --wpe -- --platform=wl

-- or --

WEBKIT_EXEC_PATH=/home/jmichaud/Development/ReleaseVersion/OpenSource/WebKitBuild/Release/bin/  WEBKIT_INJECTED_BUNDLE_PATH=/home/jmichaud/Development/ReleaseVersion/OpenSource/WebKitBuild/Release/lib/ WEBKIT_TOP_LEVEL=/home/jmichaud/Development/ReleaseVersion/OpenSource COG_MODULEDIR=/home/jmichaud/Development/ReleaseVersion/OpenSource/WebKitBuild/Release/Tools/cog-prefix/src/cog-build/platform/ gdb --args /home/jmichaud/Development/ReleaseVersion/OpenSource/WebKitBuild/Release/Tools/cog-prefix/src/cog-build/launcher/cog -P x11

Clone this wiki locally