J. Ryan Stinnett

A Convolution of Software and Electronics

Building Firefox for Linux 32-bit

Background

As part of my work on the Stylo / Quantum CSS team at Mozilla, I needed to be able to test changes to Firefox that only affect Linux 32-bit builds. These days, I believe you essentially have to use a 64-bit host to build Firefox to avoid OOM issues during linking and potentially other steps, so this means some form of cross-compiling from a Linux 64-bit host to a Linux 32-bit target.

I already had a Linux 64-bit machine running Ubuntu 16.04 LTS, so I set about attempting to make it build Firefox targeting Linux 32-bit.

I should note that I only use Linux occasionally at the moment, so there could certainly be a better solution than the one I describe. Also, I recreated these steps after the fact, so I might have missed something. Please let me know in the comments.

This article assumes you are already set up to build Firefox when targeting 64-bit.

Multiarch Packages (Or: How It’s Supposed to Work)

Recent versions of Debian and Ubuntu support the concept of “multiarch packages” which are intended to allow installing multiple architectures together to support use cases including… cross-compiling! Great, sounds like just the thing we need.

We should be able to install1 the core Gecko development dependencies with an extra :i386 suffix to get the 32-bit version on our 64-bit host:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
(host) $ sudo apt install libasound2-dev:i386 libcurl4-openssl-dev:i386 libdbus-1-dev:i386 libdbus-glib-1-dev:i386 libgconf2-dev:i386 libgtk-3-dev:i386 libgtk2.0-dev:i386 libiw-dev:i386 libnotify-dev:i386 libpulse-dev:i386 libx11-xcb-dev:i386 libxt-dev:i386 mesa-common-dev:i386
Reading package lists... Done
Building dependency tree
Reading state information... Done
Some packages could not be installed. This may mean that you have
requested an impossible situation or if you are using the unstable
distribution that some required packages have not yet been created
or been moved out of Incoming.
The following information may help to resolve the situation:

The following packages have unmet dependencies:
 libgtk-3-dev:i386 : Depends: gir1.2-gtk-3.0:i386 (= 3.18.9-1ubuntu3.3) but it is not going to be installed
                     Depends: libatk1.0-dev:i386 (>= 2.15.1) but it is not going to be installed
                     Depends: libatk-bridge2.0-dev:i386 but it is not going to be installed
                     Depends: libegl1-mesa-dev:i386 but it is not going to be installed
                     Depends: libxkbcommon-dev:i386 but it is not going to be installed
                     Depends: libmirclient-dev:i386 (>= 0.13.3) but it is not going to be installed
 libgtk2.0-dev:i386 : Depends: gir1.2-gtk-2.0:i386 (= 2.24.30-1ubuntu1.16.04.2) but it is not going to be installed
                      Depends: libatk1.0-dev:i386 (>= 1.29.2) but it is not going to be installed
                      Recommends: python:i386 (>= 2.4) but it is not going to be installed
 libnotify-dev:i386 : Depends: gir1.2-notify-0.7:i386 (= 0.7.6-2svn1) but it is not going to be installed
E: Unable to correct problems, you have held broken packages.

Well, that doesn’t look good. It appears some of the Gecko libraries we need aren’t happy about being installed for multiple architectures.

Switch Approaches to chroot

Since multiarch packages don’t appear to be working here, I looked around for other approaches. Ideally, I would have something fairly self-contained so that it would be easy to remove when I no longer need 32-bit support.

One approach to multiple architectures that has been around for a while is to create a chroot environment: effectively, a separate installation of Linux for a different architecture. A utility like schroot can then be used to issue the chroot(2) system call which makes the current session believe this sub-installation is the root filesystem.

Let’s grab schroot so we’ll be able to enter the chroot once it’s set up:

1
(host) $ sudo apt install schroot

There are several different types of chroots you can use with schroot. We’ll use the directory type, as it’s the simplest to understand (just another directory on the existing filesystem), and it will make it simpler to expose a few things to the host later on.

You can place the directory wherever, but some existing filesystems are mapped into the chroot for convenience, so avoiding /home is probably a good idea. I went with /var/chroot/linux32:

1
(host) $ sudo mkdir -p /var/chroot/linux32

We need to update schroot.conf to configure the new chroot:

1
2
3
4
5
6
7
8
9
10
11
(host) $ sudo cat << EOF >> /etc/schroot/schroot.conf
[linux32]
description=Linux32 build environment
aliases=default
type=directory
directory=/var/chroot/linux32
personality=linux32
profile=desktop
users=jryans
root-users=jryans
EOF

In particular, personality is important to set for this multi-arch use case. (Make sure to replace the user names with your own!)

