【笔记】学习Android.mk(四)

一、如何编译Jar包

要在 Android 项目中编译生成 Jar 包,你需要在 Android.mk 文件中使用 BUILD_STATIC_JAVA_LIBRARY 或者 BUILD_SHARED_JAVA_LIBRARY 来定义一个 Java 库模块。以下是一个示例:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

# 定义模块名称和源文件
LOCAL_MODULE := myjavamodule
LOCAL_SRC_FILES := MyClass1.java MyClass2.java

# 以下二选一:
# 1. 生成静态的jar包
include $(BUILD_STATIC_JAVA_LIBRARY)
# 2. 生成动态的jar包
include $(BUILD_JAVA_LIBRARY)

在这个示例中,我们使用了 BUILD_STATIC_JAVA_LIBRARY 来定义一个静态 Java 库模块。你可以在 LOCAL_SRC_FILES 中指定你的 Java 源文件列表,然后执行 ndk-build 命令来编译生成 Jar 包。

请注意,使用 BUILD_STATIC_JAVA_LIBRARY 生成的 Jar 包是静态的,意味着其中的类文件将被打包成一个 Jar 文件,但不会包含依赖的库。如果你的项目依赖其他的 Jar 包,你需要手动添加它们。

如果你想生成一个动态 Java 库,可以使用 BUILD_SHARED_JAVA_LIBRARY,但在 Android NDK r20 版本之后,Google 移除了对动态 Java 库的支持,因此建议使用静态 Java 库。

二者的区别:
静态jar包里面包含的都是.class文件,可以在任何JVM中运行
动态jar包里面包含的都是.dex文件,所以只能运行在Dalvik 虚拟机(Android 4.4 及更早版本)或 ART 虚拟机(Android 5.0 及更高版本)

二、如何编译Apk

使用 ndk-build 或者 mm 命令来执行编译和构建过程。

以下是一个简单的 Android.mk 文件示例,用于构建一个包含 Java 源文件和资源文件的 APK:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

# 定义模块名称和源文件
LOCAL_MODULE := mymodule
LOCAL_SRC_FILES := $(call all-java-files-under, src/main/java)

# 编译生成的Apk名字
LOCAL_PACKAGE_NAME := YOU_APK_NAME
# 添加资源文件
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/src/main/res

# 指定依赖的系统库
LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4

include $(BUILD_PACKAGE)

# 指定系统库的路径
$(call import-module,build/libs/android-support-v4)

在这个示例中,我们假设项目的 Java 源文件位于 src/main/java 目录下,资源文件位于 src/main/res 目录下。我们使用了 all-java-files-under 函数来自动查找 Java 源文件。我们还指定了一个名为 android-support-v4 的系统库作为静态 Java 库的依赖项。

你可以使用 ndk-build 命令来构建 APK 文件:

ndk-build

执行完成后,你将会在项目的 libs 目录下找到生成的 APK 文件。请注意,使用 Android.mk 文件构建 APK 的方法相对复杂,通常情况下推荐使用 Android Studio 或 Gradle 构建系统来构建 APK。

生成的Apk文件名为YOU_APK_NAME.apk

三、Apk中导入Jar包和库文件

Android.mk 文件中引用 Jar 包,使用 LOCAL_STATIC_JAVA_LIBRARIES 或者 LOCAL_SHARED_JAVA_LIBRARIES 变量来指定依赖的 Java 库。以下是一个示例:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

# 定义模块名称和源文件
LOCAL_MODULE := mymodule
LOCAL_SRC_FILES := file1.cpp file2.cpp

# 添加头文件包含路径
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include

# 指定依赖的系统库
LOCAL_LDLIBS := -llog

# 指定依赖的 Java 库
LOCAL_STATIC_JAVA_LIBRARIES := myjava_lib

include $(BUILD_SHARED_LIBRARY)

# 指定要引用的 Jar 包
include $(CLEAR_VARS)
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := myjava_lib:libs/myjava_lib.jar
include $(BUILD_MULTI_PREBUILT)

在这个示例中,我们首先使用 LOCAL_STATIC_JAVA_LIBRARIES 变量指定了一个名为 myjava_lib 的 Java 库作为静态依赖项。然后,我们使用 LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES 变量指定了 myjava_lib Jar 包的路径。最后,我们使用 BUILD_MULTI_PREBUILT 来添加预构建的 Java 库。

你需要将 myjava_lib.jar 放置在 libs 目录下,并确保 libs 目录在 Android.mk 文件的相对路径中。这样,当执行 ndk-build 命令时,构建系统将会将 Jar 包与本地代码一起打包到最终的 APK 文件中。

四、预编译Jar包

要在 Android.mk 文件中使用预编译的 Jar 包,你可以使用 LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES 或者 LOCAL_PREBUILT_SHARED_JAVA_LIBRARIES 变量来指定预编译的 Jar 包。以下是一个示例:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

