Android NDK 콘솔용 Makefile

2009.11.12 19:11 from Android
안드로이드는 adb를 통해 shell 접근이 가능하다. NDK에서 사용하는 함수 확인이나 디버깅을 이렇게 shell에서 간단하게 확인해 보는것이 JNI를 통하는 것 보다 쉬울수도 있다.

Makefile
ANDROID_NDK=c:\andoird\android-ndk-1.6_r1

NDKROOT:=$(shell cygpath -u '$(ANDROID_NDK)')
SYSROOT:=$(NDKROOT)/build/platforms/android-4/arch-arm
TOOLCHAINDIR:=$(NDKROOT)/build/prebuilt/windows/arm-eabi-4.2.1/bin
TARGET_CC := $(TOOLCHAINDIR)/arm-eabi-gcc.exe
TARGET_LD := $(TOOLCHAINDIR)/arm-eabi-ld.exe

TARGET_LIBGCC := $(shell $(TARGET_CC) -mthumb-interwork -print-libgcc-file-name)
TARGET_LDLIBS := -Wl,-rpath-link=$(SYSROOT)/usr/lib $(TARGET_LIBGCC)
TARGET_CRTBEGIN_STATIC_O  := $(SYSROOT)/usr/lib/crtbegin_static.o
TARGET_CRTBEGIN_DYNAMIC_O := $(SYSROOT)/usr/lib/crtbegin_dynamic.o
TARGET_CRTEND_O := $(SYSROOT)/usr/lib/crtend_android.o
STDLIBS=c m stdc++
TARGET_SHARED_LIBRARIES:=$(foreach STDLIBS, $(STDLIBS), $(SYSROOT)/usr/lib/lib$(STDLIBS).so)
TARGET_STATIC_LIBRARIES:=$(foreach STDLIBS, $(STDLIBS), $(SYSROOT)/usr/lib/lib$(STDLIBS).a)
TARGET=test

INCLUDE:=-I$(SYSROOT)/usr/include
CFLAGS+=-c $(DEFINE) $(INCLUDE) \
    -march=armv5te -mtune=xscale \
    -msoft-float -fpic \
    -mthumb-interwork \
    -ffunction-sections \
    -funwind-tables \
    -fstack-protector \
    -fno-short-enums \
    -fshort-wchar \
    -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ \
    -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__
   
EXEFLAGS=-nostdlib -Bdynamic \
    -Wl,-dynamic-linker,/system/bin/linker \
    -Wl,--gc-sections \
    -Wl,-z,nocopyreloc \
    $(TARGET_SHARED_LIBRARIES) \
    $(TARGET_CRTBEGIN_DYNAMIC_O) \
    $(TARGET_STATIC_LIBRARIES) \
    $(TARGET_LDLIBS) \
    $(TARGET_CRTEND_O)   

all: $(TARGET)

$(TARGET): main.o
    $(TARGET_CC) $(EXEFLAGS) -o test main.o
   
clean:
    rm $(TARGET) main.o
   
main.o: main.c
    $(TARGET_CC) $(CFLAGS) -o $@ $<

main.c

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv)
{
    FILE* hFile = fopen("a.txt", "w");
   
    fprintf(hFile, "1234");
    fclose(hFile);
   
    return 0;
}

실행예
adb push test /data
adb shell
# cd /data
# chmod 777 test ; ./test
저작자 표시 비영리
신고
Posted by NOP 트랙백 0 : 댓글 1
NDK의 Makefile을 사용하지 않는 간단버전의 Makefile, target은 so파일

# tool chain setting
ANDROID_NDK16=c:\andoird\android-ndk-1.6_r1
NDKROOT:=$(shell cygpath -u '$(ANDROID_NDK16)')
SYSROOT:=$(NDKROOT)/build/platforms/android-4/arch-arm
TOOLCHAINDIR:=$(NDKROOT)/build/prebuilt/windows/arm-eabi-4.2.1/bin
CC:=$(TOOLCHAINDIR)/arm-eabi-gcc.exe
CXX:=$(TOOLCHAINDIR)/arm-eabi-g++.exe
AR:=$(TOOLCHAINDIR)/arm-eabi-ar.exe
LD:=$(TOOLCHAINDIR)/arm-eabi-ld.exe

TARGET_LIBGCC := $(shell $(CC) -mthumb-interwork -print-libgcc-file-name)
TARGET_LDLIBS := -Wl,-rpath-link=$(SYSROOT)/usr/lib $(TARGET_LIBGCC)
TARGET_CRTBEGIN_STATIC_O  := $(SYSROOT)/usr/lib/crtbegin_static.o
TARGET_CRTBEGIN_DYNAMIC_O := $(SYSROOT)/usr/lib/crtbegin_dynamic.o
TARGET_CRTEND_O := $(SYSROOT)/usr/lib/crtend_android.o
STDLIBS=c m stdc++
TARGET_SHARED_LIBRARIES:=$(foreach STDLIBS, $(STDLIBS), $(SYSROOT)/usr/lib/lib$(STDLIBS).so)
TARGET_STATIC_LIBRARIES:=$(foreach STDLIBS, $(STDLIBS), $(SYSROOT)/usr/lib/lib$(STDLIBS).a)
INCLUDE:=-I$(SYSROOT)/usr/include

CFLAGS+=-c $(DEFINE) $(INCLUDE) \
    -march=armv5te -mtune=xscale \
    -msoft-float -fpic \
    -mthumb-interwork \
    -ffunction-sections \
    -funwind-tables \
    -fstack-protector \
    -fno-short-enums \
    -fshort-wchar \
    -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ \
    -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__
