news 2026/10/18 9:36:31

Brave浏览器源码编译实战:从环境搭建到定制拦截规则

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Brave浏览器源码编译实战:从环境搭建到定制拦截规则

简介:Brave浏览器是一款以隐私保护和高效浏览为核心的开源网络浏览器,覆盖MacOS、Windows、Linux及Android多平台,适合关注在线安全、希望摆脱广告干扰的技术爱好者与普通用户。资源包共52个文件,约145KB,以JavaScript脚本为主,辅以Markdown文档、JSON配置、Python工具、RST说明及PNG、SVG等素材,涵盖构建、同步、本地化、补丁更新与测试等模块,并附LICENSE、Jenkinsfile、Makefile等工程文件,便于理解项目结构与开发流程。目前已有896人学习下载。通过该资源,读者可获取Brave浏览器源码的目录组织方式,了解广告拦截、隐私模式、跨平台同步等特性的实现线索,并借助脚本与文档快速上手构建、调试与二次开发,为研究开源浏览器架构提供实用参考。

1. 从一份浏览器源码包说起:它到底能解决什么

如果你正在找一个能直接编译、能改、能塞进自己业务逻辑的浏览器内核,而不是只会在设置里点来点去的成品,那这份 brave-browser 的源码包值得你花一个下午拆一拆。它覆盖 macOS、Windows、Linux 三个桌面端,同时把 Android 端的构建入口也一并放进来了,等于把 Chromium 那套庞大又劝退的工程体系,重新整理成了一份「能照着跑通」的目录结构。我拿到手的第一反应不是它有多完整,而是它把很多原本散落在 Chromium 文档角落里的编译参数、依赖版本、平台差异,提前替你踩平了一部分。适合谁?适合做客户端定制的、做隐私增强功能的、想研究浏览器广告拦截与追踪防护实现路径的工程师。不适合只想找个浏览器日常用的人,那是另一回事。

2. 源码包结构拆解:从目录到构建入口

2.1 顶层目录里哪些是真正要动的

打开压缩包,第一层通常能看到src/、build/、patches/、scripts/这几类目录。src/是主体,里面又按 Chromium 的老规矩分成chrome/、content/、third_party/、components/。很多人一上来就扎进chrome/browser/找功能入口,结果编译一次四十分钟,改一行等半天。我的习惯是先看patches/,因为 brave 的很多差异化能力——广告拦截、追踪防护、Brave Rewards——并不是直接写在src/里,而是以补丁形式叠加在 Chromium 之上的。这意味着你如果直接改src/,下次同步上游时冲突会非常难受。

scripts/目录是这份包最值钱的地方。它通常包含build.sh、sync.sh、package.sh这类脚本,把gclient、gn、ninja的调用顺序固定下来。新手最容易翻车的地方就是跳过脚本手动执行gn gen,结果参数对不上,报一堆undefined symbol。我一般会先读build.sh里的gn args,把is_official_build、is_debug、target_cpu、enable_nacl这几个关键开关记下来,后面调参才有依据。

2.2 构建入口与平台差异

桌面端和 Android 端的构建入口是分开的。桌面端走gn gen out/Default然后ninja -C out/Default chrome,Android 端则要先source build/android/envsetup.sh,再gn gen out/Android --args='target_os="android" target_cpu="arm64"'。这里有个血泪经验:Android 构建对 JDK 版本极其敏感,JDK 11 和 JDK 17 混用会直接卡在javac阶段,报invalid source release。我一般会在~/.bashrc里把JAVA_HOME锁死到脚本里指定的那个版本,而不是依赖系统默认。

# 桌面端最小构建流程,假设已安装 depot_tools export PATH="$PWD/depot_tools:$PATH" gclient sync --with_branch_heads --with_tags gn gen out/Default --args=' is_debug=false is_official_build=true target_cpu="x64" enable_nacl=false blink_symbol_level=0 ' ninja -C out/Default chrome -j 8

这段脚本里,gclient sync负责拉齐所有第三方依赖,--with_branch_heads是为了后续能切分支。gn gen里的is_official_build=true会开启 LTO 和更激进的优化,编译时间翻倍但产物更小;blink_symbol_level=0是砍掉 Blink 的调试符号,能省下好几个 G 的磁盘。ninja -j 8的并行数别盲目拉满,内存 16G 的机器开到 8 已经是上限,再高会触发 OOM Killer,编译进程直接被系统杀掉,日志里只留一个Killed,非常玄学。

2.3 补丁机制与功能定位

