Preparation Steps
Pull WebKit source code (if the entire repository is too large, shallow clone is sufficient)
git clone [email protected]:WebKit/WebKit.git
💡 Note that not every WebKit commit is guaranteed to compile successfully on every platform, so it’s best to choose a commit from a released version based on Tags
For example, if you need to compile for iOS, you can refer to the WebKit versions in different iOS versions:
Safari Version | iOS System Version | WebKit Commit SHA1 |
---|---|---|
15.2 | 15.2 | de716213341fb69ca485433834244ae0de02fb03 |
15.1 | 15.1.1 | ff9adb92d9179a1fddd300aabb6668c1a2ab14e6 |
15.1 | ||
15 | 15.0.2 | 6a577b88c820c9744976abfe014ee1089d124150 |
15.0.1 | ||
15.0 |
Additionally, since conditions vary across devices, the most reliable approach is to first check the webkit CI machine list to find a recently successful build version number from a machine with similar operating system version and Xcode version to yours.
For example, I found this build has similar machine configuration to mine and is also a successful build record for iOS 15 Simulator that I want to build, so I’ll try building at this commit (though the commit sha1 isn’t visible here, you can find the corresponding commit through the commit message)
Place the following content in environment variables (remember to replace the WEBKIT_PROJECT variable)
export WEBKIT_PROJECT="$HOME/path-to-webkit"
export PATH="$WEBKIT_PROJECT/Tools/Scripts:$PATH" # For convenient script calls
export PYTHONPATH="$WEBKIT_PROJECT/Tools/Scripts:$PYTHONPATH" # To make lldb_webkit.py run correctly
export DYLD_FRAMEWORK_PATH="$WEBKIT_PROJECT/WebKitBuild/Debug" # Make Xcode or Safari use our compiled WebKit instead of the system one
Then add the following to ~/.lldbinit (remember to replace <path-to-webkit>
), this script helps us display C++ variables in a better format in Xcode:
command script import <path-to-webkit>/Tools/lldb/lldb_webkit.py
Also replace line 1063 of lldb_webkit.py code from A to B (should be a current WebKit script bug):
def get_child_index(self, name):
if name == "m_table":
return self.tableSize()
else:
return int(name.lstrip('[').rstrip(']'))
def get_child_index(self, name):
if name == "m_table" or name == "m_tableForLLDB":
return self.tableSize()
else:
return int(name.lstrip('[').rstrip(']'))
Then compile the code, the artifacts will be placed in the $WEBKIT_PROJECT/WebKitBuild directory:
build-webkit --debug
If you need to build for iOS, you can choose:
sudo Tools/Scripts/configure-xcode-for-embedded-development
build-webkit --debug --ios-simulator
This script will mainly build the following projects:
- libwebrtc
- TestWebKitAPI
- gtest
- WebKitTestRunner
- DumpRenderTree
- WebKit
- WebKitLegacy
- WebCore
- WebGPU
- JavaScriptCore
- WTF
- bmalloc
- ANGLE
- ImageDiff
Next, open the project with Xcode
open WebKit.xcworkspace/
Configure the project settings (File > Workspace Settings… > Advanced… > Custom > Relative to Workspace) to let Xcode know our built artifacts are in the WebKitBuild directory:
Select MiniBrowser in the top Run Scheme:
If needed, you can change the default address to localhost address in Tools/MiniBrowser/Mac/SettingsController.m:
Click run and start debugging!
Debugging Entry Points
- Creating Document object: DocumentWriter::begin(const URL& urlReference, bool dispatch, Document* ownerDocument)
- Parsing HTML StyleSheets: resolveStyle
- Document::resolveStyle(ResolveStyleType type): Resolves document style, which includes parsing StyleSheets in the document
- Element::resolveStyle(const RenderStyle* parentStyle): Resolves Style belonging to a single Dom
Debugging Tips
Identifying the Element corresponding to the current RenderObject
You can print in lldb:
# Print id
p ((WebCore::HTMLElement &)this->m_node).m_elementData.m_ptr->m_idForStyleResolution
# Print class
p ((WebCore::HTMLElement &)this->m_node).m_elementData.m_ptr->m_classNames.m_data.m_ptr
# Print tag
p ((WebCore::HTMLElement &)this->m_node).m_tagName.m_impl.m_ptr->m_localName
Dump Render Tree
<path-to-webkit>/WebKitBuild/Debug/DumpRenderTree <url>
This will print out the Render Object corresponding to the Dom in the webpage