38
votes

I'm trying to compile a static library to use on Android but I can't figure out how to compile it. The library uses standard libraries (stdio.h etc...) and libxml2.

I am trying to compile using arm-eabi-gcc but I get the following error:

/cygdrive/c/android-ndk-r4/build/platforms/android-8/arch-x86/usr/include/asm/posix_types.h:15:28: error: posix_types_64.h: No such file or directory

How do I get this to work?

3

3 Answers

50
votes

As I understand it, the correct method is to use ndk-build and not invoking the compiler directly.

In Android.mk you need to specify a module for each static library you want to compile, and then specify that your shared library should use it.

Example of a modified Android.mk file of the hello-jni sample project:

LOCAL_PATH := $(call my-dir)

# Define vars for library that will be build statically.
include $(CLEAR_VARS)
LOCAL_MODULE := <module_name>
LOCAL_C_INCLUDES := <header_files_path>
LOCAL_SRC_FILES :=  <list_of_src_files>

# Optional compiler flags.
LOCAL_LDLIBS   = -lz -lm
LOCAL_CFLAGS   = -Wall -pedantic -std=c99 -g

include $(BUILD_STATIC_LIBRARY)

# First lib, which will be built statically.
include $(CLEAR_VARS)
LOCAL_MODULE := hello-jni
LOCAL_STATIC_LIBRARIES := <module_name>
LOCAL_C_INCLUDES := <header_files_path>
LOCAL_SRC_FILES := hello-jni.c

include $(BUILD_SHARED_LIBRARY)

If you want control over which modules to compile when you run ndk-build you can create create a Application.mk file (in the same directory as Android.mk) and list all the modules as in the following example:

APP_MODULES := <module_name_1> <module_name_2> ... <module_name_n>
9
votes

In response to

Can you generate a static library (.a file) without a shared library that uses it?

(which really should have been its own question), the answer is yes.

By default, the NDK will only build executables and shared libraries (with their dependencies of course). You can, however, force the NDK to build a standalone static library by explicitly referencing it in your Application.mk.

Assuming your static library module is LOCAL_MODULE := libXYZ, add the following line to Application.mk (creating the file in the same folder as your Android.mk if it doesn't exist):

APP_MODULES := XYZ

Note the the APP_MODULES value does not include the lib prefix included in your static library module name.

Alternatively, if you don't want to create an Application.mk, you can specify the value on the command line: ndk-build APP_MODULES=XYZ

4
votes

A cool trick: if you have an Android.mk file, you can change the build type from:

include $(BUILD_SHARED_LIBRARY)

to

include $(BUILD_STATIC_LIBRARY)

and .a libraries will be output to the obj/ folder into their respective architectures when you ndk-build the library.