Hacking & Contributing to Servo On Windows

Like many cross-platform open source projects, Servo, the high-performance browser engine project written in Rust, has always been a bit of a nightmare to build and run on Windows. Luckily, thanks to the Rust team and Servo community, most of the issues have been squashed and we can now launch it with nothing more than just PowerShell, plus with a full stack of native Windows libraries and tool usage.

Why did this take so long to happen?

A brief history..

Back in 2013 when Servo development started, it only ran on Linux systems and OSX. This was largely due to the developers of Servo being on those operating systems.

As a byproduct, Servo ended up with many Linux-based dependencies (make, gcc, etc.), the build system would make hard-coded calls to /bin/:/usr/bin/[etc]. Migrating these to cross-platform took time. Servo engineer Lars Bergstrom explains:

“Certainly font support and build system stuff has taken the most effort. In general, making sure that all of the hundreds of crates in the Servo dependency graph not only build but work correctly on Windows has taken a lot of effort.

A lot of things (including Servo) were also easy to get over on MinGW with a “unixy” Windows experience, but getting a true, native Windows experience using MSVC took a lot longer.

A year later, the quick and easy solution to running Servo on Windows was to emulate a Linux environment, so this led to arcane setup instructions using msys and mingw on Windows. Although Servo would build, it seemed like more of a temporary solution.

A Windows branch of Servo was created, with many build steps fixed over time; and modules, which used only Linux components, stubbed out. One by one, we were able to tick off the incompatibilities.

There’s been a push by a few of us, with a lot of help from Vlad, to have Servo properly building on Windows and using the Microsoft Visual C++ compiler (MSVC) for some time. And finally we’re there!

So how to begin developing? For these examples I will be using Windows 10 x64.

 

Let’s get started

You don’t have to do your editing in here, but Visual Studio (VS) allows us to actually debug the binary. We can pause at any moment and edit breakpoints (more on this later).

Let’s go to https://www.visualstudio.com/downloads/ and download “Visual Studio 2017 Community”.

Once it downloads, and you get the options to come up, navigate to the individual components tab and select:

  • C++/CLI support
  • Profiling Tools
  • Visual C++ tools for Cmake
  • VC++ 2017 v141 toolset

We will need to add the build tools VS has given us to our system path.

Navigate to environment variables, and add this to the Path variable:

