Start collecting documentation, and add an in-tree glossary. Encourage new contributors to add missing entries as appropriate.

This commit is contained in:
Josh Matthews 2016-04-18 12:42:33 -04:00
parent a76af66abb
commit c0524b3c47
5 changed files with 33 additions and 6 deletions

284
docs/HACKING_QUICKSTART.md Normal file
View file

@ -0,0 +1,284 @@
# Hacking Servo - Quickstart
This guide covers the basics things one needs to know to start hacking Servo.
It doesn't cover how Servo works (see the [documentation](#documentation) section for that),
but describe how to setup your environment to compile, run and debug Servo.
## Building Servo
Building Servo is quite easy. Install the prerequisites described in the [README](./README.md) file. Then type:
```shell
./mach build -d
```
*Note: on Mac, you might run into a SSL issue while compiling. You'll find a solution to this problem [here](https://github.com/sfackler/rust-openssl/issues/255).*
The `-d` option means "debug build". You can also build with the `-r` option which means "release build". Building with `-d` will allow you to use a debugger (lldb). A `-r` build is more performant. Release builds are slower to build.
You can use and build a release build and a debug build in parallel.
## Running Servo
The servo binary is located in `target/debug/servo` (or `target/release/servo`). You can directly run this binary. But we recommend using `./mach` instead:
``` shell
./mach run -d -- http://github.com
```
… is equivalent to:
``` shell
./target/debug/servo http://github.com
```
If you build with `-d`, run with `-d`. If you build with `-r`, run with `-r`.
## ./mach
`mach` is a python utility that does plenty of things to make our life easier (build, run, run tests, update dependencies… see `./mach --help`). Beside editing files and git commands, everything else is done via `mach`.
``` shell
./mach run -d [mach options] -- [servo options]
```
The `--` separates `mach` options from `servo` options. This is not required, but we recommend it. `mach` and `servo` have some options with the same name (`--help`, `--debug`), the `--` makes it clear where options apply.
## Mach and Servo options
This guide only covers the most important options. Be sure to look at all the available mach commands and the servo options:
``` shell
./mach --help # mach options
./mach run -- --help # servo options
```
## Some basic Rust
Even if you have never seen any Rust code, it's not too hard to read Servo's code. But there are some basics things one must know:
- [Match](https://doc.rust-lang.org/book/match.html) and [Patterns](https://doc.rust-lang.org/book/patterns.html)
- [Options](http://rustbyexample.com/std/option.html)
- [Expression](http://rustbyexample.com/expression.html)
- [Traits](http://rustbyexample.com/trait.html)
- That doesn't sound important, but be sure to understand how `println!()` works, especially the [formatting traits](https://doc.rust-lang.org/std/fmt/#formatting-traits)
This won't be enough to do any serious work at first, but if you want to navigate the code and fix basic bugs, that should do it. It's a good starting point, and as you dig into Servo source code, you'll learn more.
For a more exhaustive documentation:
- [doc.rust-lang.org](https://doc.rust-lang.org)
- [rust by example](http://rustbyexample.com)
## Cargo and Crates
A Rust library is called a crate. Servo uses plenty of crates. These crates are dependencies. They are listed in files called `Cargo.toml`. Servo is split in components and ports (see `components` and `ports` directories). Each has its own dependencies, each has its own `Cargo.toml` file.
`Cargo.toml` files list the dependencies. You can edit this file.
For example, `components/net_traits/Cargo.toml` includes:
```
[dependencies.stb_image]
git = "https://github.com/servo/rust-stb-image"
```
But because `rust-stb-image` API might change over time, it's not safe to compile against the `HEAD` of `rust-stb-image`. A `Cargo.lock` file is a snapshot of a `Cargo.toml` file which includes a reference to an exact revision, ensuring everybody is always compiling with the same configuration:
```
[[package]]
name = "stb_image"
source = "git+https://github.com/servo/rust-stb-image#f4c5380cd586bfe16326e05e2518aa044397894b"
```
This file should not be edited by hand. In a normal Rust project, to update the git revision, you would use `cargo update -p stb_image`, but in Servo, use `./mach cargo-update -p stb_image`.
See [Cargo's documentation about Cargo.toml and Cargo.lock files](http://doc.crates.io/guide.html#cargotoml-vs-cargolock).
## Working on a Crate
As explained above, Servo depends on a lot of libraries, which makes it very modular. While working on a bug in Servo, you'll often end up in one of its dependencies. You will then want to compile your own version of the dependency (and maybe compiling against the HEAD of the library will fix the issue!).
For example, I'm trying to bring some cocoa events to Servo. The Servo window on Desktop is constructed with a library named [Glutin](https://github.com/tomaka/glutin). Glutin itself depends on a cocoa library named [cocoa-rs](http://github.com/servo/cocoa-rs). When building Servo, magically, all these dependencies are downloaded and built for you. But because I want to work on this cocoa event feature, I want Servo to use my own version of *glutin* and *cocoa-rs*.
This is how my projects are laid out:
```
~/my-projects/servo/
~/my-projects/cocoa-rs/
~/my-projects/glutin/
```
These are all git repositories.
To make it so that servo uses `~/my-projects/cocoa-rs/` and `~/my-projects/glutin/` , create a `~/my-projects/servo/.cargo/config` file:
``` shell
$ cat ~/my-projects/servo/.cargo/config
paths = ['../glutin', '../cocoa-rs']
```
This will tell any cargo project to not use the online version of the dependency, but your local clone.
For more details about overriding dependencies, see [Cargo's documentation](http://doc.crates.io/guide.html#overriding-dependencies).
## Debugging
### Logging:
Before starting the debugger right away, you might want get some information about what's happening, how, and when. Luckily, Servo comes with plenty of logs that will help us. Type these 2 commands:
``` shell
./mach run -d -- --help
./mach run -d -- --debug help
```
A typical command might be:
``` shell
./mach run -d -- -i -y 1 -t 1 --debug dump-layer-tree /tmp/a.html
```
… to avoid using too many threads and make things easier to understand.
On OSX, you can add some Cocoa-specific debug options:
``` shell
./mach run -d -- /tmp/a.html -- -NSShowAllViews YES
```
You can also enable some extra logging (warning: verbose!):
```
RUST_LOG="debug" ./mach run -d -- /tmp/a.html
```
Using `RUST_LOG="debug"` is usually the very first thing you might want to do if you have no idea what to look for. Because this is very verbose, you can combine these with `ts` (`moreutils` package (apt-get, brew)) to add timestamps and `tee` to save the logs (while keeping them in the console):
```
RUST_LOG="debug" ./mach run -d -- -i -y 1 -t 1 /tmp/a.html 2>&1 | ts -s "%.S: " | tee /tmp/log.txt
```
You can filter by crate or module, for example `RUST_LOG="layout::inline=debug" ./mach run …`. Check the [env_logger](http://doc.rust-lang.org/log/env_logger/index.html) documentation for more details.
Use `RUST_BACKTRACE=1` to dump the backtrace when Servo panics.
### println!()
You will want to add your own logs. Luckily, many structures [implement the `fmt::Debug` trait](https://doc.rust-lang.org/std/fmt/#fmt::display-vs-fmt::debug), so adding:
``` rust
println!("foobar: {:?}", foobar)
```
usually just works. If it doesn't, maybe foobar's properties implement the right trait.
### Debugger
To run the debugger:
``` shell
./mach run -d --debug -- -y 1 -t 1 /tmp/a.html
```
This will start `lldb` on Mac, and `gdb` on Linux.
From here, use:
``` shell
(lldb) b a_servo_function # add a breakpoint
(lldb) run # run until breakpoint is reached
(lldb) bt # see backtrace
(lldb) frame n # choose the stack frame from the number in the bt
(lldb) thread list
(lldb) next / step / …
(lldb) print varname
```
And to search for a function full name/regex:
```shell
(lldb) image lookup -r -n <name> #lldb
(gdb) info functions <name> #gdb
```
See this [lldb tutorial](http://lldb.llvm.org/tutorial.html) and this [gdb tutorial](http://www.unknownroad.com/rtfm/gdbtut/gdbtoc.html).
To inspect variables and you are new with lldb, we recommend using the `gui` mode (use left/right to expand variables):
```
(lldb) gui
┌──<Variables>───────────────────────────────────────────────────────────────────────────┐
│ ◆─(&mut gfx::paint_task::PaintTask<Box<CompositorProxy>>) self = 0x000070000163a5b0 │
│ ├─◆─(msg::constellation_msg::PipelineId) id │
│ ├─◆─(url::Url) _url │
│ │ ├─◆─(collections::string::String) scheme │
│ │ │ └─◆─(collections::vec::Vec<u8>) vec │
│ │ ├─◆─(url::SchemeData) scheme_data │
│ │ ├─◆─(core::option::Option<collections::string::String>) query │
│ │ └─◆─(core::option::Option<collections::string::String>) fragment │
│ ├─◆─(std::sync::mpsc::Receiver<gfx::paint_task::LayoutToPaintMsg>) layout_to_paint_port│
│ ├─◆─(std::sync::mpsc::Receiver<gfx::paint_task::ChromeToPaintMsg>) chrome_to_paint_port│
└────────────────────────────────────────────────────────────────────────────────────────┘
```
If lldb crashes on certain lines involving the `profile()` function, it's not just you. Comment out the profiling code, and only keep the inner function, and that should do it.
## Tests
This is boring. But your PR won't get accepted without a test. Tests are located in the `tests` directory. You'll see that there are a lot of files in there, so finding the proper location for your test is not always obvious.
First, look at the "Testing" section in `./mach --help` to understand the different test categories. You'll also find some `update-*` commands. It's used to update the list of expected results.
To run a test:
```
./mach test-wpt tests/wpt/yourtest
```
### Updating a test:
In some cases extensive tests for the feature you're working on may already exist under tests/wpt:
- Make a release build
- run `./mach test-wpt --release --log-raw=/path/to/some/logfile`
- run [`update-wpt` on it](https://github.com/servo/servo/blob/master/tests/wpt/README.md#updating-test-expectations)
This may create a new commit with changes to expectation ini files. If there are lots of changes,
it's likely that your feature had tests in wpt already.
Include this commit in your pull request.
### Add a new test:
If you need to create a new test file, it should be located in `tests/wpt/mozilla/tests` or in `tests/wpt/web-platform-tests` if it's something that doesn't depend on servo-only features. You'll then need to update the list of tests and the list of expected results:
```
./mach test-wpt --manifest-update
```
## Documentation:
- Servo's directory structure: [ORGANIZATION.md](./ORGANIZATION.md)
- http://doc.servo.org/servo/index.html
- https://github.com/servo/servo/wiki
- http://rustbyexample.com
- https://doc.rust-lang.org
- Cargo & crates: http://doc.crates.io/guide.html
- mach help: `./mach --help`
- servo options: `./mach run -- --help`
- servo debug options: `./mach run -- --debug help`
## Ask questions
### IRC
IRC channels (irc.mozilla.org):
- #servo
- #rust
- #cargo
### Mailing list
https://lists.mozilla.org/listinfo/dev-servo

108
docs/ORGANIZATION.md Normal file
View file

@ -0,0 +1,108 @@
# Servo's directory structure:
* components
* canvas
* Implementation of painting threads for 2d and WebGL canvases.
* canvas_traits
* APIs to the canvas crate for crates that don't want to depend on the canvas crate for build speed reasons.
* compositing
* Integration with OS windowing/rendering and event loop, as well as management of resources for a top-level browsing context (ie. tab).
* devtools
* in-process server to allow manipulating browser instances via a remote Firefox developer tools client.
* devtools_traits
* APIs to the devtools crate for crates that don't want to depend on the devtools crate for build speed reasons.
* etc
* Useful tools and scripts for developers.
* gfx
* Draws the result of laying out a page, and sends the result to the compositor.
* gfx_traits
* APIs to the gfx crate for crates that don't want to depend on the gfx crate for build speed reasons.
* layout
* Converts page content into positioned, styled boxes and passes the result to the renderer.
* layout_traits
* APIs to the layout crate for crates that don't want to depend on the layout crate for build speed reasons.
* msg
* Shared APIs for communicating between specific threads and crates.
* net
* Network protocol implementations, and state and resource management (caching, cookies, etc.).
* net_traits
* APIs to the net crate for crates that don't want to depend on the net crate for build speed reasons.
* plugins
* Syntax extensions, custom attributes, and lints.
* profile
* Memory and time profilers.
* profile_traits
* APIs to the profile crate for crates that don't want to depend on the profile crate for build speed reasons.
* script
* Implementation of the DOM (native Rust code and bindings to SpiderMonkey).
* script_traits
* APIs to the script crate for crates that don't want to depend on the script crate for build speed reasons.
* servo
* Entry points for the servo application and libservo embedding library.
* style
* APIs for parsing CSS and interacting with stylesheets and styled elements.
* style_traits
* APIs to the style crate for crates that don't want to depend on the style crate for build speed reasons.
* util
* assorted utility methods and types that are commonly used throughout the project.
* webdriver_server
* In-process server to allow manipulating browser instances via a WebDriver client.
* webdriver_traits
* APIs to the webdriver crate for crates that don't want to depend on the webdriver crate for build speed reasons.
* mach
* A command-line tool to help with developer tasks.
* ports
* cef
* Embedding implementation for the Chrome Embedding Framework (CEF) API.
* glutin
* Embedding implementation for the `glutin` windowing library.
* gonk
* Embedding implementation for the Firefox OS devices.
* python
* servo
* Implementations of servo-specific mach commands.
* mach
* Implementation of `mach` command-line tool.
* tidy
* Python package of code lints that are automatically run before merging changes.
* resources
* Files used at run time. Need to be included somehow when distributing binary builds.
* support
* android
* Libraries that require special handling for building for Android platforms
* rust-task_info
* Library for obtaining information about memory usage for a process
* target
* debug
* Build artifacts generated by `./mach build --debug`.
* doc
* Documentation is generated here by the `rustdoc` tool when running `./mach doc`
* release
* Build artifacts generated by `./mach build --release`.
* tests
* dromaeo
* Harness for automatically running the Dromaeo testsuite.
* heartbeats
* Tools for periodic measurement of energy consumption.
* html
* Manual tests and experiments.
* jquery
* Harness for automatically running the jQuery testsuite.
* power
* Tools for measurement of power consumption.
* unit
* Unit tests using rustcs built-in test harness.
* wpt
* W3C web-platform-tests and csswg-tests along with tools to run them and expected failures.
# Major dependencies
* <https://github.com/servo/rust-mozjs/>, <https://github.com/servo/mozjs/>: bindings to SpiderMonkey
* <https://github.com/hyperium/hyper/>: an HTTP implementation
* <https://github.com/servo/html5ever/>: an HTML5 parser
* <https://github.com/servo/ipc-channel/>: an IPC implementation
* <https://github.com/PistonDevelopers/image/>: image decoders
* <https://github.com/tomaka/glutin/>: cross-platform windowing and input
* <https://github.com/servo/rust-azure/>: bindings to Moz2D/Azure (cross-platform 2D rendering library)
* <https://github.com/servo/rust-cssparser/>: a CSS parser
* <https://github.com/servo/rust-selectors/>: a CSS selector matching library
* <https://github.com/cyderize/rust-websocket/>: a WebSocket protocol implementation
* <https://github.com/servo/rust-url/>: an implementation of the URL specification

27
docs/glossary.md Normal file
View file

@ -0,0 +1,27 @@
### Compositor ###
The thread that receives input events from the operating system and forwards them to the constellation. It is also in charge of compositing complete renders of web content and displaying them on the screen as fast as possible.
### Constellation ###
The thread that controls a collection of related web content. This could be thought of as an owner of a single tab in a tabbed web browser; it encapsulates session history, knows about all frames in a frame tree, and is the owner of the pipeline for each contained frame.
### Display list ###
TODO
### Layout thread ###
A thread that is responsible for laying out a DOM tree into layers of boxes for a particular document. Receives commands from the script thread to lay out a page and either generate a new display list for use by the renderer thread, or return the results of querying the layout of the page for use by script.
### Pipeline ###
A unit encapsulating a means of communication with the script, layout, and renderer threads for a particular document. Each pipeline has a globally-unique id which can be used to access it from the constellation.
### Script thread (alt. script task) ###
A thread that executes JavaScript and stores the DOM representation of all documents that share a common [origin](https://tools.ietf.org/html/rfc6454). This thread translates input events received from the constellation into DOM events [per the specification](https://w3c.github.io/uievents/), invokes the HTML parser when new page content is received, and evaluates JS for events like timers and `<script>` elements.
### Renderer thread (alt. paint thread) ###
A thread which translates a display list into a series of drawing commands that render the contents of the associated document into a buffer, which is then sent to the compositor.