OSX(Macos) 下编译 WebRTC - Android

美景总是好的

介绍

这段时间基于 Mediasoup 的开源又搞了一遍 WebRTC 的客户端的搭建, 需要支持 iOS, Android, Windows各平台的使用, 这次可以基于较新(M99) 的 WebRTC 版本封装 SDK.

WebRTC 的官方编译这不同系统的 SDK, 也是需要几个操作系统(OSX, Linux, Windows)的环境支持, 如果长期需要三个系统支持编译切换起来也麻烦了. 网上有用虚拟机编译的, 但本人对虚拟机的性能一直比较不看好(虚拟机用的也不熟), 所以还是最好能直接在 OSX 上支持.

在猿辅导的时候是通过阉割了 WetRTC 工具链中的所有 Java支持的部分, 只保留了 C++ 的支持, 可以统一在 OSX 上编译 iOS, Mac, Android, 对于开发环的简化和统一确实起到了一些作用.

这次还是想彻底搞一搞(当然 Windows 环境暂时没办法做交叉编译, 还是需要 Windows 环境), 主要针对是 OSX 上编译 WebRTC Android, 因为计划 JNI 的框架也使用 WebRTC 里的 generate jni 的这套流程, 所以需要保留对 Java, Android 的完整支持, 编译的时候直接有检查 JNI 的错误, 对于开发来说能提早暴露出不少问题.

目录

修改内容主要真对下面三个大的分类

  • 环境准备
  • 工具链修改
  • gn gen 命令行参数

环境准备

WebRTC 代码准备

创建两个目录分别执行 fetch webrtc_android, fetch webrtc_ios, 我们下面就直接称为 webrtc_android 和 webrtc_ios.

切换到同一分支后使用 gclient sync 进行工具链的同步, 使用 webrtc_ios 为基础, 毕竟这是标准的 Macos 环境工具链.

根目录 .cipd 目录

webrtc_android 目中 gclient sync 后, third_party 有些内容会软连接到根目录下的 .cipd 里的内容, 把 .cipd 目录直接覆盖到 webrtc_ios 目录中.

ios 的 .cipd 没什么用直接替换就行了.

third_party 合并

webrtc_android/third_party 目录下的 android 开头的一些目录直接 覆盖掉 webrtc_ios/third_party

编译中还会有个别缺失的, 可以根据报错信息再覆盖过去, 例如 libunwindstack.

Android NDK & SDK

webrtc_android/src/third_party/android_ndk, webrtc_android/src/third_party/android_sdk 是 WebRTC 编译 Android 用的 NDK, SDK, 目前NDK版本是 22, 但这是 Linux 版本, 不能在 Macos 上使用.

手动下载 Android NDK, 我们使用自定义的 NDK

目前测试 NDK23,24编译还有问题, 如果有需要可以自行研究下, 或者等 Google 更新工具链.

JDK

  • 手动下载 JDK, 需要11 或者以后的版本, 替换到 third_party/jdk/current 目录下
  • 下载 jdk8, 解压缩后找到里面的 rt.jar, 也 copy 到 third_party/jdk/current 目录下

rt.jar 在 jdk8 版本后已经从 jdk 里删除了

AAPT2

AAPT2(Android Asset Packaging Tool)是Android Studio和Android Gradle Plugin用于编译和打包应用程序资源的构建工具。
https://developer.android.com/studio/command-line/aapt2

手动下载 OSX 的 aapt2 替换到 third_party/android_build_tools/aapt2

好了... 环境这就准备的差不多了...下面开始需要修改一些编译的脚本.

工具链修改

third_party 目录

third_party/ijar/BUILD.gn
if (is_linux || is_chromeos) {
  ...
}

这个环境判断条件, 直接注释掉, 否则当执行到ijar 的时候会报错.

third_party/android_sdk/BUILD.gn
# public_deps = [ "$android_ndk_root:cpu_features" ]
public_deps = [ "//third_party/android_ndk:cpu_features" ]

因为我们用官方下载的 NDK 是没有 cpu_features 的 gn 配置, 我们可以继续用原有 third_party 目录下的配置, 但因为我们后面会修改掉 android_ndk_root 的环境变量, 所以改成直接引用绝对路径.

build 工具链配置

build/android/gyp/util/build_utils.py

根据自己放 rt.jar 位置修改 RT_JAR_PATH.

# RT_JAR_PATH = os.path.join(DIR_SOURCE_ROOT, 
# 'third_party', 'jdk', 'extras', 'java_8', 'jre', 'lib', 'rt.jar')
RT_JAR_PATH = os.path.join(JAVA_HOME, 'rt.jar')
build/android/gyp/util/server_utils.py

注释掉这一段.

