Android NDK 工具链的使用方法(Standalone Toolchain)

首先需要确定目标机器的指令集。

如果是 x86 的机器,用 x86-4.4.3 版本的工具链;如果是 arm 指令的,用 arm-linux-androideabi-4.4.3 版本 (x86-4.4.3 和 arm-linux-androideabi-4.4.3 位于ndk目录中)

1、gcc 的sysroot 选项

sysroot 选项设定 gcc 在编译源码的时候,寻找头文件和库文件的根目录。可以这样调用 gcc --sysroot=/tmp/gcc-arm (及其他选项)。NDK 根目录下的 platforms 目录中的各个子目录的路径都可以直接传给 gcc --sysroot=<dir>。为了简化操作,可以在linux系统的命令终端执行以下命令,设置SYSROOT环境变量,$NDK是ndk的根目录。

$ SYSROOT=$NDK/platforms/android-8/arch-arm

2、调用 NDK gcc(第1种方法)。 设置 SYSROOT之后,要把它传给 gcc 的 --sysroot 选项。由于unix/linux自带的gcc并非交叉编译工具,而我们需要使用的是ndk中提供的交叉编译工具(也是gcc),所以需要想办法让编译脚本找到ndk中的gcc,而不要去寻找系统中的gcc。而 unix/linux 系统的编译脚本常常会用 CC 环境变量来引用编译器,所以通过把 CC 设置为ndk中的gcc的路径,就能帮助编译脚本找到正确的gcc(我们还能顺便加上--sysroot选项)。

将CC 按如下设置

           $ export CC="$NDK/toolchains/<name>/prebuilt/<host-system>/bin/<prefix>gcc --sysroot=$SYSROOT"

           $ $CC -o foo.o -c foo.c  (不必执行这一行,这条命令是调用gcc编译程序)

          上面第1行之后之后,再去执行./configure 就可以编译出arm程序了。不过还需要考虑共享库的链接问题,要确保该程序没有链接ndk未提供的共享库。该方法的缺陷就是,不能使用 C++ STL(STLport 或 GNU libstdc++ ),也不能使用异常机制和RTTI。

3、调用NDK编译器(第2种方法,更简单)

      android ndk 提供脚本,允许自己定制一套工具链。例如:

      $NDK/build/tools/make-standalone-toolchain.sh --platform=android-5 --install-dir=/tmp/my-android-toolchain [ --arch=x86 ]

      将会在/tmp/my-android-toolchain 中创建 sysroot 环境和 工具链。--arch 选项选择目标程序的指令架构,默认是为 arm。

      如果不加 --install-dir 选项,则会创建 /tmp/ndk/<toolchain-name>.tar.bz2。

      (执行 make-standalone-toolchain.sh --help 查看帮助。)

      运行之后,这样使用:

      $ export PATH=/tmp/my-android-toolchain/bin:$PATH

      $ export CC=arm-linux-androideabi-gcc

      $ export CXX=arm-linux-androideabi-g++

      $ export CXXFLAGS="-lstdc++"

     执行完以上设置环境变量的命令之后,就可以直接编译了(例如,执行 ./configure 然后 make 得到的就是 arm 程序了)。不用再设定 sysroot, CC 了。而且,可以使用 STL,异常,RTTI。

4、ABI 兼容性

     ndk 同时支持 arm5 和 arm7,一般只用 arm5就好了。arm7是高端一点的,NDK 默认也是 arm5 。

     推荐加上 -mthumb 选项给gcc,来生成 16-bit Thumb-1 指令。

     如果要用 arm7,可以设定 CFLAGS='-march=armv7-a -mfloat-abi=softfp', 使用 Thumb-2 指令,且这两个选项不能分开!

5、警告 & 限制

5.1 Windows支持

Windows 上的NDK 工具链不依赖 Cygwin,因而速度比用 Cygwin 快一点,但是这些工具不能理解

Cygwin 的路径名(例如, /cygdrive/c/foo/bar)。只能理解  C: /cygdrive/c/foo/bar 这类路径

不过,NDK 提供的build工具能够很好地应对上述问题(ndk-build)

