ios webrtc源码怎么下载和编译

WebRTC 支持 Windows, Mac OS X, Linux, Android 和 iOS 平台,本文以 iOS 平台为例来描述 WebRTC 的源码下载和编译过程。

安装 depot_tools 工具包

下载源码的时候,要用到 depot_tools 工具包,这是 Chromium 官方推荐的工具包,具备下载、同步、编译、上传代码等功能。depot_tools 的详细介绍见 Using depot_tools。depot_tools 包含如下工具包:

gclient
gcl
git-cl
svn [只在 Windows 上使用]
drover
cpplint.py
pylint
presubmit_support.py
repo
wtf
weekly
git-gs
zsh-goodies

step 1:开启 VPN 服务

depot_tools 源码属于 Google 的服务,即墙外资源,在获取 depot_tools 源码前,先需要开启 VPN 服务,然后在终端执行命令

git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
suntongmiandeMacBook-Pro:~ suntongmian$ cd /Users/suntongmian/Documents/develop/webrtc 
suntongmiandeMacBook-Pro:webrtc suntongmian$
suntongmiandeMacBook-Pro:webrtc suntongmian$ git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
正克隆到 'depot_tools'...
fatal: unable to access 'https://chromium.googlesource.com/chromium/tools/depot_tools.git/': Failed to connect to chromium.googlesource.com port 443: Operation timed out
suntongmiandeMacBook-Pro:webrtc suntongmian$ 

出现 “Failed to connect to chromium.googlesource.com port 443: Operation timed out” 问题后,需要检查 VPN 服务是否开启,网络状况是否良好。如果在 VPN 服务开启和网络状况良好的情况下,仍然不能 clone 代码成功,那就需要检查终端能否成功访问墙外的资源。

我开启了 VPN 服务,网络状况也很好,也能通过 Google 浏览器访问资源,但就是不能 clone depot_tools 源码成功。这个时候,我通过命令 curl 来检查终端是否具备翻墙功能。

首先,在终端执行命令

curl www.baidu.com
suntongmiandeMacBook-Pro:webrtc suntongmian$ curl www.baidu.com
<!DOCTYPE html>
<!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=http://s1.bdstatic.com/r/www/cache/bdorz/baidu.min.css><title>百度一下,你就知道</title></head> <body link=#0000cc> <div id=wrapper> <div id=head> <div 
www.baidu.com/img/gs.gif> </p> </div> </div> </div> </body> </html>
suntongmiandeMacBook-Pro:webrtc suntongmian$ 

可以看到,能很快获取到 www.baidu.com 的资源。说明网络是正常的。

其次,在终端执行命令

curl www.google.com
suntongmiandeMacBook-Pro:webrtc suntongmian$ curl www.google.com
curl: (7) Failed to connect to www.google.com port 80: Operation timed out
suntongmiandeMacBook-Pro:webrtc suntongmian$ 

可以看到,出现了请求超时的问题。说明通过终端不能访问 Google 服务。那该怎么解决呢?

我的 MacBook 电脑上使用了 ShadowsocksX 客户端来启动 VPN 服务,但只支持浏览器能使用 VPN 服务。我参考了 MAC 终端走代理服务器 一文中提到的方法来解决这个问题。

我的 ShadowsocksX 客户端中 Socks5 配置信息如下

本地Socks5监听地址:127.0.0.1
本地Socks5监听端口:10808
连接超时:60

通过 Socks5 的配置信息,在终端中执行命令

export http_proxy=socks5://127.0.0.1:10808
export https_proxy=socks5://127.0.0.1:10808
export all_proxy=socks5://127.0.0.1:10808
suntongmiandeMacBook-Pro:webrtc suntongmian$ export http_proxy=socks5://127.0.0.1:10808
suntongmiandeMacBook-Pro:webrtc suntongmian$ 
suntongmiandeMacBook-Pro:webrtc suntongmian$ export https_proxy=socks5://127.0.0.1:10808
suntongmiandeMacBook-Pro:webrtc suntongmian$ 
suntongmiandeMacBook-Pro:~ suntongmian$ export all_proxy=socks5://127.0.0.1:10808
suntongmiandeMacBook-Pro:~ suntongmian$ 

提示:执行后,只对当前终端起作用。重启终端后,默认失效。

启动了终端代理,然后再次执行命令

