You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在基于Android.mk的Android项目中引入CMake项目?

如何在Android.mk构建的项目中引入仅提供CMakeLists.txt的依赖(funchook & capstone)

问题描述

我正在构建Android原生项目,当前采用Android.mk进行构建。现需引入两个依赖项目:funchook(依赖capstone),但这两个项目仅提供CMakeLists.txt而非Android.mk,请问是否有方法引入这些CMake项目?

当前项目目录结构:

├── build.gradle
├── jni
│   ├── Android.mk
│   ├── Application.mk
│   ├── example.cpp
│   └── libcxx
└── src
    └── main
        └── AndroidManifest.xml

Android.mk 配置:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := example
LOCAL_SRC_FILES := example.cpp
LOCAL_STATIC_LIBRARIES := libcxx
LOCAL_LDLIBS := -llog
include $(BUILD_EXECUTABLE)

include jni/libcxx/Android.mk

Application.mk 配置:

APP_ABI      := armeabi-v7a arm64-v8a x86 x86_64
APP_CPPFLAGS := -std=c++17 -fno-exceptions -fno-rtti -fvisibility=hidden -fvisibility-inlines-hidden
APP_STL      := none
APP_PLATFORM := android-21

AndroidManifest.xml 配置:

<?xml version="1.0" encoding="utf-8"?>
<manifest package="native" />

解决方案

方法1:通过ndk-build直接调用CMake构建依赖

ndk-build(r21及以上版本)支持在Android.mk中调用CMake编译外部项目,生成静态库后直接链接到主项目:

  1. 将funchook和capstone源码放到项目jni/thirdparty目录下,结构如下:

    jni/
    └── thirdparty/
        ├── capstone/
        └── funchook/
    
  2. 修改主Android.mk,添加依赖编译逻辑:

    LOCAL_PATH := $(call my-dir)
    
    # 编译capstone静态库
    include $(CLEAR_VARS)
    LOCAL_MODULE := capstone
    LOCAL_SRC_FILES := thirdparty/capstone/CMakeLists.txt
    # 传递CMake编译参数,关闭动态库、测试编译
    LOCAL_CMAKE_FLAGS := -DCAPSTONE_BUILD_SHARED=OFF -DCAPSTONE_BUILD_STATIC=ON -DCAPSTONE_BUILD_TESTS=OFF
    include $(BUILD_CMAKE_PROJECT)
    
    # 编译funchook静态库(依赖capstone)
    include $(CLEAR_VARS)
    LOCAL_MODULE := funchook
    LOCAL_SRC_FILES := thirdparty/funchook/CMakeLists.txt
    LOCAL_CMAKE_FLAGS := -DFUNCHOOK_BUILD_SHARED=OFF -DFUNCHOOK_BUILD_STATIC=ON -DFUNCHOOK_USE_CAPSTONE=ON
    LOCAL_STATIC_LIBRARIES := capstone
    include $(BUILD_CMAKE_PROJECT)
    
    # 更新主可执行文件的依赖
    include $(CLEAR_VARS)
    LOCAL_MODULE := example
    LOCAL_SRC_FILES := example.cpp
    LOCAL_STATIC_LIBRARIES := libcxx capstone funchook
    LOCAL_LDLIBS := -llog
    include $(BUILD_EXECUTABLE)
    
    include jni/libcxx/Android.mk
    

方法2:预编译依赖为静态库后引入

提前用CMake编译好对应ABI的静态库,再复制到项目中通过Android.mk引用:

  1. 用CMake或Android Studio针对每个目标ABI(armeabi-v7a、arm64-v8a等)编译capstone和funchook的静态库(.a文件)。

  2. 在项目jni目录下创建libs/[ABI]结构,将对应ABI的静态库放入:

    jni/
    └── libs/
        ├── armeabi-v7a/
        │   ├── libcapstone.a
        │   └── libfunchook.a
        ├── arm64-v8a/
        │   ├── libcapstone.a
        │   └── libfunchook.a
        ├── x86/
        │   ├── libcapstone.a
        │   └── libfunchook.a
        └── x86_64/
            ├── libcapstone.a
            └── libfunchook.a
    
  3. 修改Android.mk引入预编译库:

    LOCAL_PATH := $(call my-dir)
    
    # 引入预编译的capstone静态库
    include $(CLEAR_VARS)
    LOCAL_MODULE := capstone
    LOCAL_SRC_FILES := libs/$(TARGET_ABI)/libcapstone.a
    include $(PREBUILT_STATIC_LIBRARY)
    
    # 引入预编译的funchook静态库
    include $(CLEAR_VARS)
    LOCAL_MODULE := funchook
    LOCAL_SRC_FILES := libs/$(TARGET_ABI)/libfunchook.a
    LOCAL_STATIC_LIBRARIES := capstone
    include $(PREBUILT_STATIC_LIBRARY)
    
    # 更新主可执行文件依赖
    include $(CLEAR_VARS)
    LOCAL_MODULE := example
    LOCAL_SRC_FILES := example.cpp
    LOCAL_STATIC_LIBRARIES := libcxx capstone funchook
    LOCAL_LDLIBS := -llog
    include $(BUILD_EXECUTABLE)
    
    include jni/libcxx/Android.mk
    

方法3:迁移整个项目到CMake构建

如果长期维护项目,建议直接切换到CMake构建,更便于依赖管理:

  1. 在app/src/main/cpp目录下创建CMakeLists.txt,替换原Android.mk逻辑:

    cmake_minimum_required(VERSION 3.18.1)
    
    project(example)
    
    # 引入capstone和funchook子项目
    add_subdirectory(../../jni/thirdparty/capstone capstone_build)
    add_subdirectory(../../jni/thirdparty/funchook funchook_build)
    
    # 构建主可执行文件
    add_executable(example
        ../../jni/example.cpp
    )
    
    # 链接依赖库
    target_link_libraries(example
        log
        libcxx
        capstone
        funchook
    )
    
    # 设置编译参数
    target_compile_options(example PRIVATE
        -std=c++17
        -fno-exceptions
        -fno-rtti
        -fvisibility=hidden
        -fvisibility-inlines-hidden
    )
    
    set_target_properties(example PROPERTIES
        CXX_STANDARD 17
    )
    
  2. 修改build.gradle配置CMake构建:

    android {
        defaultConfig {
            externalNativeBuild {
                cmake {
                    abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
                    arguments "-DANDROID_PLATFORM=android-21", "-DANDROID_STL=none"
                }
            }
        }
        externalNativeBuild {
            cmake {
                path "src/main/cpp/CMakeLists.txt"
            }
        }
    }
    

内容的提问来源于stack exchange,提问作者Alexandru Nitan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 01:30:10