Controlling C++ Standard Template Library (STL) in CMake for Android Development


Purpose

  • The STL provides essential data structures and algorithms for C++.
  • Controls the Standard Template Library (STL) implementation used when building C++ code for Android.

Availability

  • Introduced in CMake version 3.4.

Values

  • Deprecated values (no longer supported)
    gnustl_static, gnustl_shared, stlport_static, stlport_shared, gabi++_static, gabi++_shared
  • c++_shared: Links against a shared version of libc++.
  • c++_static: Links against a static version of libc++.
  • system: Uses the system's default STL (typically gnustl_shared).
  • none: No STL is linked (not recommended for most projects).

Setting the Variable

  • Command Line
    Use -DANDROID_STL=value when invoking CMake.
  • CMakeLists.txt
    Use set(CMAKE_ANDROID_STL_TYPE "value") before creating your target.

Impact on Compilation

  • CMake automatically configures these settings based on the chosen STL.
  • The chosen CMAKE_ANDROID_STL_TYPE value influences compiler flags and linker settings.

Choosing the Right Value

  • c++_shared
    Use this if you want to share the STL across multiple applications (less common). Be aware of potential compatibility issues with older Android versions.
  • c++_static
    Use this if you need more control over the STL or if the system's STL is unavailable. However, it can increase binary size.
  • system (default if not set)
    Generally recommended for most Android projects as it leverages the system's pre-installed STL.

Important Considerations

  • Deprecated Values
    Avoid using the deprecated STL types (gnustl_static, gnustl_shared, etc.) as they might not be supported in newer NDK versions.
  • Gradle Integration
    If using Gradle, it might override your CMake settings. Coordinate the STL configuration between CMake and Gradle.
  • NDK Compatibility
    Ensure your chosen STL is supported by your Android NDK version. Refer to the NDK documentation for guidance.


Setting in CMakeLists.txt

# Use system's default STL (recommended for most projects)
set(CMAKE_ANDROID_STL_TYPE SYSTEM)

# Create your target here
add_executable(my_cpp_app main.cpp)

Setting on Command Line

# Use static libc++
cmake -DANDROID_STL=c++_static ..

# Build the project
make

Using c++_shared (less common)

# Use shared libc++ (be aware of potential compatibility issues)
set(CMAKE_ANDROID_STL_TYPE c++_shared)

# Create your target here
add_library(my_cpp_lib main.cpp)


Using the System's Default STL

  • This is the recommended approach for most projects. Setting CMAKE_ANDROID_STL_TYPE to SYSTEM leverages the STL pre-installed on the Android device, ensuring compatibility and minimizing build complexity.

Manually Specifying Linker Flags (Advanced)

Using a Different Build System

  • If CMAKE_ANDROID_STL_TYPE doesn't meet your specific needs, consider alternative build systems like NDK's ndk-build. However, this requires adapting your build process and might not be as integrated with modern development workflows as CMake.
ApproachProsCons
CMAKE_ANDROID_STL_TYPE (Recommended)Simple, compatible, well-supportedLimited control over specific STL version
Manual Linker Flags (Advanced)Full control over STL selectionComplex setup, error-prone, requires deep CMake knowledge
Different Build System (NDK-Build)More control over specific build optionsMore complex setup, requires different workflow

In most cases, sticking with CMAKE_ANDROID_STL_TYPE and choosing the appropriate value (SYSTEM, c++_static, or c++_shared) is the recommended approach. It offers a balance of control and ease of use for Android C++ development.