002-chromium新老版本编译
xinali opened this issue · 0 comments
chromium build
[toc]
latest update: 2024.03.08
因为工作需要,需要经常构建多个平台各种版本的chromium
,所以可能会遇到各种各样的问题,
在这里做一下记录,会不断更新遇到的最新问题
所有的源码和相关工具,尽力别使用挂载的方式挂在
wsl
或virtualbox/vmware
中,挂载的方式,无论是编译,还是git
操作,速度都会特别慢
初次构建(latest on linux)
-
准备depot_tools:
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git export PATH=/xxx/path/to/depot_tools:$PATH
-
获取
chromium
源码mkdir ~/chromium && cd ~/chromium fetch --nohooks chromium
-
构建及获取依赖
cd src ./build/install-build-deps.sh gclient runhooks
-
构建
chrome
gn gen out/Default autoninja -C out/Default chrome
只要按照流程走,一般构建最新版,不会出问题
初次构建(latest on windows)
直接利用构建脚本
@echo off
rem 设置源码路径
set chromium_dir="G:\chromium"
set chromium_source=%chromium_dir%\src
rem 设置不更新depot_tools
set DEPOT_TOOLS_WIN_TOOLCHAIN=0
rem 设置depot_tools路径
rem 如果有多版本的depot_tools,根据需要设定特定版本
set DEPOT_TOOLS_PATH=G:\codes\depot_tools
set PATH=%DEPOT_TOOLS_PATH%;%PATH%
rem 针对环境存在多个版本python时
rem 可能还需要设置python路径
rem set PYTHON_PATH=G:\tools\Python27
rem set PATH=%PYTHON_PATH%;%PATH%
rem 设置vs版本
set vs2022_install=D:\tools\vs_community
rem 编译
cd %chromium_source%
gn gen out\Release
ninja -C out\Release chrome
build older version
# 切换分支或commit
git checkout old_version
# 设置depot_tools不自动升级
export DEPOT_TOOLS_UPDATE=0
# 设置依赖
COMMIT_DATE=$(git log -n 1 --pretty=format:%ci)
cd ~/depot_tools
git checkout $(git rev-list -n 1 --before="$COMMIT_DATE" main)
# 清理原始第三方库
git clean -ffd
# 同步第三方库
gclient sync -D --force --reset
# 构建依赖
./build/install-build-deps.sh
# 上古版本构建依赖
./build/gyp_chromium
gclient runhooks
# 构建chrome
gn gen out/Default
ninja -C out/Default chrome
如果想要构建一个调试版本,在gn
后,更改out/Default
目录args.gn
中的参数
is_debug = true
is_component_build = true
symbol_level = 2
编译问题
chromium
代码非常复杂,所以在不同的系统不同的版本的编译过程中会遇到非常多的问题,以下主要是记录我自己遇到的各种问题
-
代理问题
如果直接在
shell
的配置文件里设置代理,在运行gclient sync/fetch --nohooks chromium
时都不一定有问题,但是在运行gclient runhooks
可能会出错,解决办法是设置.boto
文件/home/[user]/.boto
,类似于[Boto] debug = 0 num_retries = 10 proxy = [proxy ip] proxy_port = [proxy port]
在启动
shell
时,载入.boto
配置文件export NO_AUTH_BOTO_CONFIG="/home/[user]/.boto"
-
webrtc
版本问题(其他库操作相同)cd src/third_party/webrtc git checkout $(git rev-list -n 1 --before="$COMMIT_DATE" main)
然后在
src/DEPS
中更改对应的webrtc
的commit id
,这种方法在很多情况下都适用,但是在某些情况下不适用,在这种方法失效时,还有另一种更加直接的方法,在对应的源码网站上下载该commit
的源码,然后放在对应目录下,这种方法的前提是,不停执行gclient sync -D --force --reset
直至最后一个需要处理的库为你需要处理的库为止,然后就可以直接build
。在处理该问题时,还遇到一个奇怪的问题,在
google
源码站上有某个commit
,代码也是根据该commit
拉取的代码,但是却无法checkout
到该commit
,这时候就必须使用第二种方法20230815 update:
针对这种无法
checkout
到固定commit
,最近发现了一个新的方法,比如webrtc
库,这里可以直接这么干fetch --nohooks webrtc git checkout branch-heads/m79
然后把
checkout
完成的代码放到chromium/src/third_party/webrtc
目录下 -
python
问题a. 目前部分老版本所使用的脚本,均为
python2
,如果使用python3
,则出错,更改默认的python
版本即可
b. 其自带的python
编译脚本存在编码错误,这个一般存在老版本中,会提示如下错误UnicodeDecodeError: 'gbk' codec can't decode byte 0xxx in position yyyy: illegal multibyte sequence
用
vscode
打开提示是utf-8
编码,但是使用如下的代码会发现其编码def guess_encoding(filename, encodings=None): if encodings is None: encodings = ['utf-8', 'iso-8859-1', 'gbk', 'big5', 'windows-1252', 'utf-16', 'utf-32'] for enc in encodings: try: with open(filename, 'r', encoding=enc) as f: f.read() return enc except UnicodeDecodeError: pass return None
在找到具体编码后,打开文件时,比如
open(file_name, 'r', encoding='windows-1252')
即可c.
depot_tools
自带python
版本在处理os.path.relpath
问题在部分
chromium
版本对应的depot_tools
中使用的python
版本为3.11.2
貌似存在问题,大概是这种情况Traceback (most recent call last): File "G:\chromium\src\mojo\public\tools\bindings\mojom_bindings_generator.py", line 418, in <module> ret = main() ^^^^^^ File "G:\chromium\src\mojo\public\tools\bindings\mojom_bindings_generator.py", line 413, in main return args.func(args, remaining_args) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "G:\chromium\src\mojo\public\tools\bindings\mojom_bindings_generator.py", line 275, in _Generate processor._GenerateModule( File "G:\chromium\src\mojo\public\tools\bindings\mojom_bindings_generator.py", line 243, in _GenerateModule generator.GenerateFiles(filtered_args) File "G:\chromium\src\mojo\public\tools\bindings\generators\mojom_ts_generator.py", line 280, in GenerateFiles self.WriteWithComment(self._GenerateWebUiModule(), ^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "G:\chromium\src\mojo\public\tools\mojom\mojom\generate\template_expander.py", line 34, in GeneratorInternal parameters = generator(*args, **kwargs2) ^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "G:\chromium\src\mojo\public\tools\bindings\generators\mojom_ts_generator.py", line 266, in _GenerateWebUiModule return self._GetParameters() ^^^^^^^^^^^^^^^^^^^^^ File "G:\chromium\src\mojo\public\tools\bindings\generators\mojom_ts_generator.py", line 228, in _GetParameters self._GetJsModuleImports(), ^^^^^^^^^^^^^^^^^^^^^^^^^^ File "G:\chromium\src\mojo\public\tools\bindings\generators\mojom_ts_generator.py", line 633, in _GetJsModuleImports os.path.relpath( File "<frozen ntpath>", line 766, in relpath
具体的修复方法
-
编译参数问题
如果想要获取
chromium
默认的编译参数,可以使用gn args out\Release --list
在
windows
系统上,使用默认参数编译,可以正常打印出调用堆栈信息,并精确到具体的函数及行号。类似于
base::internal::TaskTracker::RunTaskImpl [0x00007FFC2C6E1322+146] (...\task_tracker.cc:679) base::internal::TaskTracker::RunContinueOnShutdown [0x00007FFC2C6E1271+113] (...\task_tracker.cc:656) base::internal::TaskTracker::RunTaskWithShutdownBehavior [0x00007FFC2C6E08EF+143] (...\task_tracker.cc:692) base::internal::TaskTracker::RunTask [0x00007FFC2C6E0259+1993] (...\task_tracker.cc:525) base::internal::TaskTracker::RunAndPopNextTask [0x00007FFC2C6DF3CA+778] (...\task_tracker.cc:418) base::internal::WorkerThread::RunWorker [0x00007FFC2C707E63+1171] (...\worker_thread.cc:438) base::internal::WorkerThread::RunPooledWorker [0x00007FFC2C707862+34] (...\worker_thread.cc:323) base::internal::WorkerThread::ThreadMain [0x00007FFC2C707668+248] (...\worker_thread.cc:303) base::`anonymous namespace'::ThreadFunc [0x00007FFC2C834A92+450] (...\platform_thread_win.cc:142)
在
linux
操作系统上,默认无法打印出调用堆栈涉及的具体行号类似于
#1 0x7fb8361725fa base::debug::StackTrace::StackTrace() #2 0x7fb8361725b5 base::debug::StackTrace::StackTrace() #3 0x7fb8236b7899 net::CertVerifyProc::Verify() #4 0x7fb823704d76 net::(anonymous namespace)::DoVerifyOnWorkerThread() #5 0x7fb823706441 base::internal::FunctorTraits<>::Invoke<>() #6 0x7fb8237063cf base::internal::InvokeHelper<>::MakeItSo<>() #7 0x7fb8237062cd base::internal::Invoker<>::RunImpl<>() #8 0x7fb823706197 base::internal::Invoker<>::RunOnce() #9 0x7fb82370788b base::OnceCallback<>::Run() #10 0x7fb823706b4f base::internal::ReturnAsParamAdapter<>() #11 0x7fb823706f1d base::internal::FunctorTraits<>::Invoke<>() #12 0x7fb823706ed3 base::internal::InvokeHelper<>::MakeItSo<>() #13 0x7fb823706e6d base::internal::Invoker<>::RunImpl<>() #14 0x7fb823706de7 base::internal::Invoker<>::RunOnce()
如果想在
linux
下打印出的堆栈显示具体的行号,可以在out/Release/args.gn
增加配置项enable_stack_trace_line_numbers = true
该配置项只在近两年的版本中支持,古早的版本可能不支持。
该配置项需要注意一点,在启用
is_asan
时,调用StackTrace
是无法打印出带有行号信息的,但是AddressSanitizer
触发时会打印出行号类似于
[801212:801212:0306/100934.195483:INFO:debug_logger.h(28)] chromium(STACK): ~DebugLogger#0 0x5561d07c968e (/home/xina1i/chromium/src/out/Release/chrome+0xca4b68d) #1 0x7f7dfc58397c (/home/xina1i/chromium/src/out/Release/libbase.so+0x158397b) #2 0x7f7dfc4a6cb4 (/home/xina1i/chromium/src/out/Release/libbase.so+0x14a6cb3) #3 0x7f7dfc4a6b25 (/home/xina1i/chromium/src/out/Release/libbase.so+0x14a6b24) ... #111 0x7f7ceba29e40 (/usr/lib/x86_64-linux-gnu/libc.so.6+0x29e3f) #112 0x5561d0782a1a (/home/xina1i/chromium/src/out/Release/chrome+0xca04a19) ================================================================= ==801212==ERROR: AddressSanitizer: heap-use-after-free on address 0x5110004111c0 at pc 0x7f7dfbc24f3f bp 0x7ffeb089feb0 sp 0x7ffeb089fea8 READ of size 1 at 0x5110004111c0 thread T0 (chrome) #0 0x7f7dfbc24f3e in base::internal::(anonymous namespace)::CrashImmediatelyOnUseAfterFree(unsigned long) base/memory/raw_ptr_asan_hooks.cc:53:17 #1 0x7f7dfbc249bf in base::internal::(anonymous namespace)::SafelyUnwrapForDereference(unsigned long) base/memory/raw_ptr_asan_hooks.cc:76:5 #2 0x5561ef31666f in BubbleContentsWrapper* base::internal::RawPtrHookableImpl<true>::SafelyUnwrapPtrForDereference<BubbleContentsWrapper>(BubbleContentsWrapper*) base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_hookable_impl.h:85:9 #3 0x5561ef43f109 in base::raw_ptr<BubbleContentsWrapper, (partition_alloc::internal::RawPtrTraits)0>::GetForDereference() const base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr.h:833:12
-
git
问题git
配置文件.git/config
(linux
),.gitconfig
(windows
)a.
fatal: Out of memory, malloc failed
git
缓存不够,通过更改git
的配置项postbuffer=1048576000
b.
Conflicting directory
目录冲突,这个很有可能是因为git
配置项中的depot_tools
目录不对,改到对应的目录即可 -
vs
环境问题a.
No supported Visual Studio can be found. Supported versions are: 17.0 (2022), 16.0 (2019), 15.0 (2017)
找不到安装的vs
信息,解决:set vs2022_install=D:\tools\vs_community
b.
Exception: Path "D:\Windows Kits\10\\include\10.0.22621.0\\um" from environment variable "include" does not exist. Make sure the necessary SDK is installed.
这个是表明目前构建的chromium
版本需要的windows SDK
版本错误或者是找不到对应的版本, 首先设置
SDK
目录set WINDOWSSDKDIR=D:\Windows Kits\10
, 然后查看
D:\Windows Kits\10\Include
目录下是否存在10.0.22621.0
版本的SDK
,如果不存在,则安装即可c.
midl.exe output different from files
该问题,根据经验应该是msvc
的版本混乱了,比如最新版的需要vs2022
,老版本的需要vs2017
, 安装完
vs2017
之后,没有重启,可能会存在该问题,重启之后,打开特定的vs2017
命令行,重新编译即可d. 提示构建代码需要更高版本的
clang
,比如third_party/llvm-build
中的clang
版本是11.0
,但是提示需要使用11.0 or newer
这个问题一般在编译老版本时出现,主要的原因在于使用了高版本的msvc
,比如安装了vs2019
, 但随着
vs
的更新其对应的msvc也会更新,这就导致部分msvc
的头文件不再支持clang10.0
, 但是我没找到在编译过程中设定只使用固定
msvc
的方法,最后没办法我装了旧版本的vs2017
解决了这个问题 -
编译工具问题
a.
LLVM ERROR: out of memory
这个问题在chromium
最近(2024.03.04
)的版本中经常性遇到,也不知道后期能不能解决
我们在正常默认编译的情况下,会使用ninja -C out\Release chrome
进行编译,ninja
会将所有可使用的cpu全部占用,所以就会有一个问题跑满的情况下,会出现大量的
clang
进程直接把所有的内存也占满,导致oom
,解决办法:ninja -C out\Release -j 12
,限制并发数,从而限制内存的使用,具体使用几个并发,可以自己测试
还有部分上古版本,会涉及到编译器和其对应的c++
标准等,这类的,最好的解决办法是找到当时最新的对应系统进行编译,不然会恶心到想吐。
调试技巧
该部分内容主要写一些在调试chromium
或者其组件过程中可能使用到的部分技巧
使用带console调试
我们在调试chromium
时,如果可以使用日志的话,一般会使用日志,但是在很多third_party
库中无法直接使用base
库中的日志功能,可能需要fprintf
这类的输出来显示我们需要的日志,所以有时候带console
的chromium
就很有用。
-
在
Build.gn
中添加链接选项if (is_win) { ldflags = ["/SUBSYSTEM:CONSOLE"] }
-
启动时启用日志并设置日志等级:
.\out\Release\chrome.exe --enable-logging --v=0
在比较新的系统中,直接使用这种方法应该会报错
ERROR at //BUILD.gn:43:13: Assignment had no effect. ldflags = ["/SUBSYSTEM:CONSOLE"] ^-------------------- You set the variable "ldflags" here and it was unused before it went out of scope.
比较通用的方法是引入
chromium
自身提供的win_console
支持import("//build/config/win/console_app.gni")
在最新版的
chromium
中已经默认支持console
编译(2024.03.05
)