# 定义模块名称和源文件
LOCAL_MODULE := mymodule
LOCAL_SRC_FILES := file1.cpp file2.cpp

# 添加头文件包含路径
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include

# 指定依赖的系统库
LOCAL_LDLIBS := -llog

# 指定预编译的 Java 库
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := myjava_lib:libs/myjava_lib.jar

include $(BUILD_SHARED_LIBRARY)

在这个示例中,我们使用 LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES 变量来指定了一个名为 myjava_lib 的预编译静态 Java 库。myjava_lib.jar 文件需要位于 libs 目录下,构建系统会自动将其打包到最终的 APK 文件中。

确保 myjava_lib.jar 文件存在于 libs 目录下,并且在执行 ndk-build 命令时能够被构建系统正确地识别和使用。

五、Android.mk中如何加判断语句选择不同的编译类型

Android.mk 文件中,你可以使用 GNU Make 提供的条件语句来添加判断语句。以下是一些常见的条件语句用法:

  1. ifeq/ifneq:用于比较两个变量是否相等或不相等。

    ifeq ($(TARGET_ARCH),arm)
        # 在目标架构为 ARM 时执行的命令
    endif
    
    ifneq ($(TARGET_ARCH),x86)
        # 在目标架构不为 x86 时执行的命令
    endif
    
  2. ifdef/ifndef:用于检查变量是否已经定义或未定义。

    ifdef TARGET_ARCH
        # 如果 TARGET_ARCH 已经定义,则执行的命令
    endif
    
    ifndef TARGET_ARCH
        # 如果 TARGET_ARCH 未定义,则执行的命令
    endif
    
  3. ifeq/ifneq (多行):条件语句也可以跨多行书写。

    ifeq ($(TARGET_ARCH),arm)
        # 在目标架构为 ARM 时执行的命令 \
        可以在这里写多行命令
    endif
    
  4. 条件语句中的逻辑运算:可以使用逻辑运算符 &&||! 结合多个条件。

    ifeq ($(TARGET_ARCH),arm) && ($(TARGET_CPU),cortex-a9)
        # 在目标架构为 ARM 且 CPU 为 cortex-a9 时执行的命令
    endif
    

这些条件语句可以让你根据不同的条件执行不同的命令或设置不同的变量。请注意,在条件语句中,变量名和条件之间需要使用括号括起来,并且条件语句的结束

六、Android.mk常用语法

Android.mk 文件是 Android NDK 中用于构建 C/C++ 代码的 Makefile 文件。它基于 GNU Make 语法,并提供了一些特定于 Android 开发的扩展。以下是一些常用的 Android.mk 文件语法和用法:

  1. 变量定义

    • 使用 := 赋值符号定义变量,例如 MY_VARIABLE := value
    • 使用 += 赋值符号向变量追加值,例如 MY_VARIABLE += new_value
  2. 包含其他 Makefile

    • 使用 include 指令可以包含其他 Makefile 文件,例如 include $(CLEAR_VARS)
  3. 清除变量

    • 使用 $(CLEAR_VARS) 来清除之前的变量定义,例如 include $(CLEAR_VARS)
  4. 条件语句

    • 使用 ifeq, ifneq, ifdef, ifndef 来进行条件判断。
    • 使用 endif 结束条件语句块。
  5. 模块定义

    • 使用 LOCAL_PATH 定义当前模块的路径,例如 LOCAL_PATH := $(call my-dir)
    • 使用 LOCAL_MODULE 定义模块名称,例如 LOCAL_MODULE := mymodule
    • 使用 LOCAL_SRC_FILES 定义模块的源文件列表,例如 LOCAL_SRC_FILES := file1.cpp file2.cpp
  6. 编译标志

    • 使用 LOCAL_CFLAGS 定义 C/C++ 编译标志,例如 LOCAL_CFLAGS := -Wall -Werror
    • 使用 LOCAL_CPPFLAGS 定义 C++ 编译标志,例如 LOCAL_CPPFLAGS := -std=c++11
  7. 链接库

    • 使用 LOCAL_LDLIBS 定义链接库,例如 LOCAL_LDLIBS := -llog
    • 使用 LOCAL_STATIC_LIBRARIES 定义静态库依赖,例如 LOCAL_STATIC_LIBRARIES := somelib
    • 使用 LOCAL_SHARED_LIBRARIES 定义动态库依赖,例如 LOCAL_SHARED_LIBRARIES := somelib
  8. 构建指令

    • 使用 include $(BUILD_SHARED_LIBRARY) 构建动态库。
    • 使用 include $(BUILD_STATIC_LIBRARY) 构建静态库。
    • 使用 include $(BUILD_EXECUTABLE) 构建可执行文件。
    • 使用 include $(BUILD_PREBUILT) 构建预编译文件。

这些是 Android.mk 文件中常用的一些语法和用法。使用这些语法和指令,你可以编写 Android.mk 文件来管理和构建你的 C/C++ 项目。

  • 21
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值