curl www.google.com
suntongmiandeMacBook-Pro:webrtc suntongmian$ curl www.google.com
<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="en"><head><meta content="Search the world's information, including webpages, images, videos and more. Google has many special features to help you find exactly what you're looking for." name="description"><meta content="noodp" name="robots"><meta content="text/html; charset=UTF-8" http-equiv="Content-Type"><meta content="/logos/doodles/2019/us-teacher-appreciation-week-2019-begins-4994791740801024-l.png" itemprop="image"><meta content="Happy US Teacher Appreciation Week 2019!" property="twitter:title"><meta content="Happy US Teacher Appreciation Week 2019! #GoogleDoodle" 
\u003E\x22,\x22psrl\x22:\x22Remove\x22,\x22sbit\x22:\x22Search by image\x22,\x22srch\x22:\x22Google Search\x22},\x22ovr\x22:{},\x22pq\x22:\x22\x22,\x22refpd\x22:true,\x22rfs\x22:[],\x22sbpl\x22:24,\x22sbpr\x22:24,\x22scd\x22:10,\x22sce\x22:5,\x22stok\x22:\x22s4ND7ehgr2lcHpcv5T93UySs4ho\x22,\x22uhde\x22:false}}';google.pmc=JSON.parse(pmc);})();</script>        </body></html>suntongmiandeMacBook-Pro:webrtc suntongmian$ 
suntongmiandeMacBook-Pro:webrtc suntongmian$ 

发现可以正常访问 www.google.com 的资源了。

解决了终端的代理问题后,再次执行命令

git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
suntongmiandeMacBook-Pro:webrtc suntongmian$ git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
正克隆到 'depot_tools'...
remote: Sending approximately 24.21 MiB ...
remote: Total 31833 (delta 22312), reused 31833 (delta 22312)
接收对象中: 100% (31833/31833), 24.21 MiB | 1.25 MiB/s, 完成.
处理 delta 中: 100% (22312/22312), 完成.
suntongmiandeMacBook-Pro:webrtc suntongmian$ 
suntongmiandeMacBook-Pro:webrtc suntongmian$ ls
depot_tools
suntongmiandeMacBook-Pro:webrtc suntongmian$

到此,可以看到 depot_tools 源码已经下载成功了。

step 2:获取 depot_tools目录

获取 depot_tools 文件夹所在的目录,在终端执行命令

pwd
suntongmiandeMacBook-Pro:webrtc suntongmian$ ls
depot_tools
suntongmiandeMacBook-Pro:webrtc suntongmian$ 
suntongmiandeMacBook-Pro:webrtc suntongmian$ pwd
/Users/suntongmian/Documents/develop/webrtc
suntongmiandeMacBook-Pro:webrtc suntongmian$ 

step 3:添加环境变量

添加环境变量,命令格式为

export PATH=$PATH:/path/depot_tools

其中,path 为上一步通过 pwd 命令获取的 depot_tools 文件夹所在目录。

在终端执行命令

export PATH=$PATH:/Users/suntongmian/Documents/develop/webrtc/depot_tools
suntongmiandeMacBook-Pro:webrtc suntongmian$ export PATH=$PATH:/Users/suntongmian/Documents/develop/webrtc/depot_tools
suntongmiandeMacBook-Pro:webrtc suntongmian$ 

提示:执行后,只对当前终端起作用。重启终端后,默认失效。

step 4:验证是否成功安装

到此,depot_tools 的配置已经完成。想知道 depot_tools 是否成功安装,在终端执行命令

fetch --help
suntongmiandeMacBook-Pro:webrtc suntongmian$ fetch --help
usage: fetch.py [options] <config> [--property=value [--property2=value2 ...]]

This script can be used to download the Chromium sources. See
http://www.chromium.org/developers/how-tos/get-the-code
for full usage instructions.

Valid options:
   -h, --help, help   Print this message.
   --nohooks          Don't run hooks after checkout.
   --force            (dangerous) Don't look for existing .gclient file.
   -n, --dry-run      Don't run commands, only print them.
   --no-history       Perform shallow clones, don't fetch the full git history.

Valid fetch configs:
  android
  android_internal
  breakpad
  chromium
  config_util
  crashpad
  dart
  depot_tools
  goma_client
  gyp
  infra
  infra_internal
  inspector_protocol
  ios
  ios_internal
  nacl
  naclports
  node-ci
  pdfium
  skia
  skia_buildbot
  syzygy
  v8
  webrtc
  webrtc_android
  webrtc_ios
suntongmiandeMacBook-Pro:webrtc suntongmian$ 

打印上面的信息,说明 depot_tools 工具包已经成功安装。接下来就可以通过 depot_tools 工具下载 WebRTC 源码了。

下载 WebRTC 源码

WebRTC 文件量较大,在下载之前,磁盘的剩余可用容量要满足:

Linux: 6.4 GB.
Linux (with Android): 16 GB (of which ~8 GB is Android SDK+NDK images).
Mac (with iOS support): 5.6GB

我使用的是 MacBook Pro 2015款机器:

macOS Mojave
版本 10.14.4

MacBook Pro (Retina, 13-inch, Early 2015)
处理器 2.7 GHz Intel Core i5
内存 8 GB 1867 MHz DDR3
启动磁盘 Macintosh HD
图形卡 Intel Iris Graphics 6100 1536 MB
磁盘空间 128 GB
可用磁盘空间 17.11 GB

我的 Mac 电脑可用磁盘空间 17.11 GB,是足以装的下 5.6 GB 文件的,好了,接下来就可以放心下载源码了。

step 1:下载所需工程

下载所需要的工程,在终端执行命令

fetch --nohooks webrtc_ios

在 “安装 depot_tools 工具包” 的步骤中,通过 fetch –help,可以看到代码目录 webrtc,webrtc_android,webrtc_ios 等。我要在 iOS 平台上使用,就选择了 webrtc_ios。选择依据见 WebRTC Native Code, iOS 中提到的 “This will fetch a regular WebRTC checkout with the iOS-specific parts added.”

这条命令执行时,要下载的文件比较多,需要耐心等待命令的执行结果。

suntongmiandeMacBook-Pro:webrtc suntongmian$ fetch --nohooks webrtc_ios
Running: gclient root
WARNING: Your metrics.cfg file was invalid or nonexistent. A new one will be created.
Running: gclient config --spec 'solutions = [
  {
    "url": "https://webrtc.googlesource.com/src.git",
    "managed": False,
    "name": "src",
    "deps_file": "DEPS",
    "custom_deps": {},
  },
]
target_os = ["ios", "mac"]
'
Running: gclient sync --nohooks --with_branch_heads

________ running 'git -c core.deltaBaseCacheLimit=2g clone --no-checkout --progress https://webrtc.googlesource.com/src.git /Users/suntongmian/Documents/develop/webrtc/_gclient_src_twA2Fg' in '/Users/suntongmian/Documents/develop/webrtc'
Cloning into '/Users/suntongmian/Documents/develop/webrtc/_gclient_src_twA2Fg'...
remote: Sending approximately 253.71 MiB ...        
remote: Counting objects: 22, done        
remote: Finding sources: 100% (22/22)           
Receiving objects:  57% (183907/320504), 74.04 MiB | 1.88 MiB/s    
[0:01:00] Still working on:
[0:01:00]   src
Receiving objects:  60% (192303/320504), 88.48 MiB | 1.35 MiB/s   
[0:01:10] Still working on:
[0:01:10]   src

...

[2:03:36] Still working on:
[2:03:36]   src/third_party/icu

[2:03:46] Still working on:
[2:03:46]   src/third_party/icu

[2:03:52] Still working on:
[2:03:52]   src/third_party/icu
Syncing projects: 100% (38/38), done.                              
Running: git submodule foreach 'git config -f $toplevel/.git/config submodule.$name.ignore all'
Running: git config --add remote.origin.fetch '+refs/tags/*:refs/tags/*'
Running: git config diff.ignoreSubmodules all
suntongmiandeMacBook-Pro:webrtc suntongmian$ 

step 2:与远端 repo 进行代码同步

与远端 repo 进行代码同步,在终端执行命令

gclient sync

这条命令执行时,要下载的文件比较多,需要耐心等待命令的执行结果。

suntongmiandeMacBook-Pro:src suntongmian$ gclient sync
Syncing projects: 100% (38/38), done.                                           

________ running '/usr/bin/python src/build/mac_toolchain.py' in '/Users/suntongmian/Documents/develop/webrtc'
Skipping Mac toolchain installation for mac

