Android version(s): N/A (build-time failure)
Android device(s): N/A (build-time failure)
Oboe version: 1.10.0 (also reproduces on main @ bd2114b)
NDK version: 30.0.15729638
App name used for testing: N/A — this is a compile error; a minimal clang++ -fsyntax-only repro is below.
Short description
src/aaudio/AAudioLoader.{h,cpp} fails to compile with NDK 30.0.15729638. Two __NDK_MAJOR__ guards assume things about NDK r30's <aaudio/AAudio.h> that are no longer true in that build, producing three type redefinitions and one failing static_assert.
Steps to reproduce
git clone --depth 1 --branch 1.10.0 https://github.com/google/oboe
cd oboe
NDK=$ANDROID_SDK_ROOT/ndk/30.0.15729638
HOST=linux-x86_64 # or darwin-x86_64 / windows-x86_64
$NDK/toolchains/llvm/prebuilt/$HOST/bin/clang++ \
--target=aarch64-linux-android21 -std=c++17 \
-Isrc -Iinclude -fsyntax-only src/aaudio/AAudioLoader.cpp
The same failure occurs through the normal Gradle/CMake build with ndkVersion "30.0.15729638"; the command above is just the smallest reproduction. It is independent of minSdkVersion, since the conflicting declarations are plain type definitions rather than function declarations behind __INTRODUCED_IN(36) / __BIONIC_AVAILABILITY_GUARD(36).
Expected behavior
AAudioLoader.cpp compiles.
Actual behavior
./AAudioLoader.h:117:14: error: redefinition of 'AAudio_FallbackMode'
<NDK>/sysroot/usr/include/aaudio/AAudio.h:2837:14: note: previous definition is here
./AAudioLoader.h:123:14: error: redefinition of 'AAudio_StretchMode'
<NDK>/sysroot/usr/include/aaudio/AAudio.h:2857:14: note: previous definition is here
./AAudioLoader.h:128:16: error: redefinition of 'AAudioPlaybackParameters'
<NDK>/sysroot/usr/include/aaudio/AAudio.h:2873:16: note: previous definition is here
AAudioLoader.cpp:592:5: error: static assertion failed due to requirement
'std::is_same<int, AAudio_DeviceType>::value': AAudio_DeviceType must be int32_t
AAudioLoader.cpp:394:42: note: expanded from macro 'ASSERT_INT32'
(Line numbers are for the 1.10.0 tag. On main @ bd2114b the static_assert is at AAudioLoader.cpp:602.)
Analysis
Two independent guard sites, same underlying cause — both were written against an earlier r30 preview:
-
AAudioLoader.h:116 — #if OBOE_USING_NDK && __NDK_MAJOR__ <= 30, carrying a // TODO: find the first NDK version containing the following values. NDK 30.0.15729638 does declare AAudio_FallbackMode, AAudio_StretchMode and AAudioPlaybackParameters, so Oboe's fallback definitions collide with it.
-
AAudioLoader.cpp:602 — ASSERT_INT32(AAudio_DeviceType) under #if __NDK_MAJOR__ >= 30. This assumes AAudio_DeviceType is a plain typedef int32_t, but it is declared as an enum with an explicit underlying type:
typedef enum AAudio_DeviceType : int32_t { ... } AAudio_DeviceType;
(frameworks/av media/libaaudio/include/aaudio/AAudio.h:901 on main), so std::is_same<int32_t, AAudio_DeviceType>::value is false. The ASSERT_INT32(aaudio_policy_t) a few lines below is unaffected — aaudio_policy_t really is typedef int32_t.
One thing that may make the fix awkward: __NDK_MAJOR__ alone cannot distinguish an early r30 preview (which apparently lacked these declarations) from a later one that has them. <android/ndk-version.h> also exposes __NDK_MINOR__, __NDK_BUILD__ and __NDK_CANARY__ if a finer discriminator is needed.
Any additional context
Originally reported against ebitengine/oto, which vendors Oboe 1.10.0 verbatim (rewriting only #include paths). The failure is entirely in upstream Oboe; nothing in the vendoring is involved.
If it helps to reproduce without an r30 NDK, the same four errors can be produced with any recent NDK by shimming the two relevant header changes onto the sysroot: force __NDK_MAJOR__ to 30 via a -I override of <android/ndk-version.h>, and add the AAudio_DeviceType enum (verbatim from AOSP frameworks/av) plus the three playback-parameter types to <aaudio/AAudio.h> via #include_next. With NDK 28.2.13676358 that yields exactly the errors quoted above, at the same line numbers. Without the shim, AAudioLoader.cpp compiles cleanly on 28.2.13676358.
Filed by Claude (Claude Code) on behalf of @hajimehoshi.
Android version(s): N/A (build-time failure)
Android device(s): N/A (build-time failure)
Oboe version: 1.10.0 (also reproduces on
main@ bd2114b)NDK version: 30.0.15729638
App name used for testing: N/A — this is a compile error; a minimal
clang++ -fsyntax-onlyrepro is below.Short description
src/aaudio/AAudioLoader.{h,cpp}fails to compile with NDK 30.0.15729638. Two__NDK_MAJOR__guards assume things about NDK r30's<aaudio/AAudio.h>that are no longer true in that build, producing three type redefinitions and one failingstatic_assert.Steps to reproduce
The same failure occurs through the normal Gradle/CMake build with
ndkVersion "30.0.15729638"; the command above is just the smallest reproduction. It is independent ofminSdkVersion, since the conflicting declarations are plain type definitions rather than function declarations behind__INTRODUCED_IN(36)/__BIONIC_AVAILABILITY_GUARD(36).Expected behavior
AAudioLoader.cppcompiles.Actual behavior
(Line numbers are for the 1.10.0 tag. On
main@ bd2114b thestatic_assertis atAAudioLoader.cpp:602.)Analysis
Two independent guard sites, same underlying cause — both were written against an earlier r30 preview:
AAudioLoader.h:116—#if OBOE_USING_NDK && __NDK_MAJOR__ <= 30, carrying a// TODO: find the first NDK version containing the following values. NDK 30.0.15729638 does declareAAudio_FallbackMode,AAudio_StretchModeandAAudioPlaybackParameters, so Oboe's fallback definitions collide with it.AAudioLoader.cpp:602—ASSERT_INT32(AAudio_DeviceType)under#if __NDK_MAJOR__ >= 30. This assumesAAudio_DeviceTypeis a plaintypedef int32_t, but it is declared as an enum with an explicit underlying type:(
frameworks/avmedia/libaaudio/include/aaudio/AAudio.h:901onmain), sostd::is_same<int32_t, AAudio_DeviceType>::valueisfalse. TheASSERT_INT32(aaudio_policy_t)a few lines below is unaffected —aaudio_policy_treally istypedef int32_t.One thing that may make the fix awkward:
__NDK_MAJOR__alone cannot distinguish an early r30 preview (which apparently lacked these declarations) from a later one that has them.<android/ndk-version.h>also exposes__NDK_MINOR__,__NDK_BUILD__and__NDK_CANARY__if a finer discriminator is needed.Any additional context
Originally reported against ebitengine/oto, which vendors Oboe 1.10.0 verbatim (rewriting only
#includepaths). The failure is entirely in upstream Oboe; nothing in the vendoring is involved.If it helps to reproduce without an r30 NDK, the same four errors can be produced with any recent NDK by shimming the two relevant header changes onto the sysroot: force
__NDK_MAJOR__to30via a-Ioverride of<android/ndk-version.h>, and add theAAudio_DeviceTypeenum (verbatim from AOSPframeworks/av) plus the three playback-parameter types to<aaudio/AAudio.h>via#include_next. With NDK 28.2.13676358 that yields exactly the errors quoted above, at the same line numbers. Without the shim,AAudioLoader.cppcompiles cleanly on 28.2.13676358.Filed by Claude (Claude Code) on behalf of @hajimehoshi.