简介: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_debug | false | 关闭调试,开启优化 | 设 true 编译慢且产物巨大 |
is_component_build | false | 静态链接,产物独立 | 设 true 在 Linux 下容易缺 so |
symbol_level | 0 | 砍符号,省磁盘 | 设 2 会多占 20G+ |
enable_nacl | false | 关掉已废弃的 NaCl | 设 true 会拉一堆旧依赖 |
target_cpu | x64 / 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 -30tee是为了保留完整日志,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 |
| Android | APK 安装 | adb install out/Android/apks/Brave.apk |
我吃过一次亏:Linux 下编译通过,但ldd显示缺libnss3.so,拿到另一台机器上直接跑不起来。从那以后我每次编译完都强制走一遍ldd和codesign,不管多急。希望帮到你。
本文还有配套的精品资源,点击获取