{"id":22225160,"url":"https://github.com/mbbill/webkit-porting","last_synced_at":"2025-10-12T19:08:28.666Z","repository":{"id":39304963,"uuid":"367482819","full_name":"mbbill/WebKit-Porting","owner":"mbbill","description":"WebKit 在嵌入式设备上的移植和定制","archived":false,"fork":false,"pushed_at":"2021-07-14T04:10:39.000Z","size":1257,"stargazers_count":10,"open_issues_count":0,"forks_count":2,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-07-05T01:03:26.722Z","etag":null,"topics":["webkit"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mbbill.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-05-14T21:25:53.000Z","updated_at":"2025-05-30T09:53:39.000Z","dependencies_parsed_at":"2022-09-01T08:01:17.312Z","dependency_job_id":null,"html_url":"https://github.com/mbbill/WebKit-Porting","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mbbill/WebKit-Porting","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mbbill%2FWebKit-Porting","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mbbill%2FWebKit-Porting/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mbbill%2FWebKit-Porting/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mbbill%2FWebKit-Porting/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mbbill","download_url":"https://codeload.github.com/mbbill/WebKit-Porting/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mbbill%2FWebKit-Porting/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279012639,"owners_count":26085158,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-12T02:00:06.719Z","response_time":53,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["webkit"],"created_at":"2024-12-03T00:15:50.760Z","updated_at":"2025-10-12T19:08:28.650Z","avatar_url":"https://github.com/mbbill.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# WebKit 在嵌入式设备上的移植和定制\n\n这个文档的标题是“WebKit 在嵌入式设备上的移植和定制”。这是标题看起来很大，而且似乎不是很容易让人明白到底要做什么，所以我先来简单介绍一下写这一系列文档的目的。\n\n一般来说提到“移植”一个项目，尤其是在嵌入式设备上的“移植”，就是把一个项目改一改，拿厂商的toolchain（一般来说是交叉编译器）编译一下，然后跑在某个特定的bsp上。这个bsp很多时候是一些特定的Linux内核加上一些用户态的支撑库，同时他们很多都是高度定制的。或者也可以是某个支持POSIX API的RTOS，例如RT-Thread smart。\n\n如果单单是希望在类似Ubuntu这样的Linux发行版上跑WebKit，那太简单了，直接编译WebKitGTK就可以了。但是如果用户态是定制的，那么很多事情就变得棘手， 比如：\n- 如果需要的第三方库不存在怎么办？例如bsp没有GTK。\n- 如果需要的第三方库和bsp提供的版本不兼容怎么办？\n- 那些高度依赖硬件的部分怎么处理？例如音频，视频，渲染加速等等。\n- 如果CPU指令集是定制的怎么办？比如遇到一个MIPS的，或者其他更诡异的芯片，我是不是要去重写JIT？那些ARM/X86_64汇编我要不要重写？\n- 如果bsp存在一些硬性限制怎么办？比如很多厂商因为安全的缘故禁止申请executable memory，那么很显然所有需要JIT的部分都无法执行了，包括JavaScript JIT, CSS JIT, Regexp JIT等等。那JIT被砍掉以后怎么跑解释器？\n- 有些厂商甚至禁止fork，任务必须是单进程，只允许多线程。那么WebKit需要的多进程模型怎么解决？\n\n还有其他许许多多诸如此类的问题。一般来说这样的项目投入都非常的大，我们都不太希望在项目进行到一半的时候遇到一些过不去的坎，以至于要推倒重来，或者导致项目失败。所以这也是我写这一系列文章的目的。\n\n## 为什么选择WebKit\n\n目前三大主流浏览器 —— Chrome，Safari(WebKit)和Firefox各自都有自己的内核，其他浏览器基本上都是从这三个改出来的。\n- Chrome在最开始的时候使用的是WebKit，没过几年就分支出来变成了Blink。Blink在Chrome里面的作用是一个排版引擎。一般来说我们平时谈论的网页渲染会经历很多个步骤，从下载，排版，绘制，CSS加速，GPU渲染等等。Blink在Chrome中主要是完成的排版和一小部分渲染工作，所以它已经不再像WebKit一样是一个完整的浏览器。从这个意义上说单独移植Blink是没有意义的，而且Blink也不能脱离Chrome单独运行。以后如果有时间我可以再写写移植Chrome的难点，但是总的来说Chrome是不适合嵌入式设备的。\n- WebKit目前支撑着Safari，Epiphany这一类略显小众的浏览器。虽然WebKit的代码规模比Chrome小很多，但也是千万行级别的。从可移植性的角度来看，WebKit比Chrome好很多，因为：\n  - WebKit原生支持Linux，目前官方有WebKitGTK和WebKitWPE可以在Linux上轻松编译。\n  - WebKit依赖库比Chrome少很多，而且可以根据需求裁剪。例如在不需要多媒体支持的时候可以裁剪掉Gstreamer。\n  - WebKit可以依赖平台本身提供的第三方库进行编译，而Chrome大多数第三方库都是自带，也就意味着需要自己移植（考虑到需要的资源，我感觉目前除了Google以外基本是不可能做到的）。\n  - WebKit可以裁剪到很小的尺寸。目前极限大概可以砍到30M以内。\n  - WebKit有一个性能非常不错的JavaScript 引擎，更难能可贵的是这个JavaScript引擎通过一定的修改可以做到完全平台无关的解释执行。这一点后面会详细说。\n  - WebKit有一个相对简单的渲染路径，虽然性能不是特别好，但是对某些特定的情况比较友好。\n  - 还有很多优点我会在下面每个章节详细说。\n- 但是无论如何WebKit都始终是一个极其庞大的项目。如果要用来做项目，那么如果没有对它细致地了解，很多事情是搞不定的。这需要时间和耐心，对着代码思考，然后慢慢的上手。希望像其他项目一样拿来改一下编译脚本就能跑是不太可能的。我会在后面每一个段落尽量解释所有难点和细节。\n\n\n## [WebKit的项目结构](Contents/ProjectStructure.md)\n\n介绍WebKit整个项目的组成结构，包括目录结构，编译组件的依赖关系等等。\n\n## [WebKit的编译过程](Contents/Compilation.md)\n\nWebKit每一个组件的编译过程都非常复杂。这部分会先大致梳理一遍整个项目的编译过程。具体每个组件的细节会在对应的章节详细介绍。\n\n\n## [WTF移植](Contents/WTF.md)\n\nWTF是Web Template Framework的缩写。这个库原本是JavaScriptCore的一部分，后面独立出来变成一个公共库，为WebKit提供一些基础组件。\n\n## [JavaScriptCore移植](Contents/JSC.md)\n\nJSC是JavaScriptCore的缩写。JSC是WebKit自带的JavaScript引擎。在早年Chrome仍然使用WebKit的时候曾有过两套JavaScript引擎的绑定，一个是JSC，另一个是V8。在Chrome独立出去以后JSC就成为WebKit默认且唯一的JavaScript引擎。\n\n## [WebCore移植](Contents/WebCore.md)\n\nWebCore是WebKit的核心组件。它主要提供的功能是排版（Layout），渲染，多媒体，网络，W3C各种标准的实现，等等。虽然其中有些功能并不完全在WebCore中实现，例如网络和渲染有单独的进程负责，但是WebCore依然是处理绝大多数事情的中心。\n\n## [WebKit的图形与渲染](Contents/Graphics.md) [WIP]\n\nWebKit目前有两套相对独立的渲染路径。一个是以Apple体系下的图形库为主，主要依靠*CoreGraphics*和*CoreAnimation*进行渲染。这个渲染路径涉及到的依赖库主要都是苹果系统上独占的闭源库，所以只能在苹果系统下使用，例如macOS或者iOS。第二个渲染路径基于GTK/Cairo/OpenGL，依靠开源的的图形库从而支持Linux系统下的`WebKitGTK`和`WebKitWPE`。这么看的话我们在移植WebKit的时候只能选择这第二条渲染路径。这个章节会讨论GTK和Cairo的2D绘图以及OpenGL支持下的CSS动画加速。\n\n## [WebKit的单进程与多进程架构](Contents/MultiProcessing.md) [WIP]\n\n可能很多人都知道Chrome的多进程架构以及因此造成的内存占用问题，很多人不知道的是目前WebKit也是如此。比如在Mac上打开Safari以后查看进程树就会发现诸如`UIProcess` `WebProcess` `NetworkPocess` 这些子进程。\n\n在Chrome中每个tab都会占用一个子进程，叫做`RenderProcess`负责渲染。WebKit中对应的子进程是`WebProcess`。虽然在功能划分上他们之间有不少区别，但是概念上大同小异，都是把一部分网页渲染的内容放到了这个子进程中。\n\n这一部分会详细介绍WebKit多进程架构的相关内容以及移植要点。\n\n\n## [WebKit多媒体支持](Contents/MultiMedia.md) [WIP]\n\n音频和视频部分与图形渲染的情形基本相同——Apple自己有一套基于自身生态系统的移植，同时开源社区维护者一套基于Gstreamer的播放器实现。他们都支持传统的url播放和目前比较流行的以MSE/EME为基础的adaptive streaming。\n\n## [WebKit功能模块裁剪](Contents/Features.md) [WIP]\n\n这部分会讨论在嵌入式平台上可以裁剪掉的一些不常用的组件，例如WebRTC等等。\n\n## [Web Inspector](Contents/Inspector.md) [WIP]\n\nInspector是WebKit的一个非常重要的组件。WebKit的Inspector支持本地和远程模式。本质上Inspector的UI也是一个网页。在本地模式时Inspector页面和被调试页面归属同一个WebKit UI进程管理，而远程模式下Inspector页面会运行在另一个浏览器上，然后通过IPC和被调试浏览器通信。远程模式类似remote gdb，但是和gdb不同的是WebKit的Inspector在Linux上走D-Bus协议，而在Apple平台走XPC协议。这部分会讨论用*WebSocket*实现Inspector来做到减少依赖以及跨平台。\n\n## 附录\n\n下面是我过去编写的一些相关资料。他们可能有一些过时，然后不全是中文，所以在以后有空的时候我会逐步翻译。\n\n- [WebKit Build Process](Appendix/WebKitBuildProcess.md)\n- [打造一个可移植的JS引擎](Appendix/PortableJSEngine.md)\n- [Ref and RefPtr](Appendix/Ref_RefPtr.md)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmbbill%2Fwebkit-porting","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmbbill%2Fwebkit-porting","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmbbill%2Fwebkit-porting/lists"}