________ running '/usr/bin/python src/tools/clang/scripts/update.py' in '/Users/suntongmian/Documents/develop/webrtc'
Downloading https://commondatastorage.googleapis.com/chromium-browser-clang/Mac/clang-359912-2.tgz 
<urlopen error [Errno 54] Connection reset by peer>
Retrying in 5 s ...
Downloading https://commondatastorage.googleapis.com/chromium-browser-clang/Mac/clang-359912-2.tgz Traceback (most recent call last):
  File "src/tools/clang/scripts/update.py", line 322, in <module>
    sys.exit(main())
  File "src/tools/clang/scripts/update.py", line 318, in main
    return UpdateClang()
  File "src/tools/clang/scripts/update.py", line 252, in UpdateClang
    DownloadAndUnpackClangPackage(sys.platform, LLVM_BUILD_DIR)
  File "src/tools/clang/scripts/update.py", line 171, in DownloadAndUnpackClangPackage
    DownloadAndUnpack(cds_full_url, output_dir, path_prefix)
  File "src/tools/clang/scripts/update.py", line 141, in DownloadAndUnpack
    DownloadUrl(url, f)
  File "src/tools/clang/scripts/update.py", line 100, in DownloadUrl
    response = urllib.urlopen(url)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 154, in urlopen
    return opener.open(url, data, timeout)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 431, in open
    response = self._open(req, data)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 449, in _open
    '_open', req)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 409, in _call_chain
    result = func(*args)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 1240, in https_open
    context=self._context)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 1194, in do_open
    h.request(req.get_method(), req.get_selector(), req.data, headers)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 1053, in request
    self._send_request(method, url, body, headers)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 1093, in _send_request
    self.endheaders(body)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 1049, in endheaders
    self._send_output(message_body)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 893, in _send_output
    self.send(msg)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 855, in send
    self.connect()
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 1266, in connect
    HTTPConnection.connect(self)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 835, in connect
    self._tunnel()
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 812, in _tunnel
    (version, code, message) = response._read_status()
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 417, in _read_status
    raise BadStatusLine(line)
httplib.BadStatusLine: ''
Error: Command '/usr/bin/python src/tools/clang/scripts/update.py' returned non-zero exit status 1 in /Users/suntongmian/Documents/develop/webrtc
suntongmiandeMacBook-Pro:src suntongmian$ 

出现了错误 “Error: Command ‘/usr/bin/python src/tools/clang/scripts/update.py’”,暂时不用管,继续后续的步骤。

执行结果中的 src/tools/clang/scripts/update.p, https://commondatastorage.googleapis.com/chromium-browser-clang/Mac/clang-359912-2.tgz 后面的步骤会用到。

ios webrtc源码编译

在执行编译前,我们需要配置好编译的参数和环境,生产出构建文件。这里就需要用到 GN 这个工具了。GN 是一个为 Ninja 生成构建文件的元构建系统。Ninja 是一个小型构建系统,特点是构建速度快。

step 1

使用 GN 来生产 Ninja 工程文件,在终端执行命令

gn gen out/ios --args='target_os="ios" target_cpu="arm64" is_debug=true'
suntongmiandeMacBook-Pro:src suntongmian$ gn gen out/ios --args='target_os="ios" target_cpu="arm64" is_debug=true'
Warning: Multiple codesigning identities match "iPhone Developer"
Warning: - D78B0B7AF39CEFA4D0F673B4D3AA517D312C97CC (selected)
Warning: - 5634EAED50D1AD95ED76F6AC8298E06590FE476B
Warning: - 2843CD233EB6A93C79C2332E4F4FC601BEDA13BC
Warning: Please use either ios_code_signing_identity or 
Warning: ios_code_signing_identity_description variable to 
Warning: control which identity is selected.

Done. Made 1378 targets from 189 files in 2200ms
suntongmiandeMacBook-Pro:src suntongmian$  

产生的工程文件在目录 /src/out/ios 下。通过命令查看下改目录下有哪些文件,在终端执行命令

ls out/ios
suntongmiandeMacBook-Pro:src suntongmian$ ls out/ios
args.gn
build.ninja
build.ninja.d
clang_x64
low_bandwidth_audio_perf_test.runtime_deps
obj
toolchain.ninja
suntongmiandeMacBook-Pro:src suntongmian$ 

step 2

编译 APP 工程,在终端执行命令

