如何在编译之前在Android.mk中运行自定义规则?

m-r*_*ric 13 android makefile android-ndk

在Android NDK中,我构建了由SWIG自动生成的JNI文件.callmanager_wrap.cpp是共享库的一部分:

LOCAL_SRC_FILES += callmanager_wrap.cpp
include $(BUILD_SHARED_LIBRARY)
Run Code Online (Sandbox Code Playgroud)

但是我想callmanager_wrap.cpp在编译之前添加/编辑.更明确一点:

cat jnistuff.txt >> callmanager_wrap.cpp
Run Code Online (Sandbox Code Playgroud)

我需要添加的内容事先知道,但callmanager_wrap.cpp不是.它由SWIG生成.最终,我的自定义规则必须运行以下命令来生成callmanager_wrap.cpp:

swig -c++ -java -package com.package.my -o callmanager_wrap.cpp callmanager.i
Run Code Online (Sandbox Code Playgroud)

根据这篇文章,无法添加自定义规则Android.mk.但在Android资源中,我相信Android.mk在BUILT或INSTALLED之后会有一些处理步骤.我尝试了以下方法:

MY_JNI_WRAP=callmanager_wrap.cpp

include $(CLEAR_VARS)

LOCAL_SRC_FILES += callmanager_wrap.cpp

LOCAL_INTERMEDIATE_TARGETS += myjni
myjni:
    echo "in myjni target"
    swig -c++ -java -package com.package.my -o $(MY_JNI_WRAP) callmanager.i
    cat jnistuff.txt >> $(MY_JNI_WRAP)

include $(BUILD_SHARED_LIBRARY)
Run Code Online (Sandbox Code Playgroud)

myjni目标从未被调用过.

  1. 什么是LOCAL_INTERMEDIATE_TARGETS用于?
  2. 如果不编写外部脚本或makefile,我可以实现我想做的事吗?

Ale*_*ohn 9

我建议如下:

include $(CLEAR_VARS)

LOCAL_SRC_FILES += callmanager_wrap.cpp
MY_JNI_WRAP := $(LOCAL_PATH)/callmanager_wrap.cpp

$(MY_JNI_WRAP):
    echo "in myjni target"
    swig -c++ -java -package com.package.my -o $(MY_JNI_WRAP) callmanager.i
    cat jnistuff.txt >> $(MY_JNI_WRAP)
.PHONY: $(MY_JNI_WRAP)

include $(BUILD_SHARED_LIBRARY)
Run Code Online (Sandbox Code Playgroud)

而已.

我可能欠你一些解释.所以我们走了:

  1. $(LOCAL_SRC_FILES)是一个相对于文件名的列表$(LOCAL_PATH),因此要从标准NDK操作外部处理文件,您需要文件的完整路径,即$(LOCAL_PATH)/callmanager_wrap.cpp.

  2. 我们指定文件.PHONY以保证每次运行ndk-build时都执行自定义操作.但是如果你知道哪些是实际的依赖关系callmanager_wrap.cpp,你可以改为指定它们,比如

    $(MY_JNI_WRAP): callmanager.i jnistuff.txt $(LOCAL_PATH)/../src/com/package/my/Something.java

    在这种情况下,您将不需要该.PHONY行.

  3. 如果希望源目录保持干净,可以.INTERMEDIATE像这样声明包装器文件:

    .INTERMEDIATE: $(MY_JNI_WRAP)

现在make会在构建之后删除包装器文件,如果它在构建之前不存在.