WebRTC-Streamer交叉编译
flyfish
文章目录
- WebRTC-Streamer交叉编译
-
- 零、前言
- 一、提前准备工作
-
- [1 安装需要的工具](#1 安装需要的工具)
- [2 可选的交叉编译工具](#2 可选的交叉编译工具)
- [3 默认执行python是python3](#3 默认执行python是python3)
- [4 获取源码](#4 获取源码)
- [5 使用其他版本的方法](#5 使用其他版本的方法)
- 二、非交叉编译编译
-
- [1 在 src目录执行 安装所需的依赖](#1 在 src目录执行 安装所需的依赖)
- [2 执行命令](#2 执行命令)
- [三、 交叉编译](#三、 交叉编译)
-
- [1 独立使用的方法,无需提供给WebRTC-Streamer使用的方法](#1 独立使用的方法,无需提供给WebRTC-Streamer使用的方法)
- [2 提供给WebRTC-Streamer使用的方法](#2 提供给WebRTC-Streamer使用的方法)
- 四、开始编译WebRTC-Streamer
- 五、以下是不同版本的编译,可能出现的错误和解决方案
-
- 问题1缺少rtmp
- [问题 2 链接问题](#问题 2 链接问题)
- [问题3 live555helper](#问题3 live555helper)
- [问题4 WebRTC和WebRTC-Streamer两者版本,其中之一过旧或者过新问题](#问题4 WebRTC和WebRTC-Streamer两者版本,其中之一过旧或者过新问题)
- [问题5 未安装工具的错误](#问题5 未安装工具的错误)
- [问题6 编译工具与代码版本问题](#问题6 编译工具与代码版本问题)
- [问题7 使用clang或者gcc不同编译器编译的情况](#问题7 使用clang或者gcc不同编译器编译的情况)
零、前言
WebRTC-Streamer源码
cpp
https://github.com/mpromonet/webrtc-streamer
官网给的三步是
1安装 Chromium depot tools
cpp
pushd ..
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
export PATH=$PATH:`realpath depot_tools`
popd
2 下载 WebRTC
cpp
mkdir ../webrtc
pushd ../webrtc
fetch --no-history webrtc
popd
3 构建 WebRTC Streamer
cpp
cmake . && make
这里实践第三步首先要编译WebRTC,然后再编译WebRTC-Streamer
webrtc编译
一、提前准备工作
1 安装需要的工具
sudo apt-get install build-essential pkg-config devhelp glade libglade2-dev
sudo apt-get install libgtk-3-dev
sudo apt install ninja-build
sudo apt install git
sudo apt install libcanberra-gtk-module
sudo apt install cmake
sudo apt install python3-pip
pip3 install dataclasses
2 可选的交叉编译工具
https://mirrors.tuna.tsinghua.edu.cn/armbian-releases/_toolchain/
3 默认执行python是python3
sudo rm /usr/bin/python
sudo ln -s /usr/bin/python3 /usr/bin/python
python --version
4 获取源码
cpp
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
创建webrtc文件夹
终端命令进入webrtc文件夹后,执行命令
加载路径
cpp
export PATH=/path/to/depot_tools:$PATH
替换成depot_tools所在路径,这里用的是
export PATH="$PATH:/home/a/source/depot_tools/"
cpp
fetch --nohooks webrtc
gclient sync
5 使用其他版本的方法
切换到分支方法
查看有哪些版本
cpp
https://webrtc.github.io/webrtc-org/release-notes/
打开链接可以看到M85 和4183
进入 webrtc/src目录,执行命令
cpp
git checkout -b m85 branch-heads/4183
gclient sync
或者通过git branch -r
查看有哪些分支
二、非交叉编译编译
可编译x86_64版本
1 在 src目录执行 安装所需的依赖
cpp
./build/install-build-deps.sh
这里实际用的是
cpp
./build/install-build-deps.sh --no-chromeos-fonts #跳过字体的安装
2 执行命令
cpp
gn gen out/Default --args='is_debug=false'
ninja -C out/Default
三、 交叉编译
可编译arm32或者arm64版本
根据自己需要选择
1 独立使用的方法,无需提供给WebRTC-Streamer使用的方法
如果是要交叉编译,需要执行
cpp
./build/linux/sysroot_scripts/install-sysroot.py --arch=arm #32位
./build/linux/sysroot_scripts/install-sysroot.py --arch=arm64 #64位
普通的交叉编译
第一步
cpp
gn gen out/linux_arm --args='target_os="linux" target_cpu="arm" use_custom_libcxx=false' #32位
gn gen out/linux_arm64 --args='target_os="linux" target_cpu="arm64" use_custom_libcxx=false' #64位
第二步
cpp
ninja -C out/linux_arm #32位
ninja -C out/linux_arm64 #64位
2 提供给WebRTC-Streamer使用的方法
交叉编译命令
还可以是如下命令
假如是arm32下
第一步
gn gen out/Release --args='rtc_use_x11=false rtc_use_pipewire=false is_clang=true use_sysroot=false target_cpu="arm" is_chrome_branded=true is_debug=false use_custom_libcxx=false rtc_include_tests=false rtc_enable_protobuf=false rtc_build_examples=false rtc_build_tools=false treat_warnings_as_errors=false rtc_enable_libevent=false rtc_build_libevent=false use_ozone=true rtc_build_json=true'
第二步
ninja -C out/Release webrtc rtc_json jsoncpp builtin_video_decoder_factory builtin_video_encoder_factory peerconnection p2p_server_utils task_queue default_task_queue_factory
四、开始编译WebRTC-Streamer
以arm32为例
cmake -DCMAKE_SYSTEM_PROCESSOR=armv7l -DCMAKE_SYSTEM_NAME=Linux -DCMAKE_C_COMPILER=/home/a/tool/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc -DCMAKE_CXX_COMPILER=/home/a/tool/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g++ -DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY -DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ONLY -DWEBRTCOZONE=Yes -DWEBRTCDESKTOPCAPTURE=OFF .
以上编译命令类似
cpp
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(tools /home/a/tool/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/)
set(CMAKE_C_COMPILER ${tools}/bin/arm-linux-gnueabihf-gcc)
set(CMAKE_CXX_COMPILER ${tools}/bin/arm-linux-gnueabihf-g++)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
可选的
cpp
set(CMAKE_SYSROOT /home/devel/rasp-pi-rootfs)
set(CMAKE_STAGING_PREFIX /home/devel/stage)
如果不想写这么长的工具路径,可以如下操作
usr/local/下建立一个arm32文件夹,将工具拷贝进去
编辑~/.bashrc加上一句
cpp
export PATH=$PATH:/usr/local/arm32/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin
五、以下是不同版本的编译,可能出现的错误和解决方案
问题1缺少rtmp
In file included from /home/a/source/webrtc-streamer/inc/CapturerFactory.h:34,
from /home/a/source/webrtc-streamer/src/PeerConnectionManager.cpp:26:
/home/a/source/webrtc-streamer/inc/rtmpvideosource.h:32:10: 致命错误: librtmp/rtmp.h:没有那个文件或目录
#include <librtmp/rtmp.h>
^~~~~~~~~~~~~~~~
编译中断。
CMakeFiles/webrt
方式1:
下载
cpp
http://rtmpdump.mplayerhq.hu/download/
rtmpdump-2.3
放置到
cpp
librtmp
/home/a/source/webrtc-streamer/inc/librtmp
然后再解决链接问题
cpp
arm-linux-gnueabihf/bin/ld: cannot find -lrtmp
arm-linux-gnueabihf/bin/ld: cannot find -lz
arm-linux-gnueabihf/bin/ld: cannot find -lgmp
方式2
不使用rtmp
更改CMakeList.txt
cpp
# rtmp ?
# find_package(PkgConfig QUIET)
# pkg_check_modules(RTMP QUIET librtmp)
# MESSAGE("RTMP_FOUND = ${RTMP_FOUND}")
# if (RTMP_FOUND)
# add_definitions(-DHAVE_RTMP)
# target_link_libraries (${CMAKE_PROJECT_NAME} ${RTMP_LIBRARIES})
# endif()
问题 2 链接问题
cpp
arm-linux-gnueabihf/bin/ld: cannot find -lX11
arm-linux-gnueabihf/bin/ld: cannot find -lXext
arm-linux-gnueabihf/bin/ld: cannot find -lXdamage
arm-linux-gnueabihf/bin/ld: cannot find -lXfixes
arm-linux-gnueabihf/bin/ld: cannot find -lXcomposite
arm-linux-gnueabihf/bin/ld: cannot find -lXrandr
arm-linux-gnueabihf/bin/ld: cannot find -lXtst
通过查看CMakeLists.txt x11需要 X11 Xext Xdamage Xfixes Xcomposite Xrandr Xtst
cpp
if (EXISTS ${WEBRTCROOT}/src/out/${CMAKE_BUILD_TYPE}/obj/modules/desktop_capture/desktop_capture.ninja)
add_definitions(-DUSE_X11)
target_link_libraries (${CMAKE_PROJECT_NAME} X11 Xext Xdamage Xfixes Xcomposite Xrandr Xtst)
endif()
简单的方法就是除去 x11 dep
webrtc增加参数
cpp
gn gen out/Release --args增加参数 use_ozone=true rtc_use_x11=false
webrtc-streamer的编译增加参数
cpp
cmake -DCMAKE_SYSTEM_PROCESSOR=armv7l -DWEBRTCOZONE=Yes -DWEBRTCDESKTOPCAPTURE=OFF .
问题3 live555helper
错误提示
cpp
struct std::atomic_flag' has no member named 'test'
详细的是
cpp
/home/a/source/webrtc-streamer/live/BasicUsageEnvironment/BasicTaskScheduler.cpp: 在成员函数'virtual void BasicTaskScheduler::SingleStep(unsigned int)'中:
/home/a/source/webrtc-streamer/live/BasicUsageEnvironment/BasicTaskScheduler.cpp:191:40: 错误: 'struct std::atomic_flag' has no member named 'test'
if (fTriggersAwaitingHandling[i].test()) {
^~~~
live555helper/CMakeFiles/liblive555helper.dir/build.make:89: recipe for target 'live555helper/CMakeFiles/liblive555helper.dir/__/live/BasicUsageEnvironment/BasicTaskScheduler.cpp.o' failed
make[2]: *** [live555helper/CMakeFiles/liblive555helper.dir/__/live/BasicUsageEnvironment/BasicTaskScheduler.cpp.o] Error 1
make[2]: *** 正在等待未完成的任务....
解决方法
增加NO_STD_LIB=1 或者 -DNO_STD_LIB
可以根据自己所需的系统更改
编译最后更改如下
if (WIN32)
target_compile_definitions(liblive555helper PUBLIC _CRT_SECURE_NO_WARNINGS=1 NO_GETIFADDRS=1)
target_link_libraries (liblive555helper ws2_32)
elseif (APPLE)
target_compile_definitions(liblive555helper PUBLIC BSD=1 SOCKLEN_T=socklen_t _FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE=1 NEED_XLOCALE_H=1)
else ()
target_compile_definitions(liblive555helper PUBLIC BSD=1 SOCKLEN_T=socklen_t _FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE=1 NO_STD_LIB=1)
endif()
问题4 WebRTC和WebRTC-Streamer两者版本,其中之一过旧或者过新问题
示例1
cpp
:208:18: 错误: 'class rtc::Thread' has no member named 'Invoke'
m_workerThread->Invoke<void>(RTC_FROM_HERE, [this, audioLayer] {
^~~~~~
:208:25: 错误: expected primary-expression before 'void'
m_workerThread->Invoke<void>(RTC_FROM_HERE, [this, audioLayer] {
^~~~
:210:6: 错误: expected primary-expression before ')' token
});
^
: 在析构函数'virtual PeerConnectionManager::~PeerConnectionManager()'中:
:340:18: 错误: 'class rtc::Thread' has no member named 'Invoke'
m_workerThread->Invoke<void>(RTC_FROM_HERE, [this] {
^~~~~~
:340:25: 错误: expected primary-expression before 'void'
m_workerThread->Invoke<void>(RTC_FROM_HERE, [this] {
^~~~
:342:6: 错误: expected primary-expression before ')' token
示例2
cpp
../../modules/audio_processing/agc2/adaptive_digital_gain_controller_unittest.cc:107:41: error: no member named 'log10f' in namespace 'std'; did you mean simply 'log10f'?
107 | const float applied_gain_db = 20.0f * std::log10f(applied_gain);
| ^~~~~~~~~~~
| log10f
../../build/linux/debian_bullseye_armhf-sysroot/usr/include/arm-linux-gnueabihf/bits/mathcalls.h:107:1: note: 'log10f' declared here
107 | __MATHCALL (log10,, (_Mdouble_ __x));
| ^
../../build/linux/debian_bullseye_armhf-sysroot/usr/include/math.h:273:3: note: expanded from macro '__MATHCALL'
273 | __MATHDECL (_Mdouble_,function,suffix, args)
| ^
../../build/linux/debian_bullseye_armhf-sysroot/usr/include/math.h:275:3: note: expanded from macro '__MATHDECL'
275 | __MATHDECL_1(type, function,suffix, args); \
| ^
../../build/linux/debian_bullseye_armhf-sysroot/usr/include/math.h:283:15: note: expanded from macro '__MATHDECL_1'
283 | extern type __MATH_PRECNAME(function,suffix) args __THROW
| ^
../../build/linux/debian_bullseye_armhf-sysroot/usr/include/math.h:303:34: note: expanded from macro '__MATH_PRECNAME'
303 | # define __MATH_PRECNAME(name,r) name##f##r
| ^
<scratch space>:211:1: note: expanded from here
211 | log10f
| ^
1 error generated.
问题5 未安装工具的错误
例如
pkg-config
cpp
ERROR at //build/config/linux/pkg_config.gni:104:17: Script returned non-zero exit code.
pkgresult = exec_script(pkg_config_script, args, "json")
^----------
Current dir: /home/a/source/webrtc/src/out/linux_arm/
Command: python3 /home/a/source/webrtc/src/build/config/linux/pkg-config.py -s /home/a/source/webrtc/src/build/linux/debian_bullseye_armhf-sysroot -a arm gmodule-2.0 gthread-2.0 gtk+-3.0
Returned 1.
stderr:
Traceback (most recent call last):
File "/home/a/source/webrtc/src/build/config/linux/pkg-config.py", line 247, in <module>
sys.exit(main())
File "/home/a/source/webrtc/src/build/config/linux/pkg-config.py", line 142, in main
prefix = GetPkgConfigPrefixToStrip(options, args)
File "/home/a/source/webrtc/src/build/config/linux/pkg-config.py", line 81, in GetPkgConfigPrefixToStrip
"--variable=prefix"] + args, env=os.environ).decode('utf-8')
File "/usr/lib/python3.6/subprocess.py", line 356, in check_output
**kwargs).stdout
File "/usr/lib/python3.6/subprocess.py", line 423, in run
with Popen(*popenargs, **kwargs) as process:
File "/usr/lib/python3.6/subprocess.py", line 729, in __init__
restore_signals, start_new_session)
File "/usr/lib/python3.6/subprocess.py", line 1364, in _execute_child
raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'pkg-config': 'pkg-config'
See //examples/BUILD.gn:665:5: whence it was called.
pkg_config("gtk_config") {
^-------------------------
See //BUILD.gn:42:17: which caused the file to be included.
deps += [ "examples" ]
dataclasses
cpp
ninja -C out/linux_arm
ninja: Entering directory `out/linux_arm'
[122/6960] ACTION //experiments:regist...der(//build/toolchain/linux:clang_arm)
FAILED: gen/experiments/registered_field_trials.h
python3 ../../experiments/field_trials.py header --output gen/experiments/registered_field_trials.h
Traceback (most recent call last):
File "../../experiments/field_trials.py", line 15, in <module>
import dataclasses
ModuleNotFoundError: No module named 'dataclasses'
[131/6960] CXX obj/logging/fake_rtc_event_log/fake_rtc_event_log.o
ninja: build stopped: subcommand failed.
问题6 编译工具与代码版本问题
例如webrtc使用旧代码时,gn版本过高导致的错误
降低gn版本
:~/source/webrtc/src$ gn gen out/Default
ERROR at //build/config/BUILDCONFIG.gn:401:1: Unknown function.
set_sources_assignment_filter(sources_assignment_filter)
gn --version
2119 (cc56a0f98bb3)
问题7 使用clang或者gcc不同编译器编译的情况
LLVM: clang / clang++(https://clang.llvm.org/)
GNU: gcc / g++( https://gcc.gnu.org/)
同样 的编译参数-std=c++17在默认的情况下,是用了不同的标准库
cpp
g++ with libstdc++ (by default)
clang++ with libc++ (by default)
在使用gcc编译的情况下,使用系统级别的函数时ibstdc++会调用glibc,Host上的gcc如果使用的glibc过高,到了Target就运行不起来
参考