Android NDK交叉编译

– 下面是分析了,不是是去允许:
export NDK_GCC=”/root/DerryAll/NDK26/tool/android-ndk-r17c/toolchains/arm-linuxandroideabi-4.9/
prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc” 【用NDK专用的gcc】
export AAA=”–sysroot=/root/DerryAll/NDK26/tool/android-ndkr17c/platforms/android-21/arch-arm 【寻库文件头文件】
-isystem /root/DerryAll/NDK26/tool/android-ndk-r17c/sysroot/usr/include 【寻找头
文件】
-isystem /root/DerryAll/NDK26/tool/android-ndk-r17c/sysroot/usr/include/armlinux-androideabi”【C运行期 寻找asm】

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

## 配置环境变量`/etc/profile`

环境变量配置交叉编译`GCC`

```latex
export NDK_GCC_x86="$NDK/toolchains/x86-4.9/prebuilt/linux-x86_64/bin/i686-
linux-android-gcc" 【i686-xx x86=32】

export NDK_GCC_x64="$NDK/toolchains/x86_64-4.9/prebuilt/linux-x86_64/bin/x86_64-
linux-android-gcc" 【x86_64-xx x86_64=64】

以后我们会操作这两个CPU架构平台

export NDK_GCC_arm="$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linuxx86_64/bin/arm-linux-androideabi-gcc" 【Derry的手机arm32 == arm-linuxandroideabi-gcc】

export NDK_GCC_arm_64="$NDK/toolchains/aarch64-linux-android-4.9/prebuilt/linuxx86_64/bin/aarch64-linux-android-gcc" 【arm64 == aarch64-linux-android-gcc】

环境变量配置库路径

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
export NDK_CFIG_x86="--sysroot=$NDK/platforms/android-21/arch-x86 -isystem
$NDK/sysroot/usr/include -isystem $NDK/sysroot/usr/include/i686-linux-android"
【i686-xx x86=32】

export NDK_CFIG_x64="--sysroot=$NDK/platforms/android-21/arch-x86_64 -isystem
$NDK/sysroot/usr/include -isystem $NDK/sysroot/usr/include/x86_64-linux-android"
【x86_64-xx x86_64=64】

以后我们会操作这两个CPU架构平台

export NDK_CFIG_arm="--sysroot=$NDK/platforms/android-21/arch-arm -isystem
$NDK/sysroot/usr/include -isystem $NDK/sysroot/usr/include/arm-linuxandroideabi"
【Derry的手机arm32 == arm-linux-androideabi-gcc】

export NDK_CFIG_arm_64="--isysroot=$NDK/platforms/android-21/arch-arm64 -isystem
$NDK/sysroot/usr/include -isystem -isystem $NDK/sysroot/usr/include/aarch64-
linux-android" 【arm64 == aarch64-linux-android-gcc】

交叉编译输出动态库

【get.h】

1
2
#include<studio.h>
int get();

【get.c】

1
2
3
4
#include "get.h"
int get(){
return 123456;
}

普通编译输出动态库

1
2
3
4
5
6
7
8
9
10
lautung@PC:/NDK01$ sudo gcc -fPIC -shared get.c -o libget.so
lautung@PC:/NDK01$ ll
total 32
drwxr-xr-x 2 root root 4096 Jun 5 17:08 ./
drwxr-xr-x 20 root root 4096 Jun 5 16:54 ../
-rw-r--r-- 1 root root 50 Jun 5 17:08 get.c
-rw-r--r-- 1 root root 30 Jun 5 17:08 get.h
-rwxr-xr-x 1 root root 15640 Jun 5 17:08 libget.so*
lautung@PC:/NDK01$ file libget.so
libget.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=292ab878cd41137679c70bfcaa6e887dd1b9a47c, not stripped

交叉编译Android平台使用的动态库

1
2
3
4
lautung@PC:/$ echo $NDK_GCC
/home/lautung/android-ndk-r17c/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-gcc
lautung@PC:/$ echo $NDK_CFIG
--isysroot=/home/lautung/android-ndk-r17c/platforms/android-21/arch-arm -isystem /home/lautung/android-ndk-r17c/sysroot/usr/include -isystem /home/lautung/android-ndk-r17c/sysroot/usr/include/aarch64-linux-android
1
2
3
4
5
6
7
~# $NDK_GCC_arm $NDK_CFIG_arm -fPIC -shared
get.c -o libgetndk.so
~# ls
get.c get.h libgetndk.so libget.so main.c mainEXE mainNDKEXE tool
~# file libgetndk.so
libgetndk.so: ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically
linked (uses shared libs), not stripped

交叉编译输出静态库

普通编译静态库

第一步:必须有目标文件 xxx.o。

1
gcc -fPIC -c get.c -o get.o 【-c 产生目标文件 xxx.o -o 输出get.o】

第二步:依靠xxx.o 才能生成静态库。

1
ar rcs -o libget.a get.o 【get.o是静态库需要生成的源文件,并不是 xxx.c】

NDK交叉编译静态库

1
2
3
4
5
6
7
export NDK_AR_x86="$NDK/toolchains/x86-4.9/prebuilt/linux-x86_64/bin/i686-linuxandroid-ar"

export NDK_AR_x64="$NDK/toolchains/aarch64-linux-android-4.9/prebuilt/linuxx86_64/bin/aarch64-linux-android-ar"

export NDK_AR_arm="$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linuxx86_64/bin/arm-linux-androideabi-ar"

export NDK_AR_arm_64="$NDK/toolchains/aarch64-linux-android-4.9/prebuilt/linuxx86_64/bin/aarch64-linux-android-ar"
1
2
$NDK_AR_arm rcs -o xxxx.a get.o 【get.o是Linux打出来的目标文件,没有经过交叉编译,AS上运
行才会报错,错误很难找】

第一步:必须使用NDK交叉编译 打出 xxx.o。

1
$NDK_GCC_arm $NDK_CFIG_arm -fPIC -c get.c -o getndk.o

第二步:编译静态库即可。

1
$NDK_AR_arm rcs -o libgetndk.a getndk.o

Android Studio的CMake配置动态库和静态库

Cmake导入静态库 动态库:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
cmake_minimum_required(VERSION 3.4.1)

# 批量导入
file(GLOB allCPP *.cpp)

add_library(
native-lib
SHARED
${allCPP})

find_library(
log-lib
log)

#[[# 导入静态库 【第二方式】 可读性更强,代码多
add_library(getndk STATIC IMPORTED)

# 开始真正导入 静态库
set_target_properties(getndk PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/libgetndk.a)]]

# 导入动态库 【第二方式】 可读性更强,代码多
add_library(getndk SHARED IMPORTED)
set_target_properties(getndk PROPERTIES
IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/../jniLibs/${CMAKE_ANDROID_ARCH_ABI}/libgetndk.so)


# QQ变声就是这样导入库的 【第一种方式】 简洁,不好理解
# set(CMAKE_CXX_FLAGS )

target_link_libraries(
native-lib
${log-lib}
getndk # 链接此静态库 到 总库 libnative-lib.so
)

CPU平台:

1
2
3
4
5
6
7
8
9
10
externalNativeBuild {
cmake {
// cppFlags "" // 默认包含四大平台
abiFilters "armeabi-v7a"
}
}

ndk {
abiFilters "armeabi-v7a"
}

参考

  1. 享学课堂