Dave
Dave

Reputation: 7689

How to write/debug Android.mk for NDK static library?

I'm trying to build a static library using the latest Android NDK (r5) and I'm not having any luck. I've been able to build and run the samples (for example, HelloJni) without any issues but starting a new project from 'scratch' has been a different story.

For this experiment, I'm trying to build libpng. My folder structure looks like this:

root
|
+--- jni
      |
      +---- Android.mk ( one line: "include $(call all-subdir-makefiles)" )
      |
      +---- png
             |
             +---- Android.mk ( see below )
             |
             +---- { a bunch of .c and .h files )

So I have two Android.mks. One for building all subprojects and one for the libpng subproject. root/jni/png/Android.mk looks like this:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := png
MODULE_PATH := $LOCAL_PATH
LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.c)
LOCAL_C_INCLUDES := $(wildcard $(LOCAL_PATH)/*.h)

LOCAL_INTERMEDIATE_TARGETS += junk
junk:
    echo $(LOCAL_SRC_FILES)

include $(BUILD_STATIC_LIBRARY)

This build setup seems to do nothing (ie running ndk-build from the root folder does nothing, even after an ndk-build clean). A verbose run (ndk-build V=1) shows some rm -f calls (deleting non-existent folders) but nothing related to the project or subproject.

I'm pretty interested in why this build script is failing but the process should have been trivial so I'm sure its nothing terribly interesting. I'm far more interested in how I could start to attack build bugs on my own. The echo call in the script above is never hit -- I have no idea how to determine what values are or why it skips the subproject. Has anyone found a way to know what the build system is trying to do?

I'd also be interested in knowing if there are docs for these tools or if its just the handful of text files in the NDK's docs folder? I've been trying to resolve this by copying pieces of random Android.mk's I've found from googling around but only the few commands used in the simple NDK samples appear to be documented, so the experience has actually just raised new questions.

Upvotes: 6

Views: 11005

Answers (3)

Paul Du Bois
Paul Du Bois

Reputation: 2171

I found that when I added a "dummy" shared library as described in the edit, the .a (which I found in obj/, implying that it was an internal detail) did not contain any of the .o files I wanted.

Additionally, the .so recompiled all the files that would have been built for the static library. So it made sense that the .a was empty.

What helped me was to add an APP_MODULES line to my Application.mk, as described in Cannot build static library with Android NDK R8 . You probably want an Application.mk anyway, as it contains other settings important for your static lib, like APP_STL, APP_PLATFORM, APP_ABI, etc.

Upvotes: 0

khayek
khayek

Reputation: 11

I've been beating myself over the head with this problem for the last two hours, and this post helped solve it. Rather than add a dummy dependency, simply invoke ndk-build (which is just a thin wrapper over make) as "ndk-build png".

Upvotes: 1

Femi
Femi

Reputation: 64700

I'd recommend getting rid of MODULE_PATH and not trying to use the wildcard: I haven't really seen that work right.

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := png
LOCAL_SRC_FILES := pngget.c pngread.c pngrutil.c pngtrans.c pngwtran.c png.c pngmem.c pngrio.c pngset.c pngwio.c pngwutil.c pngerror.c pngpread.c pngrtran.c pngwrite.c
LOCAL_C_INCLUDES := png.h pngconf.h pngpriv.h

include $(BUILD_STATIC_LIBRARY)

Also, there's some serious path magic I haven't fully deciphered: somehow Eclipse does the right thing, but getting it to jump through the proper hoops from the command line is still hit or miss for me.

EDIT: so was moderately interested in figuring this out, as its been a while since I played with the NDK. When I use the original file it didn't compile, but when I placed the png source code in the directory jni and then use this Android.mk file:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := png
LOCAL_SRC_FILES := pngget.c pngread.c pngrutil.c pngtrans.c pngwtran.c png.c pngmem.c pngrio.c pngset.c pngwio.c pngwutil.c pngerror.c pngpread.c pngrtran.c pngwrite.c
LOCAL_C_INCLUDES := png.h pngconf.h pngpriv.h

include $(BUILD_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := png2
LOCAL_STATIC_LIBRARIES := png

include $(BUILD_SHARED_LIBRARY)

it built both the libpng.a and libpng2.so in the obj/local/armeabi folder. I'm guessing it simply won't build an static library if there is no dependency.

Upvotes: 10

Related Questions