【问题标题】:Android NDK: how to include Android.mk into another Android.mk (hierarchical project structure)?Android NDK:如何将 Android.mk 包含到另一个 Android.mk(分层项目结构)中?
【发布时间】:2023-04-06 20:37:01
【问题描述】:

看起来有可能,但我的脚本产生了奇怪的结果:

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

include $(LOCAL_PATH)/libos/Android.mk
include $(LOCAL_PATH)/libbase/Android.mk
include $(LOCAL_PATH)/utils/Android.mk

LOCAL_MODULE := native
include $(BUILD_SHARED_LIBRARY)

只有第一个包含被解析得很好,其他 Android.mk 文件被搜索到奇怪的路径。 有什么建议吗?

更新:我破坏了我的建筑环境...在办公室还可以,但在家里 LOCAL_PATH:= $(call my-dir) 将 LOCAL_PATH 定义为 NDK 目录而不是项目目录.这是我的建筑批次:

set BASHPATH=K:\cygwin\bin\bash
set PROJECTDIR=/cygdrive/h/Alex/Alex/Work/Android/remote-android
set NDKDIR=/cygdrive/h/Alex/Programming_Docs/Android/android-ndk-r6/ndk-build
set APP_BUILD_SCRIPT=/cygdrive/h/Alex/Alex/Work/Android/project/jni/Android.mk
set DEV_ROOT=h:/Alex/Alex/Work/Android/project

%BASHPATH% --login -c "cd %PROJECTDIR% && %NDKDIR%"

更新:我完全不明白这东西是如何组成路径的。我的路径出现错误,例如“/cygdrive/d/project/jni//cygdrive/d/Soft/project/jni/libos/src/libos.cpp”。这是在我决定指定根目录中的所有文件之后Android.mk 而不是包含子模块。

更新 2:不走运,这也不起作用:

LOCAL_PATH:= $(call my-dir)
# Include makefiles here.
include $(LOCAL_PATH)/libos/Android.mk
include $(LOCAL_PATH)/libbase/Android.mk
include $(LOCAL_PATH)/utils/Android.mk

# Clear variables here.
 include $(CLEAR_VARS)

【问题讨论】:

  • 我会冒险并建议也许第一个 Android.mk 正在重新定义 LOCAL_PATH。尝试使用其他变量名,例如AARDVARK,看看会发生什么。

标签: android android-ndk makefile


【解决方案1】:

这里已经很晚了,但如果有人读到这个问题,解决路径损坏问题的一种方法(指向从 jni 中插入文件的 ndk)是在你的 jni 文件夹中:

include $(call all-subdir-makefiles)

然后在它的每个子文件夹中(在 OP 的情况下为 libos、libbase 和 ustils)一个这种形式的 Android.mk:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_C_INCLUDES        := $(LOCAL_PATH)
LOCAL_MODULE            := utils
LOCAL_SRC_FILES         := one.c
LOCAL_SRC_FILES         += two.c

第二个 Android.mk 与 jni 文件夹中的子文件夹中的 one.c 和 two.c 文件。

请注意,尝试一些事情

LOCAL_PATH_BIS_WEIRD_OTHER_NAME := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_C_INCLUDES        := $(LOCAL_PATH_OTHER_FUNKY_NAME)
LOCAL_MODULE            := utils
LOCAL_SRC_FILES         := one.c
LOCAL_SRC_FILES         += two.c

将再次导致编译器在寻找 ndk 所在的源代码时感到困惑。

因此,在 jni 的每个子目录中完全以这种形式使用 LOCAL_PATH := $(call my-dir)include $(call all-subdir-makefiles) strong> 在 jni 本身中,你不应该有问题。

希望这会对某人有所帮助。

编辑:发生这种行为是因为包含 $(CLEAR_VARS) 没有删除保存在 LOCAL_PATH 中的内容。

【讨论】:

  • 救命稻草!弄乱我所有的路径和东西,直到我使用这个解决方案......因为这样的怪癖,我总是害怕使用 NDK 构建系统。
【解决方案2】:

这就是我的做法。

需要注意的是,我没有将任何 C++ 源代码放在构建目录中,因为其中大部分是独立于平台的。这只是意味着 LOCAL_PATH 不是项目目录的子目录,/jni 中的唯一文件是 2 个 .mk 文件。

无论如何,这里有一个完整的顶级 Android.mk 和一个包含在真实项目中的文件:

顶层:

LOCAL_PATH := $(abspath $(call my-dir)/../../../src)

# utility to create paths for included makefiles
local-rel-path = $(patsubst /%,%,$(subst $(LOCAL_PATH),,$(abspath $1)))

include $(CLEAR_VARS)

LOCAL_MODULE := NativeApp

LOCAL_LDLIBS := -lGLESv1_CM

# As opposed to "thumb"
LOCAL_ARM_MODE := arm

LOCAL_SRC_FILES :=

#
# includes
#
# Note that LOCAL_C_INCLUDE is relative to thr NDK root, unlike source paths
# (or you can just make 'em absolute)
#
STL_INC_DIR = /cygdrive/c/STLport-5.2.1/stlport

MY_LOCAL_C_INCLUDES := core satcalc bruce/bruce/inc bruce/gfx/inc bruce/ui/inc bruce/unzip bruce/libpng

LOCAL_C_INCLUDES := $(addprefix $(LOCAL_PATH)/,$(MY_LOCAL_C_INCLUDES)) $(STL_INC_DIR) 

ifeq ($(APP_OPTIM),debug)
# debug
LOCAL_CFLAGS = -DPLATFORM_ANDROID -D_DEBUG -fvisibility=hidden
else
#release
LOCAL_CFLAGS = -DPLATFORM_ANDROID -fvisibility=hidden
endif

LOCAL_STATIC_LIBRARIES := 

#
# Code
#
include $(LOCAL_PATH)/core/Android.mk
include $(LOCAL_PATH)/satcalc/Android.mk
include $(LOCAL_PATH)/bruce/bruce/src/Android.mk
include $(LOCAL_PATH)/bruce/gfx/src/Android.mk
include $(LOCAL_PATH)/bruce/ui/src/Android.mk
include $(LOCAL_PATH)/bruce/unzip/Android.mk
include $(LOCAL_PATH)/bruce/libpng/Android.mk

#
# Build it
#
include $(BUILD_SHARED_LIBRARY)

...以及包含的 Android.mk:

MY_PATH = $(call my-dir)

MY_LOCAL = $(call local-rel-path, $(MY_PATH))

MY_SRC_FILES = Font.cpp Gfx2d_ogles.cpp SgaState.cpp \
        Sprite.cpp TImage.cpp TImageOgles.cpp 

LOCAL_SRC_FILES += $(addprefix $(MY_LOCAL)/,$(MY_SRC_FILES))