brave 的广告拦截核心在components/brave_shields/,追踪防护的规则集通常以adblock-rust或类似的 Rust 组件形式存在。如果你要改拦截规则,别去改src/chrome/,而是找patches/下对应的.patch文件,改完再重新应用。应用补丁的命令一般是:

# 在 src 目录下应用单个补丁 git apply ../patches/brave_shields_custom.patch # 如果冲突,先看 reject 文件 find . -name "*.rej" -exec cat {} \;

git apply失败时生成的.rej文件会告诉你哪几行没打上,通常是上游 Chromium 改了同名函数签名。这时候要么手动合并,要么用patch -p1 --merge走三方合并。我一般会先把补丁按功能分组,每次只应用一组,编译通过再应用下一组,避免一次性炸掉整个构建。

3. 从零编译到跑通:参数、依赖与排错

3.1 依赖安装的版本陷阱

Linux 下编译 Chromium 系浏览器,官方文档列了一长串apt install,但真正会卡住你的是版本。比如libc++的 ABI 版本、clang的版本必须和buildtools/里自带的那个一致。我见过最典型的翻车是系统装了clang-14,但源码要求clang-16,链接阶段报undefined reference to std::__1::...。解决办法不是升级系统 clang,而是直接用depot_tools里的clang,在gn args里加clang_use_chrome_plugins=false和use_custom_libcxx=true。

Windows 端则是另一套坑。必须用depot_tools自带的python3和ninja,Visual Studio 的版本要严格对应,比如vs2019和vs2022的toolchain路径不同。我一般会在gn args里显式写visual_studio_version="2019",而不是让它自动探测。自动探测在装了多个 VS 版本的机器上经常选错,报msvc_toolchain not found。

3.2 编译参数怎么调才不翻车

gn args里几个关键参数直接决定你能不能编过:

参数推荐值作用翻车点
is_debugfalse关闭调试,开启优化设 true 编译慢且产物巨大
is_component_buildfalse静态链接,产物独立设 true 在 Linux 下容易缺 so
symbol_level0砍符号,省磁盘设 2 会多占 20G+
enable_naclfalse关掉已废弃的 NaCl设 true 会拉一堆旧依赖
target_cpux64 / arm64目标架构和主机不一致时需交叉编译工具链

我一般会先跑一次gn gen不带任何自定义参数,看默认值是什么,再逐项覆盖。直接抄网上的参数列表,很容易因为源码版本不同导致某个参数已废弃,gn直接报unknown argument。

3.3 编译失败时先看什么

编译报错别急着搜,先看日志最后 50 行。ninja的报错通常分三类:依赖缺失(fatal error: xxx.h: No such file)、链接错误(undefined reference)、工具链错误(clang: error: unknown argument)。依赖缺失多半是gclient sync没跑完,重新跑一次并加--force。链接错误先确认is_component_build和use_custom_libcxx是否匹配。工具链错误直接检查gn args里的clang_version和visual_studio_version。

# 查看完整编译日志并过滤错误 ninja -C out/Default chrome -j 8 2>&1 | tee build.log grep -E "error:|fatal error:|undefined reference" build.log | head -30

tee是为了保留完整日志,grep过滤出关键错误行。如果错误行超过 30 条,说明是系统性问题,别逐条修,先回退到上一个能编过的参数组合。

4. 避坑与常见问题排查

4.1 现象:gclient sync卡在Fetching不动

原因:默认走的是git协议拉取,某些网络环境下会超时,但gclient不会主动报错,只是无限重试。解决:在.gclient文件里把solutions的url改成https开头,并设置GIT_HTTP_LOW_SPEED_LIMIT和GIT_HTTP_LOW_SPEED_TIME环境变量,让 git 快速失败而不是挂死。

4.2 现象:编译到一半报Killed,没有其他错误

原因:ninja -j并行数过高,内存耗尽被系统 OOM Killer 杀掉。解决:把-j降到 4 或 6,或者加交换分区。我一般会在编译前用free -h看可用内存,按每核 1.5G 估算并行数。

4.3 现象:Android 端gn gen报no such file: build/android/envsetup.sh

原因:gclient sync没有拉取 Android 相关依赖,或者target_os没设对。解决:先确认.gclient里target_os = ['android'],再跑gclient sync,最后source build/android/envsetup.sh。顺序错了就会找不到文件。

4.4 现象:补丁应用后编译报redefinition of ...

原因:补丁和当前源码版本不匹配,同一个函数被定义了两次。解决:先git checkout -- .回退所有改动,再逐个补丁应用,每应用一个就编译一次,定位到具体是哪个补丁冲突。别一次性全打上。

