Android开发基础(2.2)--利用NDK搭建自己的Android交叉工具链
2011-02-26 16:51
477 查看
上篇提到的都是使用现有的ndk-build建立共享库。如何建立可执行的C/C++文件?将jni/Android.mk内的
include $(BUILD_SHARED_LIBRARY)
改成include $(BUILD_EXECUTABLE)
即可。那么,想“自由使用”工具链,比如
像
直接使用gcc/g++那样,尤其是想往Android上面移植 C/C++程序或者库时,如何才能跳出ndk-build的限制?
I.提取Android的gcc工具链
如果你想偷懒的话,你很幸运,有现成的
,附件的perl脚本agcc(csdn搞不出附件,只好链接新帖子
)
,即可以完成工具链的抽取和封装,可以像使用 gcc 那样使用它,它最先来自
plausible.org/andy/agcc
不过这个是面对整个Android开发包的(包括Android/SDK/NDK的所有文件),而且没有C++/STL支持,我对它进行了修改,使它与上篇给出的ndk-r4配合,完全支持c/c++。
如果你想自己动手,请这样做:
1.分别对
1)生成可执行文件
2)静态库
3)
动态库
4)多个源文件 的不同类型的工程使用
#ndk-build -B V=1
命令,会让ndk-build “揭露出”整个工具链的不同使用过程
,比如上篇中的helloworld工程:
显示:
Compile thumb : helloworld <= /opt/android/android-ndk-r4c/samples/helloworld/jni/helloworld.c
/opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/arm-eabi-gcc -I/opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/include -fpic -mthumb-interwork -ffunction-sections -funwind-tables -fstack-protector -fno-short-enums -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ -Wno-psabi -march=armv5te -mtune=xscale -msoft-float -mthumb -Os -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 -I/opt/android/android-ndk-r4c/samples/helloworld/jni -DANDROID -Wa,--noexecstack -O2 -DNDEBUG -g -c -MMD -MP -MF /opt/android/android-ndk-r4c/samples/helloworld/bin/ndk/local/armeabi/objs/helloworld/helloworld.o.d /opt/android/android-ndk-r4c/samples/helloworld/jni/helloworld.c -o /opt/android/android-ndk-r4c/samples/helloworld/bin/ndk/local/armeabi/objs/helloworld/helloworld.o
SharedLibrary : libhelloworld.so
/opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/arm-eabi-gcc -nostdlib -Wl,-soname,libhelloworld.so -Wl,-shared,-Bsymbolic /opt/android/android-ndk-r4c/samples/helloworld/bin/ndk/local/armeabi/objs/helloworld/helloworld.o -Wl,--whole-archive -Wl,--no-whole-archive /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/lib/libstdc++.a /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/lib/libsupc++.a /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/libgcc.a /opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/lib/libc.so /opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/lib/libm.so -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-rpath-link=/opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/lib /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/lib/libstdc++.a /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/lib/libsupc++.a /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/libgcc.a -o /opt/android/android-ndk-r4c/samples/helloworld/bin/ndk/local/armeabi/libhelloworld.so
......
从这些命令记录分别提取出
1)工具的名称和位置
例如gcc/g++工具是 arm-eabi-gcc/g++,位置是
/opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/。。
2)工具相关选项和参数
交叉编译时,最重要的就是编译工具的相关参数设置,以及从环境中提取的文件(头文件夹,链接文件,库文件..)。下面的从上面提取的相关参数就不用我解释了吧?(如果不熟悉这些的话,真的不应该直接从Android上手学交叉编译,道理你们懂的。。)
CC
=
arm-eabi-gcc
CFLAGS/CXXFLAGS
="-fpic -mthumb-interwork -ffunction-sections -funwind-tables -fstack-protector -fno-short-enums -Wno-psabi -march=armv5te -mtune=xscale -msoft-float -mthumb -Os -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64"
CPPFLAGS
="-I/opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/include -fpic -mthumb-interwork -ffunction-sections -funwind-tables -fstack-protector -fno-short-enums -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ -I/opt/android/android-ndk-r4c/samples/helloworld/jni -DANDROID
"
CXX
=arm-eabi-g++
LDFLAGS
= "-nostdlib -Wl,-soname,libhelloworld.so -Wl,-shared,-Bsymbolic -Wl,--whole-archive -Wl,--no-whole-archive /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/lib/libstdc++.a /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/lib/libsupc++.a /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/libgcc.a /opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/lib/libc.so /opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/lib/libm.so -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-rpath-link=/opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/lib /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/lib/libstdc++.a /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/lib/libsupc++.a /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/libgcc.a"
3)工具的使用过程
主要是面对不同的源文件(.c/.cpp/.o/.h...),以及不同的目标(生成什么?.o/.exe/.s...),工具的使用过程和参数都是不同的,比如上例:
.c-->.o
$CC $CPPFLAGS $CFLAGS helloworld.c -c -g -o helloworld.o
仅仅 预处理-->编译,未链接
然后
.o-->.so
$CC $LDFLAGS helloworld.o -o libhelloworld.so
完成链接
4)大家可以查看其他几类情况,使用的工具和参数各不相同。
II.直接使用工具链
提取出了工具链,弄清其不同参数和工作流程后,就可以自己指明使用了。首先将工具加入$PATH,然后,例如编译如下的两个全面测试C++功能的.cpp文件,要求ahoo.cpp -->libahoo.so(动态库);a.cpp+libahoo.so --->a(程序):
ahoo.h
ahoo.cpp
a.cpp
命令就是:(都是先编译,再链接,注意参数的区别)
1)ahoo.cpp--->ahoo.o a.cpp-->a.o
arm-eabi-g++ ahoo.cpp -I/opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/include -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ -DANDROID -DNDEBUG -mthumb-interwork -march=armv5te -mtune=xscale -msoft-float -mthumb -fpic -fPIC -ffunction-sections -funwind-tables -fstack-protector -fno-short-enums -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 -Wno-psabi -Wa,--noexecstack -Os -O2 -c -o ahoo.o
arm-eabi-g++ a.cpp -I/opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/include -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ -DANDROID -DNDEBUG -mthumb-interwork -march=armv5te -mtune=xscale -msoft-float -mthumb -fpic -fPIC -ffunction-sections -funwind-tables -fstack-protector -fno-short-enums -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 -Wno-psabi -Wa,--noexecstack -Os -O2 -c -o a.o
2) ahoo.o -->libahoo.so
arm-eabi-gcc
ahoo.o -nostdlib -Wl,-shared,-Bsymbolic -Wl,--whole-archive
-Wl,--no-whole-archive -Wl,--no-undefined -Wl,-z,noexecstack
-Wl,-rpath-link=/opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/lib
-L/opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/lib
-lc -lm
/opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/arm-eabi/lib/libstdc++.a
/opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/arm-eabi/lib/libsupc++.a
/opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/lib/gcc/arm-eabi/4.4.0/libgcc.a
-o libahoo.so
3) a.o -->a
arm-eabi-gcc a.o -nostdlib -Bdynamic -Wl,-dynamic-linker,/system/bin/linker -Wl,--gc-sections -Wl,-z,nocopyreloc -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-rpath-link=/opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/lib -L/opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/lib -lc -lm /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/arm-eabi/lib/libstdc++.a /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/arm-eabi/lib/libsupc++.a /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/lib/gcc/arm-eabi/4.4.0/libgcc.a /opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/lib/crtend_android.o /opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/lib/crtbegin_dynamic.o -o a -lahoo -L./
你是什么感觉呢,不觉得太长太麻烦了吗?何苦呢?何必呢?所以我才将所有的内容都封装在agcc
内的啊,你难道不想也这样做吗?(尤其是对程序或者库进行 ./configure 的时候!),上面的例子,直接用我的agcc
的话(先将包含arm-eabi-*的路径加入$PATH
)
#agcc ahoo.cpp -shared -o libahoo.so
Compile Thumb++ :ahoo.cpp ===> ahoo.o
...
Link ARM shared lib : ahoo.o ====> libahoo.so
...
#agcc a.cpp -o a -lahoo -L./
Compile Thumb++ :a.cpp ===> a.o
....
Link ARM executable : a.o ====> a
...
# file a
a: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), not stripped
#file libahoo.so
libahoo.so: ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked, not stripped
#arm-eabi-readelf -d a
Dynamic section at offset 0x132cc contains 23 entries:
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [libc.so]
0x00000001 (NEEDED) Shared library: [libm.so]
0x00000001 (NEEDED) Shared library: [libahoo.so]
0x00000020 (PREINIT_ARRAY) 0x1c2a4
0x00000021 (PREINIT_ARRAYSZ) 0x8
.................
搞定!现在你也可以从自己的NDK出发提取组合自己的工具链了吧!
include $(BUILD_SHARED_LIBRARY)
改成include $(BUILD_EXECUTABLE)
即可。那么,想“自由使用”工具链,比如
像
直接使用gcc/g++那样,尤其是想往Android上面移植 C/C++程序或者库时,如何才能跳出ndk-build的限制?
I.提取Android的gcc工具链
如果你想偷懒的话,你很幸运,有现成的
,附件的perl脚本agcc(csdn搞不出附件,只好链接新帖子
)
,即可以完成工具链的抽取和封装,可以像使用 gcc 那样使用它,它最先来自
plausible.org/andy/agcc
不过这个是面对整个Android开发包的(包括Android/SDK/NDK的所有文件),而且没有C++/STL支持,我对它进行了修改,使它与上篇给出的ndk-r4配合,完全支持c/c++。
如果你想自己动手,请这样做:
1.分别对
1)生成可执行文件
2)静态库
3)
动态库
4)多个源文件 的不同类型的工程使用
#ndk-build -B V=1
命令,会让ndk-build “揭露出”整个工具链的不同使用过程
,比如上篇中的helloworld工程:
显示:
Compile thumb : helloworld <= /opt/android/android-ndk-r4c/samples/helloworld/jni/helloworld.c
/opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/arm-eabi-gcc -I/opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/include -fpic -mthumb-interwork -ffunction-sections -funwind-tables -fstack-protector -fno-short-enums -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ -Wno-psabi -march=armv5te -mtune=xscale -msoft-float -mthumb -Os -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 -I/opt/android/android-ndk-r4c/samples/helloworld/jni -DANDROID -Wa,--noexecstack -O2 -DNDEBUG -g -c -MMD -MP -MF /opt/android/android-ndk-r4c/samples/helloworld/bin/ndk/local/armeabi/objs/helloworld/helloworld.o.d /opt/android/android-ndk-r4c/samples/helloworld/jni/helloworld.c -o /opt/android/android-ndk-r4c/samples/helloworld/bin/ndk/local/armeabi/objs/helloworld/helloworld.o
SharedLibrary : libhelloworld.so
/opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/arm-eabi-gcc -nostdlib -Wl,-soname,libhelloworld.so -Wl,-shared,-Bsymbolic /opt/android/android-ndk-r4c/samples/helloworld/bin/ndk/local/armeabi/objs/helloworld/helloworld.o -Wl,--whole-archive -Wl,--no-whole-archive /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/lib/libstdc++.a /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/lib/libsupc++.a /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/libgcc.a /opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/lib/libc.so /opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/lib/libm.so -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-rpath-link=/opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/lib /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/lib/libstdc++.a /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/lib/libsupc++.a /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/libgcc.a -o /opt/android/android-ndk-r4c/samples/helloworld/bin/ndk/local/armeabi/libhelloworld.so
......
从这些命令记录分别提取出
1)工具的名称和位置
例如gcc/g++工具是 arm-eabi-gcc/g++,位置是
/opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/。。
2)工具相关选项和参数
交叉编译时,最重要的就是编译工具的相关参数设置,以及从环境中提取的文件(头文件夹,链接文件,库文件..)。下面的从上面提取的相关参数就不用我解释了吧?(如果不熟悉这些的话,真的不应该直接从Android上手学交叉编译,道理你们懂的。。)
CC
=
arm-eabi-gcc
CFLAGS/CXXFLAGS
="-fpic -mthumb-interwork -ffunction-sections -funwind-tables -fstack-protector -fno-short-enums -Wno-psabi -march=armv5te -mtune=xscale -msoft-float -mthumb -Os -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64"
CPPFLAGS
="-I/opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/include -fpic -mthumb-interwork -ffunction-sections -funwind-tables -fstack-protector -fno-short-enums -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ -I/opt/android/android-ndk-r4c/samples/helloworld/jni -DANDROID
"
CXX
=arm-eabi-g++
LDFLAGS
= "-nostdlib -Wl,-soname,libhelloworld.so -Wl,-shared,-Bsymbolic -Wl,--whole-archive -Wl,--no-whole-archive /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/lib/libstdc++.a /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/lib/libsupc++.a /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/libgcc.a /opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/lib/libc.so /opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/lib/libm.so -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-rpath-link=/opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/lib /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/lib/libstdc++.a /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/lib/libsupc++.a /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/libgcc.a"
3)工具的使用过程
主要是面对不同的源文件(.c/.cpp/.o/.h...),以及不同的目标(生成什么?.o/.exe/.s...),工具的使用过程和参数都是不同的,比如上例:
.c-->.o
$CC $CPPFLAGS $CFLAGS helloworld.c -c -g -o helloworld.o
仅仅 预处理-->编译,未链接
然后
.o-->.so
$CC $LDFLAGS helloworld.o -o libhelloworld.so
完成链接
4)大家可以查看其他几类情况,使用的工具和参数各不相同。
II.直接使用工具链
提取出了工具链,弄清其不同参数和工作流程后,就可以自己指明使用了。首先将工具加入$PATH,然后,例如编译如下的两个全面测试C++功能的.cpp文件,要求ahoo.cpp -->libahoo.so(动态库);a.cpp+libahoo.so --->a(程序):
ahoo.h
#include <cstdlib> #include <stdexcept> #include <string> #include <cstdio> void ahoo(char** ); class A { public: A(); ~A(); }; class B:public A { public: B(); ~B(); };
ahoo.cpp
#include"ahoo.h" int hana; A::A(){printf("ahoooooooooo coming!/n");} A::~A(){printf("ahoooooooooo dying!/n");} void ahoo(char** a) { hana = 100; printf("sizeof hana:%d/n",hana); *a=(char*) malloc(256); memset(*a,0,256); std::string s = "Hello from JNI !"; try { if (std::getenv("NON_EXISTENT_ENVIRONMENT_VARIABLE") == NULL) throw std::runtime_error("libahoo.so:--exception.runtime_error.string:/t--琉球の海風にいる !"); } catch (std::exception &ex) { s = ex.what(); s = s+"/nlibahoo.so:--exception.catch.string:/t--You are Foooooooooyoooooooed!/n"; } strcpy(*a,s.c_str()); }
a.cpp
#include "ahoo.h" #include"pthread.h" B::B(){printf("bagaaaaaaaaa coming!/n");} B::~B(){printf("bagaaaaaaaaa dying!/n");} template <typename T> class C { public: T a; T b; C(T fa,T fb):a(fa),b(fb){printf("%s/n%s/n",a.c_str(),b.c_str());} }; typedef void* (*thread_main_t)(void*); extern int hana; int main() { pthread_t thread; char* ah =NULL; B* pb=new B; delete pb; C<std::string> c("Horaaaaaaaaaaa","Woraaaaaaaaaaaa"); pthread_create(&thread,NULL,(thread_main_t)&ahoo,(void*)&ah); pthread_join(thread,NULL); printf("sizeof hana:%d/n",hana); if(ah) { printf("%s",ah); free(ah); } std::string str="づっと、づっと乙女の側に居るように!/n"; printf("a/t:--string:/t--%s/n",str.c_str()); return 0; }
命令就是:(都是先编译,再链接,注意参数的区别)
1)ahoo.cpp--->ahoo.o a.cpp-->a.o
arm-eabi-g++ ahoo.cpp -I/opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/include -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ -DANDROID -DNDEBUG -mthumb-interwork -march=armv5te -mtune=xscale -msoft-float -mthumb -fpic -fPIC -ffunction-sections -funwind-tables -fstack-protector -fno-short-enums -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 -Wno-psabi -Wa,--noexecstack -Os -O2 -c -o ahoo.o
arm-eabi-g++ a.cpp -I/opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/include -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ -DANDROID -DNDEBUG -mthumb-interwork -march=armv5te -mtune=xscale -msoft-float -mthumb -fpic -fPIC -ffunction-sections -funwind-tables -fstack-protector -fno-short-enums -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 -Wno-psabi -Wa,--noexecstack -Os -O2 -c -o a.o
2) ahoo.o -->libahoo.so
arm-eabi-gcc
ahoo.o -nostdlib -Wl,-shared,-Bsymbolic -Wl,--whole-archive
-Wl,--no-whole-archive -Wl,--no-undefined -Wl,-z,noexecstack
-Wl,-rpath-link=/opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/lib
-L/opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/lib
-lc -lm
/opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/arm-eabi/lib/libstdc++.a
/opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/arm-eabi/lib/libsupc++.a
/opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/lib/gcc/arm-eabi/4.4.0/libgcc.a
-o libahoo.so
3) a.o -->a
arm-eabi-gcc a.o -nostdlib -Bdynamic -Wl,-dynamic-linker,/system/bin/linker -Wl,--gc-sections -Wl,-z,nocopyreloc -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-rpath-link=/opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/lib -L/opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/lib -lc -lm /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/arm-eabi/lib/libstdc++.a /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/arm-eabi/lib/libsupc++.a /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/lib/gcc/arm-eabi/4.4.0/libgcc.a /opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/lib/crtend_android.o /opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/lib/crtbegin_dynamic.o -o a -lahoo -L./
你是什么感觉呢,不觉得太长太麻烦了吗?何苦呢?何必呢?所以我才将所有的内容都封装在agcc
内的啊,你难道不想也这样做吗?(尤其是对程序或者库进行 ./configure 的时候!),上面的例子,直接用我的agcc
的话(先将包含arm-eabi-*的路径加入$PATH
)
#agcc ahoo.cpp -shared -o libahoo.so
Compile Thumb++ :ahoo.cpp ===> ahoo.o
...
Link ARM shared lib : ahoo.o ====> libahoo.so
...
#agcc a.cpp -o a -lahoo -L./
Compile Thumb++ :a.cpp ===> a.o
....
Link ARM executable : a.o ====> a
...
# file a
a: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), not stripped
#file libahoo.so
libahoo.so: ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked, not stripped
#arm-eabi-readelf -d a
Dynamic section at offset 0x132cc contains 23 entries:
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [libc.so]
0x00000001 (NEEDED) Shared library: [libm.so]
0x00000001 (NEEDED) Shared library: [libahoo.so]
0x00000020 (PREINIT_ARRAY) 0x1c2a4
0x00000021 (PREINIT_ARRAYSZ) 0x8
.................
搞定!现在你也可以从自己的NDK出发提取组合自己的工具链了吧!
相关文章推荐
- Android开发基础(2.1)--NDK 的搭建和基本用法
- 史上最易懂的Android jni开发资料--NDK环境搭建
- android studio ndk环境搭建 和开发
- ubuntu10.10下,搭建Android SDK/NDK开发环境
- android开发学习---linux下开发环境的搭建&& android基础知识介绍
- Android-NDK开发之基础--Android JNI开发高级篇(JNI中的常用方法)
- windows下eclipse搭建android_ndk开发环境
- Android-NDK开发之基础--Android JNI开发高级篇(JNI中的常用方法)
- centos 6 下开发android ,sdk ndk环境搭建
- Android-NDK开发之基础--Android JNI实例代码(四)-- JNI中的异常处理实例代码
- Android的NDK开发(2)————利用Android NDK编写一个简单的HelloWorld
- Android基础-1 基于Eclipse的开发环境搭建
- Windows下NDK开发环境的搭建(Cygwin+Android-SDK+NDK)(转)
- android Jni NDK开发环境搭建及其简单实例的编写
- androidの搭建NDK开发环境
- 在Windows下搭建Android2.2开发环境
- win7 64位利用eclipse搭建android开发环境教程
- 史上最易懂的Android jni开发资料--NDK环境搭建
- linux下android开发环境搭建及NDK安装(转)
- Android基础之用Eclipse搭建Android开发环境和创建第一个Android项目(Windows平台)