上一篇只是谈到了大方向。有些具体的东西还是没有讲清楚,这次专门讲讲 android ndk .
先看看 android ndk 的目录 layout 大概长的怎么样 .
root
|------ apps , 所有你要编译的 C c ++ code 都放到这个目录下。
|------ build
| |---- platforms 下面目前为止放了 3 sub fold , 里面分别放了 android 需要的 include , library( 提供的 library 有限)
| |------ android 3 代表 android 1.5
| |------ android 4 代表 android 1.6
| |------ android 5 代表 android 2.0
| |---- prebuilt 该目录下存放 toolchain 的可执行档案 , 以及 include & library . 对于 arm - eabi - 4.4 . 0 了解不多 .
| |------ arm - eabi - 4.2 . 1
| |------------ bin 所有的 toolchain excute file
| |------------ arm - eabi
| |------ include
| |------ lib
| |---- tools 这个目录下存放了很多有用的工具,包括下载, build toolchain
|------ docs 必须仔细读的文档
|------ out 生成的所有临时文件

先从 docs 开始谈,这个也是非常重要的一步。
1. 纠正 Android - mk . txt 中写的 ndk 只能编译出 static library shared library , 实际上他还提供了命令编译可执行程序 .
a . include $( BUILD_SHARED_LIBRARY)
b . include $( BUILD_STATIC_LIBRARY)
c . include $( BUILD_EXECUTABLE)
理论上能编译出 so 文件,当然能编译出 execute 文件 . 只是 ndk 是否提供这个接口。
2. apps 目录下,新建一个目录 , 再建立 project 目录 , 这一级目录下建立 Application . mk , 再建立一个 sub fold jni , jni 里面放的都是 c c ++ 源代码 , 还有 Android . mk . Android . mk 就必须仔细写了 .
常用的有 LOCAL_PATH := $( call my - dir) //访问当前path下的所有子目录,
< 1 >. LOCAL_DEBUG := no| yes
< 2 >. LOCAL_OS := linux //目标平台
< 3 >. LOCAL_ARCH := arm //目标平台cpu
< 4 >. LOCAL_ARM_MODE := arm //CPU指令集
< 5 >. COMMON_DEFINES += ISP = isp_arm9 - D_ARM_ //这里通常会把要移植的library中的各种flag写在这里.(从待移植中的Configure或者Makefile中拷贝过来)
< 6 >. ifeq( $( DEBUG ), no)
COMMON_FLAGS += -s - O2 - fno - strict - aliasing - DNDEBUG - fno - rtti //好像都采用O2优化,fno-rtti 告诉C++不要runtime 中的一些support.
< 7 >. COMMON_COMPILE_FLAGS += - fPIC += - msoft - float += march = armv5t

相对应的有了 COMMON_XXX 就有了 LOCAL_XXX ,
我们可以定义相关的
< 1 >. LOCAL_MODULE := libxxx //定义要编译的moule
< 2 >. LOCAL_CFLAGS := - I $( LOCAL_PATH )/ xxx / include 以及局部 FLAG( Configure 或者 Makefile 中拷贝过来) //定义search .h fold
< 3 >. LOCAL_CXXFILES := //和上面是相同的,只是这个是C++的,上面的是C
< 4 >. LOCAL_SRC_FILES := XXX . c XXX . cpp XXX . hpp //定义源代码
< 5 >. include $( BUILD_STATIC_LIBRARY) 定义该模块是静态的
要编译到 android 上运行的 excutable , 还会依赖
< 1 >. LOCAL_LDLIBS := - L library_path - lxx //定义库的路径,以及要的library, 这里其实用的都是动态库.
android , 有一个参数是: - dynamic - linker ,/ system / bin / linker , 采用的不是标准的 linux 下的 ld . so . 6( 好像是这个数字,具体的不清楚了) , 而是 / system / bin / linker 来链接 . 这也是为什么我们用其他编译器(比如 codesourcery )编译出来的东西不能在 android 上直接跑的原因,而一定要加上 - static 参数,也就是说用 codesourcery 编译出来的东西必须不依赖 android 的调度,而是靠编译时把所有的库全部加入 . 所以这时候写出来的 helloworld 都可能会有 1 ~ 2 Mb . 提到了 liner , 就不得不提到 android bionic , 这个 C runtime library 设计并不是功能特别强大 , 并且有些 gnu glic 中的函数没有实现 , 这是移植时会碰到的问题 . 而且 , 这个 C runtime library 也并没有采用 crt0 . o , crt1 . o , crti . o crtn . o , crtbegin . o crtend . o , 而是采用了 android 自己的 crtBegin_dynamic . o , crtBegin_static . o crtEnd_android . o crt1 . o crt0 . o 的后续演进版本 , crt1 . o 中会非常重要的 . init 段和 . fini 段以及 _start 函数的入口 .. init 段和 . fini 段实际上是靠 crti . o 以及 crtn . o 来实现的 . init 段是 main 函数之前的初始化工作代码 , 比如全局变量的构造 . fini 段则负责 main 函数之后的清理工作 . crti . o crtn . o 是负责 C 的初始化 , C ++ 则必须依赖 crtbegin . o crtend . o 来帮助实现 .
So , 在标准的 linux 平台下 , link 的顺序是 : ld crt1 . o crti . o [ user_objects ] [ system_libraries ] crtn . o
而在 android , link 的顺序是 : arm - eabi - g ++ crtBegin_dynamic . o [ user_objects ] [ system_libraries ] crtEnd_android . o
所以这就是从另一个方面说明为什么不适合 codesourcery 之类编译来开发 android 底层东西的原因了 , 这里我不包括BSP 之类 .
< 2 >. LOCAL_STATIC_LIBRARIES := //excute file 依赖的库
< 3 >. include $( BUILD_EXCUTEABLE)
在谈谈 platform 目录下的东西 , 这里面要说的是可能 include library 中包含的头文件和 library 文件不太够 , 我们可以使用 busybox for android 把我们要的资料都给 pull 出来 . 或者编译 android 源代码 , 需要的都东西都会有 .
prebuilt 目录下 , 有我们编译器的可执行文件 , 但是很不幸 android toolchain 不支持 STL . 目前支持 STL 有两种方法 :
1. 使用 STLPort( 据说这种方式不是太好)
2. 重新编译使 android toolchain 支持 STL .
关于如何使 android toolchain 支持 STL , 我后续在谈 .

更多相关文章

  1. Java.lang.UnsatisfiedLinkError :nativeSetExternalAssetPath错
  2. Activity作为dialog展示,如何添加自定义圆角背景
  3. 毕业设计心得与整理-APP-主题切换
  4. Tensorflow编译android平台的so库和jar包
  5. Android(安卓)自定义滚动选择日期
  6. android 反编译心得
  7. ubuntu 12.04 build android的问题
  8. Master OpenCV with Pratical Computer Vision Projects——如何
  9. Eclipse编译带so库或jar包的android应用

随机推荐

  1. androidの高仿支付宝扫描动画效果
  2. Android Studio Gradle两种更新方式
  3. 关于Android(安卓)O系统短信拦截的流程
  4. android5.0以上对于APP_SWITCH和HOME键的
  5. Android启动模拟器出现:Failed to allocat
  6. Android监听软键盘的方式
  7. edittext光标不闪烁的问题
  8. Avoiding Memory Leaks
  9. Android训练课程(Android(安卓)Training)
  10. Android(安卓)apk签名、第三方内置、图标