Android NDK:如何包含Android.mk进入另一个Android.Mk(分层项目结构)



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

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:cygwinbinbash
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)

有点晚了,但是如果有人读到这个问题,解决路径破碎问题(指向ndk而不是来自jni的文件)的一种方法是在jni文件夹中:

include $(call all-subdir-makefiles)

,然后在它的每个子文件夹(libos, libase和ustils在OP的情况下)一个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

where this second Android。在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),并且在jni本身中包含$(call all-subdir-makefiles),您应该不会有问题。

希望对大家有所帮助。

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

我是这样做的。

需要注意的是,我没有将任何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))

我的方法是这样的:

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

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

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

这个设置已经在一个真实的项目中进行了测试,并且工作正常。

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

你做对了。这是包含Android的正确方式。这实际上是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
如果你还有问题,请告诉我。希望这对你有帮助!:)

很晚才回答,但我遇到了这个问题,这些解决方案都没有用。解决方案很简单:如下所示,设置一个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

我测试下面的代码ok

# 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"

最新更新