2013년 3월 27일 수요일

Android NDK를 사용한 boost library 빌드 방법

이전 블로그에서 이전 함 (원본 글 2013/03/27 작성)

[준비물]

- boost for Android의 git repository의 파일들
 . https://github.com/MysticTreeGames/Boost-for-Android
 . git clone 해서 받아도 되고 귀찮으면 zip으로 한꺼번에 받아도 되고

- boost source code, Android NDK
 . boost source code는 boost for Android가 다운로드 받아 준다. 


[boost for android 실행 (Boost source code 다운로드 및 빌드)]

1. boost for build에 명시되어 있는 표에 맞춰서 Andorid NDK 다운로드

Boost for Android

Boost for android is a set of tools to compile the main part of the Boost C++ Libraries for the Android platform.Currently supported boost versions are 1.45.0, 1.48.0, 1.49.0 and 1.53.0.To compile Boost for Android you may use one of the following NDKs:
NDK / boost1.451.481.491.53
r4 customized by Dmitry Moskalchuk aka CrystaX.x
r5 from the official android repository.x
r5 customized by CrystaX.x
r7 customized by CrystaX.xxx
r8 from the official android repository.xxx
r8b from the official android repository.xx
r8c from the official android repository.x
r8d from the official android repository.xx
r8e from the official android repository.xx

* Android NDK 32bit version 사용 필요, build for boost가 인식 못함. 
 . Android NDK의 RELEASE.txt에서 64bit description을 제거해도 toolchaing등이 32bit에 맞춰 설정 되어 있음.

2. build-android 실행

* 다운받은 build for andoid 내 build-android.sh 실행
 . option들 중에는 boost version을 정하는 --boost, 빌드 대상 library를 정하는 --with[out]-libraries 가 있음.

haha@cs-portable:~/source/Boost-for-Android$ ./build-android.sh --help
Usage: build-android.sh [options] <ndk-root>

       Boost For Android
Copyright (C) 2010 Mystic Tree Games

Valid options (defaults are in brackets):

  --help                         Print this help.
  --verbose                      Enable verbose mode.
  --output=<path>                Specify specific log output path (only terminal output by default)
  --boost=<version>              Boost version to be used, one of {1.53.0,1.49.0, 1.48.0, 1.45.0}, default is 1.53.0.
  --clean                        Delete all previously downloaded and built files, then exit.
  --download                     Only download required files and clean up previus build. No build will be performed.
  --with-libraries=<list>        Comma separated list of libraries to build.
  --without-libraries=<list>     Comma separated list of libraries to exclude from the build.

