Как запустить пользовательское правило в Android.mk перед компиляцией?
В Android NDK я создаю файлы JNI, созданные автоматически SWIG. callmanager_wrap.cpp является частью общей библиотеки:
LOCAL_SRC_FILES += callmanager_wrap.cpp
include $(BUILD_SHARED_LIBRARY)
Но я хотел бы добавить/отредактировать callmanager_wrap.cpp
перед компиляцией. Чтобы быть более явным:
cat jnistuff.txt >> callmanager_wrap.cpp
Содержимое, которое мне нужно добавить, известно заранее, но callmanager_wrap.cpp не. Он генерируется SWIG. В конечном счете, мое пользовательское правило должно выполнить следующую команду для генерации callmanager_wrap.cpp:
swig -c++ -java -package com.package.my -o callmanager_wrap.cpp callmanager.i
Согласно этот пост, невозможно добавить пользовательские правила к Android.mk
. Но в Android-источниках, я считаю, что есть несколько шагов обработки Android.mk
после ВСТУПЛЕНИЯ или УСТАНОВКИ. Я попробовал следующее:
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)
Но цель myjni
никогда не вызывается.
- Для чего используется LOCAL_INTERMEDIATE_TARGETS?
- Могу ли я достичь того, что я хочу сделать здесь, не создавая внешний файл script или makefile?
Ответы
Ответ 1
Я бы предложил следующее:
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)
Что это.
Я, вероятно, должен объяснить вам некоторые объяснения. Итак, идем:
-
$(LOCAL_SRC_FILES)
- список имен файлов относительно $(LOCAL_PATH)
, поэтому для обращения к файлу вне стандартных действий NDK вам нужен полный путь для вашего файла, который равен $(LOCAL_PATH)/callmanager_wrap.cpp
.
-
Мы указываем файл как .PHONY
, чтобы гарантировать, что пользовательское действие выполняется каждый раз при запуске ndk-build. Но если вы знаете, какие фактические зависимости callmanager_wrap.cpp
, вы можете указать их вместо этого, например
$(MY_JNI_WRAP): callmanager.i jnistuff.txt $(LOCAL_PATH)/../src/com/package/my/Something.java
В этом случае вам не понадобится строка .PHONY
.
-
Если вы хотите, чтобы ваш исходный каталог оставался чистым, вы можете объявить файл-обертку как .INTERMEDIATE
следующим образом:
.INTERMEDIATE: $(MY_JNI_WRAP)
Теперь make удалит файл оболочки после сборки, если он не существовал до сборки.
Ответ 2
Я сделал это так:
скажем, мне нужно создать файл .s из файла .ll
# custom build
source_ll_files := $(wildcard *.ll)
%.s:
llc -o [email protected] $(patsubst %.s,%.ll,[email protected])
LOCAL_SRC_FILES += $(patsubst %.ll,%.s,$(source_ll_files))
# end