Подтвердить что ты не робот

Как запустить пользовательское правило в 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?
4b9b3361

Ответ 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