Alby's blog

世上没有巧合,只有巧合的假象。

0%

在 macOS 12.2.1(Apple M1)/Xcode 13.2.1(MacOSX12.1.sdk) 下编译 libmediasoupclient

一、代理设置

1
2
export http_proxy=http://127.0.0.1:8001
export https_proxy=http://127.0.0.1:8001

export ALL_PROXY=socks5://127.0.0.1:1080 好像不行。另,没试过 export ALL_PROXY=http://127.0.0.1:8001

二、WebRTC 源码下载

1
2
3
4
5
6
7
8
9
10
11
12
13
cd /Users/alby/Workspace/OpenSource/webrtc
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
export PATH=$(pwd)/depot_tools:$PATH

mkdir webrtc-checkout
cd webrtc-checkout

fetch --nohooks webrtc_ios # 注意,对于 macOS 和 iOS 都是 webrtc_ios。即,既不是 webrtc 也不是 webrtc_mac 。
gclient sync

cd src
git checkout -b m94 refs/remotes/branch-heads/4606
gclient sync

三、WebRTC 编译

1
2
3
4
cd /Users/alby/Workspace/OpenSource/webrtc/webrtc-checkout/src
gn gen out/m94 --args='is_debug=false is_component_build=false is_clang=true rtc_include_tests=false rtc_use_h264=true use_rtti=true mac_deployment_target="10.11" use_custom_libcxx=false rtc_build_tools=false rtc_build_examples=true'

ninja -C out/m94

注意,mac_deployment_target="10.11"。尝试用 12.1 等会失败,因为 WebRTC 使用了一些在高版本已经弃用的接口。

四、libmediasoupclient 源码下载

1
2
3
4
5
cd /Users/alby/Workspace/OpenSource/webrtc
git clone https://github.com/versatica/libmediasoupclient.git

cd libmediasoupclient/
git checkout 3.X.Y.

五、libmediasoupclient 编译

1
2
3
4
5
6
7
8
9
10
11
cd /Users/alby/Workspace/OpenSource/webrtc/libmediasoupclient

cmake . -Bbuild \
-DLIBWEBRTC_INCLUDE_PATH:PATH=/Users/alby/Workspace/OpenSource/webrtc/webrtc-checkout/src \
-DLIBWEBRTC_BINARY_PATH:PATH=/Users/alby/Workspace/OpenSource/webrtc/webrtc-checkout/src/out/m94/obj \
-DCMAKE_CXX_FLAGS="-fvisibility=hidden" \
-DCMAKE_OSX_DEPLOYMENT_TARGET="10.11" \
-DMEDIASOUPCLIENT_BUILD_TESTS=OFF \
-DMEDIASOUPCLIENT_LOG_TRACE=OFF \
-DMEDIASOUPCLIENT_LOG_DEV=OFF
make -C build/

-DCMAKE_OSX_DEPLOYMENT_TARGET="10.11",最好和编译 WebRTC 时保持一致。

六、mediasoup-broadcaster-demo 编译

1
2
3
4
5
6
7
8
9
10
11
cd /Users/alby/Workspace/OpenSource/webrtc
git clone https://github.com/versatica/mediasoup-broadcaster-demo.git
cd mediasoup-broadcaster-demo

cmake . -Bbuild \
-DLIBWEBRTC_INCLUDE_PATH:PATH=/Users/alby/Workspace/OpenSource/webrtc/webrtc-checkout/src \
-DLIBWEBRTC_BINARY_PATH:PATH=/Users/alby/Workspace/OpenSource/webrtc/webrtc-checkout/src/out/m94/obj \
-DOPENSSL_INCLUDE_DIR:PATH=/opt/homebrew/opt/openssl@1.1/include \
-DCMAKE_USE_OPENSSL=ON

make -C build

如有必要:brew install openssl@1.1

问题

1、libmediasoupclient 相关

在编译 libmediasoupclient 的过程中如果出现与 #define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */ 行有关的错误,将其改为 #define CATCH_TRAP() asm(".inst 0xd4200000")。见https://github.com/versatica/libmediasoupclient/issues/140

2、absl 相关

如果在链接时报类似错误:

1
2
3
Undefined symbols for architecture arm64:
"webrtc::VideoFrame::Builder::set_update_rect(std::__1::optional<webrtc::VideoFrame::UpdateRect> const&)", referenced from:
RtcVideoCapturer::OnFrame(webrtc::VideoFrame const&) in RtcVideoCapturer.o

用命令 nm -A libwebrtc.a | grep set_update_rect | c++filt 查看该方法的符号也是存在的:

1
libwebrtc.a:video_frame.o: 00000000000006c4 T webrtc::VideoFrame::Builder::set_update_rect(absl::optional<webrtc::VideoFrame::UpdateRect> const&)

但是 libwebrtc 用的是 absl::optional,在应用程序中使用的是 std::optional,需保持一致。

webrtc-checkout/src/third_party/abseil-cpp/absl/base/options.hABSL_OPTION_USE_STD_ANYABSL_OPTION_USE_STD_OPTIONAL ABSL_OPTION_USE_STD_STRING_VIEWABSL_OPTION_USE_STD_VARIANT 四个宏的值改为从 2 改为 0 再重新编译 webrtc:

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
// ABSL_OPTION_USE_STD_OPTIONAL
//
// This option controls whether absl::optional is implemented as an alias to
// std::optional, or as an independent implementation.
//
// A value of 0 means to use Abseil's implementation. This requires only C++11
// support, and is expected to work on every toolchain we support.
//
// A value of 1 means to use an alias to std::optional. This requires that all
// code using Abseil is built in C++17 mode or later.
//
// A value of 2 means to detect the C++ version being used to compile Abseil,
// and use an alias only if a working std::optional is available. This option
// is useful when you are building your program from source. It should not be
// used otherwise -- for example, if you are distributing Abseil in a binary
// package manager -- since in mode 2, absl::optional will name a different
// type, with a different mangled name and binary layout, depending on the
// compiler flags passed by the end user. For more info, see
// https://abseil.io/about/design/dropin-types.

// User code should not inspect this macro. To check in the preprocessor if
// absl::optional is a typedef of std::optional, use the feature macro
// ABSL_USES_STD_OPTIONAL.

#define ABSL_OPTION_USE_STD_OPTIONAL 0 // 由 2 改为 0

参考资料

libmediasoupclient v3 Installation
Mac M1 fails to build while building tests