10、Android.mk基础介绍|C++ android.mk实战

Android.mk基本概念和结构
Android.mk 文件是 Android 构建系统中定义编译规则的配置文件,主要用于描述哪些源文件需要编译,以及如何编译它们。
常见的 Android.mk 文件结构:


image.png

• LOCAL_PATH:表示当前模块的路径,通常使用 (call my-dir)。 • include(CLEAR_VARS):清除之前定义的所有 LOCAL_ 变量,确保不会影响当前模块。
• LOCAL_MODULE:定义模块名称。
• LOCAL_SRC_FILES:定义模块的源文件。
• include $(BUILD_SHARED_LIBRARY):表示编译为动态库(共享库)。

常用变量
• LOCAL_MODULE:定义模块的名称,即生成的目标文件名(例如 .so 文件或可执行文件)。
• LOCAL_SRC_FILES:指定模块的源代码文件列表,支持 .c、.cpp、.java 等文件。
• LOCAL_C_INCLUDES:指定 C/C++ 头文件路径(包括目录)。
• LOCAL_LDLIBS:指定链接时使用的库(例如 -llog 表示链接 liblog.so)。
• LOCAL_STATIC_LIBRARIES:指定静态链接的库。

编译可执行文件
Android.mk 中除了编译库文件外,还可以编译可执行文件。使用 include $(BUILD_EXECUTABLE) 而不是 BUILD_SHARED_LIBRARY。

image.png

静态库和动态库
静态库使用 include (BUILD_STATIC_LIBRARY),动态库使用 include(BUILD_SHARED_LIBRARY)。
示例编译静态库:

image.png

模块间依赖
模块间的依赖关系可以通过 LOCAL_STATIC_LIBRARIES 或 LOCAL_SHARED_LIBRARIES 实现。例如,一个模块可以依赖另一个库:

image.png

常见的编译目标
• include $(BUILD_SHARED_LIBRARY):编译为共享库(.so)。

• include $(BUILD_STATIC_LIBRARY):编译为静态库(.a)。

• include $(BUILD_EXECUTABLE):编译为可执行文件。

编译预处理
可以通过 LOCAL_CFLAGS 和 LOCAL_CPPFLAGS 添加编译时的预处理宏、优化选项或警告级别等。例如:
LOCAL_CFLAGS := -Wall -O2
LOCAL_CPPFLAGS := -DDEBUG=1

多文件编译
在 LOCAL_SRC_FILES 中可以指定多个源文件,分行书写或者以空格隔开:
LOCAL_SRC_FILES := file1.c file2.c file3.c

子目录中的 Android.mk
如果你的项目有多个子目录,可以在顶级 Android.mk 文件中使用 (call all-subdir-makefiles) 来包含子目录中的 Android.mk: include(call all-subdir-makefiles)

实战开发:
目录结构:


image.png
  1. 生成 C++ 静态库
    static_lib/hello_static.cpp

    include <iostream>

    void print_static_hello(){
    std::cout << "Hello from static library!" << std::endl;
    }

static_lib/Android.mk

 LOCAL_PATH := $(call my-dir)
 include $(CLEAR_VARS)

 LOCAL_MODULE := libhello_static #定义静态库名称
 LOCAL_SRC_FILES := hello_static.cpp #指定源文件

 include $(BUILD_STATIC_LIBRARY) #编译目标为静态库

编译:

 mmm external/project/static_lib
  1. 生成 C++ 动态库
    shared_lib/hello_shared.cpp

    include <iostream>

    void print_shared_hello(){
    std::cout << "Hello from shared library!" << std::endl;
    }

shared_lib/Android.mk

 LOCAL_PATH := $(call my-dir)
 include $(CLEAR_VARS)
 LOCAL_MODULE := libhello_shared
 LOCAL_SRC_FILES := hello_shared.cpp

 include $(BUILD_SHARED_LIBRARY)

编译

  mmm external/project/shared_lib 
  1. 生成可执行文件并依赖静态库和动态库

executable/main.cpp

 #include <iostream>

 extern void print_static_hello();
 extern void print_shared_hello();

 int main(){
         print_static_hello();
         print_shared_hello();
         return 0;
 }

executable/Android.mk

 LOCAL_PATH := $(call my-dir)

 include $(CLEAR_VARS)

 LOCAL_MODULE := hello_executable
 LOCAL_SRC_FILES := main.cpp

 LOCAL_STATIC_LIBRARIES := libhello_static
 LOCAL_SHARED_LIBRARIES := libhello_shared

 include $(BUILD_EXECUTABLE)

编译:

  mmm external/project/executable 
  1. 调试运行

    adb push out/target/product/xxx/system/bin/hello_executable  /system/bin/
    adb push out/target/product/xxx/system/lib64/libhello_shared.so  /system/lib64/
    adb shell 
    cd system/bin/
    chmod +x hello_executable  
    

    ./hello_executable

output结果:


image.png

思考:未来遇到真实的c++项目,需要根据公司业务需求,自己写一个c++模块的项目 ,怎么进行?

  1. 编码: how?
  2. 写Android.mk或Android.bp编译脚本: 怎么写呢?重点。。。
  3. 编译: how?
  4. 调试:how?
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

友情链接更多精彩内容