Firefox will want access to shared memory as well, so we’ll need to add that to the set of mapped filesystems in the chroot:

1
2
3
(host) $ sudo cat << EOF >> /etc/schroot/desktop/fstab
/dev/shm       /dev/shm        none    rw,bind         0       0
EOF

Now we need to install the 32-bit system inside the chroot. We can do that with a utility called debootstrap:

1
2
(host) $ sudo apt install debootstrap
(host) $ sudo debootstrap --variant=buildd --arch=i386 --foreign xenial /var/chroot/linux32 http://archive.ubuntu.com/ubuntu

This will fetch all the packages for a 32-bit installation and place them in the chroot. For a cross-arch bootstrap, we need to add --foreign to skip the unpacking step, which we will do momentarily from inside the chroot. --variant=buildd will help us out a bit by including common build tools.

To finish installation, we have to enter the chroot. You can enter the chroot with schroot and it remains active until you exit. Any snippets that say (chroot) instead of (host) are meant to be run inside the chroot.

So, inside the chroot, run the second stage of debootstrap to actually unpack everything:

1
(chroot) $ /debootstrap/debootstrap --second-stage

Let’s double-check that things are working like we expect:

1
2
(chroot) $ arch
i686

Great, we’re getting closer!

Install packages

Now that we have a basic 32-bit installation, let’s install the packages we need for development. The apt source list inside the chroot is pretty bare bones, so we’ll want to expand it a bit to reach everything we need:

1
2
3
4
5
(chroot) $ sudo cat << EOF > /etc/apt/sources.list
deb http://archive.ubuntu.com/ubuntu xenial main universe
deb http://archive.ubuntu.com/ubuntu xenial-updates main universe
EOF
(chroot) $ sudo apt update

Let’s grab the same packages from before (without :i386 since that’s the default inside the chroot):

1
(chroot) $ sudo apt install libasound2-dev libcurl4-openssl-dev libdbus-1-dev libdbus-glib-1-dev libgconf2-dev libgtk-3-dev libgtk2.0-dev libiw-dev libnotify-dev libpulse-dev libx11-xcb-dev libxt-dev mesa-common-dev python-dbus xvfb yasm

You may need to install the 32-bit version of your graphics card’s GL library to get reasonable graphics output when running in the 32-bit environment.

1
(chroot) $ sudo apt install nvidia-384

We’ll also want to have access to the X display inside the chroot. The simple way to achieve this is to disable X security in the host and expose the same display in the chroot:

1
2
(host) $ xhost +
(chroot) $ export DISPLAY=:0

We can verify that we have accelerated graphics:

1
2
3
(chroot) $ sudo apt install mesa-utils
(chroot) $ glxinfo | grep renderer
OpenGL renderer string: GeForce GTX 1080/PCIe/SSE2

Building Firefox

In order for the host to build Firefox for the 32-bit target, it needs to access various 32-bit libraries and include files. We already have these installed in the chroot, so let’s cheat and expose them to the host via symlinks into the chroot’s file structure:

1
2
3
(host) $ sudo ln -s /var/chroot/linux32/lib/i386-linux-gnu /lib/
(host) $ sudo ln -s /var/chroot/linux32/usr/lib/i386-linux-gnu /usr/lib/
(host) $ sudo ln -s /var/chroot/linux32/usr/include/i386-linux-gnu /usr/include/

We also need Rust to be able to target 32-bit from the host, so let’s install support for that:

1
(host) $ rustup target add i686-unknown-linux-gnu

We’ll need a specialized .mozconfig for Firefox to target 32-bit. Something like the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
(host) $ cat << EOF > ~/projects/gecko/.mozconfig
export PKG_CONFIG_PATH="/var/chroot/linux32/usr/lib/i386-linux-gnu/pkgconfig:/var/chroot/linux32/usr/share/pkgconfig"
export MOZ_LINUX_32_SSE2_STARTUP_ERROR=1
CFLAGS="$CFLAGS -msse -msse2 -mfpmath=sse"
CXXFLAGS="$CXXFLAGS -msse -msse2 -mfpmath=sse"
if test `uname -m` = "x86_64"; then
  CFLAGS="$CFLAGS -m32 -march=pentium-m"
  CXXFLAGS="$CXXFLAGS -m32 -march=pentium-m"
  ac_add_options --target=i686-pc-linux
  ac_add_options --host=i686-pc-linux
  ac_add_options --x-libraries=/usr/lib
fi
EOF

This was adapted from the mozconfig.linux32 used for official 32-bit builds. I modified the PKG_CONFIG_PATH to point at more 32-bit files installed inside the chroot, similar to the library and include changes above.

