转载:
就怕这种事:沙漠中的海市蜃楼。
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.
Android ndk r5의 함정.... 일상생활
2011.02.21 15:01
Android ndk에서 부터는 C++의 RTTI와 exception을 지원하게 되었다.
하지만 왠지 환경을 세팅하고 빌드를 해도 잘 동작하지 않았고..
이런 저런 뻘짓 결과 STL을 위한 libstdc++.a 라이브러리가 arm-linux-androideabi-4.4.3 기준으로만
빌드 되어 있기 때문이라는 걸로 결론을 내렸다.
아직은 r4b-crystax를 써야 할듯 하다.
---
CMake로 CURL을 Android에 맞게 빌드 해 봤다
CMake로 CURL을 Android에 맞게 빌드 해 봤다. 기타
2010.03.30 22:07
생각보다 괴랄할 것이므로 아래를 열기전에 마음을 가다듬도록 하자.
[#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 <sys/select.h> #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를 평소에 자주 쓰지만 특정 상황에 맞게 세팅 하는 건 역시 괴로운 일이다.