How to use a custom toolchain with ndk-build?

1.5k views Asked by At

I've spent a day on this and can't seem to configure my dev environment for a NDK toolchain that will support standard C++ libraries. The story is I'm trying to cross compile libnfnetlink and libnetfilter_queue for ARM (Android).

First I'm using the following:

  • Nexus 5 with CyanogenMod 11 (I forget, doesn't matter I'm not even on the device yet)
  • Ubuntu 12.04 32-bit
  • Android SDK bundle: adt-bundle-linux-x86-20140702
  • Android NDK: android-ndk-r10c

There is a great blog on doing this here but its incomplete as Netfilter uses stlc++ and there's no word on a NDK install/setup that would work with simply calling ndk-build. Just copying the files into /jni and calling ndk-build won't work alone.

Anyways, my specific problem is when I straight copy the Netfilter lib source structure into an empty Project's /jni directory, I get this:

user@ubuntu:~/Projects/NetfilterTest/NetfilterNativeTest/jni$ ndk-build
[armeabi] Compile thumb  : netfilter_queue <= libnetfilter_queue.c
In file included from /home/user/Projects/NetfilterTest/NetfilterNativeTest/jni/libnetfilter_queue/src/libnetfilter_queue.c:35:0:
/home/user/Projects/NetfilterTest/NetfilterNativeTest/jni/libnetfilter_queue/src/internal.h:4:20: fatal error: config.h: No such file or directory
compilation terminated.
make: *** [/home/user/Projects/NetfilterTest/NetfilterNativeTest/obj/local/armeabi/objs/netfilter_queue/libnetfilter_queue/src/libnetfilter_queue.o] Error 1

The config.h file can't be found. After some googling I realize its because the standard C++ libraries aren't available in the prebuilt tool chains.

Everything points to me creating my own tool chain. So I build my own cross compiler using the scripts that the NDK includes.

cd /home/user/android-ndk-r10c/build/tools
./make-standalone-toolchain.sh --platform=android-19 --ndk-dir=/home/user/android-ndk-r10c/ --install-dir=/home/user/android-ndk-r10c/prebuilt/android-arm/android-19

To confirm that config.h is included in my tool chain I searched for it. It's there:

user@ubuntu:~/Projects/NetfilterTest/NetfilterNativeTest/jni$ find /home/user/android-ndk-r10c/prebuilt/android-arm/android-19/ -iname config.h
/home/user/android-ndk-r10c/prebuilt/android-arm/android-19/sysroot/usr/include/linux/config.h

Naturally I need to setup my environment and the Android.mk

JAVA_HOME=/usr/local/java/jdk1.6.0_45
JRE_HOME=$JAVA_HOME/jre
ANDROID_SDK=/home/user/adt-bundle-linux-x86-20140702
ANDROID_NDK=/home/user/android-ndk-r10c
ANDROID_CHAIN=/home/user/android-ndk-r10c/prebuilt/android-arm/android-19

PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin:$ANDROID_SDK/sdk/platform-tools:$ANDROID_SDK/sdk/tools:$ANDROID_NDK:$ANDROID_CHAIN/bin

SYSROOT=$ANDROID_NDK/platforms/android-19/arch-arm

CC=arm-linux-androideabi-gcc

export CC
export ANDROID_SDK
export ANDROID_NDK
export SYSROOT
export JAVA_HOME
export JRE_HOME
export PATH

Here's my Android.mk (based on Roman10's blog:

LOCAL_PATH:=$(call my-dir)

#####################################################################
#                     build libnflink                               #
#####################################################################
include $(CLEAR_VARS)
LOCAL_MODULE:=nflink
LOCAL_C_INCLUDES:= $(LOCAL_PATH)/libnfnetlink/include
LOCAL_SRC_FILES:=\
    libnfnetlink/src/iftable.c \
    libnfnetlink/src/rtnl.c \
    libnfnetlink/src/libnfnetlink.c

include $(BUILD_STATIC_LIBRARY)

#####################################################################
#                   build libnetfilter_queue                        #
#####################################################################

include $(CLEAR_VARS)
LOCAL_C_INCLUDES := $(LOCAL_PATH)/libnfnetlink/include \
    $(LOCAL_PATH)/libnetfilter_queue/include
LOCAL_MODULE:=netfilter_queue
LOCAL_SRC_FILES:=libnetfilter_queue/src/libnetfilter_queue.c
LOCAL_STATIC_LIBRARIES:=libnflink

include $(BUILD_STATIC_LIBRARY)

#####################################################################
#                     build our code                                #
#####################################################################

include $(CLEAR_VARS)
LOCAL_C_INCLUDES := $(LOCAL_PATH)/libnfnetlink/include \
    $(LOCAL_PATH)/libnetfilter_queue/include
LOCAL_MODULE:=nfqnltest
#LOCAL_LDLIBS:=-lstdc++
LOCAL_SRC_FILES:=nfqnl_test.c
LOCAL_STATIC_LIBRARIES:=libnetfilter_queue
LOCAL_LDLIBS:=-llog -lm

include $(BUILD_EXECUTABLE)

I still get config.h not found using ndk-build.

I've read that the ndk-build command leverages a config.mk/setup.mk that Google includes in the NDK and has to be modified to point to an alternative toolchain.

I'm completely floored that Google's own tools can't simply point to a custom toolchain that they give you scripts to create. If anyone has any suggestions on how I can use my toolchain to compile Netfilter or just in general it would be a great help.

Thanks in advance!

1

There are 1 answers

1
mstorsjo On BEST ANSWER

I can't find any reference to either internal.h or config.h when I search for a version of libnetfilter_queue.c on the web, so I'm not sure what version of the file you're using - can you point to which one you have?

Also, the config.h it looks for isn't the one you found in your toolchain (which should be included as linux/config.h) but most probably is one that you're expected to generate by running a configure script. So unless you've run the configure script (or have a pregenerated config.h from elsewhere) you can't really build it.

Finally, nothing of this has anything to do with libstdc++ since all your source files seem to be pure C, not C++.