mac环境

如何在 Android Studio 里单步调试 WebRTC Android 的 native 代码。

WebRTC 代码下载

  • depot tools 是 chromium 代码库管理工具,包括代码管理、依赖管理、工作流程管理等;
  • Android/Linux、Windows、iOS/macOS WebRTC 本身的代码是同一个仓库,但依赖工具不同,所以不可能放到一起,我的移动硬盘里就有 webrtc_android 和 webrtc_ios 两个目录,一共 46 GB;
  • depot tools 的运行基于 python 2.x 环境,且需要是官方 build(--version 选项不能输出额外信息);
  • 各个系统的 buildtools 是需要运行 gclient runhooks 进行下载的,而且是自动检测运行时的系统,只下载当前系统的;
  • gn/clang format 下载地址:https://storage.googleapis.com/chromium-clang-format/0679b295e2ce2fce7919d1e8d003e497475f24a3 , https://storage.googleapis.com/chromium-gn/9be792dd9010ce303a9c3a497a67bcc5ac8c7666 , 替换 hash 值即可,其他 download_from_google_storage 的步骤都可以这样解决(替换 bucket 和 hash);

顺便说说我下载代码的方式:

  • 首先准备一台可上网的路由器,我的是华硕 RT-AC68U + koolshare 380.63_0-X7.2(升级后 format jffs at next boot 并重启) + 离线安装***插件
  • 然后在阿里云香港开一个按量付费的最低配云主机,0.07 元/小时,流量 1 元/GB,速度很快,能到 MB/s 级别,完整下载花费也不会超过 50 元,下完之后释放;
  • 把配好 ss 及 ss 自启动的镜像做成自定义镜像,并创建创建实例模板,再需要更新代码时一键启动无需配置,只需到路由器后台改下 IP 即可;
  • 有了这个环境之后,也就可以轻松给 WebRTC 提交 patch 了,我都提交了好几个 patch 了

Xcode 调试 WebRTC iOS demo

  • src/examples/BUILD.gn 中,搜索 ios_app_bundle("AppRTCMobile"),为其中增加以下内容(bundle id 设置为实际使用的独特 id):

extra_substitutions = [ "PRODUCT_BUNDLE_IDENTIFIER=com.github.piasy.AppRTCMobile", ]

  • src 目录下执行 gn gen out/xcode_ios_arm64 --args='target_os="ios" target_cpu="arm64"' --ide=xcode;
  • 用 Xcode 打开 src/out/ios/all.xcworkspace,run target 选择 AppRTCMobile,工程文件的设置 target 也选择 AppRTCMobile;
  • 修改 src/examples/objc/AppRTCMobile/ios/Info.plist,设置同样的 bundle id;
  • 在工程文件的 general tab 中,手动选择 Info.plist 为 src/examples/objc/AppRTCMobile/ios/Info.plist;选择了 plist 之后,可能 Xcode 不会显示 bundle id 等信息,这是 Xcode 的一个小 bug,先查看一个其他文件,再查看工程文件,就能看到了;
  • 勾选「Automatically manage signing」,选择合适的 team;
  • 点击 run 即可,和调试普通 iOS app 一样;
  • clean 工程并不会清除 ninja 脚本编译的结果,所以不必担心耗时;
  • 更新代码后,可能需要删掉老的 src/third_party/llvm-build/ 目录,然后执行 gclient run_hooks 下载新的 llvm;
  • 在 examples/objc/AppRTCMobile/ARDAppEngineClient.m 里,修改 kARDRoomServerHostUrl, kARDRoomServerJoinFormat, kARDRoomServerJoinFormatLoopback, kARDRoomServerMessageFormat, kARDRoomServerLeaveFormat 这四个变量的域名为实际部署的 AppRTC server 域名/地址,即可连接自己的 server;

Android Studio 调试 WebRTC Android demo

首先,官方有个 issue,讲的就是 Android Studio 的支持,遗憾的是现在还没有解决方案。

但是,不就是编译么,手写一个 CMakeLists.txt 就好了嘛(在此省略描述编写 CMakeLists.txt 过程中解决各种问题的五千字)。

写好了的 CMakeLists.txt 和 build.gradle 就在这里!就在这里!!就在这里!!!超链接文字这么长,应该能点到吧 :)

注:这个 CMakeLists.txt 基于 #24277 提交,且只适配了 arm64-v8a 架构,其他代码版本、架构可能存在问题,不保证可以使用。此外,一定要搭配工程里的 build.gradle 使用,因为还要靠它生成一些代码。