ninja -C out/ios AppRTCMobile
suntongmiandeMacBook-Pro:src suntongmian$ ninja -C out/ios AppRTCMobile
ninja: Entering directory `out/ios'
[1/2732] CXX obj/api/audio_codecs/audio_codecs_api/audio_codec_pair_id.o
FAILED: obj/api/audio_codecs/audio_codecs_api/audio_codec_pair_id.o 
../../third_party/llvm-build/Release+Asserts/bin/clang++ -MMD -MF obj/api/audio_codecs/audio_codecs_api/
/bin/sh: ../../third_party/llvm-build/Release+Asserts/bin/clang++: No such file or directory

...

/bin/sh: ../../third_party/llvm-build/Release+Asserts/bin/clang++: No such file or directory

...

isystem../../buildtools/third_party/libc++abi/trunk/include -fvisibility-inlines-hidden -Wnon-virtual-dtor -Woverloaded-virtual -c ../../api/audio_codecs/ilbc/audio_encoder_ilbc.cc -o obj/api/audio_codecs/ilbc/audio_encoder_ilbc/audio_encoder_ilbc.o
/bin/sh: ../../third_party/llvm-build/Release+Asserts/bin/clang++: No such file or directory
ninja: build stopped: subcommand failed.
suntongmiandeMacBook-Pro:src suntongmian$ 

出现错误 “/bin/sh: ../../third_party/llvm-build/Release+Asserts/bin/clang++: No such file or directory”。原因是 /src/third_party/llvm-build 目录下找不到可执行文件 clang++。

先查看 /src/third_party/llvm-build 目录下的文件,在终端执行命令

ls third_party/llvm-build
suntongmiandeMacBook-Pro:src suntongmian$ ls third_party/llvm-build
cr_build_revision
suntongmiandeMacBook-Pro:src suntongmian$

发现确实没有可执行文件 clang++。 那就手动下载文件包,放置到对应的目录下。根据 “二、下载 WebRTC 源码” 的 step 2 命令执行结果中提到的的下载地址 https://commondatastorage.googleapis.com/chromium-browser-clang/Mac/clang-359912-2.tgz,在终端执行命令

curl https://commondatastorage.googleapis.com/chromium-browser-clang/Mac/clang-359912-2.tgz -o third_party/llvm-build/clang.tgz
suntongmiandeMacBook-Pro:src suntongmian$ curl https://commondatastorage.googleapis.com/chromium-browser-clang/Mac/clang-359912-2.tgz -o third_party/llvm-build/clang.tgz
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 27.9M  100 27.9M    0     0  1167k      0  0:00:24  0:00:24 --:--:-- 1469k
suntongmiandeMacBook-Pro:src suntongmian$

将下载的 clang.tgz 压缩包解压并根据报错信息重命名为 Release+Asserts,在终端执行命令

ls third_party/llvm-build
mkdir third_party/llvm-build/Release+Asserts
tar zxvf third_party/llvm-build/clang.tgz -C third_party/llvm-build/Release+Asserts
suntongmiandeMacBook-Pro:src suntongmian$ ls third_party/llvm-build
clang.tgz    cr_build_revision
suntongmiandeMacBook-Pro:src suntongmian$ 
suntongmiandeMacBook-Pro:src suntongmian$ mkdir third_party/llvm-build/Release+Asserts
suntongmiandeMacBook-Pro:src suntongmian$ 
suntongmiandeMacBook-Pro:src suntongmian$ tar zxvf third_party/llvm-build/clang.tgz -C third_party/llvm-build/Release+Asserts
x bin/
x bin/clang
x bin/clang++
x bin/clang-cl

...

x include/c++/v1/ios
x include/c++/v1/iosfwd
x include/c++/v1/iostream

...

x include/c++/v1/support/android/
x include/c++/v1/support/android/locale_bionic.h

...

x include/c++/v1/version
x include/c++/v1/wchar.h
x include/c++/v1/wctype.h
suntongmiandeMacBook-Pro:src suntongmian$ 
suntongmiandeMacBook-Pro:src suntongmian$ ls third_party/llvm-build/Release+Asserts/
bin        buildlog.txt    include     lib
suntongmiandeMacBook-Pro:src suntongmian$ 
suntongmiandeMacBook-Pro:src suntongmian$ ls third_party/llvm-build/Release+Asserts/bin
clang        clang-cl    llvm-symbolizer
clang++        llvm-pdbutil    llvm-undname
suntongmiandeMacBook-Pro:src suntongmian$ 

为什么要将下载的 clang.tgz 压缩包解压并根据报错信息重命名为 Release+Asserts 这是依据 “二、下载 WebRTC 源码” 的 step 2 命令执行结果中提到的信息 src/tools/clang/scripts/update.py,在终端执行命令查看该脚本的信息

cat tools/clang/scripts/update.py
suntongmiandeMacBook-Pro:src suntongmian$ cat tools/clang/scripts/update.py
#!/usr/bin/env python
# Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""This script is used to download prebuilt clang binaries. It runs as a
"gclient hook" in Chromium checkouts.

It can also be run stand-alone as a convenient way of installing a well-tested
near-tip-of-tree clang version:

  $ curl -s https://raw.githubusercontent.com/chromium/chromium/master/tools/clang/scripts/update.py | python - --clang-dir=.
"""

# TODO: Running stand-alone won't work on Windows due to the dia dll copying.

from __future__ import print_function

... 

try:
  import urllib2 as urllib
except ImportError: # For Py3 compatibility
  import urllib.request as urllib
  import urllib.error as urllib

import zipfile


# Do NOT CHANGE this if you don't know what you're doing -- see
# https://chromium.googlesource.com/chromium/src/+/master/docs/updating_clang.md
# Reverting problematic clang rolls is safe, though.
CLANG_REVISION = '359912'
CLANG_SUB_REVISION = 2

PACKAGE_VERSION = '%s-%s' % (CLANG_REVISION, CLANG_SUB_REVISION)
RELEASE_VERSION = '9.0.0'

CDS_URL = os.environ.get('CDS_CLANG_BUCKET_OVERRIDE',
    'https://commondatastorage.googleapis.com/chromium-browser-clang')

# Path constants. (All of these should be absolute paths.)
THIS_DIR = os.path.abspath(os.path.dirname(__file__))
CHROMIUM_DIR = os.path.abspath(os.path.join(THIS_DIR, '..', '..', '..'))
LLVM_BUILD_DIR = os.path.join(CHROMIUM_DIR, 'third_party', 'llvm-build',
                              'Release+Asserts')

STAMP_FILE = os.path.normpath(
    os.path.join(LLVM_BUILD_DIR, '..', 'cr_build_revision'))
FORCE_HEAD_REVISION_FILE = os.path.normpath(os.path.join(LLVM_BUILD_DIR, '..',
                                                   'force_head_revision'))



def DownloadUrl(url, output_file):
  """Download url into output_file."""
  CHUNK_SIZE = 4096
  TOTAL_DOTS = 10
  num_retries = 3
  retry_wait_s = 5  # Doubled at each retry.

  while True:
    try:
      sys.stdout.write('Downloading %s ' % url)
      sys.stdout.flush()
      response = urllib.urlopen(url)
      total_size = int(response.info().getheader('Content-Length').strip())
      bytes_done = 0
      dots_printed = 0     

...

    except urllib.URLError as e:
      sys.stdout.write('\n')
      print(e)
      if num_retries == 0 or isinstance(e, urllib.HTTPError) and e.code == 404:
        raise e
      num_retries -= 1
      print('Retrying in %d s ...' % retry_wait_s)

...

def DownloadAndUnpack(url, output_dir, path_prefix=None):
  """Download an archive from url and extract into output_dir. If path_prefix 

def DownloadAndUnpackClangPackage(platform, output_dir, runtimes_only=False):
  cds_file = "clang-%s.tgz" %  PACKAGE_VERSION

...

def UpdateClang():
  GCLIENT_CONFIG = os.path.join(os.path.dirname(CHROMIUM_DIR), '.gclient')

...

  DownloadAndUnpackClangPackage(sys.platform, LLVM_BUILD_DIR)

...

  if args.llvm_force_head_revision:
    print('--llvm-force-head-revision can only be used for --print-revision')
    return 1

  if args.clang_dir:
    global LLVM_BUILD_DIR, STAMP_FILE
    LLVM_BUILD_DIR = os.path.abspath(args.clang_dir)
    STAMP_FILE = os.path.join(LLVM_BUILD_DIR, 'cr_build_revision')

  return UpdateClang()


if __name__ == '__main__':
  sys.exit(main())
suntongmiandeMacBook-Pro:src suntongmian$ 

从该脚本的注释信息 This script is used to download prebuilt clang binaries 可以得知该脚本作用就是下载 clang 可执行文件。其中 clang 的版本信息为 CLANG_REVISION = '359912' CLANG_SUB_REVISION = 2 RELEASE_VERSION = '9.0.0'llvm-build 的目录信息为 LLVM_BUILD_DIR = os.path.join(CHROMIUM_DIR, 'third_party', 'llvm-build', 'Release+Asserts')

再次在终端执行命令

ninja -C out/ios AppRTCMobile
suntongmiandeMacBook-Pro:src suntongmian$ ninja -C out/ios AppRTCMobile
ninja: Entering directory `out/ios'
[2735/2736] CODE SIGNING //examples:Ap...//build/toolchain/mac:ios_clang_arm64)
FAILED: AppRTCMobile.app/AppRTCMobile AppRTCMobile.app/_CodeSignature/CodeResources AppRTCMobile.app/embedded.mobileprovision AppRTCMobile.app/Info.plist 
python ../../build/config/ios/codesign.py code-sign-bundle -t=iphoneos -i=D78B0B7AF39CEFA4D0F673B4D3AA517D312C97CC -b=obj/examples/AppRTCMobile -e=../../build/config/ios/entitlements.plist AppRTCMobile.app -P=../../build/config/mac/plist_util.py -p=gen/examples/AppRTCMobile_generate_info_plist.plist -p=gen/examples/AppRTCMobile_partial_info.plist
Error: no mobile provisioning profile found for "com.google.AppRTCMobile".
ninja: build stopped: subcommand failed.
suntongmiandeMacBook-Pro:src suntongmian$ 