haha@cs-portable:~/source/Boost-for-Android$ ./build-android.sh 
To follow build in another terminal, please use: tail -F /home/haha/source/Boost-for-Android/logs/myst-log-14385.log
Building boost version: 1.53.0
Using AndroidNDKRoot = /home/haha/_program/android-ndk-r8e
Detected Android NDK version 8e
Building with TOOLSET=gcc-androidR8e CXXPATH=/home/haha/_program/android-ndk-r8e/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86/bin/arm-linux-androideabi-g++ CXXFLAGS= -L -L -lgcc
Downloading boost 1.53.0 please wait...
Resolving downloads.sourceforge.net (downloads.sourceforge.net)... 216.34.181.59
Connecting to downloads.sourceforge.net (downloads.sourceforge.net)|216.34.181.59|:80... connected.
HTTP request sent, awaiting response... 302 Found
Resolving garr.dl.sourceforge.net (garr.dl.sourceforge.net)... 193.206.140.34, 2001:760:ffff:b0::34
Connecting to garr.dl.sourceforge.net (garr.dl.sourceforge.net)|193.206.140.34|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 55765258 (53M) [application/octet-stream]
Saving to: `/home/haha/source/Boost-for-Android/boost_1_53_0.tar.bz2'

     0K .......... .......... .......... .......... ..........  0% 46.5K 19m30s
    50K .......... .......... .......... .......... ..........  0% 71.2K 16m6s

* 기본으로는 static library로 빌드가 되며 아래 메세지가 나와도 library들 빌드와 header 복사는 된 상태 임

 . "./build-android.sh: 318: ./build-android.sh: Bad substitution"

* 몇건은 실패하는데.. 사실 system, filesystem, thread, date_time 정도만 있어도 문제는 없어서..
    혹시나 더 필요하다면 좀 찾아봐야 하는데.. 귀찮음..
* 생성된 libraries는 JNI project에서 추가하여 사용하면 되고 만약 so를 사용할 것이라면 Android phone에 deploy하는 것을 확인해야 함.

 ...skipped <p../build/lib>libboost_thread-gcc-mt-1_53.so.1.53.0 for lack of <pbin.v2/libs/thread/build/gcc-androidR8e/release/threading-multi>libboost_thread-gcc-mt-1_53.so.1.53.0...
...skipped <p../build/lib>libboost_thread-gcc-mt-1_53.so for lack of <p../build/lib>libboost_thread-gcc-mt-1_53.so.1.53.0...
...failed updating 6 targets...
...skipped 18 targets...
...updated 10251 targets...
./build-android.sh: 328: ./build-android.sh: Bad substitution
Done!
haha@cs-portable:~/source/Boost-for-Android$ find . -name *.a*
./build/lib/libboost_date_time-gcc-mt-1_53.a
./build/lib/libboost_regex-gcc-mt-1_53.a
./build/lib/libboost_iostreams-gcc-mt-1_53.a
./build/lib/libboost_thread-gcc-mt-1_53.a
./build/lib/libboost_filesystem-gcc-mt-1_53.a
./build/lib/libboost_system-gcc-mt-1_53.a
./build/lib/libboost_program_options-gcc-mt-1_53.a
./build/lib/libboost_signals-gcc-mt-1_53.a




[Android NDK를 사용한 Native 개발 시 참고]
  
* Android NDK 버전 마다 C++ library의 버전 차이로 인한 이슈 존재
Native에서 고급? C++ feature를 사용하는 경우.. 상용화 입장에서는 고생 함.
참고로 boost는 주 빌드 방법은 Android NDK + GNU_STL을 사용하고 RTTI, EXCEPTION feature는 제외하고 컴파일 함.

* NDK에서 지원하는 C++ library들의 조합은 다음과 같다.

    system                   Use the default minimal system C++ runtime library.
    gabi++_static      - Use the GAbi++ runtime as a static library.
    gabi++_shared   - Use the GAbi++ runtime as a shared library.
    stlport_static        - Use the STLport runtime as a static library.
    stlport_shared     - Use the STLport runtime as a shared library.
    gnustl_static        - Use the GNU STL as a static library.
    gnustl_shared      - Use the GNU STL as a shared library.

The capabilities of the various runtimes vary. See this table:

                 C++       C++   Standard
              Exceptions  RTTI    Library
    system        no       no        no
    gabi++       yes      yes        no
    stlport         yes      yes       yes
    gnustl         yes      yes       yes

 . $ANDROID_NDK/doc 내 파일들 참고
   : CPLUSPLUS-SUPPORT.html  NDK-BUILD.html  NDK-GDB.html  NDK-STACK.html

* 팀원들의 NDK의 버전을 통일하는 것이 혹시나 모를 이상항 링크 에러 등을 방지하는데 도움 

* Native library들을 빌드하는 NDK 버전과 Native library들이 사용하는 다른 native library들을 빌드한 NDK 버전을 통일하는 것을 추천

* JNI 빌드할때 모든 빌드 결과물의 arm, thumb mode를 맞춰라. 안 맞을 경우 원인 모를 crash 발생 가능하다.

2013년 3월 21일 목요일

Serialization between C++ and Java

이전 블로그에서 이전 함 (원본 글 2013/03/21 작성)

여러 모듈에서 사용되는 arguments들을 공통된 format을 사용하여 native의 data를 Java 단으로 올리기 위해서 방법을 찾아 보려 했었다...

JNI에서는 기본적인 primitive data type은 변환이 가능하고 간단한 object type으로 mapping이 가능하다. 

Table 3-1 Primitive Types and Native Equivalents

Java Type

Native Type

Description

boolean

jboolean

unsigned 8 bits

byte

jbyte

signed 8 bits

char

jchar

unsigned 16 bits

short

jshort

signed 16 bits

int

jint

signed 32 bits

long

jlong

signed 64 bits

float

jfloat

32 bits

double

jdouble

64 bits

void

void

N/A

 


하지만 하위 모듈들에서 어떤 type을 사용할지 모른다는 제약으로 인해 ...

naive하게 native단과 java단 사이에 전달될 data structure를 단순화 하고 
전달하는 값은 arguments들을 Serialization한 값을 사용하는게 어떨까 했었다..

일단 Serialization 관련 해서 찾아보니 다음과 같다.

C++
- boost serialization library
 . 깔끔 하고 사용하기 편하다. 
 . serialization을 한 값을 보면 꽤나 단순한 형태이다.
 . 다만 boost library의 version에 따른 호환성이 있을 수 도 있지 않을까.... 라는 택도 없는 생각이..

Java
 . 뭐 java야 기본으로 지원하니까...
 . 좀 더 자세히 보자면 : http://javapapers.com/core-java/java-serialization/


Protocol Buffers 
 . Google에서 제공하는 open source
 . protocol을 format에 맞춰 기술하고 사용 언어에 맞춰 이를 컴파일 하여 사용
 . C++, Java, Python을 지원
 . 이종 언어간 (C++, Java, Python) protocol Data를 공유하고자 할 경우
 . Andorid상에서 native library를 사용하여 공유하고자 할 경우 

What Are Protocol Buffers?

Protocol buffers are Google's language-neutral, platform-neutral, extensible mechanism for serializing structured data – think XML, but smaller, faster, and simpler. You define how you want your data to be structured once, then you can use special generated source code to easily write and read your structured data to and from a variety of data streams and using a variety of languages – Java, C++, or Python.
The download provides the complete source code for the protocol buffer compiler and all the classes your generated code needs, together with building and installation instructions.
 우
SWIG
 . 사실 tutorial만 봐서는 사용할 수 있을지 모르겠다. 공통 interface description을 사용해서  여러 언어를 대상으로 코드를 생성 할 수 있을 것 같은데.... data의 변환 문제는 해결 할 수 없는 다른 범주의  solution 임

XX Library
. 찾다 보니 Java 진영쪽에서 C++ object들을 Java에서 사용할 수 있게끔 해주는 package가 있던데... 아직 완벽한것 같지 않고 제약이 있었던 것 같았다.. 
 . 링크를 다시 못찾아서 이렇게 정리만..



일단 간단하게 하려면 그냥 내가 serialization용 protocol을 만들어서 주고 받고 
공통의 container에 <name, value> 정도의 정보만 제공할 수 있을 것 같다...

좀 더 나아가면 가 종단에서는 Abstract factory를 만들어서 전달하고자 하는 data type에 따란
container object를 생성하되 각 object들은 Serialization interface를 구현하여 
JNI 단에서 전달하는 string을 parsing/serialize를 하는 방법도 있을 수 있겠다.

능력이 그거 밖에 안되네..

좀 심각하게 고민한다면 Protocol buffers를 고려해 볼 만 한데 그렇게 까지 중요한 부분이 아니라서.... 

2013년 3월 13일 수요일

Ubuntu 원격 접속 방법 (Xrdp, VNC, Cygwin X)

이전 블로그에서 이전 함 (원본 글 2013/03/13 작성)

Ubuntu를 설치하고 윈도우에서 원격 접속을 하려고 프로그램을 찾아봤는데
마땅히 맘에 드는게 없다. 
그나마 간편하고 맘에 드는게 윈도우 보조프로그램의 원격 데스크탑 연결 이지만 copy & Paste가 되지 않아.. 좀 아니 많이 아쉽..



윈도우에서 Ubuntu의 application을 실행 할 수 있게 해준다. 
뭐 Xmanager가 훨 좋지만 이건 공짜고 하니.
그럭저럭 쓸만한데 윈도우 조절 같은데 좀 불안정 할 때가 있음.

* 최신 CygwinX에서 연결 안될 때 참고할 게시물
: http://charlie0301.blogspot.kr/2015/12/windows-ubuntu-cygwinx.html

설치 및 설정
 . 설치
 Cygwin/X packages are located in the X11 category.
  • xorg-server (required, the Cygwin/X X Server)
  • xinit (required, scripts for starting the X server: xinit, startx, startwin (and a shortcut on the Start Menu to run it),startxdmcp.bat )
  • xorg-docs (optional, man pages)
  • X-start-menu-icons (optional, adds icons for X Clients to the Start menu)
  • You may also select any X client programs you want to use, and any fonts you would like to have available.
  • You may also want to ensure that the inetutils or openssh packages are selected if you wish to use telnet or ssh connections to run remote X clients.

 . 연결
On your Windows machine:
  1. Make sure you have the openssh package installed.
  2. Launch Cygwin/X
  3. Ensure the DISPLAY environment variable is set correctly. (This step is not neccessary if you are entering your commands into an X terminal, as DISPLAY must already be set in that case)
    $ export DISPLAY=:0.0
    
     (안되면 export $DISPLAY=:0)
  4. Run the ssh command to connect to the remote host:
    $ ssh -Y username@remote_hostname_or_ip_address
    
  5. Enter your password when prompted by ssh.
  6. Your ssh session should now show you a shell prompt for your remote machine.
    Note: The ssh server will automatically set the DISPLAY environment variable appropriately, typically to something likelocalhost:10.0, so clients will connect to a proxy X11 display on the remote host from which the X11 protocol will be forwarded over ssh to your X server.
    If your login scripts unconditionally set DISPLAY to something else, this will break X11 forwarding.
  7. You can now launch remote X clients in your ssh session, for example:
    $ xterm &
    
    will launch an xterm running on your remote host that will display on your Cygwin/X screen.
  8. Launch other remote clients in the same manner. I recommend starting the remote clients in the background, by appending & to the command name, so that you don't have to open several ssh sessions.
Note: By default, the OpenSSH server does not allow forwarded X connections. This must be configured on the remote host by adding X11Forwarding yes to the sshd_config configuration file. The OpenSSH server must be restarted or SIGHUP'ed to re-read the configuration file after it is changed.
Note: The OpenSSH server requires the xauth command to be available to forward X connections. Consequently, it must be installed on the remote host.



윈도우즈 원격 데스크탑 연결을 사용한 Xrdp serve로 연결

가장 빠르고 화면 표시가 깔끔하다. 
해상도 조절도 잘되고 윈도우에서 전체 화면으로 이용해도 무리가 없다.

단점으로는 
 - 해상도 마다 connection이 생성되고 
 - 윈도우로 Copy & Paste가 안된다.
 - 종종 원격 데스크탑이 focus를 받는 상황(as foreground window)에 떠 있는 상태에서 screen lock되어 login창이 뜨면 특정 키가 안먹을 때가 있음. => Windows key를 누른 다음 키 입력
 - Ubuntu 12.4 LTS에서는 한글 자판 설정이 안된다. (source를 컴파일해서 설치 하던가 자판 파일 수정 필요)
설치 및 설정

sudo apt-get install xrdp

메뉴가 제대로 보이지 않을 경우...

echo "gnome-session --session=ubuntu-2d" > ~/.xsession


* 원격 데스크탑 내에서 D key를 누를 경우 창이 사라지는 문제 관련 해결 링크


VNC Server로 연결

사실 많이 써보진 않았는데 화면이 너무 느리다. client 마다 편차가 심해 한두번 깔아보고 안썼음.
리눅스에서 사용중인 screen을 공유할 수 있어 unique한 화면을 사용할 수 있는 것은 장점.
그리고 다양한 VNC viewer가 존재하고 VNC Server 기능은 기본으로 Ubuntu에서 제공한다.

VNC Viewer로 접속

1. Ubuntu에서 Remote desktop 사용 설정
   Remote Desktop > Sharing > Allow other users to view your desktop > check
   Security > Require the user to enter this password > check > password submit

 
 

2. 윈도우에 VNC viewer 설치
3. Ubuntu 주소를 설정하고 연결 (xxx.xxx.xxx.xxx:0)