不过 clone 下来之后,别急着用 Android Studio 打开,首先要修改一下 libjingle_peerconnection/build.gradle,设置以下变量:

  • webrtc_repo: WebRTC Android 代码仓库路径;
  • android_jar: Android SDK 的 android.jar 路径;
  • py2: Python 2.x 可执行文件的路径;
  • protoc: protobuf 编译程序的路径,注意它的版本需要和 WebRTC 代码库匹配,我没找到这个程序在代码库里的位置,但我发现用 gn + ninja 编译一次后,会在 out/dir/clang_x64 目录下生成这个程序;

修改完了 build.gradle 之后也不要着急,还要修改 Android Studio 启动配置,编辑 ~/Library/Preferences/AndroidStudio3.1/studio.vmoptions(替换为正确版本),修改 -Xms, -Xmx, -XX:MaxPermSize, -XX:ReservedCodeCacheSize 这四个参数:

-Xms4096m-Xmx14336m-XX:+UseG1GC-XX:-UseParNewGC-XX:-UseConcMarkSweepGC-XX:MaxPermSize=4096m-XX:ReservedCodeCacheSize=2048m-XX:+UseCompressedOops-XX:-OmitStackTraceInFastThrow-Dsun.io.useCanonCaches=false

最后,还要把 CMakeLists.txt 的内容注释了一部分后再打开,sync 成功后解除一部分注释,再 sync,再解除注释,否则 Android Studio build symbols 一整天也不见完。当然,土豪顶配 MBP 也许可以直接打开。

对了,我使用的 Android Studio 版本是 3.1.4。

好了,为了表达我激动的心情,放上一个录屏视频:

macOS 下 用 gn + ninja 编译 WebRTC Android

Android Studio 的调试毕竟只是为了加断点做一些流程分析,而且写出来的 CMakeLists.txt 和 build.gradle 也只能算是一个临时解决方案,靠谱的编译方式,还得是 gn + ninja,

  • 先在 docker 镜像里 sync 好 linux 的版本(直接在 macOS 里下载我猜应该也可以,但我没试过,欢迎大家尝试后分享结果);
  • 创建 src/third_party/android_tools_mac 目录,并把 macOS 的 ndk 和 sdk 放入其中;
  • 修改 src/build/config/android/config.gni:

declare_args() { android_ndk_root = "//third_party/android_tools_mac/ndk" android_ndk_version = "r16" android_ndk_major_version = 16 android_sdk_root = "//third_party/android_tools_mac/sdk" android_sdk_version = 28 android_sdk_build_tools_version = "27.0.3" android_sdk_tools_version_suffix = "-26.0.0-dev" lint_android_sdk_root = "//third_party/android_tools_mac/sdk" lint_android_sdk_version = 26

  • 修改 src/build/toolchain/gcc_solink_wrapper.py 末尾部分:

# Finally, strip the linked shared object file (if desired).ifargs.strip:result=subprocess.call(wrapper_utils.CommandToRun([args.readelf[:-7]+"strip",'-o',args.output,args.sofile]))

  • 下载 src/buildtools/mac 下定义版本的 macOS 版的 clang-format 和 gn,下载方法见上文;
  • 本地 build llvm,因为下载的 macOS 版本都没有 llvm-ar 这个程序,build 命令:env LLVM_FORCE_HEAD_REVISION=1 ./src/tools/clang/scripts/update.py;
  • 把 $JAVA_HOME/bin 加到 PATH /usr/bin 的前面,这样找到的就会是正确的 jdk 路径,就能找到 rt.jar 了,否则会报错 No such file or directory: '/System/Library/Frameworks/JavaVM.framework/Versions/A/jre/lib/rt.jar';
  • 确保在 Python 2.x 的 shell 里执行 gn 和 ninja 即可编译;

Windows 编译和使用静态库

  • 首先可能会提示 winsock.h 和 winsock2.h 里的符号重定义,这是因为 windows.h 在 winsock2.h 之前被 include 导致的,我们在包含 WebRTC 头文件之前,先 #include winsock2.h 即可;
  • 对 std min max 的使用导致 error C2589: '(' : illegal token on right side of '::' 错误,在项目中增加 NOMINMAX 宏定义即可解决;
  • 对 av_err2str() 的使用会导致 error C4576: a parenthesized type followed by an initializer list is a non-standard explicit type conversion syntax 错误,暂时无解,只能去掉;
  • ninja 编出来的 webrtc.lib 太小(7MB 左右),且 VS 提示文件已损坏……我发誓之前编译成功过一个版本,但后来突然就不行了,已弃疗,不过论坛里的这个帖子也许有用;

https://blog.piasy.com/2018/08/14/build-webrtc/

Android Studio xcode单步调试 WebRTC Android & iOS的更多相关文章

  1. LINUX上使用GDB单步调试Chromium Android C++代码。

    ###动机###在LINUX使用GDB单步调试Chromium Android C++代码. [1]编译android平台Chromium, 修改GN文件中编译选项:-g -O0 使得编译优化更少,便 ...

  2. Mac android studio真机调试步骤

    Mac android studio真机调试步骤 这些步骤是在百度中查找的,当时记录下来了,过了个把月了,今天写出来,我也重温步骤. 1.找到android的SDK路径,一般是 /user/你的电脑名 ...

  3. Android Studio连接手机调试教程已决解

    Android Studio连接手机调试教程 Windows电脑连接安卓手机需要下载安装驱动,确保电脑联上网络. 准备条件: 1.电脑上安装应用宝软件. 2.手机开发者选项里面打开USB调试,USB安 ...

  4. android studio 导入一个已有的android studio project作为lib使用

    android studio 导入一个已有的android studio project作为lib使用 新项目来了. 需要搭建框架. android studio对我来说还是很陌生,之前一个项目在同事 ...

  5. 【Android Studio使用教程3】Android Studio的一些设置 体验更好了

    Android Studio 简单设置 界面设置 默认的 Android Studio 为灰色界面,可以选择使用炫酷的黑色界面. Settings --> Appearance --> T ...

  6. xcode单步调试快捷键

    xcode单步调试快捷键f6,但是磨人f6是用来调节键盘亮度的,在系统偏好,键盘设置里面,做如下设置就可以了.

  7. 解决Android Studio Conflict with dependency 'com.android.support:support-annotations'报错

    解决Android Studio Conflict with dependency 'com.android.support:support-annotations'报错 在Android Studi ...

  8. Android studio 安装与配置【Android学习入门】

    终于下定决心认真学习Android开发了. 之前在很多平台看到很多大牛们学习Android的经验和心得,纸上得来终觉浅. 这里推荐stormzhang老师总结的Android学习之路. 为了防止电脑卡 ...

  9. 使用 Android Studio 开发工具创建一个 Android 应用程序,显示一行文字“Hello Android”,并将应用程序的名称更改为“FirstApp”。

    需求说明: 使用 Android Studio 开发工具创建一个 Android 应用程序,显示一行文字"Hello Android",并将应用程序的名称更改为"Firs ...

随机推荐

  1. ELK收集mysql_slow.log

    关于慢查询的收集及处理也耗费了我们太多的时间和精力,如何在这一块也能提升效率呢?且看本文讲解如何利用ELK做慢日志收集. ELK 介绍 ELK 最早是 Elasticsearch(以下简称ES).Lo ...

  2. haproxy 关闭ssl3

    在使用的过程中,我们发现在用IE浏览器的时候 我们设置成 然后我们的网站会出现部分页面不出来 然后我们也发现在扫面网站链接的时候 所以当务之急是关闭ssl3 我这里的反向代理使用的是haproxy 版 ...

  3. 单例模式在JDBC数据库连接操作里的应用

    设计模式之单例模式一般应用在在数据库操作里,数据库操作就要常常创建实例,然后进行数据库操作,全部就能够 将数据库操作的方法.进行封装,然后採用单例模式进行设计,然后採用单例模式之后,就能够节约系统资源 ...

  4. k8s相关文档

    kube-dns组件架构区别看这个就够了 http://cizixs.com/2017/04/11/kubernetes-intro-kube-dns kubed-dns设置细节看这个就够了 http ...

  5. STL学习笔记— —无序容器(Unordered Container)

    简单介绍 在头文件<unordered_set>和<unordered_map> 中定义 namespace std { template <typename T, ty ...

  6. [Windows Azure] Building the web role for the Windows Azure Email Service application - 3 of 5

    Building the web role for the Windows Azure Email Service application - 3 of 5. This is the third tu ...

  7. javascript基础拾遗(十二)

    1.javascript的单线程特性 在javascript中,所有的代码都是单线程的 因此所有的网络操作,浏览器事件,都必须是异步执行的,异步执行的逻辑是回调. function callback( ...

  8. iOS应用管理(字典转模型)

    1. 新建appViewModel 1.1声明需要的属性 //NSString一般用copy来修饰 @property(nonatomic,copy)NSString *name; @property ...

  9. python类里面使用装饰器

    参考:http://m.blog.csdn.net/blog/wklken/8118942 def on(name, *args_of_on, **kwargs_of_on): def handle_ ...

  10. 当滚动列表的时候,让input框失去焦点(移动端会收起键盘)

    1.拓展scroll.vue事件 beforeScroll:{ type:Boolean, default:false } if(this.beforeScroll){//滚动列表的时候收起键盘(移动 ...