至此,编译 APP 的过程结束了。虽然出现了 “Error: no mobile provisioning profile found for “com.google.AppRTCMobile”.” 的报错,但这并不是太重要,我只关心编译过程的其它环节正确无误。这个 Error 信息表示 APP 的包名 “com.google.AppRTCMobile” 没有与之对应的苹果开发者证书的配置文件,将该 APP 安装到手机上后,会因证书配置文件的问题无法使用。这个问题很好解决,就是改 APP 的包名,在编译的时候选择对应的苹果开发者证书的配置文件后,重新编译就行了。

进入目录 /src/out/ios 可以看下编译后产生了哪些文件。在终端执行命令

ls out/ios
suntongmiandeMacBook-Pro:src suntongmian$ ls out/ios
AppRTCMobile.app
WebRTC.framework
args.gn
build.ninja
build.ninja.d
clang_x64
gen
low_bandwidth_audio_perf_test.runtime_deps
obj
pyproto
toolchain.ninja
suntongmiandeMacBook-Pro:src suntongmian$ 

在这一步,其实可以得到我想要的 WebRTC 库文件了,即 WebRTC.framework

step 3

虽然上一步,在编译 WebRTC 的演示 APP 时,可以得到 WebRTC.framework 库文件,但这不是正常获取库文件的路子。编译 WebRTC 库文件的方法有2种,分别为 ninja 命令行,python 脚本。

