Android NDK r5 C++ STL this problem is fixed in r5c

 

转载:

 

就怕这种事:沙漠中的海市蜃楼。

NDK r5 中 的 C++ STL 就是。

 

 

http://www.modoohut.com/archives/%E8%AF%95%E4%BA%86%E4%B8%8Bandroid-ndk-r5.html

 

试了下Android NDK r5

Android, by cola_tin.

始终觉得google在NDK上花的力气不够,  NDK对c++的支持很不好, 或许g认为在NDK下应该用C++是奢侈的, 那tmd上层还java虚拟机呢. NDK r4虽然支持c++, 但是没有stl支持(没有stl的c++还算c++吗), 幸好有个crystax的版本, 对stl支持很好.

NKD r5出来有段时间了, 今天看了一下, 对c++的支持大有改进, 加入两种stl的实现, 一个默认的和一个gnu的.  于是把r4 crystax换成r5试了下, 默认的那个stl链接时老是报~exception multiple definition, 换gnu版本就ok了. 在2.2的虚拟机下跑了下, 正常, 换到2.1就出问题了, 2.1还没法用gdb调试. 用”ndk r5 2.1″狗了一下, 发现很多人有这样的问题,  找到一个解释 https://review.source.android.com//#change,21309 (没被墙, 表示惊讶). 引用如下

Due to a bug in the implementation of __cxa_finalize() that was only
fixed in Android 2.2, any code linked with gnustl_static would crash
when running on Android 2.1 or older.

This adds a local patch to libsupc++ to detect the problem at runtime
and avoid the crash. Note that this results in a leak of a thread-specific
storage key on these older platforms.

也就是说ndk r5编译的c++ native无法在2.1及以下版本跑, 这不扯淡嘛, 算了, 继续用r4 crystax.

 

 

http://blog.zcube.kr/5498

 

Android ndk r5의 함정.... 일상생활

Android ndk에서 부터는 C++의 RTTI와 exception을 지원하게 되었다.
하지만 왠지 환경을 세팅하고 빌드를 해도 잘 동작하지 않았고..
이런 저런 뻘짓 결과 STL을 위한 libstdc++.a 라이브러리가 arm-linux-androideabi-4.4.3 기준으로만
빌드 되어 있기 때문이라는 걸로 결론을 내렸다.

아직은 r4b-crystax를 써야 할듯 하다.

 

---

 

http://blog.zcube.kr/1993

 

CMake로 CURL을 Android에 맞게 빌드 해 봤다

 

CMake로 CURL을 Android에 맞게 빌드 해 봤다. 기타

언제나 그렇듯이 세팅좀 하려면 항상 무시하는 CMAKE를 가지고 CURL을 안드로이드에 맞게 빌드해 봤다.

생각보다 괴랄할 것이므로 아래를 열기전에 마음을 가다듬도록 하자.