-  if BUILD_SERVER_ENV_VARIABLE in os.environ:
-    return False
-  with contextlib.closing(socket.socket(socket.AF_UNIX)) as sock:
-    try:
-      sock.connect(SOCKET_ADDRESS)
-      sock.sendall(
-          json.dumps({
-              'name': name,
-              'cmd': argv,
-              'cwd': os.getcwd(),
-              'stamp_file': stamp_file,
-          }).encode('utf8'))
-    except socket.error as e:
-      # [Errno 111] Connection refused. Either the server has not been started
-      #             or the server is not currently accepting new connections.
-      if e.errno == 111:
-        return False
-      raise e
build/config/c++/BUILD.gn

不使用 buildtools 下的 c++ 标准库实现, 统一使用自己下载的 NDK.

+  if (!(is_android && host_os == "mac")) {
     include_dirs += [ "//buildtools/third_party/libc++" ]
+  }
+  if (!(is_android && host_os == "mac")) {
      cflags_cc += [
        "-nostdinc++",
        "-isystem" + rebase_path("$libcxx_prefix/include", root_build_dir),
        "-isystem" + rebase_path("$libcxxabi_prefix/include", root_build_dir),
      ]
+  }
build/compiler/BUILD.gn

NDK22 的 clang version 是11, 有些选项是不支持.

...
-  cflags += [ "-mno-outline-atomics" ]   // clang 12.0.0 支持
... 

-  cflags += [ "-ffile-compilation-dir=." ] // clang 13.0.0 支持

...

-  cflags += [
-    "-Xclang",
-    "-fuse-ctor-homing", // clang 13.0.0 支持
-  ] 

个别不支持警告也可以适当关闭.
"-Wno-unused-but-set-variable",

gn gen 命令行参数

clang_use_chrome_plugins

使用官方下载的 NDK, 内部的 clang 是没有 google 添加的 plugin, 这里要禁用

clang_use_chrome_plugins=false
use_lld

NDK 22 LLD 现在是默认链接器, 不需要显式设置 use_lld

use_lld=false
use_custom_libcxx

使用 NDK 带的 c++ 标准库, 禁用 buildtools 下的.

use_custom_libcxx=false
Android SDK

使用自定义的 SDK, 根据自己使用的路径和 buildtools 版本设置

android_sdk_root="${ANDROID_SDK_ROOT}"
android_sdk_version="32"
android_sdk_build_tools_version="32.0.0"
Android NDK

使用自定义的 NDK, 根据自己使用的路径和版本设置

clang_base_path="${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/darwin-x86_64"
target_sysroot="${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/darwin-x86_64/sysroot"
android_ndk_root="${ANDROID_NDK_ROOT}"
android_ndk_major_version=22
gn gen 例子

到这里基本配置已经修改的差不多了, 可以在 OSX 上也像 Linux 上一样的对 Android 进行支持了. 下面是 gn gen 生成 Android 工程的一个例子(debug 版本), 包含了上面的一些设置, 和和其他平台共用的一些设置, 作为参考:

gn gen out/android/debug/arm64 --args="target_cpu="arm64" target_os="android" rtc_include_ilbc=false rtc_build_examples=false rtc_build_tools=false rtc_enable_protobuf=false rtc_enable_sctp=false rtc_include_tests=false libyuv_include_tests=false rtc_disable_trace_events=true enable_dsyms=true rtc_use_h264=true rtc_build_x264=true ffmpeg_branding="Chrome" treat_warnings_as_errors=false clang_use_chrome_plugins=false use_lld=false use_custom_libcxx=false clang_base_path="/Users/edy/Library/Android/sdk/ndk/22.1.7171670/toolchains/llvm/prebuilt/darwin-x86_64" target_sysroot="/Users/edy/Library/Android/sdk/ndk/22.1.7171670/toolchains/llvm/prebuilt/darwin-x86_64/sysroot" android_ndk_root="/Users/edy/Library/Android/sdk/ndk/22.1.7171670" android_ndk_major_version=22 android_sdk_root="/Users/edy/Library/Android/sdk" android_sdk_version="32" android_sdk_build_tools_version="32.0.0" symbol_level=2 is_debug=true"

结束语

这些流程是通过事后的一些修改记录整理出来的, 如果有什么遗漏或者不同 arch 的问题, 各位看官们可以评论, 后面也会进行补充和修改.
需要替换和修改的东西并不多, 不清楚为什么 Google 不从官方直接支持, 可以省去大家不少事.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,277评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,689评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,624评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,356评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,402评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,292评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,135评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,992评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,429评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,636评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,785评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,492评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,092评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,723评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,858评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,891评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,713评论 2 354

推荐阅读更多精彩内容