I'm not on the android team, but in general it's easier to maintain reverse-compatibility with C ABIs than with C++ ABIs.
And the plethora of libraries and the modest size of the standard library are part of the problem. Let's say you're writing a C++ library that understands git and lets users develop more complex applications with your libgitxx as a building block. Whose filesystem primitives (file, directory, path, user, etc.) do you use? There's really not a satisfactory answer to that question.
Point being, C ABIs don't have this problem as much. They tend to just pass around ints and char. Maybe there are some structs to pass around, but they tend to be made up of ints, char, etc.
As such, backward compatibility (binary-wise) is not needed.
Android, Chrome, etc. are another matter - former has an SDK, and I guess you may need that there, but I don't have much experience with it.
In Android's case, the ABI would be whatever g++, now clang, shipped with NDK support.
Additionally there are ways to implement compatible ABIs in C++.
In any case, they are wrapping the C++ classes already, either via C or Java, so they could offer them as well.
Instead, one needs to write unsafe C code, JNI boilerplate or wrap them again in C++.
> Additionally there are ways to implement compatible ABIs in C++.
Eh... when even compilation flags affect ABIs, it's hard for a particlar C++ file to have a stable ABI. The same is true in C, of course, but the way C libraries are generally designed, it's simpler to be ABI compatible. In C++, arcane and unexpected things like noexcept specifications (affected by changes in underlying libraries!) can change your ABI.
> Instead, one needs to write unsafe C code, JNI boilerplate or wrap them again in C++.
That's a fair point. There might be reasons they'd do that (SLAs they can afford), but that's a presumption.
Which circles back to my statement about "The C mentality of some devs dragged into C++ world.".
Many useful C++ libraries were not standardized in the early days beyond STL, because many thought C++ should be like C where libraries are whatever the OS provides and nothing else.
Which is clearly visible in the decision to have ANSI C and POSIX APIs as two separate standards, although most C compilers try to provide some kind of additional POSIX compatibility, specially visible in non-POSIX OSes.
Thankfully, the ANSI C++ committee realized the mistake and now we are getting a useful set of libraries into the standard.
As for compilation flags, even for C it is only true if all compilers on the platform follow the same ABI.
And you still need to provide all variants anyway (debug, single and multithreaded, hard and soft float, pre-defined pre-processor macros, ...).
C ABI only appears to be simple in OSes that happen to be written in C.
Grated that is the case nowadays with most being UNIX clones, besides Windows and mainframes, but it wasn't always like that.
I remember the pain of trying to mix multiple C compilers back in the 90's.
> C ABI only appears to be simple in OSes that happen to be written in C.
I'd say that C is the only language that (mostly accidentally and non-standard, for the reasons you state) provides a simple a (relatively) stable ABI.
The C mentality of some devs dragged into C++ world.
Already in the 90's we had very nice high level C++ libraries, that could compete with what Java offered later.
Turbo Vision on MS-DOS, Object Windows Library and Visual Components Library on Windows. All from Borland.
PowerPlant on Mac OS, from Metrowerks.
From Microsoft, we had MFC, which started high level like those ones (originally named Afx), but then the beta testers requested for it to just be a thin layer over Win16 and it was reborn as MFC.
Many of the modern C++ patterns were already possible with those libraries, but the C wisdom made many not use them.
Another modern example is Android NDK, Google writes the code in nice C++ classes, that get exposed as low level C APIs, or have a Java JNI barrier (e.g. Skia).