Thursday, October 29, 2009

Android NDK Makefile

(1) install NDK 1.6 in say
~/Android/android-ndk-1.6_r1

download http://developer.android.com/sdk/ndk/1.6_r1/index.html

(2) install SDK 1.6 in say
~/Android/android-sdk-linux_x86-1.6_r1

download http://developer.android.com/sdk/1.6_r1/index.html

(3) you can compile standalone C program like this hello.c using the Makefile below

#include <stdio.h>
int main() {
  printf("hello, NDK makefile world\n");
  return 0;
}


(4) Create Makefile
Makefile Select all

APP=hello

NDK_DIR := /cygdrive/c/Android/android-ndk-1.6_r1
#NDK_DIR := ~/Android/android-ndk-1.6_r1
NDK_HOST := windows
#NDK_HOST := linux-x86
#NDK_HOST := darwin-x86
SDKTOOL := /cygdrive/c/Android/android-sdk-windows-1.6_r1/tools
#SDKTOOL := ~/Android/android-sdk-linux_x86-1.6_r1/tools
#SDKTOOL := ~/Android/android-sdk-mac_x86-1.6_r1/tools

TOOLCHAIN_PREFIX := $(NDK_DIR)/build/prebuilt/$(NDK_HOST)/arm-eabi-4.2.1/bin/arm-eabi-
CC := $(TOOLCHAIN_PREFIX)gcc
CPP := $(TOOLCHAIN_PREFIX)g++
LD := $(CC)

COMMON_FLAGS := -mandroid -ffunction-sections -fdata-sections -Os -g --sysroot=$(NDK_DIR)/build/platforms/android-4/arch-arm \
-fPIC \
-fvisibility=hidden \
-D__NEW__

CFLAGS := $(COMMON_FLAGS)

CFLAGS += -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ -DANDROID -DSK_RELEASE -DNDEBUG

CFLAGS += -UDEBUG -march=armv5te -mtune=xscale -msoft-float -mthumb-interwork -fpic -ffunction-sections -funwind-tables -fstack-protector -fmessage-length=0 -Bdynamic


CPPFLAGS := $(COMMON_FLAGS) \
-fno-rtti -fno-exceptions \
-fvisibility-inlines-hidden

LDFLAGS += --sysroot=$(NDK_DIR)/build/platforms/android-4/arch-arm
LDFLAGS += -Bdynamic -Wl,-dynamic-linker,/system/bin/linker -Wl,--gc-sections -Wl,-z,nocopyreloc
LDFLAGS += -L$(NDK_DIR)/build/prebuilt/$(NDK_HOST)/arm-eabi-4.2.1/lib/gcc/arm-eabi/4.2.1/android
LDFLAGS += -L$(NDK_DIR)/build/prebuilt/$(NDK_HOST)/arm-eabi-4.2.1/lib/gcc/arm-eabi/4.2.1
LDFLAGS += -L$(NDK_DIR)/build/prebuilt/$(NDK_HOST)/arm-eabi-4.2.1/lib/gcc
LDFLAGS += -L$(NDK_DIR)/build/prebuilt/$(NDK_HOST)/arm-eabi-4.2.1/arm-eabi/lib
LDFLAGS += -nostdlib -lc -llog -lgcc \
--no-undefined -z $(NDK_DIR)/build/platforms/android-4/arch-arm/usr/lib/crtbegin_dynamic.o $(NDK_DIR)/build/platforms/android-4/arch-arm/usr/lib/crtend_android.o

OBJS += $(APP).o

all: $(APP)

$(APP): $(OBJS)
$(LD) $(LDFLAGS) -o $@ $^

%.o: %.c
$(CC) -c $(CFLAGS) $< -o $@

%.o: %.cpp
$(CPP) -c $(CFLAGS) $(CPPFLAGS) $< -o $@

install: $(APP)
$(SDKTOOL)/adb push $(APP) /data/local/bin/$(APP)
$(SDKTOOL)/adb shell chmod 755 /data/local/bin/$(APP)

run:
$(SDKTOOL)/adb shell /data/local/bin/$(APP)

clean:
@rm -f $(APP).o $(APP)


(5) connect device and test using

make all
make install run


(6) compile C++ program example1.cpp (no STL)

make APP=example1 all install run


example1.cpp Select all

#include <stdio.h>