【讨论】:

    【解决方案3】:

    我的做法是这样的:

    LOCAL_PATH:= $(call my-dir)
    
    # Clear variables here.
    include $(CLEAR_VARS)
    
    # Current module settings.
    LOCAL_MODULE := native
    # setup some source files
    LOCAL_SRC_FILES := file1.c file2.c
    # setup some includes
    LOCAL_C_INCLUDES := $(LOCAL_PATH)/libos/include
    # setup the included libs for the main module
    LOCAL_STATIC_LIBRARIES := libos libbase utils # note that order matters here
    
    include $(BUILD_SHARED_LIBRARY)
    
    # Include makefiles here. Its important that these 
    # includes are done after the main module, explanation below.
    
    # create a temp variable with the current path, because it 
    # changes after each include
    ZPATH := $(LOCAL_PATH)
    
    include $(ZPATH)/libos/Android.mk
    include $(ZPATH)/libbase/Android.mk
    include $(ZPATH)/utils/Android.mk
    

    注意,这包括当前模块变量的设置之后完成。这是必需的,因为每个包含都会修改 LOCAL_PATH 变量(实际上它会修改 $(call my-dir) 返回的内容),这就是为什么必须最后完成包含。

    这将自动编译所有包含的模块(或者如果使用 clean 调用则为 clean),然后链接所有包含的库。

    此设置已在实际项目中进行了测试,并且可以正常工作。

    答案取自这里:https://docs.google.com/document/d/1jDmWgVgorTY_njX68juH5vt0KY_FXWgxkxmi2v_W_a4/edit

    【讨论】:

      【解决方案4】:

      你在正确的轨道上。这是将 Android.mk 文件包含在另一个文件中的正确方法——它实际上是 Android make 系统所要求的。需要注意的一点是,清除变量的行应该出现在您包含其他 makefile 之后,如下所示:

      LOCAL_PATH:= $(call my-dir)
      
      # Include makefiles here.
      include $(LOCAL_PATH)/libos/Android.mk
      include $(LOCAL_PATH)/libbase/Android.mk
      include $(LOCAL_PATH)/utils/Android.mk
      
      # Clear variables here.
      include $(CLEAR_VARS)
      
      # Final settings.
      LOCAL_MODULE := native
      include $(BUILD_SHARED_LIBRARY)
      

      我还要提一下,您可能想设置也可能不想设置其他重要标志,包括以下(我的一个 makefile 中的示例):

      # Settings.
      LOCAL_C_INCLUDES             := $(MY_INCLUDES)
      LOCAL_STATIC_LIBRARIES       := $(MY_MODULES) 
      LOCAL_WHOLE_STATIC_LIBRARIES := $(MY_WHOLE_MODULES) 
      LOCAL_LDLIBS                 := -lz -llog -lGLESv1_CM -lGLESv2 
      LOCAL_ARM_MODE               := arm
      LOCAL_MODULE                 := game
      

      最后,我发现嵌入在 Android ndk 中的文档特别有用。我的位于以下位置:

      android-ndk-r6/documentation.html
      

      如果您还有其他问题,请告诉我。希望这可以帮助! :)

      【讨论】:

      • 另外,我是否需要在每个包含的 .mk 中指定诸如 LOCAL_ARM_MODE := arm 之类的内容,还是只在顶层指定一次?
      • CLEAR_VARS 清除生成文件中的所有“LOCAL_”变量,“LOCAL_PATH”除外。此外,所有设置都是本地的(因此名称中有“LOCAL_”),因此它们仅适用于它们所在的 makefile,因此您必须将它们放在任何地方。最后,在文档中,查看 Application.mk 文件 - 它可用于指定适用于所有 makefile 的标志。 :)
      • 明白,谢谢。那么,包含的 .mk 不能重新定义顶级 .mk 的 LOCAL_PATH 吗?或者是否包含它以便它不是一个独立的实体,而是顶级文件的一部分?
      • 试过你的建议 - 也不起作用。我觉得我正在失去理智。
      • 我总是用 LOCAL_PATH 获得的 $(LOCAL_PATH) 得到错误的路径:= $(call my-dir),通常是 NDK 的路径。根据我是拼写 LOCAL_SRC_FILES := src/libos.cpp 还是 LOCAL_SRC_FILES := $(LOCAL_PATH)/src/libos.cpp 我得到不同的结果,在不同的makefile中总是很奇怪和不同。我只是不明白解析器的操作逻辑。
      【解决方案5】:

      这里的答案很晚,但我遇到了这个问题,这些解决方案都没有用。解决方案很简单:详细here,设置一个MY_LOCAL_PATH 变量并每次重新分配LOCAL_PATH

      MY_LOCAL_PATH := $(call my-dir)
      
      LOCAL_PATH := $(MY_LOCAL_PATH)
      
      ... declare one module
      
      include $(LOCAL_PATH)/foo/Android.mk
      
      LOCAL_PATH := $(MY_LOCAL_PATH)
      
      ... declare another module
      

      【讨论】:

        【解决方案6】:

        我测试下面的代码没问题。

        # I want only second-level mk files, that is the direct sub-directories
        # in the current path.
        include $(wildcard */*/Android.mk)
        # include $(call all-subdir-makefiles)  ## $(wildcard $(call my-dir)/*/Android.mk)
        # include $(call all-makefiles-under,$(LOCAL_PATH))
        

        Android.mk

        # I dunno why it's an empty result for $(call all-subdir-makefiles).
        # $(info [^-^ print-test] all-subdir-makefiles = "$(call all-subdir-makefiles) ")
        $(info [print-test] assert "jni/Android.mk" = "$(wildcard */Android.mk)") # print: jni/Android.mk
        $(info [print-test] $$(wildcard */*/Android.mk) = "$(wildcard */*/Android.mk)") # print: jni/xxdir/Android.mk
        

        我打印结果:

        $ cd your_project_path
        $ ndk-build
        [print-test] assert "jni/Android.mk" = "jni/Android.mk"
        [print-test] (wildcard */*/Android.mk) = "jni/HelloWorld/Android.mk jni/MessagePack/Android.mk"
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-12-01
          • 1970-01-01
          • 2015-03-31
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多