方法 1

使用 ninja 命令行编译,在终端执行命令

ninja -C out/ios framework_objc
suntongmiandeMacBook-Pro:src suntongmian$ ninja -C out/ios framework_objc
ninja: Entering directory `out/ios'
ninja: no work to do.
suntongmiandeMacBook-Pro:src suntongmian$

可以看到 “ninja: no work to do.”,为什么会提示这条信息呢?原因在于上一步骤中已经编译产生了 WebRTC.framework 库文件。如果想看看只编译库文件的过程,那可以不执行上一步骤中编译 APP 的环节,即不执行命令 ninja -C out/ios AppRTCMobile,现在的情况是我们已经执行了该条命令,那直接删掉已经存在的 WebRTC.framework 库文件就行了。在终端执行命令

rm -rf out/ios/WebRTC.framework
suntongmiandeMacBook-Pro:src suntongmian$ rm -rf out/ios/WebRTC.framework
suntongmiandeMacBook-Pro:src suntongmian$ 
suntongmiandeMacBook-Pro:src suntongmian$ ls out/ios
AppRTCMobile.app
args.gn
build.ninja
build.ninja.d
clang_x64
gen
low_bandwidth_audio_perf_test.runtime_deps
obj
pyproto
toolchain.ninja
suntongmiandeMacBook-Pro:src suntongmian$ 

再次在终端执行命令

ninja -C out/ios framework_objc
suntongmiandeMacBook-Pro:src suntongmian$ ninja -C out/ios framework_objc
ninja: Entering directory `out/ios'
[97/97] STAMP obj/sdk/framework_objc.stamp
suntongmiandeMacBook-Pro:src suntongmian$ 
suntongmiandeMacBook-Pro:src suntongmian$ ls out/ios
AppRTCMobile.app
WebRTC.framework
args.gn
build.ninja
build.ninja.d
clang_x64
gen
low_bandwidth_audio_perf_test.runtime_deps
obj
pyproto
toolchain.ninja
suntongmiandeMacBook-Pro:src suntongmian$ 

生成的 WebRTC.framework 库文件在 out/ios 目录下。

方法 2

使用 python 脚本 /src/tools_webrtc/ios/build_ios_libs.py 编译,在终端执行命令

