使用NDK构建带CMake的C++ Android库并集成至Android Studio
Great question! Let's break this down step by step—yes, you absolutely can use CMake directly with the NDK to build your prebuilt libraries, and we'll cover both the build process and integration into Android Studio in detail.
一、Build Arm Architecture Prebuilt Libraries with NDK + CMake
First, make sure you have the Android NDK installed (via Android Studio's SDK Manager is easiest) and that your existing C++ projects already have valid CMakeLists.txt configurations.
1. Validate Your Project's CMake Setup
For each of your two projects (ProjectA and ProjectB), ensure their CMakeLists.txt is configured to output either a static (.a) or shared (.so) library:
- Static library example:
add_library(ProjectA STATIC ${ALL_SOURCE_FILES}) - Shared library example:
add_library(ProjectA SHARED ${ALL_SOURCE_FILES})
2. Run Cross-Compilation with NDK Toolchain
The NDK provides a preconfigured CMake toolchain file to handle Android cross-compilation. Open a terminal and run these commands for each project:
For ProjectA (Arm64-v8a example):
# Navigate to ProjectA's root directory cd /path/to/your/ProjectA # Create a build directory for Android Arm64 mkdir build-android-arm64 && cd build-android-arm64 # Configure CMake with NDK toolchain cmake .. \ -DCMAKE_TOOLCHAIN_FILE=/path/to/your/ndk/build/cmake/android.toolchain.cmake \ -DANDROID_ABI=arm64-v8a \ -DANDROID_PLATFORM=android-24 \ # Set your minimum supported Android version -DCMAKE_BUILD_TYPE=Release # Execute the build cmake --build .
Repeat the exact same steps for ProjectB, just swap the directory path. To support other Arm architectures like armeabi-v7a, simply replace -DANDROID_ABI=arm64-v8a with -DANDROID_ABI=armeabi-v7a.
3. Extract the Prebuilt Libraries
After building, you'll find the resulting .a/.so files in the build-android-arm64/lib (or lib64 for 64-bit) subdirectory. Don't forget to keep a copy of all header files from your C++ projects—you'll need them for integration.
二、Integrate Prebuilt Libraries into Android Studio
You have two options here: using CMake (recommended, as it aligns with modern Android NDK workflows) or using Android.mk/Application.mk. We'll cover both.
Option 1: Integrate with CMake (Recommended)
Organize Library Files
In your Android Studio app module, create alibsdirectory and structure it by ABI:app/libs/ arm64-v8a/ libProjectA.so (or libProjectA.a) libProjectB.so (or libProjectB.a) armeabi-v7a/ libProjectA.so (or libProjectA.a) libProjectB.so (or libProjectB.a)Place all header files from your C++ projects in
app/src/main/cpp/include, grouped by project:app/src/main/cpp/include/ ProjectA/ core.h utils.h ProjectB/ api.h types.hUpdate App's CMakeLists.txt
If your app doesn't have aCMakeLists.txtyet, create one inapp/src/main/cpp. Add these configurations to import and link your prebuilt libraries:cmake_minimum_required(VERSION 3.22.1) # Import ProjectA prebuilt library add_library(ProjectA SHARED IMPORTED) set_target_properties(ProjectA PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libProjectA.so # For static libraries, replace SHARED with STATIC and update the file extension to .a ) # Import ProjectB prebuilt library add_library(ProjectB SHARED IMPORTED) set_target_properties(ProjectB PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libProjectB.so ) # If you have your own JNI code, define your native library here add_library(native-lib SHARED src/main/cpp/native-lib.cpp) # Link prebuilt libraries and system libraries to your native code target_link_libraries(native-lib ProjectA ProjectB log # Example system library, add others as needed ) # Add header file paths so your JNI code can include them target_include_directories(native-lib PRIVATE src/main/cpp/include)Configure App's build.gradle
Update your module-levelbuild.gradleto enable CMake and point to your library files:android { ... defaultConfig { ... externalNativeBuild { cmake { cppFlags "" abiFilters 'arm64-v8a', 'armeabi-v7a' // Match the ABIs you built } } } externalNativeBuild { cmake { path "src/main/cpp/CMakeLists.txt" // Path to your CMake config version "3.22.1" // Match the CMake version bundled with your NDK } } sourceSets { main { jniLibs.srcDirs = ['libs'] // Tell Android Studio where to find prebuilt libs } } }
Option 2: Integrate with Android.mk
If you prefer using the traditional NDK build system, follow these steps:
Organize Files
Use the samelibsand header directory structure as described in Option 1.Create Android.mk
Inapp/src/main/jni, create anAndroid.mkfile:LOCAL_PATH := $(call my-dir) # Import ProjectA include $(CLEAR_VARS) LOCAL_MODULE := ProjectA LOCAL_SRC_FILES := ../../libs/$(TARGET_ARCH_ABI)/libProjectA.so # Use .a for static libs include $(PREBUILT_SHARED_LIBRARY) # Use PREBUILT_STATIC_LIBRARY for static libs # Import ProjectB include $(CLEAR_VARS) LOCAL_MODULE := ProjectB LOCAL_SRC_FILES := ../../libs/$(TARGET_ARCH_ABI)/libProjectB.so include $(PREBUILT_SHARED_LIBRARY) # Define your own JNI library (if applicable) include $(CLEAR_VARS) LOCAL_MODULE := native-lib LOCAL_SRC_FILES := native-lib.cpp LOCAL_C_INCLUDES += $(LOCAL_PATH)/../cpp/include # Header file path LOCAL_SHARED_LIBRARIES := ProjectA ProjectB # Use LOCAL_STATIC_LIBRARIES for static libs LOCAL_LDLIBS := -llog # System library dependency include $(BUILD_SHARED_LIBRARY)Create Application.mk
In the samejnidirectory, create anApplication.mkfile to specify target ABIs and platform:APP_ABI := arm64-v8a armeabi-v7a APP_PLATFORM := android-24 # Minimum supported Android versionUpdate build.gradle
Modify your module-levelbuild.gradleto use ndk-build:android { ... defaultConfig { ... externalNativeBuild { ndkBuild { abiFilters 'arm64-v8a', 'armeabi-v7a' } } } externalNativeBuild { ndkBuild { path "src/main/jni/Android.mk" } } sourceSets { main { jniLibs.srcDirs = ['libs'] } } }
Quick Notes to Avoid Issues
- Always use the CMake version bundled with your NDK to avoid compatibility conflicts.
- For static libraries, ensure all transitive dependencies are included in your build to prevent linker errors.
- Test your app on emulators or physical devices matching the ABIs you built for.
内容的提问来源于stack exchange,提问作者Chris R