class counter {
public:
int some_data;
char some_other_data[100];
int i;

void increment_counter() {i++;}
void decrement_counter() {i--;}
int query_counter() {return i;}

void set_counter(int new_value);
};

void counter::set_counter(int new_value)
{
i = new_value;
}

main()
{
counter apples;
counter oranges;
counter *pointer_to_counter = NULL;
counter array_of_counters[10];
int x = 5;

apples.some_data = x;

apples.set_counter(10);
apples.increment_counter();
apples.increment_counter();

oranges.set_counter(5);
oranges.decrement_counter();

printf("%d apples and %d oranges\n",
apples.query_counter(),
oranges.query_counter());
}





Saturday, October 24, 2009

Android NDK add stlport and compile C++ program

(1) Assume you have Android ndk 1.6 and your ndk directory is in ~/Android/android-ndk-1.6_r1 and you are using mac
download ndk-wrapper from

cd ~/Android
git clone git://umbel.mooo.com/ndk-wrappers.git


reference
http://umbel.mooo.com/git?p=ndk-wrappers.git;a=summary

(2) Edit ~/Android/ndk-wrappers/setup.sh and add these

export HOST=darwin-x86
export NDK_DIR=~/Android/android-ndk-1.6_r1
export NDK_WRAPPERS_BASE=~/Android/ndk-wrappers


(3) Edit ~/Android/ndk-wrappers/scripts/build-stlport.sh ad add these

export NDK_WRAPPERS_BASE=~/Android/ndk-wrappers
export PATH=~/Android/ndk-wrappers/bin:$PATH


(4) Edit ~/Android/ndk-wrappers/scripts/env-utils.sh and change / add these

SYSROOT="${NDK_DIR}/build/platforms/android-4/arch-arm"
HOST=darwin-x86


For linux
HOST=linux-x86

For CYGWIN
HOST=windows

(5) Change ~/Android/ndk-wrappers/stlport/build/lib/android.mak
from

--sysroot=$(NDK_DIR)/build/platforms/android-1.5/arch-arm \


to

--sysroot=$(NDK_DIR)/build/platforms/android-4/arch-arm \


(6) Add link

cd ~/Android/ndk-wrappers/stlport/build/Makefiles/gmake
ln -s linux arm-linux


(7) For Mac only, upgrade sed using Mac port

sudo port install gsed
sudo ln -s /opt/local/bin/gsed /opt/local/bin/sed



(8) build stlport

cd ~/Android/ndk-wrappers
export NDK_DIR=~/Android/android-ndk-1.6_r1
./setup.sh


(9) Create hello.cpp to test

#include <iostream>
using namespace std;
int main() {
  cout << "hello, world\n";
  return 0;
}


(10) Compile

~/Android/ndk-wrappers/bin/arm-linux-g++ -o hello hello.cpp -L~/Android/ndk-wrappers/stlport/build/lib/obj/arm-linux-gcc/so


(11) Sent to device for testing

adb push hello /data/local/bin/hello
adb shell chmod 755 /data/local/bin/hello
adb shell /data/local/bin/hello


You can use Makefile
Makefile Select all

APP := hello
SDKTOOL := ~/Android/android-sdk-mac_x86-1.6_r1/tools
WRAPPER := ~/Android/ndk-wrappers
STLLIB := -L~/Android/ndk-wrappers/stlport/build/lib/obj/arm-linux-gcc/so
BIN := $(WRAPPER)/bin
CPP := $(BIN)/arm-linux-g++
CC := $(BIN)/arm-linux-gcc

all: $(APP)

OBJS += $(APP).o

$(APP): $(OBJS)
$(CPP) $(LDFLAGS) -o $@ $(STLLIB) $^

%.o: %.c
$(CC) -c $(INCLUDE) $(CFLAGS) $< -o $@

%.o: %.cpp
$(CPP) -c $(INCLUDE) $(CFLAGS) $(CPPFLAGS) $< -o $@

install: $(APP)
$(SDKTOOL)/adb push $(APP) /data/local/bin/$(APP)
$(SDKTOOL)/adb shell chmod 755 /data/local/bin/$(APP)

shell:
$(SDKTOOL)/adb shell

run:
$(SDKTOOL)/adb shell /data/local/bin/$(APP)

clean:
@rm -f $(APP).o $(APP)






Tuesday, October 6, 2009