Two related changes that ship together because they touch the same
build-script + docs surface and were verified together on-device.
16 KiB alignment
- zygisk/build.rs: pass `-Wl,-z,max-page-size=16384` to lld so the
cdylib's LOAD segments line up on 16 KiB pages. NDK r28+ already
does this by default, but the flag keeps r27 builds compatible.
- lsposed/native/build.rs: new file, same flag, for libvpnhide_checks.so.
- docs/development.md: bumped the NDK requirement to r28+ and noted
the 16 KiB rationale.
Verified via `llvm-readelf -l`: both libvpnhide_zygisk.so and
libvpnhide_checks.so now show `Align 0x4000` on every LOAD segment.
Unified build entry points
- kmod/build.py replaces kmod/build-zip.py. Single script that
auto-detects whether to build natively (we're inside the DDK image
or `--kdir` was passed) or to spawn `ghcr.io/ylarod/ddk-min` via
podman/docker. CI uses the same script with `--inside-container`.
- zygisk/build-zip.py renamed to zygisk/build.py for symmetry; logic
unchanged.
- kmod/BUILDING.md rewritten — local build is now one command:
`./kmod/build.py --kmi android14-6.1` (or `--all`). The old
hand-rolled podman/docker recipes are gone.
- .github/workflows/ci.yml updated to call the new entry points.
The DDK image tag in CI now has a comment pointing at
`DDK_IMAGE_TAG` in kmod/build.py as the source of truth.
- README.{md,en.md}, kmod/README.md, zygisk/README.md, docs/releasing.md,
scripts/build_lib.py: reference updates.
- README.en.md: also fixes a "bacame" typo and tightens the Windows
zygisk-build note (the aux.rs / libgit2 issue is still real).
Verified end-to-end on Pixel 8 Pro (husky, android14-6.1, Android 16):
APK installs, kmod + zygisk modules load, all 26 self-checks PASS in
Enforcing, 22/26 PASS in Permissive (the same 4 by-design FAILs as
before — kmod doesn't cover those paths in Permissive).
|
||
|---|---|---|
| .. | ||
| added-align-native-cdylib-load-segments-on-f3b0.md | ||
| fixed-catch-tunnels-renamed-to-the-kernel-d126.md | ||
| fixed-dashboard-vpn-active-detection-now-matches-5f3a.md | ||
| fixed-kmod-stop-hanging-rtm-getlink-dumps-171a.md | ||
| fixed-native-diagnostics-now-recognize-utun-l2tp-5a82.md | ||
| fixed-notification-time-increased-to-make-it-fc9a.md | ||
| fixed-restore-debug-logging-flag-for-the-dcb2.md | ||
| fixed-save-snackbar-on-the-app-hiding-fcab.md | ||
| README.md | ||
| removed-drop-redundant-netlink-rtm-getlink-recv-8c6c.md | ||
Unreleased changelog fragments
Each .md file here is a single entry that will land in the next
release. ./scripts/release.py rotates all fragments into history[0]
of lsposed/app/src/main/assets/changelog.json and deletes the files.
Adding an entry
./scripts/changelog.py <type> "<EN text>" "<RU text>"
Types: added, changed, fixed, removed, deprecated, security.
This writes a single file changelog.d/<type>-<slug>-<hex4>.md. That's
the only file modified — CHANGELOG.md is regenerated only at release
time, so two concurrent PRs can't collide on it. The 4-char hex suffix
is random; two teammates picking the same slug still produce different
filenames.
Commit the new fragment alongside your code change. To preview the
pending (fragments-only) changelog, run ./scripts/preview-changelog.py.
Fragment file format
Filename: <type>-<slug>-<hex4>.md — the type is part of the name so
you can tell what kind of change a fragment is at a glance in the
directory listing.
Body: a date line on top, then two language sections. Renders directly on GitHub — no TOML, no YAML frontmatter, no parser dependency.
_2026-04-19_
## English
App no longer crashes when ...
## Русский
Приложение больше не падает когда ...
The date is in YYYY-MM-DD format, wrapped in _…_ so GitHub renders
it as a subtle italic line. changelog.py writes today's date
automatically; when editing by hand, keep the format literal so the
parser recognises it.
Leading/trailing whitespace inside each language section is stripped when loaded. Fragments are sorted chronologically by that date when the Unreleased preview is rendered; ties fall back to filename order.
Prefer the changelog.py script for creating fragments; editing by
hand works but you need to match the filename pattern and section
headings exactly.