<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>J. Ryan Stinnett</title>
    <link>https://convolv.es/</link>
    <description>Recent content on J. Ryan Stinnett</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-gb</language>
    <lastBuildDate>Fri, 01 Nov 2024 16:10:32 +0000</lastBuildDate><atom:link href="https://convolv.es/atom.xml" rel="self" type="application/rss+xml" />
    <item xml:base="https://convolv.es/blog/2024/11/01/capabilities-effects/">
      <title>Extensibility via capabilities and effects</title>
      <link>https://convolv.es/blog/2024/11/01/capabilities-effects/</link>
      <pubDate>Fri, 01 Nov 2024 16:10:32 +0000</pubDate>
      
      <guid>https://convolv.es/blog/2024/11/01/capabilities-effects/</guid>
      <description>Much of today&amp;rsquo;s software limits user extensibility. This article explores one potential route forward using capabilities, effects, and extension-time type checking to provide a more predictable extension path.</description>
      <content:encoded><![CDATA[<p><em>This is a submission for the <a href="https://forum.malleable.systems/t/challenge-problem-fearless-extensibility/205">fearless extensibility challenge
problem</a> organised by the <a href="https://malleable.systems">Malleable Systems Collective</a>.</em></p>
<hr>
<p>Much of today&rsquo;s software limits user extensibility.
If you&rsquo;re lucky, there may be a plugin system of some kind,
but that will only support whatever actions
the upstream vendor imagines and deigns to support.
If it&rsquo;s open source, you could fork and customise,
but that&rsquo;s not accessible to most.
Even if you have the expertise,
it entails a pile of maintenance work to stay up to date.
If it&rsquo;s closed source,
you&rsquo;re essentially out of luck.</p>
<p>There have been some historical extension systems that allowed
a high degree of freedom (e.g. legacy Firefox extensions).
As mentioned by the <a href="https://forum.malleable.systems/t/challenge-problem-fearless-extensibility/205">challenge problem</a>,
while those approaches may offer a high degree of user freedom,
they also open the door to malware and
create maintenance issues for the extension host.</p>
<p>This article explores one potential route forward using
capabilities, effects, and extension-time type checking
to provide a more predictable extension path for
users, extension authors, and platform maintainers alike.</p>
<h2 id="disclaimers-and-assumptions">Disclaimers and assumptions</h2>
<p>I&rsquo;ve perhaps already spooked the dynamic language fans with words like
&ldquo;type checking&rdquo; and &ldquo;effect&rdquo; above&hellip; 😅
I&rsquo;m not attempting to claim that static types are the only way here.
I just returned from SPLASH (an academic PL conference)
where several statically typed effects systems were in the air,
so my thoughts just happen to biased in that direction at the moment.
I&rsquo;ve scribbled a few more thoughts about a dynamic version
towards the end in the Implementation section.</p>
<p>This article focuses on cases where
the source (or a typed IR derived from source)
for both the extension and the extension host are available,
as tooling would need to analyse the combination of both.</p>
<h2 id="goal">Goal</h2>
<p>The key ability we wish to achieve is arbitrary extension / modification of the
extension host while preserving safe and correct operation overall and also
permitting host maintainers to refactor without fear.</p>
<p>As an example,
let&rsquo;s imagine the host program we want to extend is a
graphics canvas (e.g. akin to Figma).
This host program has a built-in color picking feature
that displays a UI to choose a color
which is then added to the recent colors palette.
Our extension author would like to extend color picking
so that all colors are adjusted to meet accessibility standards.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-scala" data-lang="scala"><span style="display:flex;"><span><span style="color:#75715e">// host
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">def</span> pickColor<span style="color:#f92672">()</span> <span style="color:#f92672">{</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">val</span> color <span style="color:#66d9ef">=</span> colorPicker<span style="color:#f92672">.</span>choose<span style="color:#f92672">()</span>
</span></span><span style="display:flex;"><span>    palette<span style="color:#f92672">.</span>add<span style="color:#f92672">(</span>color<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// extension
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">def</span> onClickPick<span style="color:#f92672">()</span> <span style="color:#f92672">{</span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// We want to call `host.pickColor`,
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>    <span style="color:#75715e">// but we need adjust `color` before it goes into the palette
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#f92672">}</span>
</span></span></code></pre></div><p>The only accessible and relevant API the host offers for extensions to use
for this case is the <code>pickColor</code> function, but our extension wants to add
behaviour in the middle of <code>pickColor</code>, so we can&rsquo;t use it as-is.</p>
<p>Dynamic languages might allow host functions like <code>pickColor</code>
to be copied by the extension and redefined,
but this is too broad for the change we wish to make.
The extension now needs to keep its modified <code>pickColor</code> up to date
with changes upstream in the host copy,
even though they aren&rsquo;t related to the behaviour it&rsquo;s adding.
From the host maintainer perspective,
you don&rsquo;t feel that you can safely refactor your code,
since every extension might contain old copies of host functions
that could break after your refactoring.</p>
<p>We&rsquo;d like to express the intent of the extension&rsquo;s behaviour change
in a targeted and precise manner
that avoids these issues.</p>
<h2 id="effects-and-capabilities">Effects and capabilities</h2>
<p>Before we get there, let&rsquo;s talk about effects.</p>
<p><a href="https://en.wikipedia.org/wiki/Effect_system">Effects</a> are a (relatively) newer programming language concept that
allows tracking user-defined side effects as types (e.g. IO, memory access,
exceptions) and also supports effect handlers to take some action when these
effects occur. They&rsquo;ve been percolating in experimental languages (<a href="https://koka-lang.github.io">Koka</a>,
<a href="https://effekt-lang.org">Effekt</a>, <a href="https://www.unison-lang.org/docs/fundamentals/abilities/">Unison</a>) for a while now, and are starting to appear
in more established ones (<a href="https://docs.scala-lang.org/scala3/reference/experimental/canthrow.html">Scala</a>, <a href="https://ocaml.org/manual/5.0/effects.html">OCaml</a>).</p>
<p>If you haven&rsquo;t encountered effects before, I suggest skimming the
<a href="https://effekt-lang.org">Effekt</a> language site, as they have an approachable intro to the key
<a href="https://effekt-lang.org/docs/concepts/effect-safety">concepts</a>. I don&rsquo;t think I can do it justice myself, and
introducing effects is beyond the scope of this article anyway.</p>
<p>Effect handlers can resume the computation that was suspended when the effect
occurred, and may even resume multiple times. Effects and their handlers
generalise many forms of control flow, including exceptions, generators, and
multithreading, allowing libraries to <a href="https://doi.org/10.1007/978-3-030-83128-8_3">flexibly provide</a> these
features, rather than requiring language designers to add special functionality
for each one.</p>
<p>Various works have <a href="https://koka-lang.github.io/koka/doc/book.html#sec-handling">made</a> <a href="https://effekt-lang.org/docs/concepts/effect-safety">connections</a>
between effects and capabilities.
A function that has e.g. a &ldquo;file read&rdquo; effect can be thought of as
requiring a &ldquo;file read&rdquo; capability.
Effect handlers can even be added to some existing languages
if we pass the handler / capability as an extra function argument
(referred to as &ldquo;capability-passing style&rdquo;).</p>
<h2 id="implicit-effects">Implicit effects</h2>
<p>Effects systems today focus on what I&rsquo;ll call &ldquo;explicit&rdquo; effects: both the code
performing the effect and its corresponding handler are written explicitly in
the program source. If you want to model additional user-defined effects, you
would add both handlers and effect performing steps to do so.</p>
<p>We can also imagine &ldquo;implicit&rdquo; effects that represent existing language
operations. For example, function calls could be treated as an implicit effect.
If we then allow handlers to be defined for these implicit effects, we gain
quite powerful control over deeply nested code.</p>
<p>Extensions can leverage this ability to make arbitrary changes to the extension
host. While that is quite a powerful technique, the static types present in both
the host and extension help to ensure reasonable behaviour is maintained by
ensuring required values are still provided as expected.</p>
<p>This code modification ability bears some resemblance to the power of
<a href="https://en.wikipedia.org/wiki/Aspect-oriented_programming">aspect-oriented programming</a>. Effect systems (especially those with
lexical effect handlers) avoid the &ldquo;spooky action at a distance&rdquo; issue that can
make AOP approaches hard to understand. Additional tooling can help further by
highlighting modified operations in the combined system (host with extensions).
Some amount of surprising host control flow seems tolerable when we gain the
ability to make arbitrary changes via extensions. Extension-time type checking
should ameliorate some concerns by ensure all modules fit together as expected.</p>

<div class="callout">
  <div>🚧</div>
	<div class="callout-inner">
    This would be a good place to show a running example&hellip;
I&rsquo;ll try to add one in a future version.
  </div>
</div>

<h2 id="safety-via-capabilities-and-isolation">Safety via capabilities and isolation</h2>
<p>Host maintainers often fear nefarious extensions
may perform various undesirable actions.
Dangerous abilities (e.g. &ldquo;delete home directory&rdquo;) can be avoided
by restricting or not providing those capabilities
to extension execution contexts.</p>
<p>In a system where extensions can modify deeply nested code,
there will likely be a need to isolate extensions
both from the host and from each other.
For example,
extension A uses handles a call effect to alter host function <code>foo</code>,
while extension B depends on its default behaviour.
Fortunately, the desired isolation falls out naturally
from a lexical effect handler model:
extension A&rsquo;s code modification is only active inside the scope of its handler.
It has no effect on other code paths in extension A,
and certainly not on other extensions.</p>
<p>It&rsquo;s likely ideal to go further and ensure execution contexts
actually are isolated from each other.
Existing concepts like
<a href="https://en.wikipedia.org/wiki/Mirror_(programming)">mirrors</a>,
<a href="https://github.com/tc39/proposal-compartments">compartments</a>, and
<a href="https://github.com/tc39/proposal-shadowrealm">realms</a>
suggest a way forward.</p>
<h2 id="extension-host-code-changes">Extension host code changes</h2>
<p>In today&rsquo;s dynamic systems where extension might mean
wholly replacing host functions with modified copies,
it can be hard to predict what madness may ensue
when the host platform refactors some code.
Issues usually only present themselves at run time
when the modified host code is somehow invoked,
or alternatively the modified code may be silently unused
if the extension includes
an outdated copy of a modified host function.</p>
<p>These concerns are easily avoided
when leveraging static types and
code modification via effects.
Effects allow for precision code modification,
so there&rsquo;s no need to copy an entire host function
just to modify one line.
Static types give extension-time assurance
that the extension and host continue to fit together
in a reasonable way.
If the host refactoring creates an incompatibility,
it will be clearly surfaced when trying to <em>load</em> the extension
(which is far better than waiting until feature <em>use</em>).</p>
<h2 id="open-questions">Open questions</h2>
<p>We&rsquo;ve examined a mechanism to modify code
nested beneath some function an extension calls,
but what if you need to modify some behaviour
that cannot be reached by any function exposed to extensions?
At first glance, it would seem like some form of reflection
is needed to gain access to these internals.
Perhaps a controlled form of reflection using
<a href="https://gbracha.blogspot.com/2010/03/through-looking-glass-darkly.html">mirrors as capabilities</a>&hellip;?
I am confident there&rsquo;s an elegant approach to be found
that integrates well with the thoughts on effects and capabilities above,
while avoiding the messy approaches of AOP.</p>
<h2 id="implementation">Implementation</h2>
<p>This approach would seem to require an execution environment that
allows dynamically hooking / modifying code
in response to changes made by extensions.
While various <a href="https://tratt.net/laurie/research/pubs/html/tratt__dynamically_typed_languages/">dynamic programming systems</a>
like those associated with JavaScript, Smalltalk, Lisp, etc.
may have some support for this,
it&rsquo;s less likely to be found in the statically typed languages,
as those often assume type checking
should be paired with ahead-of-time compilation.</p>
<p>I imagine <a href="https://en.wikipedia.org/wiki/Metaobject">metaobject protocols</a>
(e.g. from Common Lisp, Smalltalk, etc.)
could accomplish similar modifications at run time.
The approach described here also makes uses of capabilities,
so <a href="https://newspeaklanguage.org">Newspeak</a> might be the closest match among dynamic languages.</p>
<p>It&rsquo;s less clear to me how dynamically typed languages
might provide extension-time sanity checks,
so that&rsquo;s a big part of why I focused on a statically typed approach.
If you see a way to do something similar in a more dynamic environment,
please do let me know!</p>
<p>A few stacks that could allow for
type-checked extension-time code modification
include:</p>
<ul>
<li>Wasm with GC and stack switching extensions (plus additional metadata)</li>
<li>Scala 3 (which preserves a <a href="https://docs.scala-lang.org/scala3/guides/tasty-overview.html">typed AST</a> for metaprogramming)</li>
</ul>
<p>Are there other technologies that might be well suited to such an approach?
Please do let me know,
as it may save me quite a lot of time and energy
as I explore this idea further!</p>
<h2 id="summary">Summary</h2>
<p>In the article, we&rsquo;ve taken a look at
(an in-progress sketch of)
one potential extensibility approach.
Is it complicated? Yes.
Is it over-engineered&hellip;? Perhaps.
I&rsquo;m okay with jumping through a few hoops if it will restore deep extensibility
while also balancing safety and maintenance concerns.</p>
<p>I&rsquo;d love to hear feedback on this!
Assuming I manage to stay focused on this topic,
I&rsquo;d like to implementing an extension system using some of the ideas here.
There are clearly some rough edges and likely better alternate approaches, so do
let me know what comes to mind.</p>
<h2 id="related-work">Related work</h2>
<p>As already mentioned, there are various languages that support some form of
effects, capabilities, or both, so do take a look at those.</p>
<p>There are many resources on
effects, capabilities, metaprogramming, etc.
that could be mentioned&hellip;
The list below mentions those that connect more directly
to the ideas in this article.
This is certainly not a comprehensive list&hellip;!</p>
<ul>
<li>
<p>Aleksander Boruch-Gruszecki, Adrien Ghosn, Mathias Payer, and Clément
Pit-Claudel. 2024. Gradient: Gradual compartmentalization via object
capabilities tracked in types. Proc. ACM Program. Lang. 8, OOPSLA2.
<a href="https://doi.org/10.1145/3689751">https://doi.org/10.1145/3689751</a></p>
</li>
<li>
<p>Gilad Bracha and David Ungar. 2004. Mirrors:
Design principles for meta-level facilities of object-oriented programming
languages. In Proc. of OOPSLA ’04.
<a href="https://doi.org/10.1145/1028976.1029004">https://doi.org/10.1145/1028976.1029004</a></p>
</li>
<li>
<p>Gilad Bracha. 2010. Through the looking glass darkly.
<a href="https://gbracha.blogspot.com/2010/03/through-looking-glass-darkly.html">https://gbracha.blogspot.com/2010/03/through-looking-glass-darkly.html</a></p>
</li>
<li>
<p>Jonathan Immanuel Brachthäuser, Philipp Schuster, and Klaus Ostermann. 2020.
Effects as capabilities: Effect handlers and lightweight effect polymorphism.
Proc. ACM Program. Lang. 4, OOPSLA.
<a href="https://doi.org/10.1145/3428194">https://doi.org/10.1145/3428194</a></p>
</li>
<li>
<p>Jonathan Immanuel Brachthäuser. 2022. What you see is what you get:
Practical effect handlers in capability-passing style.
<a href="https://doi.org/10.1007/978-3-030-83128-8_3">https://doi.org/10.1007/978-3-030-83128-8_3</a></p>
</li>
<li>
<p>Chip Morningstar. 2017. What are capabilities?
<a href="http://habitatchronicles.com/2017/05/what-are-capabilities/">http://habitatchronicles.com/2017/05/what-are-capabilities/</a></p>
</li>
<li>
<p>Éric Tanter. 2006. Reflection and open implementations.
University of Chile.
<a href="https://www.dcc.uchile.cl/TR/2009/TR_DCC-20091123-013.pdf">https://www.dcc.uchile.cl/TR/2009/TR_DCC-20091123-013.pdf</a></p>
</li>
<li>
<p>Jeremy Yallop. 2023. Effects bibliography.
<a href="https://github.com/yallop/effects-bibliography">https://github.com/yallop/effects-bibliography</a></p>
</li>
</ul>
]]></content:encoded>
    </item>
    
    <item xml:base="https://convolv.es/blog/2024/08/17/clang-ir-opt-level/">
      <title>Optimisation-dependent IR decisions in Clang</title>
      <link>https://convolv.es/blog/2024/08/17/clang-ir-opt-level/</link>
      <pubDate>Sat, 17 Aug 2024 22:27:06 +0100</pubDate>
      
      <guid>https://convolv.es/blog/2024/08/17/clang-ir-opt-level/</guid>
      <description>I used to naively assume that Clang always handed off the same IR to the LLVM optimisation pipeline regardless of optimisation level. In an attempt to gain a bit more understanding into exactly what kinds of decisions depend on optimisation level in Clang, I surveyed the IR emission code paths.</description>
      <content:encoded><![CDATA[<p>I used to naively assume that Clang always handed off &ldquo;basically&rdquo; the same IR to
the LLVM optimisation pipeline regardless of optimisation level. I was at least
aware of the <code>optnone</code> attribute set on functions when compiling at <code>-O0</code>, but
I&rsquo;ve slowly started to notice there are more divergences than just that.</p>
<h2 id="survey">Survey</h2>
<p>In an attempt to gain a bit more understanding into exactly what kinds of
decisions depend on optimisation level in Clang, I surveyed the <a href="https://github.com/search?q=repo%3Allvm%2Fllvm-project+path%3A%2F%5Eclang%5C%2Flib%5C%2FCodeGen%5C%2F%2F+OptimizationLevel&amp;type=code">IR emission
code
paths</a>.
I examined Clang source at commit <code>7c4c72b52038810a8997938a2b3485363cd6be3a</code>
(2024-08).</p>
<p>I ignored decisions related to specialised language specifics (Objective-C, ARC,
HLSL, OpenMP) and ABI details.</p>
<ul>
<li>When optimisation is disabled
<ul>
<li><a href="https://github.com/llvm/llvm-project/blob/997e5e870337e4a25b82be5b01e8f7675c350070/clang/lib/CodeGen/CGBlocks.cpp#L1503-L1513">Add <code>block.addr</code> stack slot to help debugger</a></li>
<li><a href="https://github.com/llvm/llvm-project/blob/1b8ab2f08998d3220e5d95003d47bb3d7cac966b/clang/lib/CodeGen/CGCXX.cpp#L38-L41">Keep destructor distinct from base class destructor to help debugger</a></li>
<li><a href="https://github.com/llvm/llvm-project/blob/92aec5192ce752c984837a93227200b54faa8679/clang/lib/CodeGen/CGStmt.cpp#L1746-L1751">Keep switch case with just <code>break</code> as separate block to help debugger</a></li>
<li><a href="https://github.com/llvm/llvm-project/blob/d179acd0484bac30c5ebbbed4d29a4734d92ac93/clang/lib/CodeGen/CodeGenFunction.cpp#L1581-L1582">Add trap call for unreachable blocks</a></li>
<li><a href="https://github.com/llvm/llvm-project/blob/92aec5192ce752c984837a93227200b54faa8679/clang/lib/CodeGen/CodeGenModule.cpp#L2485-L2488">Add <code>optnone</code> function attribute</a></li>
</ul>
</li>
<li>When optimisation is enabled
<ul>
<li><a href="https://github.com/llvm/llvm-project/blob/e91e0f52895e2b23bd690a86dbaafd979e027d29/clang/lib/CodeGen/CGBuiltin.cpp#L2585-L2587">Check if <code>errno</code> is disabled</a></li>
<li><a href="https://github.com/llvm/llvm-project/blob/e91e0f52895e2b23bd690a86dbaafd979e027d29/clang/lib/CodeGen/CGBuiltin.cpp#L3366-L3370">Pass <code>__builtin_expect</code> along via <code>llvm.expect</code></a> (<a href="https://github.com/llvm/llvm-project/blob/e91e0f52895e2b23bd690a86dbaafd979e027d29/clang/lib/CodeGen/CGBuiltin.cpp#L3392-L3396">2</a>)</li>
<li><a href="https://github.com/llvm/llvm-project/blob/4497ec293a6e745be817dc88027169bd5e4f7246/clang/lib/CodeGen/CGClass.cpp#L1309-L1312">Add various virtual table invariants and assumptions</a> (more in same file)</li>
<li><a href="https://github.com/llvm/llvm-project/blob/2f8f58dd17a11934e8c8ec212b6474f76fb18e61/clang/lib/CodeGen/CGDecl.cpp#L1008-L1009">Split constant struct / array stores into sequence for each field</a></li>
<li><a href="https://github.com/llvm/llvm-project/blob/07f8a65d09608d67bfd6adbd62bb0999c7363456/clang/lib/CodeGen/CGDeclCXX.cpp#L158-L160">Add various variable invariants</a></li>
<li><a href="https://github.com/llvm/llvm-project/blob/92aec5192ce752c984837a93227200b54faa8679/clang/lib/CodeGen/CGExpr.cpp#L2010-L2015">Add load range metadata</a></li>
<li><a href="https://github.com/llvm/llvm-project/blob/92aec5192ce752c984837a93227200b54faa8679/clang/lib/CodeGen/CGExpr.cpp#L2240-L2244">Add matrix index assumptions</a> (<a href="https://github.com/llvm/llvm-project/blob/92aec5192ce752c984837a93227200b54faa8679/clang/lib/CodeGen/CGExpr.cpp#L2403-L2407">2</a>, <a href="https://github.com/llvm/llvm-project/blob/e108853ac8fad27ff22be9303c87d90bcdf0ef53/clang/lib/CodeGen/CGExprScalar.cpp#L2005-L2006">3</a>)</li>
<li><a href="https://github.com/llvm/llvm-project/blob/92aec5192ce752c984837a93227200b54faa8679/clang/lib/CodeGen/CGExpr.cpp#L3842-L3850">Collapse trap calls</a></li>
<li><a href="https://github.com/llvm/llvm-project/blob/3ad31e12ccfc7db25f3cbedc4ee966e7099ac78f/clang/lib/CodeGen/CGExprCXX.cpp#L2277-L2280">Add exact dynamic casts</a></li>
<li><a href="https://github.com/llvm/llvm-project/blob/92fc1eb0c1ae3813f2ac9208e2c74207aae9d23f/clang/lib/CodeGen/CGLoopInfo.cpp#L822-L828">Add loop unrolling metadata</a></li>
<li><a href="https://github.com/llvm/llvm-project/blob/92aec5192ce752c984837a93227200b54faa8679/clang/lib/CodeGen/CGStmt.cpp#L870-L872">Add condition likelihood</a> (<a href="https://github.com/llvm/llvm-project/blob/92aec5192ce752c984837a93227200b54faa8679/clang/lib/CodeGen/CGStmt.cpp#L1049-L1051">2</a>, <a href="https://github.com/llvm/llvm-project/blob/92aec5192ce752c984837a93227200b54faa8679/clang/lib/CodeGen/CGStmt.cpp#L1264-L1266">3</a>, <a href="https://github.com/llvm/llvm-project/blob/92aec5192ce752c984837a93227200b54faa8679/clang/lib/CodeGen/CGStmt.cpp#L1367-L1369">4</a>, <a href="https://github.com/llvm/llvm-project/blob/d179acd0484bac30c5ebbbed4d29a4734d92ac93/clang/lib/CodeGen/CodeGenFunction.cpp#L3037-L3040">5</a>)</li>
<li><a href="https://github.com/llvm/llvm-project/blob/92aec5192ce752c984837a93227200b54faa8679/clang/lib/CodeGen/CGStmt.cpp#L2212-L2215">Track condition likelihood</a></li>
<li><a href="https://github.com/llvm/llvm-project/blob/92aec5192ce752c984837a93227200b54faa8679/clang/lib/CodeGen/CGStmt.cpp#L2264-L2271">Pass <code>__builtin_unpredictable</code> along via metadata</a> (<a href="https://github.com/llvm/llvm-project/blob/d179acd0484bac30c5ebbbed4d29a4734d92ac93/clang/lib/CodeGen/CodeGenFunction.cpp#L2039-L2045">2</a>)</li>
<li><a href="https://github.com/llvm/llvm-project/blob/d179acd0484bac30c5ebbbed4d29a4734d92ac93/clang/lib/CodeGen/CodeGenFunction.cpp#L73-L74">Add lifetime markers</a></li>
<li><a href="https://github.com/llvm/llvm-project/blob/92aec5192ce752c984837a93227200b54faa8679/clang/lib/CodeGen/CodeGenModule.cpp#L402-L406">Add type-based alias analysis (TBAA) metadata</a> (<a href="https://github.com/llvm/llvm-project/blob/123c036bd361de9ed6baa0090e5942105764e8db/clang/lib/CodeGen/CodeGenTBAA.cpp#L277-L279">2</a>, <a href="https://github.com/llvm/llvm-project/blob/123c036bd361de9ed6baa0090e5942105764e8db/clang/lib/CodeGen/CodeGenTBAA.cpp#L407-L408">3</a>)</li>
<li><a href="https://github.com/llvm/llvm-project/blob/92aec5192ce752c984837a93227200b54faa8679/clang/lib/CodeGen/CodeGenModule.cpp#L1031-L1046">Add strict virtual table metadata</a></li>
<li><a href="https://github.com/llvm/llvm-project/blob/92aec5192ce752c984837a93227200b54faa8679/clang/lib/CodeGen/CodeGenModule.cpp#L4048-L4049">Preserve function declarations</a></li>
<li><a href="https://github.com/llvm/llvm-project/blob/92aec5192ce752c984837a93227200b54faa8679/clang/lib/CodeGen/CodeGenModule.cpp#L4101-L4103">Add opportunistic virtual tables</a></li>
</ul>
</li>
</ul>
<h2 id="example">Example</h2>
<p>If you&rsquo;d like to explore the differences yourself, take a look at this <a href="https://godbolt.org/z/GrbohjcWa">Compiler
Explorer example</a>. The input source is not too
interesting (I&rsquo;ve grabbed a random slice of Git source files that I happened to
have on hand). The left IR view shows <code>-O0</code> and the right IR view shows <code>-O1</code>
with LLVM passes disabled. We can ask Clang to produce LLVM IR without sending
it through the LLVM optimisation pipeline by adding <code>-Xclang -disable-llvm-passes</code> (a useful tip for LLVM archaeology).</p>
<p><a href="https://godbolt.org/z/GrbohjcWa"><img loading="lazy" src="ce.png" alt="Compiler Explorer playground comparing O0 and O1 LLVM IR"  />
</a></p>
<p>After diffing the two outputs, there are two features that are only activated
when optimisation is enabled that appear to be responsible for most of the
differences in this example:</p>
<ul>
<li>Lifetime markers</li>
<li>Type-based alias analysis (TBAA) metadata</li>
</ul>
<p>Lifetime markers are especially interesting in this example, as Clang actually
reshapes control flow (adding several additional <code>cleanup</code> blocks) so that it
can insert these markers (which are calls to LLVM intrinsic functions
<code>llvm.lifetime.start/end</code>).</p>
]]></content:encoded>
    </item>
    
    <item xml:base="https://convolv.es/talks/debug-info-metrics/">
      <title>Accurate coverage metrics for compiler-generated debugging information</title>
      <link>https://convolv.es/talks/debug-info-metrics/</link>
      <pubDate>Thu, 11 Apr 2024 00:00:00 +0000</pubDate>
      
      <guid>https://convolv.es/talks/debug-info-metrics/</guid>
      <description>In this talk, we propose some new metrics, computable by our tools, which could serve as motivation for language implementations to improve debugging quality.</description>
      <content:encoded><![CDATA[<p>Conference talk (<a href="https://www.youtube.com/watch?v=LePAdLTRa4Q">video</a>, <a href="/talks/2024/EuroLLVM/Debug%20info%20metrics.pdf">slides</a>)
presented at <a href="https://llvm.swoogo.com/2024eurollvm/agenda">EuroLLVM 2024</a></p>
<p><a href="https://www.youtube.com/watch?v=LePAdLTRa4Q"><img loading="lazy" src="video.png" alt=""  />
</a></p>
<p>This talk covers research I worked on together with Stephen Kell. See also our
CC 2024 <a href="/cv/#debug-info-metrics">paper</a> on this topic.</p>
<h2 id="abstract">Abstract</h2>
<p>Many debugging tools rely on compiler-produced metadata to present a
source-language view of program states, such as variable values and source line
numbers. While this tends to work for unoptimised programs, current compilers
often generate only partial debugging information in optimised programs. Current
approaches for measuring the extent of coverage of local variables are based on
crude assumptions (for example, assuming variables could cover their whole
parent scope) and are not comparable from one compilation to another. In this
talk, we propose some new metrics, computable by our tools, which could serve as
motivation for language implementations to improve debugging quality.</p>
]]></content:encoded>
    </item>
    
    <item xml:base="https://convolv.es/guides/lto/">
      <title>Link-time optimisation (LTO)</title>
      <link>https://convolv.es/guides/lto/</link>
      <pubDate>Wed, 08 Nov 2023 15:49:51 +0000</pubDate>
      
      <guid>https://convolv.es/guides/lto/</guid>
      <description>I recently started exploring link-time optimisation (LTO), which I used to think was just a single boolean choice in the compilation and linking workflow, and perhaps it was like that a while ago&amp;hellip; I&amp;rsquo;ve learned that these days, there are many different dimensions of LTO across compilers and linkers today and more variations are being proposed all the time.
In this &amp;ldquo;living guide&amp;rdquo;, I aim to cover the LTO-related features I have encountered thus far.</description>
      <content:encoded><![CDATA[<p>I recently started exploring link-time optimisation (LTO),
which I used to think was just a single boolean choice
in the compilation and linking workflow,
and perhaps it was like that a while ago&hellip;
I&rsquo;ve learned that these days,
there are many different dimensions of LTO across
compilers and linkers today and more variations
<a href="https://discourse.llvm.org/t/rfc-a-unified-lto-bitcode-frontend/61774">are</a>
<a href="https://discourse.llvm.org/t/rfc-ffat-lto-objects-support/63977">being</a>
<a href="https://discourse.llvm.org/t/rfc-integrated-distributed-thinlto/69641">proposed</a>
all the time.</p>
<p>In this &ldquo;living guide&rdquo;,
I aim to cover the LTO-related features I have encountered thus far.
I intend to keep updating this going forward
as I learn about new details in this space.
I am sure there are even more corners to cover,
so if you see something that should be added, corrected, etc.
please <a href="/contact">contact me</a>.</p>
<p>I am <em>not</em> aiming to provide specific recommendations here,
as there are many tradeoffs to consider
and different applications of LTO will weigh each of those differently.
Instead, I hope this is a broadly useful portrayal of the facts.</p>
<p>This guide focuses on common toolchains for languages like C, Rust, etc. which
typically use ahead-of-time (AOT) compilation and linking. Alternative
toolchains for these languages and common toolchains for other languages may use
other strategies like interpreting, JIT compilation, etc. Those other language
implementation strategies do not offer LTO-like features (that I know of), so
I have ignored them here.</p>
<p>I hope this guide is useful to experienced compiler users and compiler hackers
who may not have heard about the latest work yet. I also hope it&rsquo;s broadly
accessible to those who may be unfamiliar with LTO.</p>
<hr>
<h2 id="basics">Basics</h2>
<p>Normal (non-LTO) compilation compiles and optimises one file at a time.
LTO can optimise across all files at once.
The overall aim of LTO is better runtime performance through whole-program
analysis and cross-module optimisation.</p>
<p>Let&rsquo;s take a high-level look at the workflow of most AOT compile and link
toolchains. We&rsquo;ll start off with the &ldquo;default&rdquo; workflow without LTO.</p>
<p><img loading="lazy" src="default-workflow.svg" alt="Default compile and link workflow with several source files optimised
separately into object files containing machine code, then linked to create the
final output"  />
</p>
<p>In the default workflow without LTO, each unit of source code is compiled and
optimised separately to produce an object file with machine code for the target
architecture. Optimisations can only consider a single source unit at a time, so
all externally accessible symbols (functions and variables) must be preserved,
even if they will end up being unused in the final linked output. The linker
then combines these object files to produce the final output (executable or
library).</p>
<p>Now let&rsquo;s look at a workflow with LTO.</p>
<p><img loading="lazy" src="lto-workflow.svg" alt=""  />
</p>
<p>In the LTO setup, we still initially compile each source unit separately and
perform some amount of optimisation, but the output is different: instead of
machine code, the output of LTO compilation is an object file containing
the compiler&rsquo;s specific internal representation (IR) for that source unit.</p>
<p>The linking stage now performs a much more complex dance than it did before.
The IR produced from compiling each source unit is read and the compiler&rsquo;s
optimisation pipeline is invoked to analyse and transform the whole program (the
precise details of this varies with different LTO features, as we&rsquo;ll see later
in this guide). This whole program stage unlocks further optimisation
opportunities, as we can remove symbols that are unused outside the whole
program, inline functions from other source units, etc.</p>
<p>With those fundamentals out of the way, let&rsquo;s look at various features and
variants that toolchains offer to further tweak and customise this process.</p>
<h2 id="features-and-variants">Features and variants</h2>

<div class="callout">
  <div>⚠️</div>
	<div class="callout-inner">
    Some of the features found in the LTO space have &ldquo;marketing&rdquo; names which do not
communicate what they actually do on a technical level.
For some descriptions below, I have used my own terminology to avoid these
issues.
Each section also lists other names things are known by, in case you want to
search for more information.
  </div>
</div>

<h3 id="basic-lto">Basic LTO</h3>
<p>This is the simplest of the LTO modes and matches the workflow described above
in <a href="#basics">Basics</a>.
Each compilation task produces object files containing the compiler&rsquo;s internal
IR format.
The linking stage combines all compilation units into a single, large module.
Interprocedural analysis and optimisation is performed on a single thread.
With large code bases, this process is likely to consume lots of memory and take
a considerable amount of time.</p>
<p><img loading="lazy" src="lto-workflow.svg" alt=""  />
</p>
<p>In terms of compile-time performance,
the LLVM project <a href="https://blog.llvm.org/2016/06/thinlto-scalable-and-incremental-lto.html">has shown</a> that compilation and linking of
the Clang 3.9 codebase with basic LTO is ~5x the non-LTO time.
This extra work achieves an average run-time performance improvement of 2.86%.</p>
<p>This mode is also referred to as &ldquo;full LTO&rdquo;.</p>
<table>
<thead>
<tr>
<th>Toolchain</th>
<th>First available</th>
<th>Option</th>
</tr>
</thead>
<tbody>
<tr>
<td>Clang</td>
<td>2.6 (2009)</td>
<td><code>-flto</code> or <code>-flto=full</code></td>
</tr>
<tr>
<td>GCC</td>
<td>4.5 (2010)</td>
<td><code>-flto -flto-partition=one</code></td>
</tr>
<tr>
<td>Rust</td>
<td>1.0 (2015)</td>
<td><code>-C lto</code></td>
</tr>
</tbody>
</table>
<h3 id="parallel-lto">Parallel LTO</h3>
<p>Toolchains have come up with a variety of related techniques to speed up the
the link-time work of LTO while preserving (most of) the run-time performance
gains. Instead of creating a single, massive module at link time, a much smaller
global index of functions likely to be inlined is computed. With that in hand,
each compilation unit can be processed in parallel at link time while still
benefiting from most of the same whole-program optimisations as <a href="#basic-lto">basic
LTO</a>.</p>
<p><img loading="lazy" src="parallel-lto-workflow.svg" alt=""  />
</p>
<p>Continuing with the same <a href="https://blog.llvm.org/2016/06/thinlto-scalable-and-incremental-lto.html">example data</a> based on building Clang 3.9,
LLVM&rsquo;s implementation of parallel LTO
achieves nearly all of the run-time performance improvement
as seen with basic LTO:
basic LTO reached a 2.86% improvement over non-LTO,
while parallel LTO achieved a 2.63% improvement over non-LTO.</p>
<p>The compilation time improves dramatically: instead of 5x non-LTO, it&rsquo;s now only
1.2x non-LTO, which is quite impressive.</p>
<p>The technical details of how each toolchain
implements parallel LTO vary somewhat.
LLVM-based toolchains (which includes Clang and Rust from our discussions here)
optimise different compilation units in parallel
and inlines across module boundaries,
but most other cross-modules optimisations are skipped.
GCC, on the other hand,
partitions (nearly) the same optimisation work
it would have done with one thread into a batch per thread.</p>
<p>This suggests that GCC&rsquo;s parallel LTO should be able to get closer than LLVM
in achieving the same run-time performance as with basic LTO
(our recurring dataset shows a 0.23% run-time delta between
LLVM&rsquo;s basic and parallel modes).
At the same time, LLVM&rsquo;s approach may be better able to handle
incremental changes in a single module of large program.
If you would like to see data comparing the two modes in GCC,
please let me know.</p>
<p>This mode is also referred to as &ldquo;thin LTO&rdquo;,
particularly in the LLVM ecosystem.
The &ldquo;thin&rdquo; concept on the LLVM side
refers to the fact that no IR is involved in the whole program analysis step.</p>
<table>
<thead>
<tr>
<th>Toolchain</th>
<th>First available</th>
<th>Option</th>
</tr>
</thead>
<tbody>
<tr>
<td>Clang</td>
<td>3.9 (2016)</td>
<td><code>-flto=thin</code></td>
</tr>
<tr>
<td>GCC</td>
<td>4.6 (2011)</td>
<td><code>-flto=auto</code> or <code>-flto=&lt;threads&gt;</code></td>
</tr>
<tr>
<td>Rust</td>
<td>1.25 (2018)</td>
<td><code>-C lto=thin</code></td>
</tr>
</tbody>
</table>
<h3 id="lto-with-mode-selection-deferred-to-link-time">LTO with mode selection deferred to link time</h3>
<p>In some applications, it may be useful to support both the <a href="#basic-lto">basic</a>
and <a href="#parallel-lto">parallel</a> LTO modes. In this arrangement, the compiler IR
attached to each object file stores all the info it needs to run either LTO mode
at link time.</p>
<p>When it&rsquo;s time to link, you can then choose either of
the basic or parallel LTO modes via link-time compiler options
(for the toolchains mentioned here,
the program commonly referred to as just the &ldquo;compiler&rdquo;
is really the &ldquo;compiler driver&rdquo;
which in turn calls the other programs in the workflow,
such as the linker).</p>
<p>This variant is also referred to as &ldquo;unified LTO&rdquo;.</p>
<table>
<thead>
<tr>
<th>Toolchain</th>
<th>First available</th>
<th>Option</th>
</tr>
</thead>
<tbody>
<tr>
<td>Clang</td>
<td>17 (2023)</td>
<td><code>-funified-lto</code></td>
</tr>
<tr>
<td>GCC</td>
<td>4.5 (2010)</td>
<td>supported by default</td>
</tr>
<tr>
<td>Rust</td>
<td>—</td>
<td>—</td>
</tr>
</tbody>
</table>
<h3 id="lto-enablement-decision-deferred-to-link-time">LTO enablement decision deferred to link time</h3>
<p>It may also be useful to push the choice of whether to use LTO at all down to
the linking step of the workflow. To support this use case, the compiler
combines <em>both</em> machine code <em>and</em> internal IR in the object files produced by
each compilation unit.</p>
<p>This variant is also referred to as &ldquo;fat LTO objects&rdquo;.</p>
<table>
<thead>
<tr>
<th>Toolchain</th>
<th>First available</th>
<th>Option</th>
</tr>
</thead>
<tbody>
<tr>
<td>Clang</td>
<td>17 (2023)</td>
<td><code>-ffat-lto-objects</code></td>
</tr>
<tr>
<td>GCC</td>
<td>4.9 (2014)</td>
<td><code>-ffat-lto-objects</code></td>
</tr>
<tr>
<td>Rust</td>
<td>—</td>
<td>—</td>
</tr>
</tbody>
</table>
<h3 id="other-details">Other details</h3>
<p>There are a few other more advanced corners of LTO, including:</p>
<ul>
<li>Distributed build support</li>
<li>Symbol visibility</li>
<li>Linker caching</li>
</ul>
<p>If you&rsquo;re curious about any of these or other aspects, please
<a href="/contact">let me know</a>!
I plan to extend this guide to document additional bits of LTO
that others are interested in.</p>
<hr>
<h4 id="acknowledgements">Acknowledgements</h4>
<p>Thanks to
<a href="https://discourse.llvm.org/u/teresajohnson">Teresa Johnson</a>,
<a href="https://www.ucw.cz/~hubicka/">Jan Hubička</a>,
<a href="https://github.com/nmdis1999">Iti Shree</a>, and
<a href="https://tratt.net/laurie/">Laurence Tratt</a>
for feedback on earlier drafts.</p>
]]></content:encoded>
    </item>
    
    <item xml:base="https://convolv.es/talks/testing-debug-info/">
      <title>Testing debug info of optimised programs</title>
      <link>https://convolv.es/talks/testing-debug-info/</link>
      <pubDate>Thu, 15 Sep 2022 00:00:00 +0000</pubDate>
      
      <guid>https://convolv.es/talks/testing-debug-info/</guid>
      <description>In this preliminary work, we symbolically execute unoptimised and optimised versions of a program which are then checked for debug info consistency. We expect this to allow testing correctness of debug info generation across a much larger portion of the compiler.</description>
      <content:encoded><![CDATA[<p>Workshop talk (<a href="https://www.youtube.com/watch?v=SIYPYP06fY0">video</a>,
<a href="/talks/2022/KLEE/Testing%20debug%20info%20of%20optimised%20programs.pdf">slides</a>)
presented at <a href="https://srg.doc.ic.ac.uk/klee22/schedule.html">KLEE 2022</a></p>
<p><a href="https://www.youtube.com/watch?v=SIYPYP06fY0"><img loading="lazy" src="video.png" alt=""  />
</a></p>
<h2 id="abstract">Abstract</h2>
<p>Debuggers rely on compiler-produced metadata to present correct variable values
and line numbers in the source language. While this tends to work for
unoptimised programs, current compilers either throw away or corrupt debugging
info in optimised programs. Current approaches for testing debug info rely on
manual test cases or only reach a small portion of the compiler. In this
preliminary work, we symbolically execute unoptimised and optimised versions of
a program which are then checked for debug info consistency. We expect this to
allow testing correctness of debug info generation across a much larger portion
of the compiler.</p>
]]></content:encoded>
    </item>
    
    <item xml:base="https://convolv.es/talks/room-to-grow/">
      <title>Room to grow: Building collaborative, open software</title>
      <link>https://convolv.es/talks/room-to-grow/</link>
      <pubDate>Fri, 29 Apr 2022 00:00:00 +0000</pubDate>
      
      <guid>https://convolv.es/talks/room-to-grow/</guid>
      <description>We examine one approach to collaborative, open software by building on Matrix, a secure, decentralised, real-time communication protocol with generic database capabilities hiding beneath its current focus on chat.</description>
      <content:encoded><![CDATA[<p>Conference talk
(<a href="https://www.hytradboi.com/2022/room-to-grow-building-collaborative-open-software">video</a>,
<a href="/talks/2022/HYTRADBOI/Room%20to%20grow%20-%20Building%20collaborative,%20open%20software.pdf">slides</a>) presented at <a href="https://www.hytradboi.com/">HYTRADBOI 2022</a></p>
<p><a href="https://www.hytradboi.com/2022/room-to-grow-building-collaborative-open-software"><img loading="lazy" src="video.png" alt=""  />
</a></p>
<h2 id="abstract">Abstract</h2>
<p><a href="https://www.inkandswitch.com/local-first/">Local-first software</a> for creative
work resets the balance of ownership away from the cloud, allowing creators to
retain control of their work while still collaborating in real time with others.
This sounds like a magical ideal, but it also raises many new questions, such
as:</p>
<ul>
<li>How should data synchronisation work?</li>
<li>What does user identity look like when collaborating?</li>
<li>How is document access defined among several people?</li>
<li>Is some kind of complex custom backend needed to handle all this?</li>
</ul>
<p>In this talk, we examine one approach to collaborative, open software by
building on <a href="https://matrix.org/">Matrix</a>, a secure, decentralised, real-time
communication protocol with generic database capabilities hiding beneath its
current focus on chat. We show through several examples and demos that Matrix
can assist with all of the questions above, allowing creative software to focus
on delivering the best experience while still meeting local-first ideals.</p>
<p>The software itself can also be collaborative and
<a href="https://malleable.systems/">malleable</a>, allowing for user customisation without
depending on upstream vendors to add a new options to achieve your goals.</p>
<h2 id="notes">Notes</h2>
<p>The following notes describe the ideas from the talk in more detail:</p>
<ul>
<li><a href="https://github.com/matrix-org/collaborative-documents/blob/main/docs/collaborative-documents.md">Matrix-native collaborative documents</a></li>
<li><a href="https://github.com/matrix-org/collaborative-documents/blob/main/docs/saguaro.md">Saguaro: prickly collaboration</a></li>
</ul>
]]></content:encoded>
    </item>
    
    <item xml:base="https://convolv.es/blog/2017/08/25/building-firefox-for-linux-32-bit/">
      <title>Building Firefox for Linux 32-bit</title>
      <link>https://convolv.es/blog/2017/08/25/building-firefox-for-linux-32-bit/</link>
      <pubDate>Fri, 25 Aug 2017 19:33:00 -0500</pubDate>
      
      <guid>https://convolv.es/blog/2017/08/25/building-firefox-for-linux-32-bit/</guid>
      <description>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.</description>
      <content:encoded><![CDATA[<h2 id="background">Background</h2>
<p>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.</p>
<p>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.</p>
<p>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.</p>
<p>This article assumes you are already set up to build Firefox when targeting
64-bit.</p>
<h2 id="multiarch-packages-or-how-its-supposed-to-work">Multiarch Packages (Or: How It&rsquo;s Supposed to Work)</h2>
<p>Recent versions of Debian and Ubuntu support the concept of
<a href="https://wiki.debian.org/Multiarch">&ldquo;multiarch packages&rdquo;</a> which are intended to allow installing multiple
architectures together to support use cases including&hellip; cross-compiling!
Great, sounds like just the thing we need.</p>
<p>We should be able to install<sup id="a1"><a href="#f1">1</a></sup> the
<a href="http://searchfox.org/mozilla-central/rev/48ea452803907f2575d81021e8678634e8067fc2/python/mozboot/mozboot/debian.py#50-61">core Gecko development dependencies</a> with an extra <code>:i386</code> suffix to get
the 32-bit version on our 64-bit host:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>(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
</span></span><span style="display:flex;"><span>Reading package lists... Done
</span></span><span style="display:flex;"><span>Building dependency tree
</span></span><span style="display:flex;"><span>Reading state information... Done
</span></span><span style="display:flex;"><span>Some packages could not be installed. This may mean that you have
</span></span><span style="display:flex;"><span>requested an impossible situation or if you are using the unstable
</span></span><span style="display:flex;"><span>distribution that some required packages have not yet been created
</span></span><span style="display:flex;"><span>or been moved out of Incoming.
</span></span><span style="display:flex;"><span>The following information may help to resolve the situation:
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>The following packages have unmet dependencies:
</span></span><span style="display:flex;"><span> libgtk-3-dev:i386 : Depends: gir1.2-gtk-3.0:i386 (= 3.18.9-1ubuntu3.3) but it is not going to be installed
</span></span><span style="display:flex;"><span>                     Depends: libatk1.0-dev:i386 (&gt;= 2.15.1) but it is not going to be installed
</span></span><span style="display:flex;"><span>                     Depends: libatk-bridge2.0-dev:i386 but it is not going to be installed
</span></span><span style="display:flex;"><span>                     Depends: libegl1-mesa-dev:i386 but it is not going to be installed
</span></span><span style="display:flex;"><span>                     Depends: libxkbcommon-dev:i386 but it is not going to be installed
</span></span><span style="display:flex;"><span>                     Depends: libmirclient-dev:i386 (&gt;= 0.13.3) but it is not going to be installed
</span></span><span style="display:flex;"><span> 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
</span></span><span style="display:flex;"><span>                      Depends: libatk1.0-dev:i386 (&gt;= 1.29.2) but it is not going to be installed
</span></span><span style="display:flex;"><span>                      Recommends: python:i386 (&gt;= 2.4) but it is not going to be installed
</span></span><span style="display:flex;"><span> libnotify-dev:i386 : Depends: gir1.2-notify-0.7:i386 (= 0.7.6-2svn1) but it is not going to be installed
</span></span><span style="display:flex;"><span>E: Unable to correct problems, you have held broken packages.
</span></span></code></pre></div><p>Well, that doesn&rsquo;t look good.  It appears some of the Gecko libraries we need
aren&rsquo;t happy about being installed for multiple architectures.</p>
<h2 id="switch-approaches-to-chroot">Switch Approaches to <code>chroot</code></h2>
<p>Since multiarch packages don&rsquo;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.</p>
<p>One approach to multiple architectures that has been around for a while is to
create a <a href="https://en.wikipedia.org/wiki/Chroot">chroot</a> environment: effectively, a separate installation of
Linux for a different architecture.  A utility like <code>schroot</code> can then be used
to issue the <code>chroot(2)</code> system call which makes the current session believe
this sub-installation is the root filesystem.</p>
<p>Let&rsquo;s grab <code>schroot</code> so we&rsquo;ll be able to enter the chroot once it&rsquo;s set up:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>(host) $ sudo apt install schroot
</span></span></code></pre></div><p>There are several different <a href="http://manpages.ubuntu.com/manpages/xenial/man5/schroot.conf.5.html">types of chroots</a> you can use with <code>schroot</code>.
We&rsquo;ll use the <code>directory</code> type, as it&rsquo;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.</p>
<p>You can place the directory wherever, but some existing filesystems are mapped
into the chroot for convenience, so avoiding <code>/home</code> is probably a good idea.  I
went with <code>/var/chroot/linux32</code>:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>(host) $ sudo mkdir -p /var/chroot/linux32
</span></span></code></pre></div><p>We need to update <code>schroot.conf</code> to configure the new chroot:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>(host) $ sudo cat &lt;&lt; EOF &gt;&gt; /etc/schroot/schroot.conf
</span></span><span style="display:flex;"><span>[linux32]
</span></span><span style="display:flex;"><span>description=Linux32 build environment
</span></span><span style="display:flex;"><span>aliases=default
</span></span><span style="display:flex;"><span>type=directory
</span></span><span style="display:flex;"><span>directory=/var/chroot/linux32
</span></span><span style="display:flex;"><span>personality=linux32
</span></span><span style="display:flex;"><span>profile=desktop
</span></span><span style="display:flex;"><span>users=jryans
</span></span><span style="display:flex;"><span>root-users=jryans
</span></span><span style="display:flex;"><span>EOF
</span></span></code></pre></div><p>In particular, <code>personality</code> is important to set for this multi-arch use case.
(Make sure to replace the user names with your own!)</p>
<p>Firefox will want access to shared memory as well, so we&rsquo;ll need to add that to
the set of mapped filesystems in the chroot:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>(host) $ sudo cat &lt;&lt; EOF &gt;&gt; /etc/schroot/desktop/fstab
</span></span><span style="display:flex;"><span>/dev/shm       /dev/shm        none    rw,bind         0       0
</span></span><span style="display:flex;"><span>EOF
</span></span></code></pre></div><p>Now we need to <a href="https://help.ubuntu.com/community/DebootstrapChroot">install the 32-bit system</a> inside the chroot.  We can do
that with a utility called <code>debootstrap</code>:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>(host) $ sudo apt install debootstrap
</span></span><span style="display:flex;"><span>(host) $ sudo debootstrap --variant=buildd --arch=i386 --foreign xenial /var/chroot/linux32 http://archive.ubuntu.com/ubuntu
</span></span></code></pre></div><p>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 <code>--foreign</code> to skip the
unpacking step, which we will do momentarily from inside the chroot.
<code>--variant=buildd</code> will help us out a bit by including common build tools.</p>
<p>To finish installation, we have to enter the chroot.  You can enter the chroot
with <code>schroot</code> and it remains active until you <code>exit</code>.  Any snippets that say
<code>(chroot)</code> instead of <code>(host)</code> are meant to be run inside the chroot.</p>
<p>So, inside the chroot, run the second stage of <code>debootstrap</code> to actually unpack
everything:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>(chroot) $ /debootstrap/debootstrap --second-stage
</span></span></code></pre></div><p>Let&rsquo;s double-check that things are working like we expect:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>(chroot) $ arch
</span></span><span style="display:flex;"><span>i686
</span></span></code></pre></div><p>Great, we&rsquo;re getting closer!</p>
<h2 id="install-packages">Install packages</h2>
<p>Now that we have a basic 32-bit installation, let&rsquo;s install the packages we need
for development.  The <code>apt</code> source list inside the chroot is pretty bare bones,
so we&rsquo;ll want to expand it a bit to reach everything we need:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>(chroot) $ sudo cat &lt;&lt; EOF &gt; /etc/apt/sources.list
</span></span><span style="display:flex;"><span>deb http://archive.ubuntu.com/ubuntu xenial main universe
</span></span><span style="display:flex;"><span>deb http://archive.ubuntu.com/ubuntu xenial-updates main universe
</span></span><span style="display:flex;"><span>EOF
</span></span><span style="display:flex;"><span>(chroot) $ sudo apt update
</span></span></code></pre></div><p>Let&rsquo;s grab the same packages from before (without <code>:i386</code> since that&rsquo;s the
default inside the chroot):</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>(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
</span></span></code></pre></div><p>You may need to install the 32-bit version of your graphics card&rsquo;s GL library to
get reasonable graphics output when running in the 32-bit environment.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>(chroot) $ sudo apt install nvidia-384
</span></span></code></pre></div><p>We&rsquo;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:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>(host) $ xhost +
</span></span><span style="display:flex;"><span>(chroot) $ export DISPLAY=:0
</span></span></code></pre></div><p>We can verify that we have accelerated graphics:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>(chroot) $ sudo apt install mesa-utils
</span></span><span style="display:flex;"><span>(chroot) $ glxinfo | grep renderer
</span></span><span style="display:flex;"><span>OpenGL renderer string: GeForce GTX 1080/PCIe/SSE2
</span></span></code></pre></div><h2 id="building-firefox">Building Firefox</h2>
<p>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&rsquo;s cheat and expose them to the host via symlinks into the
chroot&rsquo;s file structure:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>(host) $ sudo ln -s /var/chroot/linux32/lib/i386-linux-gnu /lib/
</span></span><span style="display:flex;"><span>(host) $ sudo ln -s /var/chroot/linux32/usr/lib/i386-linux-gnu /usr/lib/
</span></span><span style="display:flex;"><span>(host) $ sudo ln -s /var/chroot/linux32/usr/include/i386-linux-gnu /usr/include/
</span></span></code></pre></div><p>We also need Rust to be able to target 32-bit from the host, so let&rsquo;s install
support for that:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>(host) $ rustup target add i686-unknown-linux-gnu
</span></span></code></pre></div><p>We&rsquo;ll need a specialized <code>.mozconfig</code> for Firefox to target 32-bit.  Something
like the following:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>(host) $ cat &lt;&lt; EOF &gt; ~/projects/gecko/.mozconfig
</span></span><span style="display:flex;"><span>export PKG_CONFIG_PATH=&#34;/var/chroot/linux32/usr/lib/i386-linux-gnu/pkgconfig:/var/chroot/linux32/usr/share/pkgconfig&#34;
</span></span><span style="display:flex;"><span>export MOZ_LINUX_32_SSE2_STARTUP_ERROR=1
</span></span><span style="display:flex;"><span>CFLAGS=&#34;$CFLAGS -msse -msse2 -mfpmath=sse&#34;
</span></span><span style="display:flex;"><span>CXXFLAGS=&#34;$CXXFLAGS -msse -msse2 -mfpmath=sse&#34;
</span></span><span style="display:flex;"><span>if test `uname -m` = &#34;x86_64&#34;; then
</span></span><span style="display:flex;"><span>  CFLAGS=&#34;$CFLAGS -m32 -march=pentium-m&#34;
</span></span><span style="display:flex;"><span>  CXXFLAGS=&#34;$CXXFLAGS -m32 -march=pentium-m&#34;
</span></span><span style="display:flex;"><span>  ac_add_options --target=i686-pc-linux
</span></span><span style="display:flex;"><span>  ac_add_options --host=i686-pc-linux
</span></span><span style="display:flex;"><span>  ac_add_options --x-libraries=/usr/lib
</span></span><span style="display:flex;"><span>fi
</span></span><span style="display:flex;"><span>EOF
</span></span></code></pre></div><p>This was <a href="http://searchfox.org/mozilla-central/rev/89e125b817c5d493babbc58ea526be970bd3748e/build/unix/mozconfig.linux32">adapted</a> from the <code>mozconfig.linux32</code> used for official 32-bit
builds.  I modified the <code>PKG_CONFIG_PATH</code> to point at more 32-bit files
installed inside the chroot, similar to the library and include changes above.</p>
<p>Now, we should be able to build successfully:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>(host) $ ./mach build
</span></span></code></pre></div><p>Then, from the chroot, you can run Firefox and other tests:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>(chroot) $ ./mach run
</span></span></code></pre></div><p><img loading="lazy" src="firefox-linux32.png" alt="Firefox running on Linux 32-bit"  />
</p>
<h2 id="footnotes">Footnotes</h2>
<p><b id="f1">1.</b> It&rsquo;s commonly suggested that people should use <code>./mach bootstrap</code> to install the Firefox build dependencies, so feel free to try that
if you wish.  I dislike scripts that install system packages, so I&rsquo;ve done it
manually here.  The bootstrap script would likely need various adjustments to
support this use case. <a href="#a1">↩</a></p>
]]></content:encoded>
    </item>
    
    <item xml:base="https://convolv.es/blog/2015/08/05/wifi-debug-fennec/">
      <title>WiFi Debugging for Firefox for Android</title>
      <link>https://convolv.es/blog/2015/08/05/wifi-debug-fennec/</link>
      <pubDate>Wed, 05 Aug 2015 15:33:00 -0500</pubDate>
      
      <guid>https://convolv.es/blog/2015/08/05/wifi-debug-fennec/</guid>
      <description>I am excited to announce that we&amp;rsquo;re now shipping WiFi debugging for Firefox for Android! It&amp;rsquo;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&amp;rsquo;re no longer tied down by a cable.</description>
      <content:encoded><![CDATA[<p>I am excited to announce that we&rsquo;re now <a href="https://bugzil.la/1180996">shipping</a> WiFi debugging for
Firefox for Android!  It&rsquo;s available in <a href="https://nightly.mozilla.org/">Firefox for Android 42</a>
with <a href="https://nightly.mozilla.org/">Firefox Nightly</a> on desktop.</p>
<p>The rest of this post will sound quite similar to the <a href="/blog/2015/03/25/wifi-debug-fxos/">previous announcement for
Firefox OS</a> support.</p>
<p>WiFi debugging allows <a href="https://developer.mozilla.org/docs/Tools/WebIDE">WebIDE</a> to connect to Firefox for Android via
your local WiFi network instead of a USB cable.</p>
<p>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&rsquo;re no longer tied down by a cable.</p>
<h2 id="security">Security</h2>
<p>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.</p>
<p>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.</p>
<h2 id="how-to-use">How to Use</h2>
<p>You&rsquo;ll need to assemble the following bits and bobs:</p>
<ul>
<li><a href="https://nightly.mozilla.org/">Firefox 42</a></li>
<li><a href="https://nightly.mozilla.org/">Firefox for Android 42</a></li>
<li><a href="https://play.google.com/store/apps/details?id=com.google.zxing.client.android">Barcode Scanner Android app by ZXing Team</a> (for QR code scanning)</li>
</ul>
<p>On your Android device:</p>
<ol>
<li>Install the <a href="https://play.google.com/store/apps/details?id=com.google.zxing.client.android">Barcode Scanner Android app by ZXing Team</a></li>
<li>Open Firefox for Android</li>
<li>Go to Developer Tools Settings on device (Settings -&gt; Developer Tools)</li>
<li>Enable Remote Debugging via Wi-Fi</li>
</ol>
<p><img loading="lazy" src="fennec-wifi-opts.png" alt="Firefox for Android WiFi Debugging Options"  />
</p>
<p>To connect from Firefox Desktop:</p>
<ol>
<li>Open WebIDE in Firefox Nightly (Tools -&gt; Web Developer -&gt; WebIDE)</li>
<li>Click &ldquo;Select Runtime&rdquo; to open the runtimes panel</li>
<li>Your Firefox for Android device should show up in the &ldquo;WiFi Devices&rdquo; section</li>
<li>A connection prompt will appear on device, choose &ldquo;Scan&rdquo; or &ldquo;Scan and Remember&rdquo;</li>
<li>Scan the QR code displayed in WebIDE</li>
</ol>
<p><img loading="lazy" src="webide-wifi-runtime.png" alt="WebIDE WiFi Runtimes"  />

<img loading="lazy" src="webide-qr-code.png" alt="WebIDE Displays the QR Code"  />
</p>
<p>After scanning the QR code, the QR display should disappear and the &ldquo;device&rdquo;
icon in WebIDE will turn blue for &ldquo;connected&rdquo;.</p>
<p>You can then access all of your remote browser tabs just as you can today over
USB.</p>
<h2 id="technical-aside">Technical Aside</h2>
<p>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.</p>
<p>By skipping ADB, we don&rsquo;t have to worry about driver confusion, especially on
Windows and Linux.</p>
<h2 id="supported-devices">Supported Devices</h2>
<p>This feature should be supported on any Firefox for Android device.  So far,
I&rsquo;ve tested it on the LG G2.</p>
<h2 id="acknowledgments">Acknowledgments</h2>
<p>Thanks to all who helped via advice and reviews while working on Android support,
including (in semi-random order):</p>
<ul>
<li>Margaret Leibovic</li>
<li>Karim Benhmida</li>
</ul>
<p>And from the larger WiFi debugging effort:</p>
<ul>
<li>Brian Warner</li>
<li>Trevor Perrin</li>
<li>David Keeler</li>
<li>Honza Bambas</li>
<li>Patrick McManus</li>
<li>Jason Duell</li>
<li>Panos Astithas</li>
<li>Jan Keromnes</li>
<li>Alexandre Poirot</li>
<li>Paul Rouget</li>
<li>Paul Theriault</li>
</ul>
<p>I am probably forgetting others as well, so I apologize if you were omitted.</p>
<h2 id="whats-next">What&rsquo;s Next</h2>
<p>If there are features you&rsquo;d like to see added, <a href="https://bugzilla.mozilla.org/enter_bug.cgi?product=Firefox&amp;component=Developer%20Tools%3A%20WebIDE">file bugs</a> or contact the
team via <a href="https://wiki.mozilla.org/DevTools/GetInvolved#Communication">various channels</a>.</p>
]]></content:encoded>
    </item>
    
    <item xml:base="https://convolv.es/blog/2015/03/25/wifi-debug-fxos/">
      <title>WiFi Debugging for Firefox OS</title>
      <link>https://convolv.es/blog/2015/03/25/wifi-debug-fxos/</link>
      <pubDate>Wed, 25 Mar 2015 08:51:00 -0500</pubDate>
      
      <guid>https://convolv.es/blog/2015/03/25/wifi-debug-fxos/</guid>
      <description>I am excited to announce that we&amp;rsquo;re now shipping WiFi debugging for Firefox OS! It&amp;rsquo;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&amp;rsquo;re no longer tied down by a cable.</description>
      <content:encoded><![CDATA[<p>I am excited to announce that we&rsquo;re now shipping WiFi debugging for Firefox OS!
It&rsquo;s available in <a href="https://developer.mozilla.org/en-US/Firefox_OS/Building">Firefox OS 3.0 / master</a> with <a href="https://nightly.mozilla.org/">Firefox Nightly</a> on desktop.</p>
<p>WiFi debugging allows <a href="https://developer.mozilla.org/docs/Tools/WebIDE">WebIDE</a> to connect to your Firefox OS device via your local
WiFi network instead of a USB cable.</p>
<p>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&rsquo;re no longer tied down by a cable.</p>
<h2 id="security">Security</h2>
<p>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.</p>
<p>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.</p>
<h2 id="how-to-use">How to Use</h2>
<p>You&rsquo;ll need to assemble the following bits and bobs:</p>
<ul>
<li><a href="https://nightly.mozilla.org/">Firefox 39</a> (2015-03-27 or later)</li>
<li>Firefox OS 3.0 (2015-03-27 or later)
<ul>
<li>Option A: <a href="https://developer.mozilla.org/en-US/Firefox_OS/Phone_guide/Flame/Updating_your_Flame#Updating_your_Flame_to_a_nightly_build">Update your Flame</a> to 3.0 / master</li>
<li>Option B: <a href="https://developer.mozilla.org/en-US/Firefox_OS/Building">Build for your device</a> from source</li>
</ul>
</li>
</ul>
<p>On Firefox OS, enable WiFi debugging:</p>
<ol>
<li>Go to Developer Settings on device (Settings -&gt; Developer)</li>
<li>Enable DevTools via Wi-Fi</li>
<li>Edit the device name if desired</li>
</ol>
<p><img loading="lazy" src="fxos-wifi-opts.png" alt="Firefox OS WiFi Debugging Options"  />
</p>
<p>To connect from Firefox Desktop:</p>
<ol>
<li>Open WebIDE in Firefox Nightly (Tools -&gt; Web Developer -&gt; WebIDE)</li>
<li>Click &ldquo;Select Runtime&rdquo; to open the runtimes panel</li>
<li>Your Firefox OS device should show up in the &ldquo;WiFi Devices&rdquo; section</li>
<li>A connection prompt will appear on device, choose &ldquo;Scan&rdquo; or &ldquo;Scan and Remember&rdquo;</li>
<li>Scan the QR code displayed in WebIDE</li>
</ol>
<p><img loading="lazy" src="webide-wifi-runtime.png" alt="WebIDE WiFi Runtimes"  />

<img loading="lazy" src="webide-qr-code.png" alt="WebIDE Displays the QR Code"  />
</p>
<p>After scanning the QR code, the QR display should disappear and the &ldquo;device&rdquo;
icon in WebIDE will turn blue for &ldquo;connected&rdquo;.</p>
<p>You can then access all of your remote apps and browser tabs just as you can
today over USB.</p>
<h2 id="technical-aside">Technical Aside</h2>
<p>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.</p>
<p>By skipping ADB, we don&rsquo;t have to worry about driver confusion, especially on
Windows and Linux.</p>
<h2 id="supported-devices">Supported Devices</h2>
<p>This feature should be supported on any Firefox OS device.  So far, I&rsquo;ve tested
it on the Flame and Nexus 4.</p>
<h2 id="known-issues">Known Issues</h2>
<p>The QR code scanner can be a bit frustrating at the moment, as real devices
appear to capture a very low resolution picture.  <a href="https://bugzil.la/1145772">Bug 1145772</a> aims
to improve this soon.  You should be able to scan with the Flame by trying a few
different orientations.  I would suggest using &ldquo;Scan and Remember&rdquo;, so that
scanning is only needed for the first connection.</p>
<p>If you find other issues while testing, please <a href="https://bugzilla.mozilla.org/enter_bug.cgi?product=Firefox&amp;component=Developer%20Tools%3A%20WebIDE">file bugs</a> or contact me
on IRC.</p>
<h2 id="acknowledgments">Acknowledgments</h2>
<p>This was quite a complex project, and many people provided advice and reviews
while working on this feature, including (in semi-random order):</p>
<ul>
<li>Brian Warner</li>
<li>Trevor Perrin</li>
<li>David Keeler</li>
<li>Honza Bambas</li>
<li>Patrick McManus</li>
<li>Jason Duell</li>
<li>Panos Astithas</li>
<li>Jan Keromnes</li>
<li>Alexandre Poirot</li>
<li>Paul Rouget</li>
<li>Paul Theriault</li>
</ul>
<p>I am probably forgetting others as well, so I apologize if you were omitted.</p>
<h2 id="whats-next">What&rsquo;s Next</h2>
<p>I&rsquo;d like to add this ability for Firefox for Android next.  Thankfully, most of
the work done here can be reused there.</p>
<p>If there are features you&rsquo;d like to see added, <a href="https://bugzilla.mozilla.org/enter_bug.cgi?product=Firefox&amp;component=Developer%20Tools%3A%20WebIDE">file bugs</a> or contact the
team via <a href="https://wiki.mozilla.org/DevTools/GetInvolved#Communication">various channels</a>.</p>
]]></content:encoded>
    </item>
    
    <item xml:base="https://convolv.es/blog/2014/10/28/debug-fennec-tabs/">
      <title>Debugging Tabs with Firefox for Android</title>
      <link>https://convolv.es/blog/2014/10/28/debug-fennec-tabs/</link>
      <pubDate>Tue, 28 Oct 2014 16:08:00 -0500</pubDate>
      
      <guid>https://convolv.es/blog/2014/10/28/debug-fennec-tabs/</guid>
      <description>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&amp;rsquo;ll need to assemble the following bits and bobs:
Firefox 36 (2014-10-25 or later) ADB Helper 0.</description>
      <content:encoded><![CDATA[<p>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.</p>
<p>As I <a href="/blog/2014/10/14/debug-fxos-tabs/">hinted</a> a few weeks ago, <a href="https://developer.mozilla.org/docs/Tools/WebIDE">WebIDE</a> would soon support connecting
to Firefox for Android via ADB Helper support, and that time is now!</p>
<h2 id="how-to-use">How to Use</h2>
<p>You&rsquo;ll need to assemble the following bits and bobs:</p>
<ul>
<li>Firefox 36 (2014-10-25 or later)</li>
<li>ADB Helper 0.7.0 or later</li>
<li>Firefox for Android 35 or later</li>
</ul>
<p>Opening WebIDE for the first time should install ADB Helper if you don&rsquo;t already
have it, but double-check it is the right version in the add-on manager.</p>
<p><img loading="lazy" src="fennec-usb-runtime.png" alt="Firefox for Android runtime appears"  />
</p>
<p>Inside WebIDE, you&rsquo;ll see an entry for Firefox for Android in the Runtime menu.</p>
<p><img loading="lazy" src="fennec-tab-list.png" alt="Firefox for Android tab list"  />
</p>
<p>Once you select the runtime, tabs from Firefox for Android will be available in
the (now poorly labelled) apps menu on the left.</p>
<p><img loading="lazy" src="fennec-tab-toolbox.png" alt="Inspecting a tab in WebIDE"  />
</p>
<p>Choosing a tab will open up the DevTools toolbox for that tab.  You can also
toggle the toolbox via the &ldquo;Pause&rdquo; icon in the top toolbar.</p>
<p>If you would like to debug Firefox for Android&rsquo;s system-level / chrome code,
instead of a specific tab, you can do that with the &ldquo;Main Process&rdquo; option.</p>
<h2 id="whats-next">What&rsquo;s Next</h2>
<p>We have even more connection UX improvements on the way, so I hope to have more
to share soon!</p>
<p>If there are features you&rsquo;d like to see added, <a href="https://bugzilla.mozilla.org/enter_bug.cgi?product=Firefox&amp;component=Developer%20Tools%3A%20WebIDE">file bugs</a> or contact the
team via <a href="https://wiki.mozilla.org/DevTools/GetInvolved#Communication">various channels</a>.</p>
]]></content:encoded>
    </item>
    
    <item xml:base="https://convolv.es/blog/2014/10/14/debug-fxos-tabs/">
      <title>DevTools for Firefox OS browser tabs</title>
      <link>https://convolv.es/blog/2014/10/14/debug-fxos-tabs/</link>
      <pubDate>Tue, 14 Oct 2014 13:29:00 -0500</pubDate>
      
      <guid>https://convolv.es/blog/2014/10/14/debug-fxos-tabs/</guid>
      <description>We&amp;rsquo;ve had various tools for inspecting apps on remote devices for some time now, but for a long time we&amp;rsquo;ve not had the same support for remote browser tabs.
To remedy this, WebIDE now supports inspecting browser tabs running on Firefox OS devices.
A few weeks back, WebIDE gained support for inspecting tabs on the remote device, but many of the likely suspects to connect to weren&amp;rsquo;t quite ready for various reasons.</description>
      <content:encoded><![CDATA[<p>We&rsquo;ve had various tools for inspecting apps on remote devices for some time now,
but for a long time we&rsquo;ve not had the same support for remote browser tabs.</p>
<p>To remedy this, <a href="https://developer.mozilla.org/docs/Tools/WebIDE">WebIDE</a> now supports inspecting browser tabs running on Firefox OS devices.</p>
<p><img loading="lazy" src="webide-tab.png" alt="Inspecting a tab in WebIDE"  />
</p>
<p>A few weeks back, WebIDE gained support for <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1009604">inspecting tabs</a> on the remote
device, but many of the likely suspects to connect to weren&rsquo;t quite ready for
various reasons.</p>
<p>We&rsquo;ve just <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=975084">landed</a> 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.</p>
<h2 id="how-to-use">How to Use</h2>
<p>After connecting to your device in WebIDE, any open browser tabs will appear at
the bottom of WebIDE&rsquo;s project list.</p>
<p><img loading="lazy" src="webide-tab-list.png" alt="Browser tab list in WebIDE"  />
</p>
<p>The toolbox should open automatically after choosing a tab.  You can also toggle
the toolbox via the &ldquo;Pause&rdquo; icon in the top toolbar.</p>
<h2 id="whats-next">What&rsquo;s Next</h2>
<p>We&rsquo;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.</p>
<p>If there are features you&rsquo;d like to see added, <a href="https://bugzilla.mozilla.org/enter_bug.cgi?product=Firefox&amp;component=Developer%20Tools%3A%20WebIDE">file bugs</a> or contact the
team via <a href="https://wiki.mozilla.org/DevTools/GetInvolved#Communication">various channels</a>.</p>
]]></content:encoded>
    </item>
    
    <item xml:base="https://convolv.es/blog/2014/08/18/webide-enabled/">
      <title>WebIDE enabled in Nightly</title>
      <link>https://convolv.es/blog/2014/08/18/webide-enabled/</link>
      <pubDate>Mon, 18 Aug 2014 10:44:00 -0500</pubDate>
      
      <guid>https://convolv.es/blog/2014/08/18/webide-enabled/</guid>
      <description>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&amp;rsquo;s UX held us back when trying support more complex workflows. With the redesign into WebIDE, we&amp;rsquo;ve already been able to add:</description>
      <content:encoded><![CDATA[<p>I am excited to announce that <a href="https://developer.mozilla.org/docs/Tools/WebIDE">WebIDE</a> 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 <a href="https://hacks.mozilla.org/2014/06/webide-lands-in-nightly/">announced</a> back in June.</p>
<p><a href="https://www.youtube.com/watch?v=n8c34wk4OnY"><img loading="lazy" src="webide-enabled-video.png" alt=""  />
</a></p>
<h2 id="features">Features</h2>
<p>While the previous App Manager tool was great, that tool&rsquo;s UX held us
back when trying support more complex workflows.  With the redesign into WebIDE,
we&rsquo;ve already been able to add:</p>
<ul>
<li>Project Editing
<ul>
<li>Great for getting started without worrying about an external editor</li>
</ul>
</li>
<li>Project Templates
<ul>
<li>Easy to focus on content from the start by using a template</li>
</ul>
</li>
<li>Improved DevTools Toolbox integration
<ul>
<li>Many UX issues arose from the non-standard way that App Manager used the
DevTools</li>
</ul>
</li>
<li><a href="https://developer.mozilla.org/docs/Tools/WebIDE/Monitor">Monitor</a>
<ul>
<li>Live memory graphs help diagnose performance issues</li>
</ul>
</li>
</ul>
<p><img loading="lazy" src="monitor.png" alt="Monitor"  />
</p>
<h2 id="transition">Transition</h2>
<p>All projects you may have created previously in the App Manager are also
available in WebIDE.</p>
<p>While the App Manager is now hidden, it&rsquo;s accessible for now at
<code>about:app-manager</code>.  We do intend to remove it entirely in the future, so
it&rsquo;s best to start using WebIDE today.  If you find any issues, please <a href="https://bugzilla.mozilla.org/enter_bug.cgi?product=Firefox&amp;component=Developer%20Tools%3A%20WebIDE">file bugs</a>!</p>
<h2 id="whats-next">What&rsquo;s Next</h2>
<p>Looking ahead, we have many more exciting things planned for WebIDE, such as:</p>
<ul>
<li>Command line integration</li>
<li>Improved support for app frameworks like Cordova</li>
<li>Validation that matches the Firefox Marketplace</li>
</ul>
<p>If there are features you&rsquo;d like to see added, <a href="https://bugzilla.mozilla.org/enter_bug.cgi?product=Firefox&amp;component=Developer%20Tools%3A%20WebIDE">file bugs</a> or contact the
team via <a href="https://wiki.mozilla.org/DevTools/GetInvolved#Communication">various channels</a>.</p>
]]></content:encoded>
    </item>
    
    <item xml:base="https://convolv.es/blog/2013/08/25/mozilla/">
      <title>Mozilla</title>
      <link>https://convolv.es/blog/2013/08/25/mozilla/</link>
      <pubDate>Sun, 25 Aug 2013 01:27:00 -0500</pubDate>
      
      <guid>https://convolv.es/blog/2013/08/25/mozilla/</guid>
      <description>In my last post (back in February&amp;hellip;), 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&amp;rsquo;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.</description>
      <content:encoded><![CDATA[<p>In my <a href="/blog/2013/02/17/into-the-open/">last post</a> (back in February&hellip;), 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&rsquo;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&rsquo;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.</p>
<p>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!</p>
<p>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.</p>
<p>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&rsquo;t even know they need.</p>
<p>It&rsquo;s going to be a blast! Hopefully I&rsquo;ll have to some fun things to share.</p>
]]></content:encoded>
    </item>
    
    <item xml:base="https://convolv.es/blog/2013/02/17/into-the-open/">
      <title>Into the Open</title>
      <link>https://convolv.es/blog/2013/02/17/into-the-open/</link>
      <pubDate>Sun, 17 Feb 2013 22:52:00 -0600</pubDate>
      
      <guid>https://convolv.es/blog/2013/02/17/into-the-open/</guid>
      <description>I&amp;rsquo;m excited to start to focusing what time I do have on the side towards open source projects. I&amp;rsquo;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&amp;rsquo;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.</description>
      <content:encoded><![CDATA[<p>I&rsquo;m excited to start to focusing what time I do have on the side towards open
source projects.  I&rsquo;m always on the lookout for good projects to help out with,
but these days I always seem to come back to web browsers.</p>
<p>In particular, I really enjoy working on tools that improve the lives of other
every day.  In that vein, I&rsquo;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.</p>
<p>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.</p>
<p>However, now that Opera has decided to switch to Chromium for future versions of
their browser, I&rsquo;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&rsquo;s impressive developer
tools, so I&rsquo;d like to help improve Firefox tools to bring them up to the level
we&rsquo;ve now come to expect and beyond.</p>
<p>Likely I&rsquo;ll dabble in both Chromium and Firefox, but no matter what it should be
an exciting time ahead!</p>
]]></content:encoded>
    </item>
    
    <item xml:base="https://convolv.es/blog/2012/10/06/materials/">
      <title>Materials, Maps, and Surfacing</title>
      <link>https://convolv.es/blog/2012/10/06/materials/</link>
      <pubDate>Sat, 06 Oct 2012 15:13:00 -0500</pubDate>
      
      <guid>https://convolv.es/blog/2012/10/06/materials/</guid>
      <description>Overview For this assignment, we learned how to apply materials to the objects we&amp;rsquo;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.</description>
      <content:encoded><![CDATA[<h3 id="overview">Overview</h3>
<p>For this <a href="http://viscom3d.blogspot.com/2012/09/materials-maps-and-surfacing.html">assignment</a>, we learned how to apply materials to the objects
we&rsquo;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.</p>
<p>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.</p>
<h3 id="environment">Environment</h3>
<p>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&rsquo;s a grassy appearance
applied, instead of just the flat green.</p>
<h3 id="robot">Robot</h3>
<p>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.</p>
<p>The eyes and mouth have a bit of an ethereal / floating feel to them thanks to
the transparency.</p>
<p>It was fun to experiment with the various parameters and material types that can
give a metallic appearance.</p>
]]></content:encoded>
    </item>
    
    <item xml:base="https://convolv.es/blog/2012/09/29/splines/">
      <title>Splines, Loft, and Lathe</title>
      <link>https://convolv.es/blog/2012/09/29/splines/</link>
      <pubDate>Sat, 29 Sep 2012 08:17:00 -0500</pubDate>
      
      <guid>https://convolv.es/blog/2012/09/29/splines/</guid>
      <description>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.</description>
      <content:encoded><![CDATA[<h3 id="overview">Overview</h3>
<p>For this <a href="http://viscom3d.blogspot.com/2012/09/spline-modeling-and-compound-objects.html">assignment</a>, 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.</p>
<h3 id="shapes-and-splines">Shapes and Splines</h3>
<p>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.</p>
<h3 id="lathe-and-loft">Lathe and Loft</h3>
<p>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.</p>
<p>I used this technique to create a pot, an inflatable pool, and a spyglass.</p>
<p>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.</p>
<p>I made several tracks and other shapes using this process:</p>
]]></content:encoded>
    </item>
    
    <item xml:base="https://convolv.es/blog/2012/09/22/basic-game-with-unity/">
      <title>Basic Game with Unity</title>
      <link>https://convolv.es/blog/2012/09/22/basic-game-with-unity/</link>
      <pubDate>Sat, 22 Sep 2012 04:42:00 -0500</pubDate>
      
      <guid>https://convolv.es/blog/2012/09/22/basic-game-with-unity/</guid>
      <description>Overview For this week&amp;rsquo;s assignment, we jumped out of the normal curriculum and went straight to using a game engine with our models from last time. We added a few common elements, like terrain and fog.
Unity Unity is a lot of fun to work with! It&amp;rsquo;s quite easy to assemble something pretty cool, and yet it is also has a lot of depth to allow you to refine details. I can definitely see myself working with this down the road, especially given the wide multi-platform support.</description>
      <content:encoded><![CDATA[<h3 id="overview">Overview</h3>
<p>For this week&rsquo;s <a href="http://viscom3d.blogspot.com/2012/09/unity-101.html">assignment</a>, we jumped out of the normal curriculum and
went straight to using a game engine with our models from last time.  We added a
few common elements, like terrain and fog.</p>
<h3 id="unity">Unity</h3>
<p>Unity is a lot of fun to work with! It&rsquo;s quite easy to assemble something pretty
cool, and yet it is also has a lot of depth to allow you to refine details. I
can definitely see myself working with this down the road, especially given the
wide multi-platform support.</p>
<h3 id="game-level">Game Level</h3>
<p>For the level itself, I modified the environment to remove the static water I
made before and surround the island with mountainous terrain.  Then I added the
animated water to get back to the original environment idea.</p>
<p>From there, I added some basic lighting and fog to match the skybox I chose.  It
was actually a bit tricky to map a collider to the island huts.  For now I used
spheres, but perhaps I&rsquo;ll need to flatten those into a single mesh for Unity to
represent them accurately.</p>
<p>There&rsquo;s definitely room for improvement along many aspects, but it&rsquo;s really
exciting to see something playable come together so quickly.</p>
]]></content:encoded>
    </item>
    
    <item xml:base="https://convolv.es/blog/2012/09/15/3d-modeling-robot-in-the-ruins/">
      <title>3D Modeling: Robot in the Ruins</title>
      <link>https://convolv.es/blog/2012/09/15/3d-modeling-robot-in-the-ruins/</link>
      <pubDate>Sat, 15 Sep 2012 05:43:00 -0500</pubDate>
      
      <guid>https://convolv.es/blog/2012/09/15/3d-modeling-robot-in-the-ruins/</guid>
      <description>Overview For our first assignment, we had to build a robot and an environment for the it to inhabit.
Robot The robot had to use exactly 1000 polygons. I chose to create a kind of transport robot with a cute appearance. I used an elongated egg shape, and gave it two propellers to maneuver. The robot is shown at an angle to suggest movement. The propellers were fun to construct, especially with the primitives, since you have to think of clever ways to build what want from just a few shapes.</description>
      <content:encoded><![CDATA[<h3 id="overview">Overview</h3>
<p>For our <a href="http://viscom3d.blogspot.com/2012/01/robot-in-ruins.html">first assignment</a>, we had to build a robot and an environment for the it to inhabit.</p>
<h3 id="robot">Robot</h3>
<p>The robot had to use exactly 1000 polygons. I chose to create a kind of
transport robot with a cute appearance. I used an elongated egg shape, and gave
it two propellers to maneuver. The robot is shown at an angle to suggest
movement.  The propellers were fun to construct, especially with the primitives,
since you have to think of clever ways to build what want from just a few
shapes. With two shapes and a few filters, I arrived at a convincing version of
propeller blades.</p>
<h3 id="environment">Environment</h3>
<p>For the environment, we had a budget of 10,000 polygons. I thought it would be
fun to create a water / island environment. However, even a poor simulation of
water quickly eats up a lot of polygons!</p>
<p>My thoughts here were that several of the robots might be used to transport
various items between the islands as needed.</p>
]]></content:encoded>
    </item>
    
    <item xml:base="https://convolv.es/blog/2012/09/07/3d-modeling-and-rendering-1/">
      <title>3D Modeling and Rendering 1</title>
      <link>https://convolv.es/blog/2012/09/07/3d-modeling-and-rendering-1/</link>
      <pubDate>Fri, 07 Sep 2012 23:20:00 -0500</pubDate>
      
      <guid>https://convolv.es/blog/2012/09/07/3d-modeling-and-rendering-1/</guid>
      <description>I&amp;rsquo;ve started taking classes at ACC to learn some visual design skills and generally extend my knowledge of how games and other media are built.
The first one is this 3D modeling class, and I&amp;rsquo;ll be maintaining a portfolio of my work as this class goes on. I&amp;rsquo;m excited to see what I can come up with! Undoubtedly my work won&amp;rsquo;t win too many awards, but hopefully I can pick up the principles and develop them further over time.</description>
      <content:encoded><![CDATA[<p>I&rsquo;ve started taking classes at ACC to learn some visual design skills and
generally extend my knowledge of how games and other media are built.</p>
<p>The first one is this 3D modeling class, and I&rsquo;ll be maintaining a portfolio of
my work as this class goes on. I&rsquo;m excited to see what I can come up with!
Undoubtedly my work won&rsquo;t win too many awards, but hopefully I can pick up the
principles and develop them further over time.</p>
<p>I think this will also give me a better understanding of the thought process that
design and creative teams go through at the various places I&rsquo;ve worked now and in
the past.</p>
<p>Anyway, should be fun! :D</p>
]]></content:encoded>
    </item>
    
    <item xml:base="https://convolv.es/blog/2012/05/07/exciting-new-blog-thing/">
      <title>Exciting new blog thing</title>
      <link>https://convolv.es/blog/2012/05/07/exciting-new-blog-thing/</link>
      <pubDate>Mon, 07 May 2012 23:28:00 -0500</pubDate>
      
      <guid>https://convolv.es/blog/2012/05/07/exciting-new-blog-thing/</guid>
      <description>&amp;hellip;to replace what exactly? My LiveJournal from college&amp;hellip;? I&amp;rsquo;ve never been great at maintaining any kind of journal / blog / whatever, but Octopress just looks like so much fun, so I had to give it a shot. Tonight I finally ripped the default theme up a bit to create a more minimalist look, which I think turned out quite well.
I&amp;rsquo;m hoping to start talking about all the crazy tech projects I&amp;rsquo;ve got brewing in my mind that I&amp;rsquo;ll one day sit down and make progress on, along with a few bits of life, work, and everything else mixed in.</description>
      <content:encoded><![CDATA[<p>&hellip;to replace what exactly? My LiveJournal from college&hellip;? I&rsquo;ve never been great at maintaining any kind of journal / blog / whatever, but <a href="http://octopress.org">Octopress</a> just looks like so much fun, so I had to give it a shot. Tonight I finally ripped the default theme up a bit to create a more minimalist look, which I think turned out quite well.</p>
<p>I&rsquo;m hoping to start talking about all the crazy tech projects I&rsquo;ve got brewing in my mind that I&rsquo;ll one day sit down and make progress on, along with a few bits of life, work, and everything else mixed in.</p>
<p>Even writing this tiny thing is more than I&rsquo;ve done in ages. Any guesses how long until the next one?</p>
]]></content:encoded>
    </item>
    
  </channel>
</rss>
