交叉编译的前期比较痛苦,为了能让这个过程比较顺利,更好的了解整个过程,还是买一个服务器比较
设备准备
1.服务器 或者 mac 或者 Ubuntu
- root 后的手机
查看手机cup架构
需要手机root 权限
先执行 adb shell
再执行 cat /prof/cpuinfo
下载 ndk
https://dl.google.com/android/repository/android-ndk-r17c-linux-x86_64.zip?hl=zh-cn
wget 命令下载
下载完成后修改文件名 这里是为了去掉zip 后面的无用字符
mv android-ndk-r17c-linux-x86_64.zip?hl=zh-cn android-ndk-r17c-linux-x86_64.zip
使用unzip 解压ndk
使用vim 执行在测试目录下随便创建一个main.c 文件,接下来我们就按照流程打一个 arm 的 exe 执行文件
linux 编译exe 执行文件指令
gcc main.c -o mainEXE
但是这个包是无法提供给andorid 使用的,想要让android 能够使用,需要利用ndk 的交叉编译
交叉编译问题及解决办法
问题1:寻找 ndk 的gcc
目录 在ndk 下面的 toolchains 目录下面
-->
/root/NDK/android-ndk-r17c/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc
注意:这里需要选择cpu架构,需要按照指定的cpu架构使用
配置环境变量后,即可方便使用
此时定义的环境变量
export NDK="/root/NDK/android-ndk-r17c"
export android_target="android-26"
export NDK_ARM_GCC="$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc"
export NDK_ARM64_GCC="$NDK/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-gcc"
export NDK_X86_GCC="$NDK/toolchains/x86-4.9/prebuilt/linux-x86_64/bin/i686-linux-android-gcc"
编译命令如下
$NDK_ARM_GCC main.c -o mainEXE
问题2: 使用 ndk 的 gcc 在编译过程中找不到 <stdio.h>
原因是没有导入lib.so 的头文件与 库文件,需要将头文件与库文件放入到目录下
头文件目录-->android-ndk-r17c/sysroot/usr/include
库文件目录-->android-ndk-r17c/platforms/android-26/arch-arm/usr/lib
注意库文件需要根据cpu 架构与 android 的版本选择 我选择的是android 26 与 arm 的架构
环境变量新增如下配置
export NDK_CFIG_x86="--sysroot=android_target/arch-x86 -isystem $NDK/sysroot/usr/include"
export NDK_CFIG_arm="--sysroot=android_target/arch-arm -isystem $NDK/sysroot/usr/include"
export NDK_CFIG_arm64="--sysroot=android_target/arch-arm64 -isystem $NDK/sysroot/usr/include"
export NDK_ARM_COMMEND="NDK_CFIG_arm"
export NDK_ARM64_COMMEND="NDK_CFIG_arm64"
export NDK_X86_COMMEND="NDK_CFIG_x86"
编译命令如下
$NDK_ARM_COMMEND main.c -o mainEXE
问题3:在ndk gcc 编译过程 找不到 <asm/type.h>
asm 的目录在ndk 的 sysroot/usr/include 目录下 在这里需要选择cpu架构,我选择arm的架构
所以他的目录就是
/root/NDK/android-ndk-r17c/sysroot/usr/include/arm-linux-androideabi
修改环境变量配置
export NDK_CFIG_x86="--sysroot=android_target/arch-x86 -isystem NDK/sysroot/usr/include/i686-linux-android"
export NDK_CFIG_arm="--sysroot=android_target/arch-arm -isystem NDK/sysroot/usr/include/arm-linux-androideabi"
export NDK_CFIG_arm64="--sysroot=android_target/arch-arm64 -isystem NDK/sysroot/usr/include/aarch64-linux-android"
编译命令如下
$NDK_ARM_COMMEND main.c -o mainEXE
问题4:将打包出来的执行文件给android 使用过程中提示 需要新增 -PIE 参数
编译命令修改如下
$NDK_ARM_COMMEND -pie main.c -o mainEXE
这次编译执行文件在android 系统运行成功
接下来就需要打包 shared 动态库
动态库linux编译指令是
gcc -fPIC -shared 文件名 -o libxxx.so
根据上面的配置交叉编译的指令为
$NDK_ARM_COMMEND -fPIC -shared get.c -o libgetarm.so
动态库打包成功
静态库打包
打包静态库需要先打包 .o文件,linux 指令如下
gcc -fPIC -c get.c -o get.o
使用get.o 打包get.c 文件,注意这里git.o 需要放在后面
ar -rcs -o get.a get.o
修改后获取.o文件的交叉编译指令如下
$NDK_ARM_COMMEND -fPIC -c get.c -o libget.o
ndk 的 ar 工具 与gcc 在共一个目录下面
需要新增环境变量
export NDK_AR_ARM="$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ar"
export NDK_AR_ARM64="$NDK/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-ar"
export NDK_AR_X86="$NDK/toolchains/x86-4.9/prebuilt/linux-x86_64/bin/i686-linux-android-ar"
修改后的编译指令为
$NDK_AR_ARM rcs -o libget.a libget.o
成功后使用sz将 .a文件与 .so文件保存在桌面就可以开始使用了