System designTroubleshooting

std::stoull is not a member of std: fix the Android NDK mismatch

'std::stoull is not a member of std' means an NDK too old for OpenCV's C++11: move to r18b or newer and point CMake at the NDK's own toolchain file.

LumaSpec Vision10 min read Share on LinkedIn

On this page 8 sections
  1. 01What the error actually means
  2. 02Likely causes, in order of probability
  3. 03Fix: pair OpenCV 4.5.1 with a matching NDK and toolchain file
  4. 04The "broken NDK" variant
  5. 05Prove the fix before the full build
  6. 06What not to do
  7. 07Prevention: pin the NDK to the OpenCV version
  8. 08Questions

You are building OpenCV 4.5.1 from source for Android on a Windows machine. Configure runs clean, and then the build dies inside the core sources with error: 'stoull' is not a member of 'std' at system.cpp line 1902. The same recipe built 3.4.11 without complaint, so the script looks innocent, and it is. This is a version mismatch: NDK r17.2.4988734 still carries the retired GNU toolchain, and with that toolchain Android's string header never declares std::stoull, which the 4.5.1 core module calls. You get the failure mechanism, the causes ranked by probability, the NDK revision to install, the exact toolchain file to hand CMake, a two-minute test that proves the fix before a full build, and the pinning habit that keeps it from coming back.

What the error actually means

The compile stopped at this line in modules/core/src/system.cpp:

size_t v = (size_t)std::stoull(valueStr);

std::stoull parses a string into an unsigned long long and arrived with C++11. The message says the compiler recognizes the std namespace but cannot find that name inside it: the standard-library headers behind this build do not declare the function. No OpenCV flag writes a missing declaration into a header, so no flag hunt fixes this.

Two version facts explain the scene. NDK r17 still shipped the GNU toolchain that r18 removed, and OpenCV's Android toolchain file of that generation selected it; with that toolchain, Android's string header lacks std::stoull. The 3.4 branch never calls that function in the sources your recipe compiles, which is why 3.4.11 sailed through untouched. OpenCV 4.x then raised the bar: it compiles as C++11 and reaches for the full C++11 string API, and the retired toolchain cannot meet it.

So the decision is simple: the NDK moves, not the CMake flags. Install r18b as the floor, or a current release such as r25b, and drive the build with the toolchain file that matches the NDK you installed.

If you only need stock modules, skip the whole problem: the prebuilt OpenCV Android SDK drops into a Gradle project, as walked through in Migrate an OpenCV Android project from Manager to a Gradle SDK setup. Building from source exists for custom module sets and patches, and that is exactly the surface where this error lives.

Likely causes, in order of probability

Four distinct failures produce this symptom. Test before changing anything: read CMAKE_CXX_COMPILER out of CMakeCache.txt in the build directory and check where it points. That single entry separates the first two causes from the rest.

Probability Log evidence Root cause Fix
Most likely error: 'stoull' is not a member of 'std' at system.cpp:1902, cached compiler is the r17 GNU toolchain NDK too old for the 4.x branch; its string header lacks std::stoull Install r18b or newer; reconfigure with the matching toolchain file
Common Same error, but the cached compiler is your MinGW g++ Configure ran without a toolchain file, so CMake picked the host compiler Pass the NDK's own build/cmake/android.toolchain.cmake via -DCMAKE_TOOLCHAIN_FILE
Less common Could not find any working toolchain in the NDK. Probably your Android NDK is broken., then CMAKE_CXX_COMPILER not set, after EnableLanguage The NDK on disk is incomplete or too old for the probing toolchain file Re-download the NDK revision, extract fully, reconfigure clean
Sneaky The error survives the NDK upgrade CMake cached the old compiler path from the failed run Delete the whole build directory before reconfiguring

One dead end to close early: turning BUILD_opencv_world off does not dodge this. The failing file belongs to the core module, which every component set compiles. World mode merely packs core into the opencv_world target, which is why your log names it; with world off the same file compiles as opencv_core and fails identically.

