diff --git a/meta-oe/recipes-devtools/android-tools/android-tools/0012-libbase-off64_t-extend-non-glibc-compat-typedef-to-musl.patch b/meta-oe/recipes-devtools/android-tools/android-tools/0012-libbase-off64_t-extend-non-glibc-compat-typedef-to-musl.patch new file mode 100644 index 0000000000..59feb3c1ed --- /dev/null +++ b/meta-oe/recipes-devtools/android-tools/android-tools/0012-libbase-off64_t-extend-non-glibc-compat-typedef-to-musl.patch @@ -0,0 +1,42 @@ +From: Khem Raj +Date: Tue, 29 Sep 2026 02:01:07 +0000 +Subject: [PATCH] libbase: extend the off64_t compat typedef to musl + +android-base/off64_t.h already works around Apple's libc not +providing the glibc LFS64 off64_t name by typedef'ing it to off_t. +musl has the exact same situation -- it never defines the LFS64 +names because its off_t is already 64-bit -- but the guard only +checked for __APPLE__, so building against musl failed: + +| system/libbase/mapped_file.cpp:47:67: error: unknown type name 'off64_t'; did you mean 'off_t'? +| system/libbase/include/android-base/file.h:105:71: error: unknown type name 'off64_t'; did you mean 'off_t'? +| system/libbase/include/android-base/mapped_file.h:50:61: error: unknown type name 'off64_t'; did you mean 'off_t'? + +Both file.h and mapped_file.h (and every .cpp that includes them) +already pull in android-base/off64_t.h, so extending its guard to +any non-glibc, non-bionic, non-Windows libc (i.e. musl) fixes all of +these call sites in a single place. + +Upstream-Status: Pending +Signed-off-by: Khem Raj +--- + system/libbase/include/android-base/off64_t.h | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/system/libbase/include/android-base/off64_t.h b/system/libbase/include/android-base/off64_t.h +index a4b7715..857ff29 100644 +--- a/system/libbase/include/android-base/off64_t.h ++++ b/system/libbase/include/android-base/off64_t.h +@@ -16,7 +16,10 @@ + + #pragma once + +-#if defined(__APPLE__) +-/** Mac OS has always had a 64-bit off_t, so it doesn't have off64_t. */ ++#if defined(__APPLE__) || \ ++ (!defined(__GLIBC__) && !defined(__BIONIC__) && !defined(_WIN32)) ++/** Mac OS has always had a 64-bit off_t, so it doesn't have off64_t. ++ * musl doesn't provide the glibc LFS64 off64_t name either, but its off_t ++ * is already 64-bit, so the same typedef works there too. */ + typedef off_t off64_t; + #endif diff --git a/meta-oe/recipes-devtools/android-tools/android-tools/0013-adb-sysdeps-provide-pread64-pwrite64-lseek64-fallba.patch b/meta-oe/recipes-devtools/android-tools/android-tools/0013-adb-sysdeps-provide-pread64-pwrite64-lseek64-fallba.patch new file mode 100644 index 0000000000..54c931c210 --- /dev/null +++ b/meta-oe/recipes-devtools/android-tools/android-tools/0013-adb-sysdeps-provide-pread64-pwrite64-lseek64-fallba.patch @@ -0,0 +1,58 @@ +From: Khem Raj +Date: Tue, 29 Sep 2026 02:36:00 +0000 +Subject: [PATCH] adb: sysdeps: provide pread64/pwrite64/lseek64 fallback for + musl + +adb_pread(), adb_pwrite() and adb_lseek() in sysdeps.h already special +case __APPLE__ to call the plain (non-LFS64) pread/pwrite/lseek, +because Mac OS never had the glibc LFS64 names. musl has the exact +same situation -- like off64_t (see +0012-libbase-off64_t-extend-non-glibc-compat-typedef-to-musl.patch), +it never defines pread64/pwrite64/lseek64 since its off_t is already +64-bit -- but these three call sites only checked for __APPLE__, so +building against musl failed: + +| sysdeps.h:522:31: error: use of undeclared identifier 'pread64' +| sysdeps.h:544:32: error: use of undeclared identifier 'pwrite64' +| sysdeps.h:554:12: error: use of undeclared identifier 'lseek64' + +Extend the same non-glibc/non-bionic/non-Windows guard used by +off64_t.h to these three functions. + +Upstream-Status: Pending +Signed-off-by: Khem Raj +--- +--- a/packages/modules/adb/sysdeps.h ++++ b/packages/modules/adb/sysdeps.h +@@ -516,7 +516,10 @@ static inline int adb_getlogin_r(char* buf, size_t bufsize) { + } + + static inline int adb_pread(borrowed_fd fd, void* buf, size_t len, off64_t offset) { +-#if defined(__APPLE__) ++#if defined(__APPLE__) || \ ++ (!defined(__GLIBC__) && !defined(__BIONIC__) && !defined(_WIN32)) ++ /* Mac OS and musl don't have the LFS64 pread64: their plain pread is ++ * already 64-bit (see android-base/off64_t.h). */ + return TEMP_FAILURE_RETRY(pread(fd.get(), buf, len, offset)); + #else + return TEMP_FAILURE_RETRY(pread64(fd.get(), buf, len, offset)); +@@ -538,7 +541,8 @@ static inline int unix_read_interruptible(borrowed_fd fd, void* buf, size_t le + } + + static inline int adb_pwrite(int fd, const void* buf, size_t len, off64_t offset) { +-#if defined(__APPLE__) ++#if defined(__APPLE__) || \ ++ (!defined(__GLIBC__) && !defined(__BIONIC__) && !defined(_WIN32)) + return TEMP_FAILURE_RETRY(pwrite(fd, buf, len, offset)); + #else + return TEMP_FAILURE_RETRY(pwrite64(fd, buf, len, offset)); +@@ -548,7 +552,8 @@ static inline int adb_pwrite(int fd, const void* buf, size_t len, off64_t offs + // (write and pwrite macros omitted: incompatible with GCC/abseil compat) + + static inline int64_t adb_lseek(borrowed_fd fd, int64_t pos, int where) { +-#if defined(__APPLE__) ++#if defined(__APPLE__) || \ ++ (!defined(__GLIBC__) && !defined(__BIONIC__) && !defined(_WIN32)) + return lseek(fd.get(), pos, where); + #else + return lseek64(fd.get(), pos, where); diff --git a/meta-oe/recipes-devtools/android-tools/android-tools/0014-daemon-auth-vendor-a-portable-b64_pton-for-non-glib.patch b/meta-oe/recipes-devtools/android-tools/android-tools/0014-daemon-auth-vendor-a-portable-b64_pton-for-non-glib.patch new file mode 100644 index 0000000000..f658fb3c57 --- /dev/null +++ b/meta-oe/recipes-devtools/android-tools/android-tools/0014-daemon-auth-vendor-a-portable-b64_pton-for-non-glib.patch @@ -0,0 +1,131 @@ +From: Khem Raj +Date: Tue, 29 Sep 2026 02:47:00 +0000 +Subject: [PATCH] daemon/auth: vendor a portable b64_pton() for non-glibc, + non-bionic libcs + +adbd's daemon/auth.cpp calls b64_pton() from to decode a +client's base64-encoded public key. Android.bp gets this on the Linux +host build by linking -lresolv ("b64_pton" comment at host_ldlibs), +and bionic (the Android target libc) provides its own. musl has +neither the symbol nor a libresolv to link against, so building +against musl failed: + +| daemon/auth.cpp:119:13: error: use of undeclared identifier 'b64_pton' +| daemon/auth.cpp:166:13: error: use of undeclared identifier 'b64_pton' + +Vendor the standard BSD base64 decoder (the same implementation +glibc's own resolv/base64.c is derived from) as a local static +function, gated to only be used where the libc doesn't already +provide it, rather than adding a new libresolv-equivalent dependency +just for this one call site. + +Upstream-Status: Pending +Signed-off-by: Khem Raj +--- +--- a/packages/modules/adb/daemon/auth.cpp ++++ b/packages/modules/adb/daemon/auth.cpp +@@ -22,6 +22,10 @@ + #include + #include + ++#if !defined(__GLIBC__) && !defined(__BIONIC__) ++#include ++#endif ++ + #include + #include + #include +@@ -49,6 +53,93 @@ + #include "transport.h" + #include "types.h" + ++#if !defined(__GLIBC__) && !defined(__BIONIC__) ++/* ++ * musl doesn't provide libresolv's b64_pton(): glibc gets it by linking ++ * -lresolv (see Android.bp's host_ldlibs) and bionic has its own, but musl ++ * has neither the symbol nor a libresolv to link. This is the standard BSD ++ * base64 decoder (the same one glibc's own resolv/base64.c is derived ++ * from), vendored here so this one call site doesn't need a new ++ * dependency. ++ */ ++static int b64_pton(const char* src, uint8_t* target, size_t targsize) { ++ static const char Base64[] = ++ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; ++ static const char Pad64 = '='; ++ int tarindex, state, ch; ++ const char* pos; ++ ++ state = 0; ++ tarindex = 0; ++ ++ while ((ch = *src++) != '\0') { ++ if (isspace(static_cast(ch))) continue; ++ ++ if (ch == Pad64) break; ++ ++ pos = strchr(Base64, ch); ++ if (pos == nullptr) return -1; ++ ++ switch (state) { ++ case 0: ++ if (target) { ++ if (static_cast(tarindex) >= targsize) return -1; ++ target[tarindex] = (pos - Base64) << 2; ++ } ++ state = 1; ++ break; ++ case 1: ++ if (target) { ++ if (static_cast(tarindex) + 1 >= targsize) return -1; ++ target[tarindex] |= (pos - Base64) >> 4; ++ target[tarindex + 1] = ((pos - Base64) & 0x0f) << 4; ++ } ++ tarindex++; ++ state = 2; ++ break; ++ case 2: ++ if (target) { ++ if (static_cast(tarindex) + 1 >= targsize) return -1; ++ target[tarindex] |= (pos - Base64) >> 2; ++ target[tarindex + 1] = ((pos - Base64) & 0x03) << 6; ++ } ++ tarindex++; ++ state = 3; ++ break; ++ case 3: ++ if (target) { ++ if (static_cast(tarindex) >= targsize) return -1; ++ target[tarindex] |= (pos - Base64); ++ } ++ tarindex++; ++ state = 0; ++ break; ++ } ++ } ++ ++ if (ch == Pad64) { ++ if (state != 2 && state != 3) return -1; ++ ++ if (state == 2) { ++ for ((void)(ch = *src++); isspace(static_cast(ch)); ++ (void)(ch = *src++)) ++ continue; ++ if (ch != Pad64) return -1; ++ (void)(ch = *src++); ++ } ++ ++ while ((ch = *src++) != '\0') { ++ if (!isspace(static_cast(ch))) break; ++ } ++ if (ch != '\0') return -1; ++ } else { ++ if (state != 0) return -1; ++ } ++ ++ return tarindex; ++} ++#endif ++ + using namespace adb::crypto; + using namespace adb::tls; + using namespace std::chrono_literals; diff --git a/meta-oe/recipes-devtools/android-tools/android-tools_35.0.2.bb b/meta-oe/recipes-devtools/android-tools/android-tools_35.0.2.bb index 623dfa7717..300a92df00 100644 --- a/meta-oe/recipes-devtools/android-tools/android-tools_35.0.2.bb +++ b/meta-oe/recipes-devtools/android-tools/android-tools_35.0.2.bb @@ -57,6 +57,9 @@ SRC_URI = "https://deb.debian.org/debian/pool/main/a/android-platform-tools/andr file://0009-libbase-include-stdint.h-in-hex.cpp.patch \ file://0010-adbd-make-systemd-sd_notify-conditional-on-HAVE_SYSTEMD.patch \ file://0011-adb-drop-non-portable-is_standard_layout-assertion.patch \ + file://0012-libbase-off64_t-extend-non-glibc-compat-typedef-to-musl.patch \ + file://0013-adb-sysdeps-provide-pread64-pwrite64-lseek64-fallba.patch \ + file://0014-daemon-auth-vendor-a-portable-b64_pton-for-non-glib.patch \ " SRC_URI[orig.md5sum] = "352376965cdef7bd7505d8fefdd43d50" @@ -81,12 +84,20 @@ SYSTEMD_PACKAGES = "${PN}-adbd" SYSTEMD_SERVICE:${PN}-adbd = "android-tools-adbd.service" CFLAGS:append = " -fPIC -std=gnu2x" +# android-base/endian.h and threads.h already have an +# ANDROID_HOST_MUSL-gated branch for building against musl (alongside their +# __GLIBC__ one); upstream expects the build system to define this macro, +# which the debian/ Makefile-based packaging used here doesn't do on its +# own. Without it those headers fall through to their Windows-only branch +# and fail with "'winsock2.h' file not found". +CFLAGS:append:libc-musl = " -DANDROID_HOST_MUSL" # The bundled fmtlib 10.2.0 validates FMT_STRING() inside a consteval # basic_format_string constructor whose parse path evaluates "it - begin()", # which current C++ frontends reject as a non-constant subexpression. Define # FMT_CONSTEVAL to empty so format-string checking falls back to fmt's runtime # path instead of the broken compile-time one. CXXFLAGS:append = " -fPIC -std=gnu++20 -D_Nonnull= -D_Nullable= -I${STAGING_INCDIR}/boringssl -DFMT_CONSTEVAL=" +CXXFLAGS:append:libc-musl = " -DANDROID_HOST_MUSL" LDFLAGS:append = " -fPIC -L${STAGING_LIBDIR}/android"