5.2 wchar_t 支持

       wchar_t  类型仅从 Android 2.3 开始支持。

      在 android-9 上, wchar_t 是 4字节。 并且 C语言库提供支持宽字符的函数

    (例外:multi-byte 编码/解码 函数 和 wsprintf/wsscanf )

      在android-9 以前的平台上,wchar_t 是1字节,而且宽字符函数不起作用。

      建议不使用 wchar_t,提供 wchar_t 支持是为了方便移植以前的代码。

5.3  异常, RTTI 和 STL

      NDK 工具链默认支持C++异常和RTTI(Run Time Type Information),可以用 -fno-exception 和 -fno-rtti 关闭(生成的机器码更小)

注意: 如果要用这两个特性,需要显式链接 libsupc++。例如: arm-linux-androideabi-g++ .... -lsupc++ 

NDK 提供了 libstdc++,因而可以用 STL,但需要显式链接 libstdc++ ( gcc ... -lstdc++)。不过在将来可以不用手动指定这个链接参数。


### 三级标题:在 Windows 环境下使用 Android NDK 工具链交叉编译生成 Android 可用的 .so 文件 在 Windows 系统中使用 Android NDK 工具链进行交叉编译,可以生成适用于 Android 平台的 `.so` 动态库文件。以下是详细的实现流程: #### 1. 安装和配置 Android NDK 首先,需要下载与操作系统匹配的 Android NDK 版本,并将其解压到指定目录(如 `C:\myndk`)[^1]。推荐使用较新版本的 NDK(如 r23b),以确保兼容性和功能支持。 在 NDK 中,可以通过 `build/tools` 目录下的 `make-standalone-toolchain.sh` 脚本生成独立的交叉编译工具链。例如,生成适用于 `arm64` 架构的工具链命令如下: ```bash make-standalone-toolchain.sh --install-dir=C:\android-toolchain --arch=arm64 --platform=android-29 ``` 其中 `--install-dir` 指定工具链安装路,`--arch` 指定目标架构,`--platform` 指定 Android API 级别[^2]。 #### 2. 配置环境变量 为了方便后续的编译操作,需要将工具链的 `bin` 目录添加到系统环境变量中。例如,将以下路添加到 `PATH`: ```bash C:\android-toolchain\bin ``` 此外,可以设置 `TOOLCHAIN_PATH` 环境变量指向工具链的 `bin` 目录,并在系统环境中激活该变量[^2]。 #### 3. 使用 CMake 进行交叉编译 使用 CMake 可以更灵活地控制交叉编译过程。在 zlib 或其他库的源码目录中创建 `CMakeLists.txt` 文件,并配置以下参数: ```cmake set(CMAKE_SYSTEM_NAME Android) set(CMAKE_SYSTEM_VERSION 29) set(CMAKE_ANDROID_ARCH_ABI arm64-v8a) set(CMAKE_ANDROID_NDK C:/myndk) set(CMAKE_ANDROID_STL_TYPE gnustl_static) ``` 然后在命令行中执行以下命令进行编译: ```bash mkdir build cd build cmake .. make ``` 这样可以生成适用于 `arm64-v8a` 架构的 `.so` 文件。如需生成其他架构(如 `armeabi-v7a` 或 `x86_64`)的 `.so` 文件,只需修改 `CMAKE_ANDROID_ARCH_ABI` 和 `CMAKE_ANDROID_NDK` 的参数即可[^3]。 #### 4. 集成到 Android 项目中 将生成的 `.so` 文件放入 Android 项目的 `app/src/main/jniLibs` 目录中,并确保每个架构的 `.so` 文件放置在对应的子目录下(如 `armeabi-v7a`、`arm64-v8a`、`x86_64`)。 在 `build.gradle` 文件中配置 NDK 构建选项: ```gradle android { ... sourceSets { main { jniLibs.srcDirs = ['src/main/jniLibs'] } } } ``` 此外,在 `CMakeLists.txt` 中添加对 `.so` 文件的引用: ```cmake add_library(zlib SHARED IMPORTED) set_target_properties(zlib PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/jniLibs/${ANDROID_ABI}/libz.so) target_link_libraries(my_native_lib zlib) ``` 这样即可在 Android 应用中调用 zlib 提供的压缩功能。 ---
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值