python tools_webrtc/ios/build_ios_libs.py --bitcode
suntongmiandeMacBook-Pro:src suntongmian$ python tools_webrtc/ios/build_ios_libs.py --bitcode
INFO:root:Building WebRTC with args: target_os="ios" ios_enable_code_signing=false use_xcode_clang=true is_component_build=false is_debug=false target_cpu="arm64" ios_deployment_target="10.0" rtc_libvpx_build_vp9=false enable_ios_bitcode=true use_goma=false enable_stripping=true
Done. Made 1376 targets from 189 files in 1727ms
INFO:root:Building target: framework_objc
ninja: Entering directory `/Users/suntongmian/Documents/develop/webrtc/src/out_ios_libs/arm64_libs'
[2614/2614] STAMP obj/sdk/framework_objc.stamp
INFO:root:Building WebRTC with args: target_os="ios" ios_enable_code_signing=false use_xcode_clang=true is_component_build=false is_debug=false target_cpu="arm" ios_deployment_target="10.0" rtc_libvpx_build_vp9=false enable_ios_bitcode=true use_goma=false enable_stripping=true
Done. Made 1377 targets from 189 files in 1953ms
INFO:root:Building target: framework_objc
ninja: Entering directory `/Users/suntongmian/Documents/develop/webrtc/src/out_ios_libs/arm_libs'
[2656/2656] STAMP obj/sdk/framework_objc.stamp
INFO:root:Building WebRTC with args: target_os="ios" ios_enable_code_signing=false use_xcode_clang=true is_component_build=false is_debug=false target_cpu="x64" ios_deployment_target="10.0" rtc_libvpx_build_vp9=false enable_ios_bitcode=true use_goma=false enable_stripping=true
Done. Made 1402 targets from 192 files in 5101ms
INFO:root:Building target: framework_objc
ninja: Entering directory `/Users/suntongmian/Documents/develop/webrtc/src/out_ios_libs/x64_libs'
[2777/2777] STAMP obj/sdk/framework_objc.stamp
INFO:root:Building WebRTC with args: target_os="ios" ios_enable_code_signing=false use_xcode_clang=true is_component_build=false is_debug=false target_cpu="x86" ios_deployment_target="10.0" rtc_libvpx_build_vp9=false enable_ios_bitcode=true use_goma=false enable_stripping=true
Done. Made 1402 targets from 192 files in 1754ms
INFO:root:Building target: framework_objc
ninja: Entering directory `/Users/suntongmian/Documents/develop/webrtc/src/out_ios_libs/x86_libs'
[2771/2771] STAMP obj/sdk/framework_objc.stamp
INFO:root:Merging framework slices.
INFO:root:Done.
suntongmiandeMacBook-Pro:src suntongmian$ 
suntongmiandeMacBook-Pro:src suntongmian$ ls out_ios_libs
WebRTC.framework    arm_libs        x86_libs
arm64_libs        x64_libs
suntongmiandeMacBook-Pro:src suntongmian$ 

生成的库文件在 out_ios_lib 目录下。脚本 tools_webrtc/ios/build_ios_libs.py 默认编译的架构是 DEFAULT_ARCHS = ENABLED_ARCHS = ['arm64', 'arm', 'x64', 'x86'],编译出来的库为动态库。查看库支持的架构,以及是静态库还是动态库,在终端执行命令

lipo -info out_ios_libs/WebRTC.framework/WebRTC
file out_ios_libs/arm64_libs/WebRTC.framework/WebRTC
suntongmiandeMacBook-Pro:src suntongmian$ lipo -info out_ios_libs/WebRTC.framework/WebRTC
Architectures in the fat file: out_ios_libs/WebRTC.framework/WebRTC are: x86_64 i386 armv7 arm64 
suntongmiandeMacBook-Pro:src suntongmian$ 
suntongmiandeMacBook-Pro:src suntongmian$ file out_ios_libs/WebRTC.framework/WebRTC
out_ios_libs/WebRTC.framework/WebRTC: Mach-O universal binary with 4 architectures: [x86_64:Mach-O 64-bit dynamically linked shared library x86_64] [arm64]
out_ios_libs/WebRTC.framework/WebRTC (for architecture x86_64):    Mach-O 64-bit dynamically linked shared library x86_64
out_ios_libs/WebRTC.framework/WebRTC (for architecture i386):    Mach-O dynamically linked shared library i386
out_ios_libs/WebRTC.framework/WebRTC (for architecture armv7):    Mach-O dynamically linked shared library arm_v7
out_ios_libs/WebRTC.framework/WebRTC (for architecture arm64):    Mach-O 64-bit dynamically linked shared library arm64
suntongmiandeMacBook-Pro:src suntongmian$ 

提示:使用了动态库的 APP 在上架 APP Store 时,会报错不支持模拟器架构 ['x64', 'x86'],所以,需要剔除动态库中的模拟器架构,只使用真机架构 [‘arm64’, ‘arm’]。

可以修改脚本 tools_webrtc/ios/build_ios_libs.py 中的参数,将编译的架构改成 DEFAULT_ARCHS = ENABLED_ARCHS = ['arm64']。为什么去掉了 arm?因为现在人们使用的苹果设备几乎都是 arm64 架构了,arm 架构的苹果设备几乎绝迹,去掉 arm,也可以减轻 WebRTC 库的体积。

版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。

(0)

相关推荐

发表回复

登录后才能评论