Now, we should be able to build successfully:

1
(host) $ ./mach build

Then, from the chroot, you can run Firefox and other tests:

1
(chroot) $ ./mach run

Firefox running on Linux 32-bit

Footnotes

1. It’s commonly suggested that people should use ./mach bootstrap to install the Firefox build dependencies, so feel free to try that if you wish. I dislike scripts that install system packages, so I’ve done it manually here. The bootstrap script would likely need various adjustments to support this use case.

WiFi Debugging for Firefox for Android

I am excited to announce that we’re now shipping WiFi debugging for Firefox for Android! It’s available in Firefox for Android 42 with Firefox Nightly on desktop.

The rest of this post will sound quite similar to the previous announcement for Firefox OS support.

WiFi debugging allows WebIDE to connect to Firefox for Android via your local WiFi network instead of a USB cable.

The connection experience is generally more straightforward (especially after connecting to a device the first time) than with USB and also more convenient to use since you’re no longer tied down by a cable.

Security

A large portion of this project has gone towards making the debugging connection secure, so that you can use it safely on shared network, such as an office or coffee shop.

We use TLS for encryption and authentication. The computer and device both create self-signed certificates. When you connect, a QR code is scanned to verify that the certificates can be trusted. During the connection process, you can choose to remember this information and connect immediately in the future if desired.

How to Use

You’ll need to assemble the following bits and bobs:

On your Android device:

  1. Install the Barcode Scanner Android app by ZXing Team
  2. Open Firefox for Android
  3. Go to Developer Tools Settings on device (Settings -> Developer Tools)
  4. Enable Remote Debugging via Wi-Fi

Firefox for Android WiFi Debugging Options

To connect from Firefox Desktop:

  1. Open WebIDE in Firefox Nightly (Tools -> Web Developer -> WebIDE)
  2. Click “Select Runtime” to open the runtimes panel
  3. Your Firefox for Android device should show up in the “WiFi Devices” section
  4. A connection prompt will appear on device, choose “Scan” or “Scan and Remember”
  5. Scan the QR code displayed in WebIDE

WebIDE WiFi Runtimes WebIDE Displays the QR Code

After scanning the QR code, the QR display should disappear and the “device” icon in WebIDE will turn blue for “connected”.

You can then access all of your remote browser tabs just as you can today over USB.

Technical Aside

This process does not use ADB at all on the device, so if you find ADB inconvenient while debugging or would rather not install ADB at all, then WiFi debugging is the way to go.

By skipping ADB, we don’t have to worry about driver confusion, especially on Windows and Linux.

Supported Devices

This feature should be supported on any Firefox for Android device. So far, I’ve tested it on the LG G2.

Acknowledgments

Thanks to all who helped via advice and reviews while working on Android support, including (in semi-random order):

  • Margaret Leibovic
  • Karim Benhmida

And from the larger WiFi debugging effort:

  • Brian Warner
  • Trevor Perrin
  • David Keeler
  • Honza Bambas
  • Patrick McManus
  • Jason Duell
  • Panos Astithas
  • Jan Keromnes
  • Alexandre Poirot
  • Paul Rouget
  • Paul Theriault

I am probably forgetting others as well, so I apologize if you were omitted.

What’s Next

If there are features you’d like to see added, file bugs or contact the team via various channels.

WiFi Debugging for Firefox OS

I am excited to announce that we’re now shipping WiFi debugging for Firefox OS! It’s available in Firefox OS 3.0 / master with Firefox Nightly on desktop.

WiFi debugging allows WebIDE to connect to your Firefox OS device via your local WiFi network instead of a USB cable.

The connection experience is generally more straightforward (especially after connecting to a device the first time) than with USB and also more convenient to use since you’re no longer tied down by a cable.

Security

A large portion of this project has gone towards making the debugging connection secure, so that you can use it safely on shared network, such as an office or coffee shop.

We use TLS for encryption and authentication. The computer and device both create self-signed certificates. When you connect, a QR code is scanned to verify that the certificates can be trusted. During the connection process, you can choose to remember this information and connect immediately in the future if desired.

How to Use

You’ll need to assemble the following bits and bobs:

On Firefox OS, enable WiFi debugging:

  1. Go to Developer Settings on device (Settings -> Developer)
  2. Enable DevTools via Wi-Fi
  3. Edit the device name if desired

Firefox OS WiFi Debugging Options

To connect from Firefox Desktop:

  1. Open WebIDE in Firefox Nightly (Tools -> Web Developer -> WebIDE)
  2. Click “Select Runtime” to open the runtimes panel
  3. Your Firefox OS device should show up in the “WiFi Devices” section
  4. A connection prompt will appear on device, choose “Scan” or “Scan and Remember”
  5. Scan the QR code displayed in WebIDE

