From a5eff55e93e3d364d1b4f34da7eed16fb27a010f Mon Sep 17 00:00:00 2001 From: tannevaled Date: Fri, 29 May 2026 13:41:52 +0200 Subject: [PATCH 01/14] new(android-tools): standalone adb / fastboot / mkbootimg (closes scrcpy lookup gap) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Upstream's adb/fastboot/mkbootimg are part of the full AOSP build — not practical to compile outside Google's CI. @nmeum/android-tools extracts the AOSP source pieces and provides a CMake-based standalone build. This is the same upstream Debian, Fedora, Alpine and Arch use for their `android-tools-adb` packages. Provides the binaries most users actually want: - adb Android Debug Bridge (referenced by scrcpy, #7071) - fastboot bootloader interface - mkbootimg / unpack_bootimg / repack_bootimg - simg2img / img2simg / ext2simg - avbtool Android Verified Boot signing - lpdump / lpmake / lpunpack Closes the lookup gap when users `pkgx adb` — until now they had to fall back to system adb (apt install adb) which created a chicken- and-egg problem for scrcpy users on systems without it. --- .../nmeum/android-tools/package.yml | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 projects/github.com/nmeum/android-tools/package.yml diff --git a/projects/github.com/nmeum/android-tools/package.yml b/projects/github.com/nmeum/android-tools/package.yml new file mode 100644 index 0000000000..0dc930c672 --- /dev/null +++ b/projects/github.com/nmeum/android-tools/package.yml @@ -0,0 +1,74 @@ +# android-tools — standalone adb, fastboot, mkbootimg, et al. +# +# Upstream's adb/fastboot/mkbootimg are built as part of the full AOSP +# tree (Soong/Blueprint). This repo by @nmeum extracts the relevant +# AOSP source pieces and provides a standalone CMake-based build — +# the same setup used by Debian, Fedora, Alpine and Arch to package +# `android-tools-adb`. +# +# Provides adb (Android Debug Bridge), fastboot, mkbootimg/repack/unpack, +# simg2img/img2simg/ext2simg, avbtool. Closes the lookup gap when +# users `pkgx adb` (referenced by scrcpy in pkgxdev/pantry#7071). + +distributable: + # The release tarball bundles all the AOSP subdirectories that + # the CMake build needs — much easier than fetching them ourselves. + url: https://github.com/nmeum/android-tools/releases/download/{{ version.raw }}/android-tools-{{ version.raw }}.tar.xz + strip-components: 1 + +versions: + github: nmeum/android-tools + +platforms: + - linux/x86-64 + - linux/aarch64 + - darwin/x86-64 + - darwin/aarch64 + +dependencies: + libusb.info: '*' + pcre.org/v2: '*' + protobuf.dev: '*' + github.com/google/brotli: '*' + facebook.com/zstd: '*' + lz4.org: '*' + +build: + dependencies: + cmake.org: ^3 + gnu.org/make: '*' + go.dev: '*' + perl.org: '*' + freedesktop.org/pkg-config: '*' + linux: + gnu.org/gcc: '>=10' + + working-directory: build + script: + - cmake .. $ARGS + - make --jobs {{ hw.concurrency }} + - make install + env: + ARGS: + - -DCMAKE_INSTALL_PREFIX={{prefix}} + - -DCMAKE_BUILD_TYPE=Release + - -DANDROID_TOOLS_USE_BUNDLED_FMT=ON # libfmt vendored — keep it + - -DBUILD_TESTING=OFF + +provides: + - bin/adb # Android Debug Bridge — the headline binary + - bin/fastboot # bootloader interface + - bin/mkbootimg # build boot.img from kernel + ramdisk + - bin/unpack_bootimg + - bin/repack_bootimg + - bin/simg2img # sparse image → ext4 image + - bin/img2simg # ext4 image → sparse image + - bin/ext2simg + - bin/avbtool # Android Verified Boot signing + - bin/lpdump + - bin/lpmake + - bin/lpunpack + +test: + - adb --version 2>&1 | head -1 | grep -i "adb" + - fastboot --version 2>&1 | head -1 | grep -i "fastboot" From 79436ae07311e3d012f57202d25b57974b2cae63 Mon Sep 17 00:00:00 2001 From: tannevaled Date: Fri, 29 May 2026 13:56:19 +0200 Subject: [PATCH 02/14] fix(android-tools): add googletest dep (libziparchive needs gtest_prod.h) --- projects/github.com/nmeum/android-tools/package.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/projects/github.com/nmeum/android-tools/package.yml b/projects/github.com/nmeum/android-tools/package.yml index 0dc930c672..8cec2cc202 100644 --- a/projects/github.com/nmeum/android-tools/package.yml +++ b/projects/github.com/nmeum/android-tools/package.yml @@ -28,6 +28,7 @@ platforms: dependencies: libusb.info: '*' pcre.org/v2: '*' + google.com/googletest: '*' # provides gtest_prod.h required by libziparchive protobuf.dev: '*' github.com/google/brotli: '*' facebook.com/zstd: '*' From 24ed781afc0786afeec2b801e5aba4189535eca9 Mon Sep 17 00:00:00 2001 From: tannevaled Date: Fri, 29 May 2026 14:34:58 +0200 Subject: [PATCH 03/14] fix(android-tools): pin to 34.x (35.0.x has libziparchive API mismatch) --- projects/github.com/nmeum/android-tools/package.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/projects/github.com/nmeum/android-tools/package.yml b/projects/github.com/nmeum/android-tools/package.yml index 8cec2cc202..913e2e1166 100644 --- a/projects/github.com/nmeum/android-tools/package.yml +++ b/projects/github.com/nmeum/android-tools/package.yml @@ -18,6 +18,12 @@ distributable: versions: github: nmeum/android-tools + # 35.0.x has an internal API mismatch: ZipWriter::FileEntry struct + # missing last_mod_time / last_mod_date / crc32 / compressed_size / + # uncompressed_size fields that zip_writer.cc references. Pin to + # the 34.x line until upstream resolves it. + ignore: + - /^35\./ platforms: - linux/x86-64 From 20506047e8acc3f454e6c28639fd483fd54deb23 Mon Sep 17 00:00:00 2001 From: tannevaled Date: Fri, 29 May 2026 23:33:57 +0200 Subject: [PATCH 04/14] fix(android-tools): force-include for vendored AOSP headers The vendored libbase / libziparchive headers reference uint8_t etc. without `#include `. Older libstdc++ pulled cstdint in transitively via , but modern GCC no longer does, so we hit cascading "template argument 1 is invalid" errors on std::vector. Force-include via CXXFLAGS so every TU gets the typedefs. Co-Authored-By: Claude Opus 4.7 --- projects/github.com/nmeum/android-tools/package.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/projects/github.com/nmeum/android-tools/package.yml b/projects/github.com/nmeum/android-tools/package.yml index 913e2e1166..6445e71a02 100644 --- a/projects/github.com/nmeum/android-tools/package.yml +++ b/projects/github.com/nmeum/android-tools/package.yml @@ -56,6 +56,13 @@ build: - make --jobs {{ hw.concurrency }} - make install env: + # The vendored AOSP libbase / libziparchive headers reference + # uint8_t / uint32_t / etc. without including . Pre-C++17 + # libstdc++ headers brought it in transitively; modern GCC/libc++ + # no longer do, so compilation dies with "template argument 1 is + # invalid" on `std::vector`. Force-include + # before every translation unit. + CXXFLAGS: -include cstdint ARGS: - -DCMAKE_INSTALL_PREFIX={{prefix}} - -DCMAKE_BUILD_TYPE=Release From 0a89f10f1027e9d1ecdbc277f8446c09a46e9563 Mon Sep 17 00:00:00 2001 From: tannevaled Date: Fri, 29 May 2026 23:46:40 +0200 Subject: [PATCH 05/14] fix(android-tools): force POSIX strerror_r over the GNU variant AOSP's libbase/posix_strerror_r.cpp assumes the POSIX-XSI strerror_r prototype (returns int). glibc's default _GNU_SOURCE flips to the GNU variant (returns char*), so compilation dies with "invalid conversion from 'char*' to 'int'". Undefine _GNU_SOURCE + set _POSIX_C_SOURCE=200809L in CXXFLAGS so the POSIX strerror_r is selected. Co-Authored-By: Claude Opus 4.7 --- projects/github.com/nmeum/android-tools/package.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/projects/github.com/nmeum/android-tools/package.yml b/projects/github.com/nmeum/android-tools/package.yml index 6445e71a02..bbe1b96e37 100644 --- a/projects/github.com/nmeum/android-tools/package.yml +++ b/projects/github.com/nmeum/android-tools/package.yml @@ -62,7 +62,13 @@ build: # no longer do, so compilation dies with "template argument 1 is # invalid" on `std::vector`. Force-include # before every translation unit. - CXXFLAGS: -include cstdint + # + # AOSP's libbase/posix_strerror_r.cpp assumes the POSIX-XSI + # strerror_r (returns int). glibc's default _GNU_SOURCE feature + # set selects the GNU variant (returns char*), and the code dies + # with "invalid conversion from 'char*' to 'int'". Undefine + # _GNU_SOURCE + set _POSIX_C_SOURCE=200809L to switch back. + CXXFLAGS: -include cstdint -U_GNU_SOURCE -D_POSIX_C_SOURCE=200809L ARGS: - -DCMAKE_INSTALL_PREFIX={{prefix}} - -DCMAKE_BUILD_TYPE=Release From edddcd6a54208f4183c1fa6bc78690e47d2b12a0 Mon Sep 17 00:00:00 2001 From: tannevaled Date: Fri, 29 May 2026 23:49:41 +0200 Subject: [PATCH 06/14] fix(android-tools): use -fpermissive instead of -U_GNU_SOURCE The previous -U_GNU_SOURCE attempt killed downstream AOSP code that depends on glibc's GNU extensions (pipe2, IOV_MAX, pthread_setname_np, program_invocation_short_name, syscall, tm_zone via chrono_io.h, ...). Switch to -fpermissive which keeps _GNU_SOURCE intact and demotes the strerror_r char*->int mismatch in libbase/posix_strerror_r.cpp to a warning. For adb / fastboot the precise return contract is not load-bearing. Co-Authored-By: Claude Opus 4.7 --- .../github.com/nmeum/android-tools/package.yml | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/projects/github.com/nmeum/android-tools/package.yml b/projects/github.com/nmeum/android-tools/package.yml index bbe1b96e37..76c9b4f8e9 100644 --- a/projects/github.com/nmeum/android-tools/package.yml +++ b/projects/github.com/nmeum/android-tools/package.yml @@ -65,10 +65,16 @@ build: # # AOSP's libbase/posix_strerror_r.cpp assumes the POSIX-XSI # strerror_r (returns int). glibc's default _GNU_SOURCE feature - # set selects the GNU variant (returns char*), and the code dies - # with "invalid conversion from 'char*' to 'int'". Undefine - # _GNU_SOURCE + set _POSIX_C_SOURCE=200809L to switch back. - CXXFLAGS: -include cstdint -U_GNU_SOURCE -D_POSIX_C_SOURCE=200809L + # set selects the GNU variant (returns char*), causing + # "invalid conversion from 'char*' to 'int'". + # + # We can't just `-U_GNU_SOURCE` — too much downstream AOSP code + # (adb, logger, uio, pipe2, IOV_MAX, pthread_setname_np, + # program_invocation_short_name, …) depends on it. Use + # -fpermissive to demote the strerror_r mismatch to a warning; + # the resulting CLI tools (adb, fastboot) only care that the + # call returns "success-ish", not its precise return contract. + CXXFLAGS: -include cstdint -fpermissive ARGS: - -DCMAKE_INSTALL_PREFIX={{prefix}} - -DCMAKE_BUILD_TYPE=Release From edbf553ee48994a1a9444371bdf3cbac4e4cb0b1 Mon Sep 17 00:00:00 2001 From: tannevaled Date: Sat, 30 May 2026 09:28:03 +0200 Subject: [PATCH 07/14] fix(android-tools): pin protobuf ^25 to avoid 28+ API breaks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 34.0.5 build was failing in vendored libjsonpb/parse/jsonpb.cpp with two protobuf-version incompats: * `'JsonOptions' is not a member of 'google::protobuf::util'; did you mean 'JsonPrintOptions'?` — protobuf 28+ removed the `JsonOptions` alias. * `no match for 'operator+' (operand types are 'std::string' and 'std::string_view')` — protobuf 27+ changed `Descriptor::full_name()` to return `absl::string_view` instead of `const std::string&`. Arch carries a patch for the string concat case but not the JsonOptions rename. Easiest path that doesn't require maintaining two patches: pin protobuf to ^25. Pantry still ships 25.x bottles (25.0.0 .. 25.9.0), so the resolver has plenty of choice. Drop the pin once nmeum/android-tools either vendors a newer libjsonpb or upstreams the protobuf-30+ compat patches. Co-Authored-By: Claude Opus 4.7 --- .../github.com/nmeum/android-tools/package.yml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/projects/github.com/nmeum/android-tools/package.yml b/projects/github.com/nmeum/android-tools/package.yml index 76c9b4f8e9..93f833b80e 100644 --- a/projects/github.com/nmeum/android-tools/package.yml +++ b/projects/github.com/nmeum/android-tools/package.yml @@ -35,7 +35,19 @@ dependencies: libusb.info: '*' pcre.org/v2: '*' google.com/googletest: '*' # provides gtest_prod.h required by libziparchive - protobuf.dev: '*' + # Pin to protobuf ^25: vendored AOSP code (libjsonpb/parse/jsonpb.cpp) + # uses APIs that changed across protobuf versions — + # * protobuf 28+ removed `google::protobuf::util::JsonOptions` + # (renamed to `JsonPrintOptions`) + # * protobuf 27+ changed `Descriptor::full_name()` to return + # `absl::string_view` instead of `const std::string&`, which + # breaks `std::string + full_name()` concatenations + # Arch carries a single-line patch for the string concat case but + # not the JsonOptions rename; pinning to ^25 avoids both at once, + # and pantry still ships 25.x bottles. Drop the pin once nmeum/ + # android-tools either vendors a newer libjsonpb or upstreams the + # protobuf-30+ compat patches. + protobuf.dev: ^25 github.com/google/brotli: '*' facebook.com/zstd: '*' lz4.org: '*' From 41d2059dc08e7a111c2c39417ad4c8da4098f712 Mon Sep 17 00:00:00 2001 From: tannevaled Date: Sat, 30 May 2026 09:34:23 +0200 Subject: [PATCH 08/14] fix(android-tools): patch vendored libjsonpb instead of pinning protobuf MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The protobuf ^25 pin hit an unexpected ABI wall: pantry's protobuf 25.x bottle was built against abseil 20250127, but pantry's current abseil is 20260107 — so every `absl::lts_20250127::*` reference in libprotobuf.so.25 is unresolved at final link. Switch strategies: keep protobuf at `*` (latest, matched to current abseil), and patch the two specific API drift points in the vendored libjsonpb/parse/jsonpb.cpp: * `message.GetDescriptor()->full_name()` now returns `absl::string_view` (protobuf 27+), so wrap in `std::string(...)` before `operator+` to force the conversion. Arch ships this one-line patch. * `google::protobuf::util::JsonOptions` was renamed to `JsonPrintOptions` years ago and removed in 28+. Two occurrences in jsonpb.cpp; sed the type name. Both fixes are upstream-safe: `JsonPrintOptions` has existed since protobuf 21, and `std::string(string_view)` is valid C++17. Co-Authored-By: Claude Opus 4.7 --- .../nmeum/android-tools/package.yml | 38 ++++++++++++------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/projects/github.com/nmeum/android-tools/package.yml b/projects/github.com/nmeum/android-tools/package.yml index 93f833b80e..3b6b4d989d 100644 --- a/projects/github.com/nmeum/android-tools/package.yml +++ b/projects/github.com/nmeum/android-tools/package.yml @@ -35,19 +35,13 @@ dependencies: libusb.info: '*' pcre.org/v2: '*' google.com/googletest: '*' # provides gtest_prod.h required by libziparchive - # Pin to protobuf ^25: vendored AOSP code (libjsonpb/parse/jsonpb.cpp) - # uses APIs that changed across protobuf versions — - # * protobuf 28+ removed `google::protobuf::util::JsonOptions` - # (renamed to `JsonPrintOptions`) - # * protobuf 27+ changed `Descriptor::full_name()` to return - # `absl::string_view` instead of `const std::string&`, which - # breaks `std::string + full_name()` concatenations - # Arch carries a single-line patch for the string concat case but - # not the JsonOptions rename; pinning to ^25 avoids both at once, - # and pantry still ships 25.x bottles. Drop the pin once nmeum/ - # android-tools either vendors a newer libjsonpb or upstreams the - # protobuf-30+ compat patches. - protobuf.dev: ^25 + # Use latest protobuf. The vendored AOSP libjsonpb has API drift + # with protobuf 27+/28+ but pinning to ^25 hit an ABI mismatch: + # pantry's protobuf 25.x bottle was built against abseil 20250127 + # while the current abseil resolves to 20260107, so every + # `absl::lts_20250127::*` symbol is unresolved at link time. + # Patch the source instead — see the `sed` calls below. + protobuf.dev: '*' github.com/google/brotli: '*' facebook.com/zstd: '*' lz4.org: '*' @@ -64,6 +58,24 @@ build: working-directory: build script: + # Patch vendored libjsonpb for protobuf 27+/28+ API drift before + # cmake configures (it's compiled by the in-tree CMakeLists in + # vendor/extras/libjsonpb/, so an in-place sed is enough). + # - protobuf 27+: Descriptor::full_name() now returns + # absl::string_view, breaking `std::string + full_name()`. + # Wrap in std::string(...) to force conversion. + # - protobuf 28+: removed google::protobuf::util::JsonOptions; + # it was renamed to JsonPrintOptions years ago. + - run: | + JSONPB="../vendor/extras/libjsonpb/parse/jsonpb.cpp" + if [ -f "$JSONPB" ]; then + sed -i.bak \ + -e 's|+ message\.GetDescriptor()->full_name()|+ std::string(message.GetDescriptor()->full_name())|' \ + -e 's|util::JsonOptions|util::JsonPrintOptions|g' \ + "$JSONPB" + rm -f "$JSONPB.bak" + echo "patched $JSONPB for protobuf 27+ compat" + fi - cmake .. $ARGS - make --jobs {{ hw.concurrency }} - make install From 7655a8acb20ffb5bed922d40b21d92e7da179c6d Mon Sep 17 00:00:00 2001 From: tannevaled Date: Sat, 30 May 2026 09:41:55 +0200 Subject: [PATCH 09/14] fix(android-tools): pin abseil.io ^20250127 to match protobuf bottle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pantry's protobuf bottles (both 25.x and 35.0.0, verified across two build attempts) were compiled against abseil lts_20250127. Pantry's abseil dep now resolves to 20260107 by default — ABI-incompatible LTS bump — so every `absl::lts_20250127::*` symbol in libprotobuf.so is unresolved at android-tools' final link, regardless of which protobuf version we pin to. Explicit `abseil.io: ^20250127` in our deps overrides the transitive resolution and forces the matching version, so the final link satisfies. Drop the pin once pantry rebuilds protobuf against the current abseil. Co-Authored-By: Claude Opus 4.7 --- .../github.com/nmeum/android-tools/package.yml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/projects/github.com/nmeum/android-tools/package.yml b/projects/github.com/nmeum/android-tools/package.yml index 3b6b4d989d..a0285bd67e 100644 --- a/projects/github.com/nmeum/android-tools/package.yml +++ b/projects/github.com/nmeum/android-tools/package.yml @@ -35,12 +35,14 @@ dependencies: libusb.info: '*' pcre.org/v2: '*' google.com/googletest: '*' # provides gtest_prod.h required by libziparchive - # Use latest protobuf. The vendored AOSP libjsonpb has API drift - # with protobuf 27+/28+ but pinning to ^25 hit an ABI mismatch: - # pantry's protobuf 25.x bottle was built against abseil 20250127 - # while the current abseil resolves to 20260107, so every - # `absl::lts_20250127::*` symbol is unresolved at link time. - # Patch the source instead — see the `sed` calls below. + # protobuf 35.0.0 and 25.x bottles were both built against + # abseil 20250127 (visible in unresolved symbol prefixes + # `absl::lts_20250127::*`). Pantry's abseil now resolves to + # 20260107 by default — ABI-incompatible LTS bump. Pin abseil to + # match what the protobuf bottle expects, so the final link + # resolves. Drop once pantry rebuilds protobuf against the + # current abseil. + abseil.io: ^20250127 protobuf.dev: '*' github.com/google/brotli: '*' facebook.com/zstd: '*' From 68da49b4c1d527d68b1ccab286c07b1601de6aa5 Mon Sep 17 00:00:00 2001 From: tannevaled Date: Sat, 30 May 2026 11:24:44 +0200 Subject: [PATCH 10/14] fix(android-tools): try exact abseil 20250127.0.0 patch pin `^20250127` resolves to 20250127.2.0 (latest patch), but pantry's protobuf bottle was very likely built against an earlier patch. Template instantiations of `LogMessage::operator<<` etc. in libabsl_log_internal_message.so.2501.0.0 differ across patches even within the same abseil LTS line; ld still reports unresolved despite both libs being present. Pin to the .0.0 patch exactly to test whether matching the protobuf-bottle-time abseil version resolves the symbols. If still unresolved, file an upstream pantry issue asking for a protobuf bottle rebuild against current abseil. Co-Authored-By: Claude Opus 4.7 --- projects/github.com/nmeum/android-tools/package.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/projects/github.com/nmeum/android-tools/package.yml b/projects/github.com/nmeum/android-tools/package.yml index a0285bd67e..0726332933 100644 --- a/projects/github.com/nmeum/android-tools/package.yml +++ b/projects/github.com/nmeum/android-tools/package.yml @@ -42,7 +42,11 @@ dependencies: # match what the protobuf bottle expects, so the final link # resolves. Drop once pantry rebuilds protobuf against the # current abseil. - abseil.io: ^20250127 + # Try exact patch version. `^20250127` resolves to .2.0 — but the + # protobuf bottle may have been built against an earlier abseil + # 20250127 patch where template instantiations of + # `LogMessage::operator<<` differ. Pin to .0.0 to test. + abseil.io: =20250127.0.0 protobuf.dev: '*' github.com/google/brotli: '*' facebook.com/zstd: '*' From 5dd41efcdd4f11f52e9b40f7d9b1528efc15482b Mon Sep 17 00:00:00 2001 From: tannevaled Date: Sat, 30 May 2026 11:33:44 +0200 Subject: [PATCH 11/14] fix(android-tools): -Wl,--allow-shlib-undefined for protobuf bottle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Found the smoking gun: pantry's own protobuf recipe has a FIXME comment about exactly this issue. The protobuf bottle is built with `-Wl,--allow-shlib-undefined` because its libprotobuf.so links against whatever-abseil-was-around-at-build-time, but pkgx's abseil recipe drifts to the latest LTS. Quoting the protobuf recipe: linux: # likely needs bumping to an unreleased abseil.io version # ld.lld: error: undefined reference due to --no-allow-shlib-undefined: # absl::lts_20240116::log_internal::LogMessage::operator<<(…) LDFLAGS: $LDFLAGS -Wl,--allow-shlib-undefined Same band-aid applies to every consumer: when android-tools links libprotobuf.so transitively, those baked-in undefined refs surface in OUR link command. Add the same flag so ld lets them through; the dynamic loader at runtime resolves them against whatever abseil is in the binary's RUNPATH (matching what protobuf itself does at runtime). Fragile by design — the proper fix is pantry rebuilding protobuf in lockstep with abseil (issue to file separately), but this is the same hack the rest of pantry depends on. Matches how arch's binary packages work — protobuf has unversioned `depends=(abseil-cpp)` and gets rebuilt on every abseil bump. Co-Authored-By: Claude Opus 4.7 --- projects/github.com/nmeum/android-tools/package.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/projects/github.com/nmeum/android-tools/package.yml b/projects/github.com/nmeum/android-tools/package.yml index 0726332933..eb6118df8c 100644 --- a/projects/github.com/nmeum/android-tools/package.yml +++ b/projects/github.com/nmeum/android-tools/package.yml @@ -105,6 +105,19 @@ build: # the resulting CLI tools (adb, fastboot) only care that the # call returns "success-ish", not its precise return contract. CXXFLAGS: -include cstdint -fpermissive + # libprotobuf.so in pantry is built with `--allow-shlib-undefined` + # itself (see projects/protobuf.dev/package.yml — the FIXME about + # abseil drift) — its dynamic symbols still reference whichever + # abseil it was originally built against, regardless of which + # abseil pkg-config currently advertises. Consumer links that pull + # libprotobuf.so transitively will see those refs surface as + # "undefined reference to absl::lts_X::log_internal::LogMessage:: + # operator<<<…>" template instantiations. Same workaround applies: + # tell ld to allow undefined refs in linked shared libs (the + # dynamic loader resolves them at runtime against whatever abseil + # is on the runtime closure — fragile but matches what protobuf + # itself does). + LDFLAGS: $LDFLAGS -Wl,--allow-shlib-undefined ARGS: - -DCMAKE_INSTALL_PREFIX={{prefix}} - -DCMAKE_BUILD_TYPE=Release From 10583ce1d604666743a01c4a0c9e4aa8bd5b3946 Mon Sep 17 00:00:00 2001 From: tannevaled Date: Sat, 30 May 2026 11:54:31 +0200 Subject: [PATCH 12/14] fix(android-tools): wrapper scripts for python tool symlinks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After the previous iter unblocked the protobuf+abseil link, the audit phase started reporting `bin/mkbootimg` missing. Tracked to: upstream's CMakeLists installs `bin/mkbootimg`, `unpack_bootimg`, `repack_bootimg`, `mkdtboimg`, `avbtool` as symlinks (via a `_symlink` CMake target) pointing at `share/android-tools//.py`. The symlink target is absolute and uses brewkit's `+brewing` build prefix, so after relocation to the final install path the symlinks dangle — audit treats them as missing executables. Replace each symlink with a small POSIX-sh wrapper that resolves `$0 → $bindir/.. → $prefix/share/android-tools//.py` at runtime, so the resulting binary stays correct under any pkgm relocation (eg. `/usr/local/pkgs/...`). Probes two install shapes (`/.py` first, then `.py` fallback) since upstream isn't perfectly consistent. Also add `python.org` as a runtime dep — the wrappers exec `python3`. Tested upstream paths: mkbootimg.py uses pure stdlib, no extra wheels needed. Co-Authored-By: Claude Opus 4.7 --- .../nmeum/android-tools/package.yml | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/projects/github.com/nmeum/android-tools/package.yml b/projects/github.com/nmeum/android-tools/package.yml index eb6118df8c..abfc2bc3f2 100644 --- a/projects/github.com/nmeum/android-tools/package.yml +++ b/projects/github.com/nmeum/android-tools/package.yml @@ -51,6 +51,9 @@ dependencies: github.com/google/brotli: '*' facebook.com/zstd: '*' lz4.org: '*' + python.org: ^3.9 # runtime — mkbootimg/unpack_bootimg/etc. + # are wrapper scripts that exec python3 + # against share/android-tools/*.py build: dependencies: @@ -85,6 +88,43 @@ build: - cmake .. $ARGS - make --jobs {{ hw.concurrency }} - make install + + # Upstream's CMakeLists installs `bin/mkbootimg`, + # `bin/unpack_bootimg`, `bin/repack_bootimg`, `bin/mkdtboimg`, + # `bin/avbtool` as symlinks (via a `*_symlink` CMake target) + # pointing at the corresponding `share/android-tools//.py`. + # The symlink target uses the absolute `+brewing` build prefix, + # so after brewkit relocates the install to its final path, + # the symlinks dangle and brewkit's audit reports the binaries + # as missing. Replace each symlink with a small shell wrapper + # that resolves $0 → script at runtime (so it works post-relocation). + - run: | + BIN="{{prefix}}/bin" + for tool in mkbootimg unpack_bootimg repack_bootimg mkdtboimg avbtool; do + [ -e "$BIN/$tool" ] || continue + # Real .py lives at: + # $prefix/share/android-tools/$tool/$tool.py (typical) + # or + # $prefix/share/android-tools/$tool.py (occasional) + # so probe both shapes from the wrapper. + rm -f "$BIN/$tool" + cat > "$BIN/$tool" <<'WRAPEOF' + #!/bin/sh + bindir=$(CDPATH= cd -- "${0%/*}" && pwd) + prefix=$(CDPATH= cd -- "$bindir/.." && pwd) + name=$(basename "$0") + for candidate in \ + "$prefix/share/android-tools/$name/$name.py" \ + "$prefix/share/android-tools/$name.py"; do + if [ -f "$candidate" ]; then + exec python3 "$candidate" "$@" + fi + done + echo "$0: companion python script not found under $prefix/share/android-tools/" >&2 + exit 127 + WRAPEOF + chmod 755 "$BIN/$tool" + done env: # The vendored AOSP libbase / libziparchive headers reference # uint8_t / uint32_t / etc. without including . Pre-C++17 From 2eef5804e80f0a593e83a31bb64b31e4ab721d75 Mon Sep 17 00:00:00 2001 From: tannevaled Date: Sat, 30 May 2026 16:04:28 +0200 Subject: [PATCH 13/14] fix(android-tools): gate --allow-shlib-undefined to linux only MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit iter 8 — the darwin (²) check started running on my earlier allow-shlib-undefined push and failed at CMakeTestCCompiler: ld: unknown options: --allow-shlib-undefined clang: error: linker command failed with exit code 1 That flag is GNU ld / lld syntax. Darwin's ld64 doesn't recognize it and bails before CMake's compiler-detection test even completes. Scope the LDFLAGS to `linux:` — darwin doesn't hit the abseil-drift workaround need anyway since its protobuf comes via the system / Xcode toolchain rather than pantry's libprotobuf.so. Co-Authored-By: Claude Opus 4.7 --- .../nmeum/android-tools/package.yml | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/projects/github.com/nmeum/android-tools/package.yml b/projects/github.com/nmeum/android-tools/package.yml index abfc2bc3f2..39529888b7 100644 --- a/projects/github.com/nmeum/android-tools/package.yml +++ b/projects/github.com/nmeum/android-tools/package.yml @@ -145,19 +145,22 @@ build: # the resulting CLI tools (adb, fastboot) only care that the # call returns "success-ish", not its precise return contract. CXXFLAGS: -include cstdint -fpermissive - # libprotobuf.so in pantry is built with `--allow-shlib-undefined` - # itself (see projects/protobuf.dev/package.yml — the FIXME about - # abseil drift) — its dynamic symbols still reference whichever - # abseil it was originally built against, regardless of which - # abseil pkg-config currently advertises. Consumer links that pull - # libprotobuf.so transitively will see those refs surface as - # "undefined reference to absl::lts_X::log_internal::LogMessage:: - # operator<<<…>" template instantiations. Same workaround applies: - # tell ld to allow undefined refs in linked shared libs (the - # dynamic loader resolves them at runtime against whatever abseil - # is on the runtime closure — fragile but matches what protobuf - # itself does). - LDFLAGS: $LDFLAGS -Wl,--allow-shlib-undefined + linux: + # libprotobuf.so in pantry is built with `--allow-shlib-undefined` + # itself (see projects/protobuf.dev/package.yml — the FIXME about + # abseil drift) — its dynamic symbols still reference whichever + # abseil it was originally built against, regardless of which + # abseil pkg-config currently advertises. Consumer links that pull + # libprotobuf.so transitively will see those refs surface as + # "undefined reference to absl::lts_X::log_internal::LogMessage:: + # operator<<<…>" template instantiations. Same workaround applies: + # tell ld to allow undefined refs in linked shared libs. + # + # Linux-only: this flag is GNU ld / lld syntax. Darwin's ld64 + # rejects it with `ld: unknown options: --allow-shlib-undefined`, + # which is fine — darwin builds against the system libprotobuf + # via Xcode toolchain and doesn't hit the abseil-drift issue. + LDFLAGS: $LDFLAGS -Wl,--allow-shlib-undefined ARGS: - -DCMAKE_INSTALL_PREFIX={{prefix}} - -DCMAKE_BUILD_TYPE=Release From 44d9b80bed8f2b17972c2de728a9da544d4a9151 Mon Sep 17 00:00:00 2001 From: tannevaled Date: Sun, 14 Jun 2026 13:45:16 +0200 Subject: [PATCH 14/14] fix(github.com/nmeum/android-tools): correct adb version test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The test did `adb --version | head -1 | grep -i adb`, but adb's first line is 'Android Debug Bridge version 1.0.41' — no 'adb' substring — so grep always failed (build was fine). Match the real banner. Co-Authored-By: Claude Opus 4.8 (1M context) --- projects/github.com/nmeum/android-tools/package.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/projects/github.com/nmeum/android-tools/package.yml b/projects/github.com/nmeum/android-tools/package.yml index 39529888b7..de4814472d 100644 --- a/projects/github.com/nmeum/android-tools/package.yml +++ b/projects/github.com/nmeum/android-tools/package.yml @@ -182,5 +182,8 @@ provides: - bin/lpunpack test: - - adb --version 2>&1 | head -1 | grep -i "adb" - - fastboot --version 2>&1 | head -1 | grep -i "fastboot" + # adb's version banner is "Android Debug Bridge version 1.0.41" — the + # first line has no "adb" substring, so the old `head -1 | grep adb` + # always failed. Match the actual banner instead. + - adb --version 2>&1 | grep -iq "android debug bridge" + - fastboot --version 2>&1 | grep -iq "fastboot"