【问题标题】:How to build multiple projects in the correct dependency order with Android NDK?如何使用 Android NDK 以正确的依赖顺序构建多个项目?
【发布时间】:2013-02-17 16:47:14
【问题描述】:

我有一系列现有的库,需要在 Android 应用程序中重复使用。布局类似于:

\库\libOne
\Libraries\libTwo [静态库]
\库\libThree
\Applications\MyApplication\ [应用程序]

libTwo 依赖于libOnelibThree 依赖于libTwo。如何让构建系统以正确的顺序构建所有库?我正在尝试使用 Eclipse,但如有必要,我可以使用命令行。

所有这些库最终都会被 Java 应用程序引用(并使用 JNI 与它们进行交互)。关于如何设置 Android.mk / Application.mk 文件的任何线索?

我尝试将BUILD_STATIC_LIBRARY 用于libTwo,但它实际上并没有输出任何文件!我期待一个libTwo.a 文件,但没有编译或构建。

我是否在应用程序中编写一个 Android.mk?还是每个项目都有一个 Android.mk?

【问题讨论】:

  • 你能分享你的 Android.mk 吗?目前尚不清楚您是如何设置项目的。
  • @AlexCohn 我还没有可用的 Android.mk,这就是问题所在。我正在寻找描述如何构建所有三个库并将它们从主应用程序链接在一起的答案。
  • 我了解到您还没有一个可以运行的 Android.mk,但您有一个尚未运行的 Android.mk,不是吗?

标签: android eclipse android-ndk


【解决方案1】:

好的,现在我看到了您的编辑,这使得回答具体问题成为可能。

如果您想使用 Android NDK 构建您的原生库,您必须至少有一个 Android.mk 文件用于您的应用程序。不过,这不是一个要求。可以通过 Cmake,或带有“传统”makefile 的“独立工具链”,或使用 MS Visual Studio 插件,或任何其他方式来构建它。重要的是结果。结果是使用兼容编译器为仿生运行时构建的共享对象。

将库放在${project_root}/libs/armeabi/ 目录(对于 ARM v6 兼容设备,x86、MIPS、arm v7a 的其他子目录)以允许 APK 构建器正确打包它,以允许应用安装程序解包正确版本(与设备处理器兼容)到设备上的/data/data/${package_name}/lib 目录中,最终能够使用System.loadLibrary(short_name) 从Java 中使用它。但也可以以不同的方式打包so 文件,手动解压,然后从设备文件系统上的任何位置加载(前提是您的应用有权写入和读取此文件)。

但如果我们过滤掉特殊情况,在${project_root}/jni 目录中放置一个Android.mk 会更舒服。在ndk-build 命令方面,每个库都是一个单独的 MODULE,但三个都可以定义在一个 Android.mk 文件中。另一方面,如果您的库是独立的(例如来自不同的第 3 方),您可能更愿意创建三个 Android.mk 文件。幸运的是,ndk-build 只不过是 gnu make 的一个包装器,Android.mk 中的简单 include 语句与任何其他 makefile 一样工作。

总而言之,您的案例可能包含在一个简单的Applications/MyApplication/ [Application]/jni/Android.mk 文件中:

include ../../Libraries/libOne/Android.mk
include ../../Libraries/libTwo/Android.mk
include ../../Libraries/libThree/Android.mk

我不知道你在 libOne 和 libTwo 之间有什么依赖关系,但是对于 libOne,文件 Libraries/libOne/Android.mk 看起来像

LOCAL_PATH = $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE    := libOne
LOCAL_SRC_FILES := first.c
include $(BUILD_STATIC_LIBRARY)

Libraries/libThree/Android.mk

LOCAL_PATH = $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE    := libThree
LOCAL_SRC_FILES := third.c
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../libOne $(LOCAL_PATH)/../libTwo
LOCAL_STATIC_LIBRARIES := libOne libTwo
include $(BUILD_SHARED_LIBRARY)

您应该从 Applications/MyApplication/ [Application] 目录运行 ndk-build - 从命令提示符或通过 Eclipse ADT 插件。

更新同样可以用jni目录下的一个Android.mk文件来表示:

LOCAL_PATH = ../../Libraries/libOne
include $(CLEAR_VARS)
LOCAL_MODULE    := libOne
LOCAL_SRC_FILES := first.c
include $(BUILD_STATIC_LIBRARY)

LOCAL_PATH = ../../Libraries/libThree
include $(CLEAR_VARS)
LOCAL_MODULE    := libThree
LOCAL_SRC_FILES := third.c
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../libOne $(LOCAL_PATH)/../libTwo
LOCAL_STATIC_LIBRARIES := libOne libTwo
include $(BUILD_SHARED_LIBRARY)

【讨论】:

  • 感谢您,我尝试使用多个 Android.mk 文件,但它导致重新定义 LOCAL_PATH 出现问题($(call my-dir) 返回 NDK 核心目录,而不是第一行未调用时的实际目录!
  • 绝对! $(call my-dir) 应该是文件中的第一行之一。但这与一个或多个Android.mk文件的问题无关。请参阅更新
【解决方案2】:

项目属性中有一个 android 部分,您可以在其中编辑库依赖项。仅当 libOne、libTwo 和 libThree 在其属性面板中标记为库时才能使用。

【讨论】:

    猜你喜欢
    • 2017-02-11
    • 2014-03-19
    • 1970-01-01
    • 2014-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多