4.5 现象:Windows 下ninja报CreateProcess failed

原因:路径里有空格或中文,ninja对路径非常敏感。解决:把源码放到纯英文无空格的路径下,比如D:\dev\brave\,别放在C:\Users\某某\Desktop\。

5. 进阶:定制拦截规则与验证方法

5.1 改拦截规则并验证生效

brave 的拦截规则通常以adblock-rust的Engine形式加载。如果你想加一条自定义规则,别直接改src/里的默认列表,而是在components/brave_shields/browser/下找到规则加载入口,通过Engine::from_rules追加。改完编译后,验证方法是打开开发者工具,在 Console 里执行:

// 检查当前页面的拦截规则是否包含自定义条目 const rules = await chrome.braveShields.getRules(); console.log(rules.filter(r => r.includes('your-custom-rule')));

如果返回空数组,说明规则没加载上,检查gn args里brave_shields_enabled是否为 true,以及规则文件路径是否被正确打包进resources.pak。

5.2 用--enable-logging看拦截日志

编译出的浏览器启动时加--enable-logging=stderr --v=1,可以在终端看到拦截引擎的详细日志。我一般会过滤adblock关键字:

./out/Default/chrome --enable-logging=stderr --v=1 2>&1 | grep -i adblock

日志里会显示每条规则匹配了哪个请求,如果某条规则一直不生效,先看日志里有没有rule parsed,没有就是规则语法写错了。

5.3 跨平台产物验证清单

编译完成后别急着打包,先按这个清单过一遍:

平台验证项命令/操作
Linux可执行文件依赖ldd out/Default/chrome看有无 missing
Windows签名与版本右键属性看版本号是否和gn args一致
macOS公证与权限codesign -dv out/Default/Chromium.app
AndroidAPK 安装adb install out/Android/apks/Brave.apk

我吃过一次亏:Linux 下编译通过,但ldd显示缺libnss3.so,拿到另一台机器上直接跑不起来。从那以后我每次编译完都强制走一遍ldd和codesign,不管多急。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/18 9:33:02

context-mode:让应用场景感知成为一等公民的设计与落地

刚开始把一个内部工具重构到能按场景自动调整行为时,我并没有意识到自己其实是在做一套“context-mode”(上下文模式)机制。当时只是觉得代码里到处是if (is.edit.page)、if (current.project xxx)这种判断太难受:新功能每加一个…

作者头像 李华
网站建设 2026/10/18 9:31:05

从脚手架到产品级插件系统:DeepSeek Harness 架构设计与工程实践

1. 从脚手架到产品:一个被低估的工程命题第一次看到“万物皆插件”这个说法,我脑子里蹦出来的不是某个具体框架,而是一个很朴素的工程直觉:真正难的不是把功能做出来,而是让功能可以被无限地拼装、替换、卸载&#xff…

作者头像 李华
网站建设 2026/10/18 9:30:55

办公用品直售系统毕设方案:SpringBoot+Vue+MySQL全栈实现

简介:基于JAVASpringBootVueMySQL开发的日常办公用品直售系统毕业设计,面向计算机专业学生,可用于毕业设计、课程设计或期末大作业;项目经导师指导并通过高分,前后端代码齐备,涵盖商品展示、购物车、订单处…

作者头像 李华
网站建设 2026/10/18 9:29:32

TI电机库框架详解:从FOC到C2000例程移植的完整拆解

直接打开一个TI电机库例程,很多人第一反应是懵的:几十个文件夹、上百个源文件、一堆看不懂的宏定义和中断函数,不知道从哪下手。这篇文章我准备把这套框架从头到尾拆一遍,讲清楚它到底分几层、每层干什么、文件之间怎么协作&#…

作者头像 李华
网站建设 2026/10/18 9:28:12

前端技能栈跨框架移植:路由机制解耦与标准化实践

1. 从一个真实困境说起:为什么技能栈会被框架绑架我见过太多团队在技术选型上反复横跳,最后把自己拖进泥潭。最典型的一个场景是:前端团队花了半年时间把一套业务组件库打磨得非常成熟,路由跳转、状态管理、权限校验、埋点上报全都…

作者头像 李华
网站建设 2026/10/18 9:27:43

零基础Linux运维实战:从虚拟机搭建到Shell脚本自动化

如果你打算进入运维行业,或者在 2026 年想给自己补一门后端工程师的底层技能,Linux 命令这一关是绕不过去的。这篇教程不给你讲一堆抽象概念,而是直接走一条完整路径:先在你自己的电脑上把虚拟机装好,再把 Linux 系统部…

作者头像 李华