[#M_펼쳐두기..|접어두기..|언제나 문제가 되는건 CMAKE_C_FLAGS 같은 플래그를 설정하면 CMAKE는 항상 먹어버린다는 것...

우선 NDK는 받아 두도록 한다.

여기서는 c:/Programs/android-ndk-r3에 설치 하였다.

그 리고 MingW를 C:/MingW에 Cygwin을 c:/cygwin에 설치 하였다.

MingW는 Mingw32-Make를 사용하기 위해, Cygwin은 cygwin1.dll을 위해 설치 하였다.

그럼 지금 부터 뻘짓을 시작하겠다.

우선 C_INCLUDE_PATH LD_LIBRARY_PATH등을 설정한다.

설정하는건 한번만 하고 끝날게 아니라 빌드 할때 마다 필요 하기 때문에 스크립트를 만들어 두자

작업환경이 윈도우라 cross.bat라는 파일을 만들었다.

set EABI_VERSION=4.2.1
set GLIBC_ADDON_OPTIONS=crtbegin_dynamic.o
set GCC_ROOT_DIRECTORY=c:/Programs/android-ndk-r3/build/prebuilt/windows/arm-eabi-%EABI_VERSION%
REM set path=%GCC_ROOT_DIRECTORY%/bin;%GCC_ROOT_DIRECTORY%/libexec/gcc/arm-eabi/%EABI_VERSION%;"C:/Program Files/CMake 2.8/bin";"C:/cygwin/bin"
set path=%GCC_ROOT_DIRECTORY%/bin;%GCC_ROOT_DIRECTORY%/libexec/gcc/arm-eabi/%EABI_VERSION%;"C:/Program Files/CMake 2.8/bin";C:/cygwin/bin
set GCC_ROOT_DIRECTORY=/cygdrive/c/Programs/android-ndk-r3/build/prebuilt/windows/arm-eabi-%EABI_VERSION%
set CPLUS_INCLUDE_PATH=%GCC_ROOT_DIRECTORY%/include:%GCC_ROOT_DIRECTORY%/lib/gcc/arm-eabi/%EABI_VERSION%/include:/cygdrive/c/Programs/android-ndk-r3/build/platforms/android-5/arch-arm/usr/include:%GCC_ROOT_DIRECTORY%/lib/gcc/arm-eabi/%EABI_VERSION%/install-tools/include:%GCC_ROOT_DIRECTORY%/lib/gcc/arm-eabi/%EABI_VERSION%/install-tools
set C_INCLUDE_PATH=%CPLUS_INCLUDE_PATH%
set TARGET_DIRECTORY=/cygdrive/c/Programs/android-ndk-r3/build/platforms/android-5
set LD_LIBRARY_PATH=%GCC_ROOT_DIRECTORY%/lib:%GCC_ROOT_DIRECTORY%/lib/gcc/arm-eabi/%EABI_VERSION%/android:%TARGET_DIRECTORY%/arch-arm/usr/lib
set LDPATH=%LD_LIBRARY_PATH%
rem -DHAVE_GLIBC_STRERROR_R=1 -D__EABI__
rem -nostdlib -Wl,-rpath-link=/cygdrive/c/Programs/android-ndk-r3/build/platforms/android-5/arch-arm/usr/lib -L/cygdrive/c/Programs/android-ndk-r3/build/platforms/android-5/arch-arm/usr/lib -lc  /cygdrive/c/Programs/android-ndk-r3/build/platforms/android-5/arch-arm/usr/lib/crtbegin_dynamic.o
set LINK_FLAGS=-nostdlib -Wl,-rpath-link=/cygdrive/c/Programs/android-ndk-r3/build/platforms/android-5/arch-arm/usr/lib -L/cygdrive/c/Programs/android-ndk-r3/build/platforms/android-5/arch-arm/usr/lib -lc
set EXE_FLAGS= /cygdrive/c/Programs/android-ndk-r3/build/platforms/android-5/arch-arm/usr/lib/crtbegin_dynamic.o
set GCC_EXTRA_CONFIG=-nostdlib -Wl,-rpath-link=%TARGET_DIRECTORY%/arch-arm/usr/lib -L/cygdrive/c/Programs/android-ndk-r3/build/platforms/android-5/arch-arm/usr/lib %TARGET_DIRECTORY%/arch-arm/usr/lib/crtbegin_static.o -lc -DHAVE_GLIBC_STRERROR_R=1 -D__EABI__
set PREFIX=arm-eabi-
set GXX=%PREFIXg++.exe
set GCC=%PREFIXgcc.exe
set ARM_BIN=C:/Programs/android-ndk-r3/build/prebuilt/windows/arm-eabi-%EABI_VERSION%/bin/
set GCC_ROOT_DIRECTORY=/cygdrive/c/Programs/android-ndk-r3/build/prebuilt/windows/arm-eabi-%EABI_VERSION%
set flags=-DCMAKE_BUILD_TYPE="MinSizeRel" -G "MinGW Makefiles" -DCMAKE_CXX_COMPILER="%ARM_BIN%%PREFIX%g++.exe" -DCMAKE_C_COMPILER="%ARM_BIN%%PREFIX%gcc.exe" -DCMAKE_AR="%ARM_BIN%%PREFIX%ar.exe" -DCMAKE_LINKER="%ARM_BIN%%PREFIX%ld.exe" -DCMAKE_SYSTEM_NAME="linux" -DCMAKE_C_FLAGS="%GCC_EXTRA_CONFIG%" -DCMAKE_CXX_FLAGS="%GCC_EXTRA_CONFIG%" -DCURL_DISABLE_LDAP=TRUE -DCURL_DISABLE_LDAPS=TRUE -DBUILD_CURL_TESTS=FALSE -DCMAKE_EXE_LINKER_FLAGS="%LINK_FLAGS% %EXE_FLAGS%" -DCMAKE_MODULE_LINKER_FLAGS="%LINK_FLAGS%" -DCMAKE_SHARED_LINKER_FLAGS="%LINK_FLAGS%"
mkdir cross
cd cross
cmake-gui %flags% ../
cd ..


:BUILD
pause
@echo off
cd cross

c:/mingw/bin/mingw32-make.exe
pause


실 제 빌드에 사용한 배치파일이다.

보면 CMAKE에 이런저런 플래그가 마구 들어가 있다. 하지만 제대로 적용이 안되고 직접 수동으로 설정해야할 목록이다 [...]

안드로이드에서 실행파일을 빌드 할때에는 그냥은 안되고 http://android-tricks.blogspot.com/2009/02/hello-world-c-program-on-using-android.html를 참고해서 해야한다.

문제는 CMake는 그 사실을 모른다는 거다. 따라서 지금부터가 삽질의 시작이다.

위 스크립트 대로라면 cmake-gui가 실행된다.

그러면 우선 configure를 버튼을 누른 후 Mingw Makefiles를 선택 한다. 그리고 맨 아래쪽에 있는 Specify options for cross-compiling을 선택한다.


다음은 운영체제를 linux로 프로세서를 arm 그리고 각각 c, c++ 컴파일러를 설정한다. 그 다음 Target Root도 설치한 디렉토리에 따라 설정한다.


아마 에러가 한번 날꺼다 무시하자

그 다음 Configure를 한번 누른다. 에러가 안나면 좋겠지만 그런건 없다. 앞으로 몇번의 에러를 더 볼테니 그냥 넘어가자.

우선 지금 테스트 파일을 컴파일 하게 하기 위해 위 링크에서 봤던대로 CMAKE_C_FLAGS에 다음과 같이 넣어 준다. (Simple View에서는 안보인다)

 -nostdlib -Wl,-rpath-link=/cygdrive/c/Programs/android-ndk-r3/build/platforms/android-5/arch-arm/usr/lib -L/cygdrive/c/Programs/android-ndk-r3/build/platforms/android-5/arch-arm/usr/lib -lc  /cygdrive/c/Programs/android-ndk-r3/build/platforms/android-5/arch-arm/usr/lib/crtbegin_dynamic.o

다 시 Configure를 눌러보자 그럼 이번엔 한단계 전진 할 수 있을 것이다. 뭔가 열심히 테스트 하기 시작한다 !!

그 럼 그 동안 몇개의 헤더를 수정해 보자.

우선 curl.h를 열고 다음을 적당히 앞쪽에 추가한다.

 #if defined(__GNUC__) && defined(__EABI__)
  #include
#endif

그 리고 curlbuild.h를 열어서 __SYMBIAN__를 찾자 그럼 __EBAI__에 대한 정보가 있다. 이걸 __GNUC__에 다음과 같이 추가해야한다.

 #elif defined(__GNUC__)
#  if defined(__i386__) || defined(__ppc__)
#   define CURL_SIZEOF_LONG           4
#    define CURL_TYPEOF_CURL_OFF_T     long long
#    define CURL_FORMAT_CURL_OFF_T     "lld"
#    define CURL_FORMAT_CURL_OFF_TU   "llu"
#    define CURL_FORMAT_OFF_T          "%lld"
#    define CURL_SIZEOF_CURL_OFF_T     8
#    define CURL_SUFFIX_CURL_OFF_T     LL
#    define CURL_SUFFIX_CURL_OFF_TU    ULL
#  elif defined(__x86_64__) || defined(__ppc64__)
#    define CURL_SIZEOF_LONG           8
#    define CURL_TYPEOF_CURL_OFF_T     long
#    define CURL_FORMAT_CURL_OFF_T     "ld"
#    define CURL_FORMAT_CURL_OFF_TU    "lu"
#    define CURL_FORMAT_OFF_T         "%ld"
#    define CURL_SIZEOF_CURL_OFF_T     8
#    define CURL_SUFFIX_CURL_OFF_T     L
#    define CURL_SUFFIX_CURL_OFF_TU    UL
#  elif defined(__EABI__)  /* Treat all ARM compilers equally */
#    define CURL_SIZEOF_LONG           4
#    define CURL_TYPEOF_CURL_OFF_T     long long
#    define CURL_FORMAT_CURL_OFF_T     "lld"
#    define CURL_FORMAT_CURL_OFF_TU   "llu"
#    define CURL_FORMAT_OFF_T          "%lld"
#    define CURL_SIZEOF_CURL_OFF_T     8
#    define CURL_SUFFIX_CURL_OFF_T     LL
#    define CURL_SUFFIX_CURL_OFF_TU    ULL
#  endif
#  define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
#  define CURL_SIZEOF_CURL_SOCKLEN_T 4
#  define CURL_PULL_SYS_TYPES_H      1
# define CURL_PULL_SYS_SOCKET_H     1

이대 로 빌드하면 strerror.c에서 에러가 난다. HAVE_GLIBC_STRERROR_R=1을 정의해 줘야한다.

아마 위 작업을 끝내도 send와 recv를 열심히 찾고 있을 것이다. 인내를 가지고 기다리자.

에러가 나면

 BUILD_CURL_TEST -> FALSE
CURL_DISABLE_LDAP -> TRUE
CURL_DISABLE_LDAPS -> TRUE

CMAKE_C_FLAGS -> -D__GNUC__ -D__EABI__ -DHAVE_GLIBC_STRERROR_R=1

CMAKE_EXE_LINKER_FLAGS -> -nostdlib -Wl,-rpath-link=/cygdrive/c/Programs/android-ndk-r3/build/platforms/android-5/arch-arm/usr/lib -L/cygdrive/c/Programs/android-ndk-r3/build/platforms/android-5/arch-arm/usr/lib -lc /cygdrive/c/Programs/android-ndk-r3/build/platforms/android-5/arch-arm/usr/lib/crtbegin_dynamic.o

CMAKE_MODULE_LINKER_FLAGS , CMAKE_SHARED_LINKER_FLAGS ->  -nostdlib -Wl,-rpath-link=/cygdrive/c/Programs/android-ndk-r3/build/platforms/android-5/arch-arm/usr/lib -L/cygdrive/c/Programs/android-ndk-r3/build/platforms/android-5/arch-arm/usr/lib -lc

이제 Configure와 Generate가 잘 된다 빌드하자.
_M#]

OTL CMake를 평소에 자주 쓰지만 특정 상황에 맞게 세팅 하는 건 역시 괴로운 일이다.
Android ,  CMake ,  CURL

 

你可能感兴趣的:(Android NDK r5 C++ STL this problem is fixed in r5c)