Author: BlinkGTK Project
Last updated: 2026-07-03
Audience: Developers who want to build a self-contained
(portable) application from the BlinkGTK binary distribution that runs
from a single directory
A portable BlinkGTK application bundles your application executable
together with the complete BlinkGTK / Chromium runtime in a single
directory, so that it runs by simply copying the directory — no
system installation (RPM/DEB) required. It relies on
$ORIGIN-relative RPATH (paths resolved relative to the
executable itself), so the directory keeps working wherever it is
moved.
However, "self-contained" has a well-defined boundary: only the BlinkGTK and Chromium runtimes are bundled. GTK4, glibc, GPU drivers and similar components come from the host system. If you do not understand this boundary, you will run into "I copied it but it does not start" situations. Chapter 2 explains the constraints in detail.
A portable build does not run everywhere. Check the following constraints carefully.
GLIBC_x.xx not found.ldd --version # host glibc version
ldd ./libblinkgtk-0.1.so.0.0.0 | grep "not found" # list missing dependencies
If even one not found line appears, the host cannot run
this build.pkg-config --modversion gtk4, or query
your distribution's package manager.--ozone-platform=wayland internally). It does not work in
X11 sessions.echo $XDG_SESSION_TYPE (it
must print wayland).--no-sandbox
works but forfeits security protection; never use it to display
untrusted content./tmp is mounted noexec, extract to a location
where execution is permitted.| Item | Requirement | Check command |
|---|---|---|
| CPU | x86_64 | uname -m |
| glibc | build-era or newer | ldd --version /
ldd ... | grep "not found" |
| GTK4 | 4.6+ (system) | pkg-config --modversion gtk4 |
| Session | Wayland | echo $XDG_SESSION_TYPE |
| GPU (EGL) | Mesa + dmabuf | isolate with software path |
| user namespaces | enabled | check on sandbox startup failure |
| Filesystem | ext4 etc. + exec allowed | mount | grep noexec |
| Japanese fonts | required on host | fc-list | grep -i mincho etc. |
Recommended layout (single self-contained directory):
myapp-portable/
├── myapp # your application executable (RPATH=$ORIGIN/lib)
├── run.sh # launch script (optional, for environment variables)
├── lib/
│ ├── libblinkgtk-0.1.so.0.0.0
│ ├── libblinkgtk-0.1.so.0 -> libblinkgtk-0.1.so.0.0.0
│ └── chromium/ # complete Chromium runtime (from the binary distribution)
│ ├── *.so # shared libraries
│ ├── icudtl.dat / snapshot_blob.bin / v8_context_snapshot.bin
│ ├── content_shell.pak
│ └── locales/ja.pak, en-US.pak
├── share/
│ └── myapp/ # your application resources
└── THIRD_PARTY_NOTICES.html # mandatory (Chapter 6)
The runtime set is obtained by copying
usr/lib64/blinkgtk-0.1/ from the binary distribution
(runtime tarball) into lib/ as-is. Do not
cherry-pick files — every Chromium runtime .so,
.pak, .dat, .bin, and
locales/ file is required at startup (missing files are the
classic cause of startup crashes).
Build your application with pkg-config. Linking the PartitionAlloc allocator shim directly is mandatory (pkg-config includes it automatically). Without the shim, page loads fail and you get a black screen.
gcc -o myapp myapp.c \
$(pkg-config --cflags --libs blinkgtk-0.1 gtk4)If you link manually without pkg-config, you must add
-lbase_allocator_partition_allocator_src_partition_alloc_allocator_shim
in addition to -lblinkgtk-0.1.
Give the executable an $ORIGIN-relative RPATH:
gcc -o myapp myapp.c \
$(pkg-config --cflags blinkgtk-0.1 gtk4) \
-Wl,-rpath,'$ORIGIN/lib' -Wl,-rpath,'$ORIGIN/lib/chromium' \
$(pkg-config --libs blinkgtk-0.1 gtk4)$ORIGIN means "the directory containing the executable
itself" and keeps resolving after the directory is moved.$ORIGIN.As an alternative to RPATH, a launch script can set
LD_LIBRARY_PATH:
#!/bin/sh
# run.sh — place directly under myapp-portable/
HERE="$(cd "$(dirname "$0")" && pwd)"
export LD_LIBRARY_PATH="$HERE/lib:$HERE/lib/chromium${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
exec "$HERE/myapp" "$@"Always verify before distributing:
# 1. Dependency completeness (zero "not found" lines)
ldd ./myapp | grep "not found"
# 2. The shim is a direct NEEDED entry
readelf -d ./myapp | grep allocator_shim
# 3. V8 snapshot consistency (normally consistent when taken from one distribution)
# Never mix libv8.so / snapshot_blob.bin / v8_context_snapshot.bin from
# different distribution versions in lib/chromium/ (causes startup crashes)
# 4. Launch test on a real Wayland session
./run.shtar czf myapp-portable-1.0-linux-x86_64.tar.gz myapp-portable/When you redistribute the BlinkGTK / Chromium runtime, the following are required:
libffmpeg.so is LGPL v2.1+. It is shipped as an independent
shared library; keep it replaceable by users (do not statically link,
remove or rename it).| Symptom | Likely cause | Action |
|---|---|---|
GLIBC_x.xx not found |
host glibc too old | update host or use a same-generation environment (§2.2) |
| Crash right after startup (SIGTRAP) | mixed V8 snapshots / shim not linked | check items 2 and 3 in §4.3 |
| No window appears | X11 session / no compositor | check $XDG_SESSION_TYPE (§2.4) |
| Page stays black | shim not linked | verify with readelf -d (§4.1) |
Permission denied |
noexec mount / lost exec bits | §2.7 (re-extract from tar.gz) |
| Starts but shows tofu/garbled text | no Japanese fonts on host | §2.9 |
| Renderer fails to start | user namespaces disabled | §2.6 |
consumer-integration-guide-en.md) — API, signals,
lifecycleinstallation/INSTALLATION-en.md) —
system installation via RPM/DEB