一、本地编译 与 交叉编译
1、本地编译
" 本地编译 " 指的是 在 目标系统 上进行编译的过程 , 生成的 可执行文件 和 函数库 只能在 目标系统 中使用 ;
如 :
- 在 Ubuntu 中 本地编译 的 可执行文件 只能在 Ubuntu 系统中执行 , 无法在 Windows / Mac / Android / iOS 系统中使用 ;
- 在 Ubuntu 中 本地编译 的 函数库 , 只能在 Ubuntu 本地开发环境中导入并使用 , 无法在其它系统中使用 ;
" 本地编译 " 不涉及 跨平台编译 或 跨体系结构编译 , 因此 不需要考虑目标系统的差异 ;
- 跨平台 指的是 不同的操作系统平台 , 如 : Windows 平台 , Linux 平台 , MacOS 平台 , Android 平台 ;
- 跨体系结构 指的是 不同的 CPU 架构 , 如 : x86 架构 , arm 架构 , x86_64 架构 , arm64 架构 ;
" 本地编译 " 的 编译器 和 编译工具链 与 本地系统的 体系结构 和 操作系统相匹配 , 编译过程简单直接 , 无须配置交叉编译相关选项 , 编译出来的 可执行文件 和 函数库 可直接使用 ;
" 本地编译 " 常用场景 :
- 在 Ubuntu 中编译 Linux 中使用的 可执行文件 和 函数库 ;
- 在 Windows 中编译 Windows 中使用的 可执行文件 和 函数库 ;
- 在 MacOS 中编译 MacOS 中使用的 可执行文件 和 函数库 ;
注意 : Android 和 iOS 必须使用交叉编译 , 无法进行本地编译 ;
2、交叉编译
" 交叉编译 " 是 在 本地系统 上 编译生成 适用于 另外一种 不同体系结构或操作系统 的 可执行文件 和 函数库 ;
交叉编译 使用场景 :
- 嵌入式系统
- 移动开发
- 跨平台开发
" 交叉编译 " 需要考虑 不同平台之间的差异 , 包括 体系结构 / 操作系统 / 依赖库 等因素 ;
" 交叉编译 " 需要准备的资源 :
- 交叉编译工具链 : 特定的编译器 , 在 A 系统编译 B 系统的函数库 , 与 B 系统编译 A 系统的函数库 和 A 系统 编译 C 系统的函数库 , 三者所用的 编译器 是不同的 ;
- 头文件 : 特定交叉编译工具链 自带的 目标系统的 头文件 ;
- 依赖库 : 特定交叉编译工具链 自带的 目标系统的 依赖库文件 , 需要与头文件匹配 ;
在交叉编译中 , 需要使用交叉编译工具链 , 并手动配置编译选项以适应目标系统的要求 , 同时还要提供 符合交叉编译要求的 头文件 和 对应的函数库 ;
3、Android 交叉编译需要的工具
在 Ubuntu 中进行 Android 平台的 C/C 函数库的交叉编译时 , 使用的工具如下 :
- 交叉编译工具链 : android-ndk-r17c/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc , 这是 Google 提供的 Android NDK 中附带的 交叉编译工具 , 编译器名称 arm-linux-androideabi-gcc 说明 该编译器 只能在 Linux 系统中编译 arm 架构的 android 平台的 可执行程序 或者 函数库 ;
- 头文件 : android-ndk-r17c/sysroot/usr/include 和 android-ndk-r17c/sysroot/usr/include/arm-linux-androideabi 目录下的文件 , 就是交叉编译时 , 使用到的头文件 ;
- 依赖库 : android-ndk-r17c/platforms/android-21/arch-arm 就是依赖库所在的目录 , 每个 Android 版本有不同的依赖库目录 , 这里使用 android-21 版本的依赖库 ;
交叉编译时 , 为 gcc 或 g 编译器设置 如下参数 , 指定 头文件 和 库文件 的 搜索路径 :
代码语言:javascript复制--sysroot=/home/book/NDK/android-ndk-r17c/platforms/android-21/arch-arm -isystem /home/book/NDK/android-ndk-r17c/sysroot/usr/include -isystem /home/book/NDK/android-ndk-r17c/sysroot/usr/include/arm-linux-androideabi
--sysroot
参数 用于指定 系统根目录 , 用于 寻找标准头文件 , 库文件 和 其他系统资源 ;-isystem
参数 用于添加 系统头文件搜索路径 , 与 -I 参数指定的头文件的区别是 , -isystem 指定的路径会被编译器认为是系统头文件的路径 , 编译器在编译时会忽略警告信心 ;
二、FFmpeg 指定目标平台的编译配置参数
1、FFmpeg 交叉编译配置回顾
这是在 【Android FFMPEG 开发】FFMPEG 交叉编译配置 ( 下载 | 配置脚本 | 输出路径 | 函数库配置 | 程序配置 | 组件配置 | 编码解码配置 | 交叉编译配置 | 最终脚本 ) 博客中 , 使用到的 在 Ubuntu 平台 交叉编译 Android 平台的 函数库 的 编译配置 ;
代码语言:javascript复制# NDK 根目录
NDK_ROOT=/root/NDK/android-ndk-r17c
# TOOLCHAIN 变量指向 gcc g 等交叉编译工具所在的目录
TOOLCHAIN=$NDK_ROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
# gcc 编译器参数
FLAGS="-isysroot $NDK_ROOT/sysroot -isystem $NDK_ROOT/sysroot/usr/include/arm-linux-androideabi -isystem $NDK_ROOT/sources/android/support/include -D__ANDROID_API__=21 -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -mthumb -Wa,--noexecstack -Wformat -Werror=format-security -O0 -fPIC"
# 编译结果输出路径
PREFIX=./android/armeabi-v7a
# 执行 configure 脚本生成 Makefile 构建脚本
./configure
--prefix=$PREFIX
--enable-small // 启用精简模式,减小生成的库的体积
--disable-programs // 禁用生成可执行程序
--disable-avdevice // 禁用音视频设备支持
--disable-encoders // 禁用编码器
--disable-muxers // 禁用复用器
--disable-filters // 禁用滤镜
--enable-cross-compile // 启用交叉编译
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- // 指定交叉编译工具链的前缀
--sysroot=$NDK_ROOT/platforms/android-21/arch-arm // 指定 Android NDK 中 Android 21 版
--extra-cflags="$FLAGS" // 额外的编译选项 , 用于设定 gcc 编译器的其它编译选项
--arch=arm // 指定目标体系结构为 ARM
--target-os=android // 指定目标操作系统为 Android
交叉编译 相关的配置 :
--enable-cross-compile
配置 启用 交叉编译 ;--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi-
配置 交叉编译工具链的前缀 ;--sysroot
配置 交叉编译工具链 的 头文件 和 函数库 搜索路径 ;--extra-cflags="$FLAGS"
配置 gcc / g 编译器的 额外选项 ;--arch=arm
配置要编译 arm 架构的 可执行程序 和 函数库 ;--target-os=android
配置 指定要编译的目标系统为 Android 系统 ;
2、配置目标 CPU 架构 --arch
--arch
参数 用于配置 目标 CPU 架构 , 常用的 配置值 有 :
- x86 : 32 位 x86 架构 ;
- x86_64 / amd64 : 64 位 x86 架构 ;
- arm : 32 位 ARM 架构 ;
- arm64 : 64 位 ARM 架构 ;
- ppc : PowerPC 架构 ;
- ppc64 : 64 位 PowerPC 架构 ;
3、配置目标操作系统 --target-os
--target-os
配置 目标操作系统 , 可选的配置选项有 :
- linux : 编译目标系统是 Linux 操作系统 ;
- darwin / macosx : 编译目标系统是 macOS 操作系统 ;
- windows : 编译目标系统是 Windows 操作系统 ;
- android : 编译目标系统是 Android 操作系统 ;
- ios : 编译目标系统是 iOS 操作系统 ;