Fix: pair OpenCV 4.5.1 with a matching NDK and toolchain file

  1. Install a newer NDK. For the 4.5.1 tree, r18b is the oldest release that finishes the core build without this error; a current r25b install, which unpacks as folder 25.1.8937393, is the fully proven combination and pairs with API level 30 on arm64-v8a.
  2. Delete the previous build directory in full. CMake caches compiler paths in CMakeCache.txt, and a reconfigure over the cached r17 settings keeps the old toolchain alive.
  3. Configure fresh, handing CMake the toolchain file that belongs to your NDK. OpenCV's bundled platforms/android/android.toolchain.cmake still drives r18b; from r19 on, use the NDK's own build/cmake/android.toolchain.cmake and retire the bundled copy from your scripts.
  4. Build with mingw32-make, adding -j plus the core count you are willing to spend.

The line below is a complete, working configure for 4.5.1 on arm64-v8a at API 30; adjust the two drive paths to where the NDK and the OpenCV source live on your machine:

cmake -G"MinGW Makefiles" \
  -DCMAKE_TOOLCHAIN_FILE=/c/Android/ndk/25.1.8937393/build/cmake/android.toolchain.cmake \
  -DANDROID_NDK=/c/Android/ndk/25.1.8937393 \
  -DANDROID_ABI=arm64-v8a \
  -DANDROID_PLATFORM=30 \
  -DANDROID_TARGET_SDK_VERSION=30 \
  -DANDROID_COMPILE_SDK_VERSION=30 \
  -DBUILD_opencv_world:BOOL=OFF \
  -DBUILD_PERF_TESTS:BOOL=OFF \
  -DBUILD_TESTS:BOOL=OFF \
  -DBUILD_DOCS:BOOL=OFF \
  /c/opencv/opencv-4.5.1
mingw32-make -j8

The "broken NDK" variant

Swap to r18b and CMake may stop earlier than any compile, straight out of the toolchain probe: Could not find any working toolchain in the NDK. Probably your Android NDK is broken., raised from platforms/android/android.toolchain.cmake, followed by CMAKE_CXX_COMPILER not set, after EnableLanguage.

Read the first message literally. The toolchain file walked the NDK looking for a working compiler and found none. Two situations produce that. The NDK on disk is incomplete: an interrupted download or extraction leaves a tree that looks right at the top and is empty where the compilers live. Or the revision on disk predates what the probing toolchain file expects.

The check takes a minute. Open the NDK folder, look under toolchains, and confirm the compiler binaries exist where the installed revision keeps them. Anything missing or empty means: re-download that exact revision, extract it completely, delete the build directory, and run the configure again. Nothing in the CMake cache and nothing in OpenCV needs editing for this case.

Prove the fix before the full build

Two checks cost less time than one failed build pass.

First, confirm the compiler CMake selected. After a clean configure, find CMAKE_CXX_COMPILER:FILEPATH in the build directory's CMakeCache.txt. It must point inside the NDK you installed, at a Clang binary under toolchains on r19 and newer. If it shows your MinGW g++ or any path outside the NDK, the toolchain file did not take effect; fix that before compiling anything.

Second, compile the exact declaration the old toolchain was missing. Save this as test_stoull.cpp:

#include <string>

int main() {
    const std::string v = "9007199254740993";
    const unsigned long long n = std::stoull(v);
    return n == 9007199254740993ULL ? 0 : 1;
}

Run the cached compiler from the first check on that file with -std=c++11 -c test_stoull.cpp. A silent compile with exit code 0 proves the string header on your toolchain declares std::stoull, which is the precise condition the line at system.cpp:1902 needs. Only then start the full mingw32-make run.

What not to do

Three detours cost an evening each and fix nothing.

Patching std::stoull out of the sources. Replacing the call with strtoull or a stream parse silences one line, but the 4.x core touches more of the C++11 string API in the same headers, so the patches multiply across modules and come back with every OpenCV update. Upgrade the NDK instead; that is one download and one flag.

Adding -std=c++11 by hand. OpenCV 4.x already compiles as C++11, so the flag is present. The declaration is absent from the toolchain's library headers, and no flag writes it back.

