I am trying to figure out how to set up one Android.mk
to depend upon another. The latter builds a native code shared library, and the former has a JNI library that depends on the shared library. Let's call these shared_lib
and service
.
Right now, the Android.mk
for service
contains code like this:
LOCAL_SRC_FILES := ../../../shared_lib/libs/armeabi/libshared_NDK.so
include $(PREBUILT_SHARED_LIBRARY)
This works, but only if shared_lib
was already built. Building service
does not build shared_lib
.
I wrote a shell script that first builds shared_lib
and then builds service
. But it seems like it should be possible to use the build system to do the build tasks.
I have tried to use $(call import-module,...)
but haven't found any syntax that works. There is so much magic in the makefile path expansion that I can never predict what will happen. For example, with this code added to the Android.mk for service
:
include $(CLEAR_VARS)
SL_DIR=$(LOCAL_PATH)/../../../shared_lib
$(call import-add-path,$(SL_DIR))
NDK_MODULE_PATH := $(SL_DIR)
$(call import-module, jni)
This didn't work at all; I got this error result:
/Users/steveha/devel/android/ndk/build/core/build-binary.mk:450: warning: overriding commands for target `obj/local/armeabi/libshared_NDK.so'
/Users/steveha/devel/android/ndk/build/core/build-binary.mk:473: warning: ignoring old commands for target `obj/local/armeabi/libshared_NDK.so'
/Users/steveha/devel/android/ndk/build/core/build-binary.mk:489: warning: overriding commands for target `libs/armeabi/libshared_NDK.so'
/Users/steveha/devel/android/ndk/build/core/build-binary.mk:489: warning: ignoring old commands for target `libs/armeabi/libshared_NDK.so'
make: *** No rule to make target `../../shared_library/jni/com_dts_SourceFile.cpp', needed by `obj/local/armeabi/objs/dts-shared-jni/com_dts_shared_SourceFile.o'. Stop.
It looks like import-add-path
is messing up the variables, thus causing the C++ source files to be searched in a wrong place. But import-module
fails without it.
Also, running ndk-build clean
in the directory of service
fails with an error if you run ndk-build clean
on shared_lib
first. Since the .so
file is listed as a local source file, it is an error for it not to be present.
ndk-build
is built on top of make
, and make
has a single global namespace, and everything I have tried for making one Android.mk
build another Android.mk
has had problems like this. The best way seems to be to explicitly call ndk-build
to get a fresh instance of make
and thus a separate namespace.
Is there any way to set things up so that ndk-build
on service
will build shared_lib
first? Bonus points if the ndk-build clean
case described above also works properly.
I never did find a pure "make" solution. Instead, I wrote a Python script to build each module in turn. It is simple and robust to run each ndk-build
in its own process.