ifeq ($(DEBUG),y)
    CFLAGS+= -O0 -g
else
    CFLAGS+= -O2
endif
LDFLAGS=-nostdlib -Wl,-soname,$(notdir $@) \
    -Wl,-shared,-Bsymbolic \
    -Wl,--no-whole-archive \
    $(TARGET_LDLIBS) \
    -Wl,--whole-archive -o

# source setting
EXCLUDES:=
SRCDIR:=../src \
    ../test/src
CSRCS:=$(foreach SRCDIR, $(SRCDIR), $(filter-out $(EXCLUDES), $(wildcard $(SRCDIR)/*.c)))
OBJS=$(CSRCS:.c=.o)
TARGET=libTest.so

INCLUDE+=
CFLAGS+=
LIBFILES+=

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

all: $(TARGET)
   
$(TARGET): $(OBJS)
        $(CC) $(LDFLAGS) $@ $(OBJS) $(LIBFILES)

clean:
    rm $(OBJS) $(TARGET)

저작자 표시 비영리
신고
Posted by NOP 트랙백 0 : 댓글 0

신규 릴리즈된 m5 버전

2008.02.17 16:47 from Android
Android가 m3 버전으로 진행되다가 m5로 갑자기 올라갔다. 물론 여러 소식에서 알려진 내용도 있고 이 버전을 위해서 Google에서 진행하는 프로그램 공모전도 연기되었다는 이야기가 들린다.

실제로 받아서 에뮬레이터를 실행해 본 결과 UI상으로도 상당한 변화가 진행된 것으로 보인다.

android_new_sdk

실제로 기존에 작성했던 코드가 m5로 넘어가면서 빌드가 되지 않았다.

아래 URL에서 확인 해보면 기존에 정의한 네이밍이 맘에 안들었나 보다. 물론 조금 더 명시적으로 변경된 듯하다.
Android SDK M5 Release - API Changes Overview
http://code.google.com/android/migrating/m3-to-m5/m5-api-changes.html

간략하게 살펴보면 다음과 같다.
AndroidManifest.xml
class= > android:name=
intent-filter: android:value > android:name
Layout.xml
id > android:id
그리고 참고로 onMotionEvent는 onTouchEvent로 변경되었다.
신고
TAG Android, M5, sdk
Posted by NOP 트랙백 0 : 댓글 0
아래의 문서는 Android가 공식적으로 NDK를 지원하지 않았을때의 문서이다.
NDK는 아래의 URL에서 다운로드 가능하다.
http://developer.android.com/sdk/ndk/1.5_r1/index.html

공식적으로 Android는 Native 빌드를 지원하지 않는다.
http://code.google.com/android/kb/general.html#c
Can I write code for Android using C/C++?
No. Android applications are written using the Java programming language.

하지만 커널까지 공개되었고 JNI 인터페이스까지 지원되는 입장에서 못할 것은 없는것 같다.

Davanum Srinivas의 블로그를 확인하면 JNI를 이용하여 Native 빌드된 바이너리를 실행하는 방법을 소개하고 있다. 내용은 다음과 같다.

NativeAdd.java class 생성

package org.apache;

import android.util.Log;

public class NativeAdd {
    static {
        try {
            Log.i("JNI", "Trying to load libNativeAdd.so");
            System.loadLibrary("NativeAdd");
        }
        catch (UnsatisfiedLinkError ule) {
            Log.e("JNI", "WARNING: Could not load libNativeAdd.so");
        }
    }

    public static native long add(long a, long b);
}

javah로 해더 파일 생성
javah -classpath ../../android.jar;../bin/classes; org.apache.NativeAdd
생성된 해더

/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class org_apache_NativeAdd */

#ifndef _Included_org_apache_NativeAdd
#define _Included_org_apache_NativeAdd
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class:     org_apache_NativeAdd
* Method:    add
* Signature: (JJ)J
*/
JNIEXPORT jlong JNICALL Java_org_apache_NativeAdd_add
  (JNIEnv *, jclass, jlong, jlong);

#ifdef __cplusplus
}
#endif
#endif

C코드로 구현부 작성

include "org_apache_NativeAdd.h"

JNIEXPORT jlong JNICALL Java_org_apache_NativeAdd_add
  (JNIEnv *env, jclass c, jlong a, jlong b)
{
    return a + b;
}

Cross comfiler로 빌드

arm-none-linux-gnueabi-gcc  -I/usr/lib/jvm/java-1.5.0-sun/include -I/usr/lib/jvm/java-1.5.0-sun/include/linux  -fpic -c org_apache_NativeAdd.c
arm-none-linux-gnueabi-ld -T armelf_linux_eabi.xsc -shared -o libNativeAdd.so org_apache_NativeAdd.o

컴파일러는 아래의 링크에서 다운로드가 가능하며 armelf_linux_eabi.xsc는 motz diary에서 설명하고 있는 Patch된 파일을 사용해야 링크에러가 발생되지 않는다.
http://www.codesourcery.com/gnu_toolchains/arm/download.html


Android로 업로딩

adb push native/libNativeAdd.so /system/lib
adb install bin/CallNative.apk

참고로 테스트 환경은 Ubuntu였으며 Windows 환경에서는 빌드되지 않았다.

신고
Posted by NOP 트랙백 0 : 댓글 0

티스토리 툴바