编译chromium
系统要求
- A mac, intel or M1
- Xcode
- The macOS SDK. 运行下面的命令来检测是不是已经安装
ls `xcode-select -p`/Platforms/MacOSX.platform/Developer/SDKs
- An APFS-formatted volume (macOS系统的默认文件系统格式)
安装 depot_tools
下载 depot_tools
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
将depot_tools添加到环境变量PATH中
export PATH="$PATH:/path/to/depot_tools"
获取chromium源码
新建chromium目录来放置源码, 需要大概100G的空间,如果没有,最后会因为空间不足而失败。
mkdir chromium && cd chromium
拉取源码, 这个取决于你的网络速度,一般要几个小时,所以可以放到晚上拉取, 还有如果失败要重试,使用gclient sync
命令
caffeinate fetch chromium
配置build参数
通过GN工具生成.ninja配置文件,通过ninja工具编译
生成build目录
gn gen out/Default
编译Chromium
有5万多个文件需要编译,一般也需要2-3个小时,所以也可以放到晚上编译。
autoninja -C out/Default chrome
运行编译好的Chromium
out/Default/Chromium.app/Contents/MacOS/Chromium
调试Chromium
目前有几种方式来调试Chromium
- 添加日志代码,然后通过日志来调试
- 使用lldb调试
- 使用Xcode调试, 这个xcode占用内存太大,不推荐使用
这次重点介绍使用lldb单步调试Chromium
重新编译Chromium debug版本
生成Xcode项目
gn gen out/Debug
添加debug参数到args.gn,
vim out/Debug/args.gn
is_debug = true is_component_build = true symbol_level = 2
重新编译chromium
autoninja -C out/Debug chrome
调试Chromium
打开Chromium
./out/Debug/Chromium.app/Contents/MacOS/Chromium
在out/Debug目录打开lldb,如果不在这个目录下面打开会导致符号表找不到,也可以使用下面的命令设置符号表路径
platform settings -w /path/to/chromium/src/out/Debug/
lldb (lldb) attach ${chrome main process id}
在主进程的代码位置(chrome/browser/ui/views/tabs/new_tab_button.cc:void NewTabButton::NotifyClick)处打断开,然后就可以开始调试了
(lldb) breakpoint set -f chrome/browser/ui/views/tabs/new_tab_button.cc --line 203 (lldb) c
打开断点后,回到chromium, 点击新建标签页,就会触发断点,然后就可以开始调试了
Process 57308 stopped * thread #1, name = 'CrBrowserMain', queue = 'com.apple.main-thread', stop reason = breakpoint 1.1 frame #0: 0x0000000152d7efe8 libchrome_dll.dylib`NewTabButton::NotifyClick(this=0x00007faed48d6000, event=0x00007ff7b6fb35e0) at new_tab_button.cc:203:28 200 } 201 202 void NewTabButton::NotifyClick(const ui::Event& event) { -> 203 ImageButton::NotifyClick(event); 204 views::InkDrop::Get(this)->GetInkDrop()->AnimateToState( 205 views::InkDropState::ACTION_TRIGGERED); 206 } Target 0: (Chromium) stopped. (lldb) n Process 57308 stopped * thread #1, name = 'CrBrowserMain', queue = 'com.apple.main-thread', stop reason = step over frame #0: 0x0000000152d7eff5 libchrome_dll.dylib`NewTabButton::NotifyClick(this=0x00007faed48d6000, event=0x00007ff7b6fb35e0) at new_tab_button.cc:204:3 201 202 void NewTabButton::NotifyClick(const ui::Event& event) { 203 ImageButton::NotifyClick(event); -> 204 views::InkDrop::Get(this)->GetInkDrop()->AnimateToState( 205 views::InkDropState::ACTION_TRIGGERED); 206 } 207 Target 0: (Chromium) stopped. (lldb) v (NewTabButton *) this = 0x00007faed48d6000 (const ui::Event &) event = 0x00007ff7b6fb35e0 {} (lldb) p event (const ui::Event) $1 = { type_ = ET_MOUSE_RELEASED time_stamp_ = { base::time_internal::TimeBase<base::TimeTicks> = { us_ = (value_ = 1573625617957) } } latency_ = { latency_components_ = { base::internal::flat_tree<ui::LatencyComponentType, base::internal::GetFirst, std::__Cr::less<void>, std::__Cr::vector<std::__Cr::pair<ui::LatencyComponentType, base::TimeTicks>, std::__Cr::allocator<std::__Cr::pair<ui::LatencyComponentType, base::TimeTicks> > > > = { comp_ = {} body_ = size=2 { [0] = { first = INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT second ={...} } [1] = { first = INPUT_EVENT_LATENCY_UI_COMPONENT second ={...} } } } } trace_id_ = -1 ukm_source_id_ = 0 coalesced_ = false began_ = false terminated_ = false source_event_type_ = MOUSE gesture_scroll_id_ = 0 touch_trace_id_ = 0 } flags_ = 2048 native_event_ = { objc_storage_ = base::apple::OwnedNSEvent::ObjCStorage @ 0x000060000212c2d0 { __value_ = 0x000060000212c2d0 } } cancelable_ = true target_ = { wrapped_ptr_ = 0x00007faed48d6000 } phase_ = EP_TARGET result_ = ER_UNHANDLED source_device_id_ = -1 properties_ = nullptr { __value_ = nullptr } }
在上面的设计过程,使用了next,print等命令,可以比较清楚看到event里面的所有内容,这样就可以很方便的调试了。