WebIDE WiFi Runtimes WebIDE Displays the QR Code

After scanning the QR code, the QR display should disappear and the “device” icon in WebIDE will turn blue for “connected”.

You can then access all of your remote apps and browser tabs just as you can today over USB.

Technical Aside

This process does not use ADB at all on the device, so if you find ADB inconvenient while debugging or would rather not install ADB at all, then WiFi debugging is the way to go.

By skipping ADB, we don’t have to worry about driver confusion, especially on Windows and Linux.

Supported Devices

This feature should be supported on any Firefox OS device. So far, I’ve tested it on the Flame and Nexus 4.

Known Issues

The QR code scanner can be a bit frustrating at the moment, as real devices appear to capture a very low resolution picture. Bug 1145772 aims to improve this soon. You should be able to scan with the Flame by trying a few different orientations. I would suggest using “Scan and Remember”, so that scanning is only needed for the first connection.

If you find other issues while testing, please file bugs or contact me on IRC.

Acknowledgments

This was quite a complex project, and many people provided advice and reviews while working on this feature, including (in semi-random order):

  • Brian Warner
  • Trevor Perrin
  • David Keeler
  • Honza Bambas
  • Patrick McManus
  • Jason Duell
  • Panos Astithas
  • Jan Keromnes
  • Alexandre Poirot
  • Paul Rouget
  • Paul Theriault

I am probably forgetting others as well, so I apologize if you were omitted.

What’s Next

I’d like to add this ability for Firefox for Android next. Thankfully, most of the work done here can be reused there.

If there are features you’d like to see added, file bugs or contact the team via various channels.

Debugging Tabs with Firefox for Android

For quite a while, it has been possible to debug tabs on Firefox for Android devices, but there were many steps involved, including manual port forwarding from the terminal.

As I hinted a few weeks ago, WebIDE would soon support connecting to Firefox for Android via ADB Helper support, and that time is now!

How to Use

You’ll need to assemble the following bits and bobs:

  • Firefox 36 (2014-10-25 or later)
  • ADB Helper 0.7.0 or later
  • Firefox for Android 35 or later

Opening WebIDE for the first time should install ADB Helper if you don’t already have it, but double-check it is the right version in the add-on manager.

Firefox for Android runtime appears

Inside WebIDE, you’ll see an entry for Firefox for Android in the Runtime menu.

Firefox for Android tab list

Once you select the runtime, tabs from Firefox for Android will be available in the (now poorly labelled) apps menu on the left.

Inspecting a tab in WebIDE

Choosing a tab will open up the DevTools toolbox for that tab. You can also toggle the toolbox via the “Pause” icon in the top toolbar.

If you would like to debug Firefox for Android’s system-level / chrome code, instead of a specific tab, you can do that with the “Main Process” option.

What’s Next

We have even more connection UX improvements on the way, so I hope to have more to share soon!

If there are features you’d like to see added, file bugs or contact the team via various channels.

DevTools for Firefox OS browser tabs

We’ve had various tools for inspecting apps on remote devices for some time now, but for a long time we’ve not had the same support for remote browser tabs.

To remedy this, WebIDE now supports inspecting browser tabs running on Firefox OS devices.

Inspecting a tab in WebIDE

A few weeks back, WebIDE gained support for inspecting tabs on the remote device, but many of the likely suspects to connect to weren’t quite ready for various reasons.

We’ve just landed the necessary server-side bits for Firefox OS, so you should be able try this out by updating your device to the next nightly build after 2014-10-14.

How to Use

After connecting to your device in WebIDE, any open browser tabs will appear at the bottom of WebIDE’s project list.

Browser tab list in WebIDE

The toolbox should open automatically after choosing a tab. You can also toggle the toolbox via the “Pause” icon in the top toolbar.

What’s Next

We’re planning to make this work for Firefox for Android as well. Much of that work is already done, so I am hopeful that it will be available soon.

If there are features you’d like to see added, file bugs or contact the team via various channels.

WebIDE enabled in Nightly

I am excited to announce that WebIDE is now enabled by default in Nightly (Firefox 34)! Everyone on the App Tools team has been working hard to polish this new tool that we originally announced back in June.

Features

While the previous App Manager tool was great, that tool’s UX held us back when trying support more complex workflows. With the redesign into WebIDE, we’ve already been able to add:

  • Project Editing
    • Great for getting started without worrying about an external editor
  • Project Templates
    • Easy to focus on content from the start by using a template
  • Improved DevTools Toolbox integration
    • Many UX issues arose from the non-standard way that App Manager used the DevTools
  • Monitor
    • Live memory graphs help diagnose performance issues

