Search code examples
androidmakefileandroid-ndkndk-build

Android.mk PREBUILT_SHARED_LIBRARY how to generate LOCAL_SRC_FILES file from script?


I have an NDK project where I build the shared libraries using the cross-compiler and standard gnu make utils. That is done with a separate script. But for the purpose of using the libraries in my project, I would like my Android.mk process to call my script to generate the shared library if it hasn't already been built, and then have Android.mk wrap it using the PREBUILT_SHARED_LIBRARY process.

Currently, if I run my script offline to generate libmy_so.so, then the following makefile will work. However, if I don't run the script explicitly first, I get the following error:

Android NDK: ERROR:/path_to_project/Android.mk:my_module: LOCAL_SRC_FILES points to a missing file

and my script is never called, so the make process is failing before even trying to resolve the dependency.

include $(CLEAR_VARS)

LOCAL_MODULE        := my_module
LOCAL_SRC_FILES     := libmy_so.so
LOCAL_EXPORT_CFLAGS := # some stuff
LOCAL_EXPORT_LDLIBS := # some stuff
$(LOCAL_PATH)/libmy_so.so:
    echo "generate file"
    $(shell run_script_that_creates_libmy_so.so)

include $(PREBUILT_SHARED_LIBRARY)

Is there a clean solution to this? I am even ok with running the script automatically as a preprocessing step (I can always have my script quietly exit if the file exists already), but I have not found an incantation that allows the LOCAL_SRC_FILES variable to point to a non-existent file. I have considered placing a dummy libmy_so.so to start, but that is an ugly hack.


Solution

  • Found a hack -- better way?

    I found a hack. The makefile prebuilt-library.mk in the NDK contains the following lines:

    ifndef prebuilt
    $(call __ndk_info,ERROR:$(LOCAL_MAKEFILE):$(LOCAL_MODULE): LOCAL_SRC_FILES points to a missing file)
    $(call __ndk_info,Check that $(prebuilt_path) exists, or that its path is correct)
    $(call __ndk_error,Aborting)
    #endif
    

    I created a copy of this file (and prebuilt-shared-library.mk to which I reference my copy of prebuilt-library.mk) and commented those lines out to stop the error. Then the trick is to make some target that is evaluated first depend on the file I want to generate. After digging through the .mk scripts in the NDK, I found that libraries serves the purpose. By adding libraries: $(LOCAL_PATH)/libmy_so.so to Android.mk, it will finally do what I want.

    include $(CLEAR_VARS)
    
    LOCAL_MODULE        := my_module
    LOCAL_SRC_FILES     := libmy_so.so
    LOCAL_EXPORT_CFLAGS := # some stuff
    LOCAL_EXPORT_LDLIBS := # some stuff
    $(LOCAL_PATH)/libmy_so.so:
        echo "generate file"
        $(shell run_script_that_creates_libmy_so.so)
    libraries: $(LOCAL_PATH)/libmy_so.so
    
    include /path/to/my/mk/files/prebuilt-shared-library.mk
    

    This is obviously less than ideal as I would like to make sure my makefiles mature with newer versions of the NDK, but it does the trick. Still interested in more elegant solutions.