C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.10.25017\bin\HostX64\x64`

While you’re here you should set a new environment variable, VisualStudioVersion to 15.0 (yes 15.0 even though it’s VS 2017). This enables cmake-using crates (libssh2-sys, etc) to build.

We’re done here for now.

rustup

rustup will manage our Rust installation and let us switch between releases, plus nightly and stable branches. It makes it very easy to update. We will be needing nightly later, so rustup is the best way to start.

Go to rustup.rs and download the installer, it will mention installing the Visual C++ build tools, but VS should have already given us this stuff from earlier, so just proceed.

Press 1 and follow the default installation.

Install rust-src

Open up PowerShell: You should now have Rust installed, you can try it out with:

$ rustc --version

Our next task is to install the rust-src, this helps VS find the source it’s looking for. (This is also a helpful step for racer support.)

Before we go ahead though, we should switch to nightly. Nightly gives us Natvis.

$ rustup default nightly
$ rustup component add rust-src

You will now have some files located at:

C:\Users\[User]\.multirust\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\src

Although not useful for now, you’ll need this path for Optional: Stepping into the standard Library further down.

Add Natvis for Rust

Natvis files gives Visual Studio-friendly visualisations of native objects in Rust. The Rust team have added Vec, LinkedList, VecDeque, String, Option plus many more Natvis visualizations.

Here’s how to use them:

C:\Users\[User]\.multirust\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\src\etc\natvis

Copy the .natvis files in here, and place them in

C:\Users\[User]\Documents\Visual Studio 2017\Visualizers

Don’t worry if Visualizers isn’t there, you can create this directory.

Building Servo

I won’t go too much into setting up Servo here, as that’s covered in: https://github.com/servo/servo/#on-windows-msvc–mingw

Build the latest version using --dev, I’m just running

$ mach.bat build --dev

in PowerShell here. It’s important you use the --dev option as debugging will not work without it.

Back to Visual Studio

Now that we have Servo built, let’s run it.

You can open up Visual Studio, File, Open, Project/Solution, change “All Project Files” to “Exe project files” and navigate to your servo.exe binary, usually in target/debug/servo.exe.

If you need to pass in arguments you can right click Servo in the solution explorer on the right. Once ready, you can click start at the top.

This should load up Servo and you may see some fancy memory profiling in the background in VS. You can pause at any point and it should land in the code where it’s paused. If this doesn’t happen make sure that Thread: is set to “Main Thread”.

For example, if the browser is idle and we pause, we may land on this line:

self.window.events_receiver.recv().ok()

Optional: Stepping into the standard Library

Remember the rust-src we installed earlier? Well this is useful if we want to see what the standard library is doing, otherwise the debugger may moan when you click on std::* functions. So in order to tell VS about rust source code we right click on the solution name on the right “Solution ‘servo’” and select properties, then inside “Common Properties/Debug Source Files” add that path to the top window.

Setting breakpoints

This is straightforward too, you can drag any Rust file from the project into VS and set a breakpoint. Click start again and the program should stop at that point. You can then step in and out of functions or use continue and breakpoints to inspect the execution of your program. You can see the stack trace and variables within scope at the bottom too!

If everything went to plan, you should have something similar to this.

Visual Studio loading Servo

Contributing

So you want to contribute but not sure where to start?

https://starters.servo.org/ has some great first-PR tickets, plus there are still quite a few easy tickets outstanding too.

About Jason Williams

Jason is a Principal Developer and Tech Lead at the BBC

More articles by Jason Williams…


10 comments

  1. Ahmed Charles

    It doesn’t seem like the instructions here can work because servo doesn’t currently support MSVC 2017. I assume that if this set of instructions was tested, it worked because MSVC 2015 was installed already. The mach.bat looks for %VS140COMNTOOLS%, which is MSVC 2015.

    Note, this can be worked around by executing the appropriate vcvarsall.bat. (I wasn’t able to get it to work under powershell and it just seems to complicate things compared to using cmd consistently.)

    However, there’s a second error, which is that the MSVC 2017 vcvarsall.bat sets %PLATFORM% to be ‘x64’ rather than ‘X64’, which is what is expected in util.host_triple() and therefore, the appropriate rust download can’t be found.

    The third problem is that if a recent version of cmake isn’t in the path, it will download 3.6.1, which doesn’t support MSVC 2017.

    The fourth problem, which I haven’t figured out how to fix is that “\servo\target\debug\build\mozjs_sys-b75999929c5a0ce6\out\dist\include\js\TraceKind.h” fails to build with MSVC 2017 due to a syntax error: (176): error C2760: syntax error: expected ‘)’ not ‘…’

    It looks like valid C++ to me, but I can’t figure out what’s going on.

    Perhaps the instructions should be changed to install MSVC 2015 until the issues with 2017 are resolved? Thanks for getting it to work on 2015. :)

    April 7th, 2017 at 01:43

    Reply

    1. Lars Bergstrom

      Ahmed,

      Thanks for the detailed investigation! I’ll open an issue on the Servo side with this information and update the instructions to point at 2015 for now.
      – Lars

      April 7th, 2017 at 10:12

      Reply

    2. Lars Bergstrom

      Ahmed,

      It should work now! One of our amazing community contributors landed https://github.com/servo/servo/pull/16307, which added support for Visual Studio 2017.
      – Lars

      April 12th, 2017 at 17:29

      Reply

  2. Volker

    Why not cross-compiling using a MinGW toolchain such as MXE? (http://mxe.cc/)

    That way, you don’t even need a Windows, or any other proprietary OS for that matter, to build your port.

    April 7th, 2017 at 04:32

    Reply

    1. Lars Bergstrom

      Volker,

      We initially used MinGW and it’s a fine product for early porting of Unix applications. Unfortunately, many of the dependencies (font libraries, etc.) are not written to use the native Windows APIs or optimized for Windows and caused Servo for Windows to have really degraded performance. Further, the debugging experience (gdb for Windows) did not integrate with the tools and was empirically far less mature and useful than even the early MSVC debugging support in Rust and LLVM.

      We continue to test building Servo with MinGW for consumers who have a requirement for such a toolchain, but we would not ship such a build to users or encourage developers work on that platform unless they have a business need for it.

      Hope that helps!
      – Lars

      April 7th, 2017 at 10:11

      Reply

    2. Michael “notriddle” Howell

      Servo would still need a Windows machine lying around to run the test suite on, so cross-compiling from Linux to Windows would not gain very much…

      April 13th, 2017 at 08:43

      Reply

  3. Kamal

    This is good news, will we see an update to this page:-

    https://download.servo.org/

    With an installer for windows?

    April 9th, 2017 at 20:54

    Reply

    1. Lars Bergstrom

      Kamal,

      We just have *one* more blocking issue on Windows, related to keyboard input. We have a tracking issue here that records the remaining work to make the download publicly available:
      https://github.com/servo/servo/issues/12125

      Sorry it isn’t ready to go quite yet!
      – Lars

      April 10th, 2017 at 11:13

      Reply

    2. Lars Bergstrom

      Kamal,

      It’s live now!
      https://blog.servo.org/2017/04/13/windows/
      – Lars

      April 14th, 2017 at 06:42

      Reply

  4. Elahn Ientile

    Great post, thanks!

    Nit: there’s an unwanted backtick at the end of the VS build tools path.

    April 13th, 2017 at 16:06

    Reply

Post Your Comment