Transition

All projects you may have created previously in the App Manager are also available in WebIDE.

While the App Manager is now hidden, it’s accessible for now at about:app-manager. We do intend to remove it entirely in the future, so it’s best to start using WebIDE today. If you find any issues, please file bugs!

What’s Next

Looking ahead, we have many more exciting things planned for WebIDE, such as:

  • Command line integration
  • Improved support for app frameworks like Cordova
  • Validation that matches the Firefox Marketplace

If there are features you’d like to see added, file bugs or contact the team via various channels.

Mozilla

In my last post (back in February…), I mentioned I was spending a lot of time on the side working on the developer tools in web browsers, particularly Firefox. I find that Mozilla’s values, which truly put the user first, are something I agree with wholeheartedly. Mozilla is in a unique position in this way, since all the other browsers are made by companies that, at the end of day, are looking to make money to appease their shareholders. Mozilla’s values are even more important to emphasize these days with the various forms of governmental spying that has been revealed in the last few months.

With that context, hopefully you can get an idea of how excited I am to say that this past Monday was my first day as a Mozilla employee, working on the Firefox Developer Tools team!

I am currently in Paris ramping up with the team for two weeks. After the first week, I am humbled to be able to say I am a part of this organization. There are so many people smarter than me here, and I am thrilled to have the opportunity to work with them. I know we will accomplish great things together.

There is so much potential in the web developer tools space. Every developer has their own workflow, favorite set of frameworks and tools, and new platform technologies and techniques are coming out at a rapid pace. While part of my job is certainly to help make all of this more efficient, there is a lot of room to shake things up by looking towards the future of web development and the tools that people don’t even know they need.

It’s going to be a blast! Hopefully I’ll have to some fun things to share.

Into the Open

I’m excited to start to focusing what time I do have on the side towards open source projects. I’m always on the lookout for good projects to help out with, but these days I always seem to come back to web browsers.

In particular, I really enjoy working on tools that improve the lives of other every day. In that vein, I’d like to focus on improvements to the developer tools in browsers today, though they are vastly better today than even a few years ago.

The main open source options as far as web browsers go are Chrome / Chromium and the various Mozilla projects, like Firefox. Near the end of 2011, I started ramping up on the Chromium project, mainly because Chrome is the main browser I used then.

However, now that Opera has decided to switch to Chromium for future versions of their browser, I’ve been reminded that Mozilla is the only party in the web development game that truly seems to be doing their best to fight for the user. The main reason I stopped using Firefox was due to Chrome’s impressive developer tools, so I’d like to help improve Firefox tools to bring them up to the level we’ve now come to expect and beyond.

Likely I’ll dabble in both Chromium and Firefox, but no matter what it should be an exciting time ahead!

Materials, Maps, and Surfacing

Overview

For this assignment, we learned how to apply materials to the objects we’ve been creating. There are many, many different ways to construct a material that you apply to 3D object. They can be procedurally generated, they can pull from textures (or maps) you create, and you can manually tune many parameters as well.

Maps are a great way to control the appearance of an object because you can make something resemble a real object quite quickly by just taking a picture and doing a bit of editing.

Environment

For the environment, I used a variety of wood textures as maps to give the huts a rustic feel. The door particularly look much more believable now. Also, the islands look much less like strange brains now there’s a grassy appearance applied, instead of just the flat green.

Robot

For the robot, I gave him a weathered, rusty metal appearance that seems to tie in well with his supportive / charming look. Old, but still functioning just fine.

The eyes and mouth have a bit of an ethereal / floating feel to them thanks to the transparency.

It was fun to experiment with the various parameters and material types that can give a metallic appearance.

Splines, Loft, and Lathe

Overview

For this assignment, we learned a few new techniques, namely how to make use of 2D shapes to give more detail to our models. Beyond simple shapes like circles and squares is the very flexible spline, which gives you a lot of control over how a line is drawn, while still be purely analytical.

Shapes and Splines

For part of the homework, we added some shapes and splines to our existing models. Below you can see the island huts from before, but with a few additional decorations, such as some scary wiring / branches, as well as door knobs and roof ornaments.

Lathe and Loft

We also learned how to take 2D paths and morph them into 3D shapes in several interesting ways. You can use lathe to revolve the path around an axis, similar to a torus.

I used this technique to create a pot, an inflatable pool, and a spyglass.

We also learned about loft, which will take a shape and replicate it in 3D across whatever path you define. This is another very powerful feature, with many ways you can customize and tune its behavior.

I made several tracks and other shapes using this process: