【问题标题】:How to write/debug Android.mk for NDK static library?如何为 NDK 静态库编写/调试 Android.mk?
【发布时间】:2023-03-21 00:39:01
【问题描述】:

我正在尝试使用最新的 Android NDK (r5) 构建一个静态库,但我没有任何运气。我已经能够毫无问题地构建和运行示例(例如 HelloJni),但从“零”开始一个新项目却是另一回事。

对于这个实验,我正在尝试构建 libpng。我的文件夹结构如下所示:

root
|
+--- jni
      |
      +---- Android.mk ( one line: "include $(call all-subdir-makefiles)" )
      |
      +---- png
             |
             +---- Android.mk ( see below )
             |
             +---- { a bunch of .c and .h files )

所以我有两个 Android.mks。一个用于构建所有子项目,一个用于 libpng 子项目。 root/jni/png/Android.mk 看起来像这样:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := png
MODULE_PATH := $LOCAL_PATH
LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.c)
LOCAL_C_INCLUDES := $(wildcard $(LOCAL_PATH)/*.h)

LOCAL_INTERMEDIATE_TARGETS += junk
junk:
    echo $(LOCAL_SRC_FILES)

include $(BUILD_STATIC_LIBRARY)

这个构建设置似乎什么都不做(即从根文件夹运行 ndk-build 什么也不做,即使在 ndk-build clean 之后也是如此)。详细运行(ndk-build V=1)显示一些 rm -f 调用(删除不存在的文件夹),但与项目或子项目无关。

我很感兴趣为什么这个构建脚本会失败,但是这个过程应该是微不足道的,所以我确信它没有什么特别有趣的。我对如何开始自己攻击构建错误更感兴趣。上面脚本中的 echo 调用永远不会被命中——我不知道如何确定什么是值或为什么它会跳过子项目。有没有人找到一种方法来了解构建系统正在尝试做什么?

我还想知道这些工具是否有文档,或者它是否只是 NDK 文档文件夹中的少数文本文件?我一直在尝试通过复制我从谷歌搜索中找到的随机 Android.mk 片段来解决这个问题,但似乎只有简单 NDK 示例中使用的少数命令被记录在案,因此这种体验实际上只是提出了新问题。

【问题讨论】:

    标签: android android-ndk


    【解决方案1】:

    我建议去掉 MODULE_PATH 而不要尝试使用通配符:我还没有真正看到它的工作原理。

    LOCAL_PATH := $(call my-dir)
    
    include $(CLEAR_VARS)
    
    LOCAL_MODULE := png
    LOCAL_SRC_FILES := pngget.c pngread.c pngrutil.c pngtrans.c pngwtran.c png.c pngmem.c pngrio.c pngset.c pngwio.c pngwutil.c pngerror.c pngpread.c pngrtran.c pngwrite.c
    LOCAL_C_INCLUDES := png.h pngconf.h pngpriv.h
    
    include $(BUILD_STATIC_LIBRARY)
    

    此外,我还没有完全理解一些严重的路径魔法:不知何故 Eclipse 做了正确的事情,但让它从命令行跳过正确的箍对我来说仍然是命中注定的。

    编辑:所以对解决这个问题有点兴趣,因为我已经有一段时间没有使用 NDK 了。当我使用原始文件时它没有编译,但是当我将png源代码放在目录jni然后使用这个Android.mk文件时:

    LOCAL_PATH := $(call my-dir)
    
    include $(CLEAR_VARS)
    
    LOCAL_MODULE := png
    LOCAL_SRC_FILES := pngget.c pngread.c pngrutil.c pngtrans.c pngwtran.c png.c pngmem.c pngrio.c pngset.c pngwio.c pngwutil.c pngerror.c pngpread.c pngrtran.c pngwrite.c
    LOCAL_C_INCLUDES := png.h pngconf.h pngpriv.h
    
    include $(BUILD_STATIC_LIBRARY)
    
    include $(CLEAR_VARS)
    LOCAL_MODULE := png2
    LOCAL_STATIC_LIBRARIES := png
    
    include $(BUILD_SHARED_LIBRARY)
    

    它在 obj/local/armeabi 文件夹中构建了 libpng.a 和 libpng2.so。我猜如果没有依赖,它根本不会构建静态库。

    【讨论】:

    • 谢谢。我已经尝试过了,它并没有改变任何行为(ndk-build 仍然是无操作的)。我也尝试过删除 LOCAL_C_INCLUDES,因为我不知道为什么会使用它。没有运气。听起来你是在建议我使用 eclipse 来生成这个 mk 文件?我不知道你能做到这一点。我也许可以使用它而不是有关如何调试 .mk 文件的说明。你能指点我如何做到这一点的说明吗?
    • 奇怪:抱歉,没用。原始参考文件是手工生成的,但除非我记错了,否则是由 Eclipse 构建的。我实际上会尝试自己构建它。需要注意的一件事:如果您在 Windows 上执行此操作,则必须确保路径中没有空格,因为在十多年后,Cygwin 仍然无法正确处理空格(不是视觉工作室ddk 做得很出色,所以这可能只是 Windows 吸风)。
    • 我将尝试删除我的文件夹结构并逐字使用您的文件。但是关于如何调试这些 .mk 文件的原始问题仍然存在。仅供参考,我在 Mac 上...
    • 呵呵:这真是神奇。这些工具的文档位于 /android-ndk-r5/docs 中,其中包含对可用内容的描述。
    • 你是我的新英雄。关于需要依赖的 Makefile 的编辑解决了它。我很尴尬。非常感谢!
    【解决方案2】:

    在过去的两个小时里,我一直在用这个问题打败自己,而这篇文章帮助解决了这个问题。与其添加一个虚拟依赖项,不如简单地调用 ndk-build(它只是对 make 的一个薄包装)作为“ndk-build png”。

    【讨论】:

      【解决方案3】:

      我发现当我按照编辑中的描述添加一个“虚拟”共享库时,.a(我在 obj/ 中找到,暗示它是一个内部细节)不包含我的任何 .o 文件想要。

      此外,.so 重新编译了所有为静态库构建的文件。所以 .a 为空是有道理的。

      帮助我的是在我的 Application.mk 中添加一个 APP_MODULES 行,如 Cannot build static library with Android NDK R8 中所述。无论如何,您可能想要一个 Application.mk,因为它包含对您的静态库很重要的其他设置,例如 APP_STL、APP_PLATFORM、APP_ABI 等。

      【讨论】:

        猜你喜欢
        • 2011-12-01
        • 1970-01-01
        • 2011-02-15
        • 2011-02-25
        • 1970-01-01
        • 2012-09-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多