You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用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.

  1. Organize Library Files
    In your Android Studio app module, create a libs directory 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.h
    
  2. Update App's CMakeLists.txt
    If your app doesn't have a CMakeLists.txt yet, create one in app/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)
    
  3. Configure App's build.gradle
    Update your module-level build.gradle to 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:

  1. Organize Files
    Use the same libs and header directory structure as described in Option 1.

  2. Create Android.mk
    In app/src/main/jni, create an Android.mk file:

    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)
    
  3. Create Application.mk
    In the same jni directory, create an Application.mk file to specify target ABIs and platform:

    APP_ABI := arm64-v8a armeabi-v7a
    APP_PLATFORM := android-24 # Minimum supported Android version
    
  4. Update build.gradle
    Modify your module-level build.gradle to 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

火山引擎 最新活动