Mixing NDK generations inside one app. A prebuilt .so produced under one NDK revision, linked into a project built under another, surfaces as undefined references at link time, a cousin of this failure. Hold the whole project to one NDK revision: the same pin-one-version rule that stops runtime drift in Docker build SDK version mismatch: pin one library version everywhere and in Edge inference device crashes: fix with SDK version pinning.

Once the library links, the remaining build-side failures are ordinary CMake hygiene: selecting the wrong module set (Missing OpenCV aruco module: fix the CMake calibration build) and relocation errors at link (CMake -fPIC relocation errors when linking a vision SDK).

Prevention: pin the NDK to the OpenCV version

The failure returns the day the pin slips, so write the pair down and hold both ends to it:

  • Record the pairing where the build lives: OpenCV 4.5.1 with NDK r25b, folder 25.1.8937393, in the worked example; treat r18b as the floor for the 4.x branch.
  • Keep one NDK revision for every native library the app links, and rebuild all of them when the revision changes, not OpenCV alone.
  • From r19 on, configure only through the NDK's own build/cmake/android.toolchain.cmake.
  • Read CMAKE_CXX_COMPILER:FILEPATH out of CMakeCache.txt immediately after every configure: five seconds that catch a wrong toolchain before any compiling starts.
  • Delete build directories on every toolchain or compiler change; never reconfigure in place over a cached configuration.
  • Where several OpenCV builds share a machine, keep their outputs apart. One process seeing two OpenCV libraries is its own crash class, covered in OpenCV version conflicts that crash vision calibration tools.

The mismatch shape here, code needing a newer toolchain than the one wired in, recurs across vision projects: from headers missing in a containerized build to build errors after a library upgrade. The systems topic page collects the rest of the build and integration fixes.

Once the build environment is settled and the device has to earn its keep on the line, the hardware side is ours to size. Smart cameras cover inspection on the device without a PC, and vision controllers are where multi-camera builds get their compute. For a second opinion on matching a build environment to a camera, the contact page reaches the applications team.

Questions

Which NDK release is the minimum for building OpenCV 4.x for Android?

For the 4.5.1 tree, r18b is the oldest release that completes the core build without the stoull failure. The pairing rule matters as much as the version number: r18b still runs with OpenCV's bundled platforms/android toolchain file, while r19 and newer should be driven by the NDK's own build/cmake/android.toolchain.cmake. A current r25b install, folder 25.1.8937393, with API 30 and arm64-v8a is a fully proven combination.

Why did OpenCV 3.4.11 build fine with the same recipe?

The requirement moved, not the script. The 3.4 branch never calls std::stoull in the sources that recipe compiles, so the old NDK had nothing to trip over. OpenCV 4.x compiles as C++11 and reaches for string conversions the retired GNU toolchain on Android does not declare, and 4.5.1 hits the missing name at system.cpp:1902. No build flag changes that: the NDK version has to move.

Can I patch the OpenCV sources instead of upgrading the NDK?

It compiles, but it does not scale. strtoull or a stream parse replaces one call, yet the 4.x core touches further C++11 additions in the same headers, so patches multiply across modules and return with each OpenCV update you take. One NDK install plus one toolchain flag costs less than maintaining a fork. Reserve source patches for machines where policy forbids installing a newer NDK, and keep them as a separate, recorded commit.

What does the 'Probably your Android NDK is broken' message actually mean?

It is CMake's toolchain probe reporting that it found no working compiler inside the NDK folder, not a verdict on your download history. The two usual reasons: an interrupted download or extraction left the tree empty where the compilers live, or the revision on disk predates what the probing toolchain file expects. Check under the NDK's toolchains folder; missing binaries mean re-download, full re-extract, delete the build directory and configure again.

Does this error affect the prebuilt OpenCV Android SDK?

No. The failure happens while OpenCV's own sources compile, so a prebuilt distribution never sees it. The risk moves to link time instead: a prebuilt .so produced under one NDK revision, linked into an app built under another, gives undefined references. If you build anything native yourself, pin a single NDK revision for every library in the project and rebuild all of them together whenever that pin changes.