Question

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.

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top