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

2023-09-06 00:20:02 作者:核能气质少年

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

  LOCAL_SRC_FILES + = callmanager_wrap.cpp
包括$(BUILD_SHARED_LIBRARY)
 

不过,我想在编译之前追加/编辑 callmanager_wrap.cpp 。为了更明确的:

 猫jnistuff.txt>> callmanager_wrap.cpp
 
Android.mk的最后尝试

内容我需要补充的是预先知道,但callmanager_wrap.cpp不是。它是由SWIG生成。最终,我的自定义规则将需要运行以下命令来生成callmanager_wrap.cpp:

 痛饮-c ++ -java -package com.package.my -o callmanager_wrap.cpp callmanager.i
 

根据这个帖子,这是不可能添加自定义规则 Android.mk 。但在Android的来源,我相信有建成或在安装后一定 Android.mk 处理步骤。我试过如下:

  MY_JNI_WRAP = callmanager_wrap.cpp

包括$(CLEAR_VARS)

LOCAL_SRC_FILES + = callmanager_wrap.cpp

LOCAL_INTERMEDIATE_TARGETS + = myjni
myjni:
    回声,在myjni目标
    痛饮-c ++ -java -package com.package.my -o $(MY_JNI_WRAP)callmanager.i
    猫jnistuff.txt>> $(MY_JNI_WRAP)

包括$(BUILD_SHARED_LIBRARY)
 

myjni 目标永远不会被调用。

在使用何种LOCAL_INTERMEDIATE_TARGETS呢? 我都不可能达到我想要在这里做,而无需编写外部脚本或Makefile的? 解决方案

我建议如下:

 包括$(CLEAR_VARS)

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

$(MY_JNI_WRAP):
    回声,在myjni目标
    痛饮-c ++ -java -package com.package.my -o $(MY_JNI_WRAP)callmanager.i
    猫jnistuff.txt>> $(MY_JNI_WRAP)
.PHONY:$(MY_JNI_WRAP)

包括$(BUILD_SHARED_LIBRARY)
 

就是这样。

我大概欠你一些解释。所以在这里我们去:

$(LOCAL_SRC_FILES)是文件名相对于 $(LOCAL_PATH),所以名单从标准NDK行动之外地址的文件,你需要完整的路径为您的文件,这是 $(LOCAL_PATH)/callmanager_wrap.cpp

我们该文件设置为 .PHONY ,以保证自定义操作每次运行的 NDK建造的时间执行。但如果你知道这是 callmanager_wrap.cpp 的实际依赖关系,而是可以指定它们,就像

$(MY_JNI_WRAP):callmanager.i jnistuff.txt $(LOCAL_PATH)/../ SRC / COM /封装/我/ Something.java

在这种情况下,你不会需要 .PHONY 行。

如果你希望你的源代码目录保持干净,你可以声明封装文件作为 .INTERMEDIATE 是这样的:

.INTERMEDIATE:$(MY_JNI_WRAP)

现在请将删除生成后的封装文件,如果构建之前并不存在的。

In Android NDK, I build JNI files generated automatically by SWIG. callmanager_wrap.cpp is part of a shared library:

LOCAL_SRC_FILES += callmanager_wrap.cpp
include $(BUILD_SHARED_LIBRARY)

But I would like to append/edit callmanager_wrap.cpp before compiling. To be more explicit:

cat jnistuff.txt >> callmanager_wrap.cpp

Content I need to add is known in advance but callmanager_wrap.cpp is not. It is generated by SWIG. Ultimately, my custom rule will have to run following command to generate callmanager_wrap.cpp:

swig -c++ -java -package com.package.my -o callmanager_wrap.cpp callmanager.i

According to this post, it is not possible to add custom rules to Android.mk. But in Android sources, I believe there are some Android.mk handling steps after BUILT or INSTALLED. I tried the following:

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)

But myjni target is never called.

What is LOCAL_INTERMEDIATE_TARGETS used for? Can I possibly achieve what I want to do here without writing an external script or makefile?

解决方案

I would suggest the following:

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)

That's it.

I probably owe you some explanations. So here we go:

$(LOCAL_SRC_FILES) is a list of file names relative to $(LOCAL_PATH), so to address a file from outside the standard NDK actions, you need the full path for your file, which is $(LOCAL_PATH)/callmanager_wrap.cpp.

We specify the file as .PHONY to guarantee that the custom action is executed every time you run ndk-build. But if you know which are actual dependencies of callmanager_wrap.cpp, you can specify them instead, like

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

In this case, you will not need the .PHONY line.

If you want your source directory to remain clean, you can declare the wrapper file as .INTERMEDIATE like this:

.INTERMEDIATE: $(MY_JNI_WRAP)

Now make will delete the wrapper file after build, if it did not exist before the build.