<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>jin.crypt.sg | Jin's blog</title>
    <link href="http://jin.crypt.sg/atom.xml" rel="self" />
    <link href="http://jin.crypt.sg" />
    <id>http://jin.crypt.sg/atom.xml</id>
    <author>
        <name>Jingwen Chen</name>
        <email>jin@crypt.sg</email>
    </author>
    <updated>2018-08-11T00:01:00Z</updated>
    <entry>
    <title>Generating pretty-printed sources with Bazel</title>
    <link href="http://jin.crypt.sg/articles/bazel-pretty-print.html" />
    <id>http://jin.crypt.sg/articles/bazel-pretty-print.html</id>
    <published>2018-08-11T00:01:00Z</published>
    <updated>2018-08-11T00:01:00Z</updated>
    <summary type="html"><![CDATA[<div class="info">
    Posted on August 11, 2018
    
</div>

<h1 id="generating-pretty-printed-sources-with-bazel">Generating pretty-printed sources with Bazel</h1>
<p><em>Originally written as an answer for <a href="https://stackoverflow.com/questions/44338445/how-to-integrate-pretty-printing-as-part-of-build-in-bazel/51332969#51332969">StackOverflow</a>.</em></p>
<h2 id="introduction">Introduction</h2>
<p>Pretty-printers are excellent for enforcing style standards across the codebase. In this article, we’ll show how to use Bazel to generate pretty-printed sources in your build.</p>
<p>This method uses involves writing a new Bazel <a href="https://docs.bazel.build/versions/master/skylark/macros.html">macro</a> and <a href="https://docs.bazel.build/versions/master/skylark/rules.html">rule</a>. There is another method via <a href="https://docs.bazel.build/versions/master/skylark/aspects.html">aspects</a>, but we are not covering that in this article.</p>
<p>For hermeticity reasons, Bazel does <strong>not</strong> modify your source files in place. If you want formatting-on-save (e.g. with <a href="https://golang.org/cmd/gofmt/"><code>gofmt</code></a> or <a href="https://prettier.io/"><code>prettier</code></a>), please use editor plugins instead.</p>
<p>As an example, let’s use the C++ tutorial from the <a href="https://github.com/bazelbuild/examples">Bazel C++ examples</a> and <code>clang-format</code> for pretty-printing.</p>
<h2 id="setup">Setup</h2>
<p>Let’s first mess up the formatting of <code>main/hello-world.cc</code>:</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="pp">#include </span><span class="im">&lt;ctime&gt;</span>



<span class="pp">#include </span><span class="im">&lt;string&gt;</span>

<span class="pp">#include </span><span class="im">&lt;iostream&gt;</span>

<span class="bu">std::</span>string get_greet(<span class="at">const</span> <span class="bu">std::</span>string&amp; who) { <span class="cf">return</span> <span class="st">&quot;Hello &quot;</span> + who; }

<span class="dt">void</span> print_localtime() {
  <span class="bu">std::</span>time_t result =
    <span class="bu">std::</span>time(<span class="kw">nullptr</span>);
  <span class="bu">std::</span>cout &lt;&lt; <span class="bu">std::</span>asctime(<span class="bu">std::</span>localtime(&amp;result));
}

<span class="dt">int</span> main(<span class="dt">int</span> argc, <span class="dt">char</span>** argv) {
  <span class="bu">std::</span>string who = <span class="st">&quot;world&quot;</span>;
  <span class="cf">if</span> (argc &gt; <span class="dv">1</span>) {who = argv[<span class="dv">1</span>];}
  <span class="bu">std::</span>cout &lt;&lt; get_greet(who) &lt;&lt; <span class="bu">std::</span>endl;
  print_localtime();


  <span class="cf">return</span> <span class="dv">0</span>;
}</code></pre></div>
<p>And this is the BUILD file to build <code>main/hello-world.cc</code>:</p>
<div class="sourceCode"><pre class="sourceCode python"><code class="sourceCode python"><span class="co"># In main/BUILD</span>
cc_binary(
    name <span class="op">=</span> <span class="st">&quot;hello-world&quot;</span>,
    srcs <span class="op">=</span> [<span class="st">&quot;hello-world.cc&quot;</span>],
)</code></pre></div>
<h2 id="macro-clang_formatted_cc_binary">Macro: <code>clang_formatted_cc_binary</code></h2>
<p>Since <code>cc_binary</code> doesn’t know anything about <code>clang-format</code> or pretty-printing in general, let’s create a macro called <code>clang_formatted_cc_binary</code> and replace <code>cc_binary</code> with it. The BUILD file now looks like this:</p>
<div class="sourceCode"><pre class="sourceCode python"><code class="sourceCode python"><span class="co"># In main/BUILD</span>
load(<span class="st">&quot;//:clang_format.bzl&quot;</span>, <span class="st">&quot;clang_formatted_cc_binary&quot;</span>)

clang_formatted_cc_binary(
    name <span class="op">=</span> <span class="st">&quot;hello-world&quot;</span>,
    srcs <span class="op">=</span> [<span class="st">&quot;hello-world.cc&quot;</span>],
)</code></pre></div>
<p>Next, create a file called <code>clang_format.bzl</code> with a macro named <code>clang_formatted_cc_binary</code>. The macro is currently just a wrapper around <code>native.cc_binary</code>:</p>
<div class="sourceCode"><pre class="sourceCode python"><code class="sourceCode python"><span class="co"># In clang_format.bzl</span>
<span class="kw">def</span> clang_formatted_cc_binary(<span class="op">**</span>kwargs):
    native.cc_binary(<span class="op">**</span>kwargs)</code></pre></div>
<p>At this point, you can build the <code>cc_binary</code> target, but it’s not running <code>clang-format</code> yet. Let’s add an intermediary rule to do that in <code>clang_formatted_cc_binary</code> which we’ll call <code>clang_format_srcs</code>:</p>
<div class="sourceCode"><pre class="sourceCode python"><code class="sourceCode python"><span class="co"># In clang_format.bzl</span>
<span class="kw">def</span> clang_formatted_cc_binary(name, srcs, <span class="op">**</span>kwargs):
    <span class="co"># Using a filegroup for code cleaniness</span>
    native.filegroup(
        name <span class="op">=</span> name <span class="op">+</span> <span class="st">&quot;_unformatted_srcs&quot;</span>,
        srcs <span class="op">=</span> srcs,
    )

    clang_format_srcs(
        name <span class="op">=</span> name <span class="op">+</span> <span class="st">&quot;_formatted_srcs&quot;</span>,
        srcs <span class="op">=</span> [name <span class="op">+</span> <span class="st">&quot;_unformatted_srcs&quot;</span>],
    )

    native.cc_binary(
        name <span class="op">=</span> name,
        srcs <span class="op">=</span> [name <span class="op">+</span> <span class="st">&quot;_formatted_srcs&quot;</span>],
        <span class="op">**</span>kwargs
    )</code></pre></div>
<p>Note that we are compiling the <code>cc_binary</code>’s the formatted sources, but retained the original <code>name</code> attribute to allow for in-place replacements of <code>cc_binary</code> -&gt; <code>clang_formatted_cc_binary</code> within BUILD files.</p>
<h2 id="rule-clang_format_srcs">Rule: <code>clang_format_srcs</code></h2>
<p>Finally, we’ll write the implementation of the <code>clang_format_srcs</code> rule, in the same <code>clang_format.bzl</code> file:</p>
<div class="sourceCode"><pre class="sourceCode python"><code class="sourceCode python"><span class="co"># In clang_format.bzl</span>
<span class="kw">def</span> _clang_format_srcs_impl(ctx):
    formatted_files <span class="op">=</span> []

    <span class="cf">for</span> unformatted_file <span class="kw">in</span> ctx.files.srcs:
        formatted_file <span class="op">=</span> ctx.actions.declare_file(<span class="st">&quot;formatted_&quot;</span> <span class="op">+</span> unformatted_file.basename)
        formatted_files <span class="op">+=</span> [formatted_file]
        ctx.actions.run_shell(
            inputs <span class="op">=</span> [unformatted_file],
            outputs <span class="op">=</span> [formatted_file],
            progress_message <span class="op">=</span> <span class="st">&quot;Running clang-format on </span><span class="sc">%s</span><span class="st">&quot;</span> <span class="op">%</span> unformatted_file.short_path,
            command <span class="op">=</span> <span class="st">&quot;clang-format </span><span class="sc">%s</span><span class="st"> &gt; </span><span class="sc">%s</span><span class="st">&quot;</span> <span class="op">%</span> (unformatted_file.path, formatted_file.path),
        )

    <span class="cf">return</span> struct(files <span class="op">=</span> depset(formatted_files))

clang_format_srcs <span class="op">=</span> rule(
    attrs <span class="op">=</span> {
        <span class="st">&quot;srcs&quot;</span>: attr.label_list(allow_files <span class="op">=</span> <span class="va">True</span>),
    },
    implementation <span class="op">=</span> _clang_format_srcs_impl,
)</code></pre></div>
<p>Here’s what this <code>clang_format_srcs</code> rule is doing:</p>
<ol style="list-style-type: decimal">
<li>Go through every source file in the target’s <code>srcs</code> attribute</li>
<li>For each source file, declare a output source file with the <code>formatted_</code> prefix</li>
<li>Run <code>clang-format</code> on the unformatted file to produce the formatted output.</li>
</ol>
<h2 id="results">Results</h2>
<p>Now, by executing <code>bazel build //main:hello-world</code>, Bazel runs the actions in <code>clang_format_srcs</code> before running the <code>cc_binary</code> compilation actions on the formatted files. We can prove this by running <code>bazel build</code> with the <code>--subcommands</code> flag:</p>
<pre><code>$ bazel build //main:hello-world --subcommands
..
SUBCOMMAND: # //main:hello-world_formatted_srcs [action &#39;Running clang-format on main/hello-world.cc&#39;]
.. 
SUBCOMMAND: # //main:hello-world [action &#39;Compiling main/formatted_hello-world.cc&#39;]
.. 
SUBCOMMAND: # //main:hello-world [action &#39;Linking main/hello-world&#39;]
..</code></pre>
<p>Looking at the contents of <code>formatted_hello-world.cc</code>, looks like <code>clang-format</code> did its job:</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="pp">#include </span><span class="im">&lt;ctime&gt;</span>
<span class="pp">#include </span><span class="im">&lt;string&gt;</span>

<span class="pp">#include </span><span class="im">&lt;iostream&gt;</span>

<span class="bu">std::</span>string get_greet(<span class="at">const</span> <span class="bu">std::</span>string&amp; who) { <span class="cf">return</span> <span class="st">&quot;Hello &quot;</span> + who; }

<span class="dt">void</span> print_localtime() {
  <span class="bu">std::</span>time_t result = <span class="bu">std::</span>time(<span class="kw">nullptr</span>);
  <span class="bu">std::</span>cout &lt;&lt; <span class="bu">std::</span>asctime(<span class="bu">std::</span>localtime(&amp;result));
}

<span class="dt">int</span> main(<span class="dt">int</span> argc, <span class="dt">char</span>** argv) {
  <span class="bu">std::</span>string who = <span class="st">&quot;world&quot;</span>;
  <span class="cf">if</span> (argc &gt; <span class="dv">1</span>) {
    who = argv[<span class="dv">1</span>];
  }
  <span class="bu">std::</span>cout &lt;&lt; get_greet(who) &lt;&lt; <span class="bu">std::</span>endl;
  print_localtime();
  <span class="cf">return</span> <span class="dv">0</span>;
}</code></pre></div>
<p>If all you want are the formatted sources without compiling them, you can run build the target with the <code>_formatted_srcs</code> suffix from <code>clang_format_srcs</code> directly:</p>
<pre><code>$ bazel build //main:hello-world_formatted_srcs
INFO: Analysed target //main:hello-world_formatted_srcs (0 packages loaded).
INFO: Found 1 target...
Target //main:hello-world_formatted_srcs up-to-date:
  bazel-bin/main/formatted_hello-world.cc
INFO: Elapsed time: 0.247s, Critical Path: 0.00s
INFO: 0 processes.
INFO: Build completed successfully, 1 total action</code></pre>
]]></summary>
</entry>
<entry>
    <title>Questions to Ask Before Writing A Bazel Rule</title>
    <link href="http://jin.crypt.sg/articles/bazel-rules-questions.html" />
    <id>http://jin.crypt.sg/articles/bazel-rules-questions.html</id>
    <published>2018-07-01T00:01:00Z</published>
    <updated>2018-07-01T00:01:00Z</updated>
    <summary type="html"><![CDATA[<div class="info">
    Posted on July  1, 2018
    
</div>

<h1 id="questions-to-ask-before-writing-a-bazel-rule">Questions to Ask Before Writing A Bazel Rule</h1>
<ol start="0" style="list-style-type: decimal">
<li><p>Do you need a <a href="https://docs.bazel.build/versions/master/skylark/rules.html">rule</a>? Can you write a <a href="https://docs.bazel.build/versions/master/skylark/macros.html">macro</a> to compose and <a href="https://docs.bazel.build/versions/master/skylark/cookbook.html#macro-multiple-rules">reuse existing rules</a>? Or an <a href="https://docs.bazel.build/versions/master/skylark/aspects.html">aspect</a> to traverse the existing build graph and <a href="https://stackoverflow.com/questions/50955999/how-to-query-list-of-data-files-used-by-a-bazel-test/50957314#50957314">execute additional actions</a>?</p></li>
<li><p>What does your rule do? Does it <a href="https://github.com/jin/awesome-bazel#rules">already exist</a>?</p></li>
<li><p>What files, if any, does it take as inputs?</p></li>
<li><p>What tool does it use? A compiler? A shell script?</p></li>
<li><p>Is the tool deterministic? Does every invocation of the tool with the same inputs generate the same outputs?</p></li>
<li><p>How is the tool provided to the rule? A binary installed in <code>/usr/bin</code>? A <a href="https://docs.bazel.build/versions/master/skylark/repository_rules.html">repository rule</a>? <a href="https://docs.bazel.build/versions/master/toolchains.html">Toolchains</a>?</p></li>
<li><p>What output files does it generate?</p></li>
<li><p>Does the rule depend on the outputs of other rules using <a href="https://docs.bazel.build/versions/master/skylark/rules.html#providers">providers</a>?</p></li>
<li><p>Does the rule provide inputs to other rules using <a href="https://docs.bazel.build/versions/master/skylark/rules.html#providers">providers</a>?</p></li>
<li><p>What actions do you need to <a href="https://docs.bazel.build/versions/master/skylark/lib/actions.html#run">construct</a> in order to generate the output files from the input files using the tool?</p></li>
</ol>
]]></summary>
</entry>
<entry>
    <title>Grok Your Bazel Build: The Action Graph</title>
    <link href="http://jin.crypt.sg/articles/bazel-action-graph.html" />
    <id>http://jin.crypt.sg/articles/bazel-action-graph.html</id>
    <published>2018-03-27T00:01:00Z</published>
    <updated>2018-03-27T00:01:00Z</updated>
    <summary type="html"><![CDATA[<div class="info">
    Posted on March 27, 2018
    
</div>

<h1 id="grok-your-bazel-build-the-action-graph">Grok Your Bazel Build: The Action Graph</h1>
<p><a href="https://bazel.build">Bazel</a> has powerful tools to inspect and monitor your build processes. <a href="https://source.bazel.build/bazel/+/1d8ad1a1394926dcc8a2edd43ea554656e907c5a">A recent addition is the <strong>Action Graph</strong>.</a></p>
<p>The action graph is different from the <strong>target dependency graph</strong>, which is generated from Bazel’s <strong>loading</strong> phase. You might know the target graph from <code>bazel query</code>:</p>
<pre><code>→ bazel query &#39;deps(//my:target)’  --output=graph &gt; target_graph.in
→ dot -Tpng &lt; target_graph.in &gt; target_graph.png
→ open target_graph.png</code></pre>
<p>If you’re looking for the target graph, check out this Bazel blog post on <a href="https://blog.bazel.build/2015/06/17/visualize-your-build.html">visualizing your build</a>.</p>
<p>The action graph contains a different set of information: file-level dependencies, full command lines, and other information Bazel needs to <strong>execute</strong> the build. If you are familiar with Bazel’s <a href="https://docs.bazel.build/versions/master/skylark/concepts.html#evaluation-model">build phases</a>, the action graph is the output of the <strong>loading and analysis</strong> phase and used during the <strong>execution</strong> phase.</p>
<p>However, Bazel does not necessarily execute every action in the graph. It only executes if it has to, that is, the action graph is the super set of what is actually executed.</p>
<p>The action graph is generated by:</p>
<ul>
<li>validating the target graph</li>
<li>analyzing the target graph</li>
<li>creating artifact representations</li>
<li>resolving artifacts’ filepaths to the relative paths in the execution root</li>
<li>applying any required configuration, like platform-specific compiler flags.</li>
</ul>
<p>You can obtain it using <code>bazel dump</code> with these flags:</p>
<ul>
<li><p><span style="white-space: nowrap;"><code>--action_graph=path/to/output</code></span>: Specifies the location of the output file. This is relative to the <code>WORKSPACE</code> root. You can also provide an absolute path.</p></li>
<li><p><span style="white-space: nowrap;"><code>--action_graph:targets=//my:target</code></span>: Specifies the target(s) you’re interested in.</p></li>
<li><p><span style="white-space: nowrap;"><code>--action_graph:include_cmdline=true</code></span>: Specifies whether to include the full generated command lines.</p></li>
</ul>
<h2 id="dumping-the-graph">Dumping the graph</h2>
<p>Let’s walk though an example of dumping the action graph of an Android application build. We will use the Android example packaged in the Bazel source tree. Note that this requires the Android SDK and NDK:</p>
<div class="sourceCode"><pre class="sourceCode python"><code class="sourceCode python">→ git clone https:<span class="op">//</span>github.com<span class="op">/</span>bazelbuild<span class="op">/</span>bazel bazel_graph <span class="op">&amp;&amp;</span> cd bazel_graph
<span class="co"># Uncomment android_{sdk, ndk}_repository lines in WORKSPACE</span>
→ grep “android_” WORKSPACE
android_sdk_repository(name <span class="op">=</span> <span class="st">&quot;androidsdk&quot;</span>)
android_ndk_repository(name <span class="op">=</span> <span class="st">&quot;androidndk&quot;</span>)</code></pre></div>
<p>Add <code>--experimental_strict_action_env</code> to the project <code>.bazelrc</code> to prevent <code>$PATH</code> pollution.</p>
<div class="sourceCode"><pre class="sourceCode python"><code class="sourceCode python">→ cat .bazelrc
build <span class="op">--</span>experimental_strict_action_env</code></pre></div>
<p>The <code>android_binary</code> target is <code>//examples/android/java/bazel:hello_world</code>. It’s defined in <code>examples/android/java/bazel/BUILD</code>:</p>
<div class="sourceCode"><pre class="sourceCode python"><code class="sourceCode python">android_binary(
    name <span class="op">=</span> <span class="st">&quot;hello_world&quot;</span>,
    srcs <span class="op">=</span> glob([
        <span class="st">&quot;MainActivity.java&quot;</span>,
        <span class="st">&quot;Jni.java&quot;</span>,
    ]),
    manifest <span class="op">=</span> <span class="st">&quot;AndroidManifest.xml&quot;</span>,
    resource_files <span class="op">=</span> glob([<span class="st">&quot;res/**&quot;</span>]),
    deps <span class="op">=</span> [
        <span class="st">&quot;:jni&quot;</span>,
        <span class="st">&quot;:lib&quot;</span>,
        <span class="st">&quot;@androidsdk//com.android.support:appcompat-v7-25.0.0&quot;</span>,
    ],
)</code></pre></div>
<p>Let’s start by running the <strong>loading and analysis</strong> phase, and skipping the <strong>execution</strong> phase with the <code>--nobuild</code> flag.</p>
<pre><code>→ bazel build --nobuild //examples/android/java/bazel:hello_world
INFO: Analysed target //examples/android/java/bazel:hello_world (31 packages loaded).
INFO: Found 1 target...
INFO: Elapsed time: 9.818s
INFO: Build completed successfully, 0 total actions</code></pre>
<p>Note <code>0 total actions</code>. This doesn’t mean that there are no generated actions, but that there are no <strong>executed</strong> actions.</p>
<p>Let’s dump the graph from the Bazel server:</p>
<pre><code>→ bazel dump --action_graph=action_graph.bin \
    --action_graph:targets=//examples/android/java/bazel:hello_world \ 
    --action_graph:include_cmdline=true
Warning: this information is intended for consumption by developers
only, and may change at any time.  Script against it at your own risk!

Dumping action graph to &#39;action_graph.bin&#39;</code></pre>
<p>We specify</p>
<pre><code>--action_graph:targets=//examples/android/java/bazel:hello_world</code></pre>
<p>because the default value of the flag is <code>...</code>, which will dump <em>every</em> analyzed target, recursively.</p>
<p>Check that the output is not empty:</p>
<pre><code>→ ls -al action_graph.bin
-rw-r--r--  1 jin  staff  101765 Mar 24 23:02 action_graph.bin</code></pre>
<p>If it is empty, it means that Bazel hasn’t analyzed the target. Make sure that <span style="white-space: nowrap;"><code>build --nobuild</code></span> and <span style="white-space: nowrap;"><code>dump --action_graph:targets</code></span> are referencing the same target.</p>
<h2 id="reading-the-graph">Reading the graph</h2>
<p><code>action_graph.bin</code> is a raw protobuf message. <a href="https://source.bazel.build/bazel/+/master:src/main/protobuf/analysis.proto?q=analysis.proto"><code>analysis.proto</code></a> is the protobuf that defines the types of the message. Let’s use the protobuf compiler, <code>protoc</code>, to decode it:</p>
<pre><code>→ protoc --decode=analysis.ActionGraphContainer \ 
    src/main/protobuf/analysis.proto \
    &lt; action_graph.bin &gt; action_graph.txt</code></pre>
<p>For reference, I’ve uploaded my <code>action_graph.txt</code> <a href="https://gist.github.com/jin/57150191419a57fc3f8aa4fe596275f0">here</a>. It’s in human readable plain text, so that’s great!</p>
<h2 id="analyzing-the-graph">Analyzing the graph</h2>
<p>Now that it is possible to read the graph, we can analyze some of the useful bits: the file contains a <em>ton</em> of information!</p>
<p>The top level message type is <code>ActionGraphContainer</code>. Let’s investigate each of these message types one by one.</p>
<div class="sourceCode"><pre class="sourceCode ruby"><code class="sourceCode ruby">message <span class="dt">ActionGraphContainer</span> {
  repeated <span class="dt">Artifact</span> artifacts = <span class="dv">1</span>;
  repeated <span class="dt">Action</span> actions = <span class="dv">2</span>;
  repeated <span class="dt">Target</span> targets = <span class="dv">3</span>;
  repeated <span class="dt">DepSetOfFiles</span> dep_set_of_files = <span class="dv">4</span>;
  repeated <span class="dt">Configuration</span> configuration = <span class="dv">5</span>;
  repeated <span class="dt">AspectDescriptor</span> aspect_descriptors = <span class="dv">6</span>;
  repeated <span class="dt">RuleClass</span> rule_classes = <span class="dv">7</span>;
}</code></pre></div>
<h3 id="ruleclass">RuleClass</h3>
<p>Starting with the simplest, we have a one <code>RuleClass</code> message.</p>
<div class="sourceCode"><pre class="sourceCode python"><code class="sourceCode python">rule_classes {
  <span class="bu">id</span>: <span class="st">&quot;0&quot;</span>
  name: <span class="st">&quot;android_binary&quot;</span>
}</code></pre></div>
<p>This is no surprise: we dumped the action graph of an <code>android_binary</code> target.</p>
<h3 id="target">Target</h3>
<div class="sourceCode"><pre class="sourceCode python"><code class="sourceCode python">targets {
  <span class="bu">id</span>: <span class="st">&quot;0&quot;</span>
  label: <span class="st">&quot;//examples/android/java/bazel:hello_world&quot;</span>
  rule_class_id: <span class="st">&quot;0&quot;</span>
}</code></pre></div>
<p>Correspondingly, there’s also one <code>Target</code> message. We see that it encodes the <code>id</code> of the target’s <code>RuleClass</code>. In this case, the <code>rule_class_id</code> refers to <code>android_binary</code>.</p>
<h3 id="configuration">Configuration</h3>
<div class="sourceCode"><pre class="sourceCode python"><code class="sourceCode python">configuration {
  <span class="bu">id</span>: <span class="st">&quot;0&quot;</span>
  mnemonic: <span class="st">&quot;darwin-fastbuild&quot;</span>
  platform_name: <span class="st">&quot;darwin&quot;</span>
}</code></pre></div>
<p>We have one build configuration mnemonic: <code>darwin-fastbuild</code>. This is a reference to our execution platform (macOS) and the <code>fastbuild</code> <a href="https://docs.bazel.build/versions/master/user-manual.html#flag--compilation_mode">compilation mode</a>.</p>
<h3 id="artifact">Artifact</h3>
<div class="sourceCode"><pre class="sourceCode python"><code class="sourceCode python">artifacts {
  <span class="bu">id</span>: <span class="st">&quot;16&quot;</span>
  exec_path: <span class="st">&quot;external/local_jdk/bin/javac&quot;</span>
}

artifacts {
  <span class="bu">id</span>: <span class="st">&quot;190&quot;</span>
  exec_path: <span class="st">&quot;bazel-out/android-armeabi-v7a-fastbuild/bin/external/androidsdk/com.android.support/_aar/unzipped/resources/support-vector-drawable-25.0.0&quot;</span>
  is_tree_artifact: true
}

artifacts {
  <span class="bu">id</span>: <span class="st">&quot;227&quot;</span>
  exec_path: <span class="st">&quot;examples/android/java/bazel/res/values/styles.xml&quot;</span>
}

artifacts {
  <span class="bu">id</span>: <span class="st">&quot;229&quot;</span>
  exec_path: <span class="st">&quot;bazel-out/host/genfiles/external/androidsdk/aapt_runner.sh&quot;</span>
}

artifacts {
  <span class="bu">id</span>: <span class="st">&quot;349&quot;</span>
  exec_path: <span class="st">&quot;bazel-out/darwin-fastbuild/bin/examples/android/java/bazel/hello_world_unsigned.apk&quot;</span>
}</code></pre></div>
<p>Every file that Bazel handles is an <code>Artifact</code>. It represents:</p>
<ol style="list-style-type: decimal">
<li><p>a source file</p></li>
<li><p>or a derived output file</p></li>
</ol>
<p>The “file” can also be a directory (e.g. artifact <code>190</code>), which is referred to as a <code>TreeArtifact</code>. Check out the detailed documentation on the different Artifact types <a href="https://github.com/bazelbuild/bazel/blob/b8765a6656415eb6380fffd20202515918880d96/src/main/java/com/google/devtools/build/lib/actions/Artifact.java#L54:L99">here</a>.</p>
<p><code>exec_path</code> is the relative path of the Artifact within the execution root. The execution root is the working directory where Bazel executes all actions during the execution phase:</p>
<pre><code>→ bazel info execution_root
.....................
/private/var/tmp/_bazel_jin/ed227ac31d5e65f9c3effb1d1fe2605e/execroot/io_bazel</code></pre>
<p>The <code>exec_path</code>s come in different prefix flavours:</p>
<ul>
<li><code>external/..</code>: Contains symlinks to external repositories, such as <code>@local_jdk</code> and <code>@androidsdk</code>.</li>
<li><code>examples/..</code>: Contains the source files. This is a symlink to the actual <code>examples/</code> folder.</li>
<li><span style="white-space: nowrap;"><code>bazel-out/host/genfiles/..</code></span>: Contains generated sources, usually from <code>genrules</code>, for the <code>host</code> target <a href="https://github.com/bazelbuild/bazel/blob/b8765a6656415eb6380fffd20202515918880d96/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java#L87">BuildConfiguration</a>.</li>
<li><span style="white-space: nowrap;"><code>bazel-out/darwin-fastbuild/bin/..</code></span>: Contains derived binary outputs for the <code>darwin</code> target BuildConfiguration.</li>
<li><code>bazel-out/android-armeabi-v7a-fastbuild/bin/..</code>: Contains derived binary outputs for the <code>android-armeabi-v7a</code> target BuildConfiguration.</li>
</ul>
<h3 id="depsetoffiles">DepSetOfFiles</h3>
<div class="sourceCode"><pre class="sourceCode python"><code class="sourceCode python">dep_set_of_files {
  <span class="bu">id</span>: <span class="st">&quot;198&quot;</span>
  transitive_dep_set_ids: <span class="st">&quot;136&quot;</span>
  direct_artifact_ids: <span class="st">&quot;292&quot;</span>
}

dep_set_of_files {
  <span class="bu">id</span>: <span class="st">&quot;136&quot;</span>
  transitive_dep_set_ids: <span class="st">&quot;137&quot;</span>
  direct_artifact_ids: <span class="st">&quot;337&quot;</span>
}</code></pre></div>
<p><code>Depset</code> is a data structure for collecting data on transitive dependencies. It’s optimized to be time and space efficient around merging, because it’s common to have very large depsets, scaling to hundreds of thousands of files. Read the <a href="https://docs.bazel.build/versions/master/skylark/depsets.html">documentation</a> to learn more about depsets.</p>
<p>In our protobuf, a <code>dep_set_of_files</code> can refer to other depsets with <code>transitive_dep_set_ids</code>, or directly to artifacts with <code>direct_artifact_ids</code>.</p>
<p>It’s crucial to highlight the ability to recursively refer to other depsets: it’s an important catalyst for space efficiency. Rule implementations should not flatten depsets to lists unless they are at the top level. Flattening large depsets incur huge memory consumption.</p>
<h3 id="action">Action</h3>
<p>Finally, we have <code>Action</code>. An action, as described in the <a href="https://source.bazel.build/bazel/+/master:src/main/protobuf/analysis.proto;l=50">protobuf’s documentation</a>, is a <em>function</em> from <code>Artifact</code> to <code>Artifact</code>. It’s might be easier to think of an <code>Action</code> as all of the information required to create an output file, which usually contains a command line representation.</p>
<div class="sourceCode"><pre class="sourceCode python"><code class="sourceCode python">actions {
  target_id: <span class="st">&quot;0&quot;</span>
  action_key: <span class="st">&quot;e121f7eb29e0828eef502582d5134d37&quot;</span>
  mnemonic: <span class="st">&quot;ResourceExtractor&quot;</span>
  configuration_id: <span class="st">&quot;0&quot;</span>
  arguments: <span class="st">&quot;bazel-out/host/bin/external/bazel_tools/tools/android/resource_extractor&quot;</span>
  arguments: <span class="st">&quot;bazel-out/darwin-fastbuild/bin/examples/android/java/bazel/hello_world_deploy.jar&quot;</span>
  arguments: <span class="st">&quot;bazel-out/darwin-fastbuild/bin/examples/android/java/bazel/_dx/hello_world/extracted_hello_world_deploy.jar&quot;</span>
  input_dep_set_ids: <span class="st">&quot;198&quot;</span>
  output_ids: <span class="st">&quot;338&quot;</span>
}

targets {
  <span class="bu">id</span>: <span class="st">&quot;0&quot;</span>
  label: <span class="st">&quot;//examples/android/java/bazel:hello_world&quot;</span>
  rule_class_id: <span class="st">&quot;0&quot;</span>
}

dep_set_of_files {
  <span class="bu">id</span>: <span class="st">&quot;198&quot;</span>
  transitive_dep_set_ids: <span class="st">&quot;136&quot;</span>
  direct_artifact_ids: <span class="st">&quot;292&quot;</span>
}

artifacts {
  <span class="bu">id</span>: <span class="st">&quot;338&quot;</span>
  exec_path: <span class="st">&quot;bazel-out/darwin-fastbuild/bin/examples/android/java/bazel/_dx/hello_world/extracted_hello_world_deploy.jar&quot;</span>
}

artifacts {
  <span class="bu">id</span>: <span class="st">&quot;292&quot;</span>
  exec_path: <span class="st">&quot;bazel-out/darwin-fastbuild/bin/examples/android/java/bazel/hello_world_deploy.jar&quot;</span>
}</code></pre></div>
<p>In this selected <code>Action</code>, we are extracting resources out of a <code>jar</code> using a tool called <code>resource_extractor</code>. The full command line is captured with the list of <code>arguments</code> with the first <code>argument</code> as the executable. Every file referenced in the command line <strong>must</strong> be an <code>Artifact</code> in either in the transitive depset(s) <code>input_dep_set_ids</code> or artifact(s) <code>output_ids</code>. This enables Bazel to discover actions to run in order to get a requested output artifact.</p>
<p>The <code>action_key</code> is computed based on the command line that will be executed, which contains information like compiler flags, library locations and system headers. This enables Bazel to keep track of actions to invalidate and re-run incrementally, and cache aggressively if there is no need to rerun an action.</p>
<p>The <code>Action</code>’s <code>configuration_id</code> is <code>0</code>, as this action is executed with the <code>darwin-fastbuild</code> BuildConfiguration.</p>
<p>Each <code>Action</code> has a mnemonic, which is a short human readable string to quickly understand what the <code>Action</code> is doing. We can grep the protobuf for all mnemonics to see mostly Android-related actions, like <code>AndroidDexer</code> and <code>RClassGenerator</code>.</p>
<pre><code>→ grep &quot;mnemonic&quot; action_graph.txt | sort | uniq
  mnemonic: &quot;AaptPackage&quot;
  mnemonic: &quot;AaptSplitResourceApk&quot;
  mnemonic: &quot;AndroidBuildSplitManifest&quot;
  mnemonic: &quot;AndroidDexManifest&quot;
  mnemonic: &quot;AndroidDexer&quot;
  mnemonic: &quot;AndroidInstall&quot;
  mnemonic: &quot;AndroidStripResources&quot;
  mnemonic: &quot;AndroidZipAlign&quot;
  mnemonic: &quot;ApkBuilder&quot;
  mnemonic: &quot;ApkSignerTool&quot;
  mnemonic: &quot;CppLink&quot;
  mnemonic: &quot;Desugar&quot;
  mnemonic: &quot;DexBuilder&quot;
  mnemonic: &quot;DexMerger&quot;
  mnemonic: &quot;Fail&quot;
  mnemonic: &quot;FileWrite&quot;
  mnemonic: &quot;InjectMobileInstallStubApplication&quot;
  mnemonic: &quot;JavaDeployJar&quot;
  mnemonic: &quot;JavaSourceJar&quot;
  mnemonic: &quot;Javac&quot;
  mnemonic: &quot;ManifestMerger&quot;
  mnemonic: &quot;RClassGenerator&quot;
  mnemonic: &quot;ResourceExtractor&quot;
  mnemonic: &quot;ShardClassesToDex&quot;
  mnemonic: &quot;Symlink&quot;
  mnemonic: &quot;Turbine&quot;
  mnemonic: &quot;darwin-fastbuild&quot;</code></pre>
<h2 id="summary">Summary</h2>
<p>The action graph is a powerful tool to gain introspection into Bazel’s analysis and execution phases. It provides just enough information to visualize the <code>Action</code> data structure before it is transformed into an executable command line as seen with the <code>--subcommands</code> flag.</p>
<p>If you wish to learn more about the underlying data representation of the action graph, check out the design document of Bazel’s parallel evaluation and incrementality model, <a href="https://bazel.build/designs/skyframe.html">Skyframe</a>.</p>
]]></summary>
</entry>
<entry>
    <title>5 minute guide to Bazel, Part 2: Command lines and tools</title>
    <link href="http://jin.crypt.sg/articles/bazel-in-5-minutes-genrule.html" />
    <id>http://jin.crypt.sg/articles/bazel-in-5-minutes-genrule.html</id>
    <published>2018-02-19T00:01:00Z</published>
    <updated>2018-02-19T00:01:00Z</updated>
    <summary type="html"><![CDATA[<div class="info">
    Posted on February 19, 2018
    
</div>

<h1 id="minute-guide-to-bazel-part-2-command-lines-and-tools">5 minute guide to Bazel, Part 2: Command lines and tools</h1>
<p><em>The aim of this guide is to get you up and running with Bazel as fast as possible. The steps will assume <a href="https://docs.bazel.build/versions/master/install.html">you have Bazel installed</a>.</em></p>
<p>This part will show how to run a command line using <code>genrule</code>. This rule is the <em>generic</em> way to specify sources, a tool (like a shell script), a command line, and the outputs. You can think of it as a way to define a function in your <code>BUILD</code> file with the following signature:</p>
<div class="sourceCode"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="ot">genrule ::</span> (name, sources, tool, command) <span class="ot">-&gt;</span> output</code></pre></div>
<p>In this example, we want to create a C source file, copy it using <code>cp</code>, and run <code>sed</code> on it with a shell script, and build an executable from the result.</p>
<p>Let’s get started in an empty directory called <code>dir</code>.</p>
<ol style="list-style-type: decimal">
<li>Create an empty <code>WORKSPACE</code> file.</li>
</ol>
<div class="sourceCode"><pre class="sourceCode sh"><code class="sourceCode bash"><span class="fu">dir</span> $ touch WORKSPACE</code></pre></div>
<ol start="2" style="list-style-type: decimal">
<li>Create a file called <code>main.c</code> and write some C in it.</li>
</ol>
<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">// dir/main.c</span>

<span class="pp">#include </span><span class="im">&lt;stdio.h&gt;</span>

<span class="dt">int</span> main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv) {
  printf(<span class="st">&quot;Hello Blaze.</span><span class="sc">\n</span><span class="st">&quot;</span>);
  <span class="cf">return</span> <span class="dv">0</span>;
}</code></pre></div>
<ol start="3" style="list-style-type: decimal">
<li>Write a <code>BUILD</code> file with the <code>genrule</code> to copy <code>main.c</code>.</li>
</ol>
<div class="sourceCode"><pre class="sourceCode py"><code class="sourceCode python"><span class="co"># dir/BUILD</span>

genrule(
  name <span class="op">=</span> <span class="st">&quot;copy_of_main&quot;</span>,
  srcs <span class="op">=</span> [<span class="st">&quot;main.c&quot;</span>],
  outs <span class="op">=</span> [<span class="st">&quot;copy_of_main.c&quot;</span>],
  cmd <span class="op">=</span> <span class="st">&quot;cp $&lt; $@&quot;</span>,
)</code></pre></div>
<p><code>$&lt;</code> expands to the location of <code>main.c</code>, and <code>$@</code> expands to the location of <code>copy_of_main.c</code>. See the full list of supported variables <a href="https://docs.bazel.build/versions/master/be/make-variables.html">here</a>.</p>
<ol start="4" style="list-style-type: decimal">
<li>Let’s build this target, <code>//:copy_of_main</code>.</li>
</ol>
<div class="sourceCode"><pre class="sourceCode sh"><code class="sourceCode bash"><span class="fu">dir</span> $ bazel build //:copy_of_main
<span class="ex">....................</span>
<span class="ex">INFO</span>: Analysed target //:copy_of_main (7 packages loaded)<span class="ex">.</span>
<span class="ex">INFO</span>: Found 1 target...
<span class="ex">Target</span> //:copy_of_main up-to-date:
  <span class="ex">bazel-genfiles/copy_of_main.c</span>
<span class="ex">INFO</span>: Elapsed time: 10.323s, Critical Path: 0.08s
<span class="ex">INFO</span>: Build completed successfully, 2 total actions

<span class="fu">dir</span> $ cat bazel-genfiles/copy_of_main.c
<span class="co">#include &lt;stdio.h&gt;</span>

<span class="ex">int</span> main(int argc, char **argv) <span class="kw">{</span>
  <span class="bu">printf</span>(<span class="st">&quot;Hello Blaze.\n&quot;</span>);
  <span class="bu">return</span> 0<span class="kw">;</span>
<span class="kw">}</span></code></pre></div>
<p>The file is copied successfully!</p>
<ol start="5" style="list-style-type: decimal">
<li>Use the <code>tool</code> attribute to specify a separate tool to run in the <code>cmd</code> string.</li>
</ol>
<p>We want to substitute the word “Blaze” with “Bazel” in the source code, because that’s the name the build system was open sourced with. Let’s write the <code>genrule</code> for that:</p>
<div class="sourceCode"><pre class="sourceCode py"><code class="sourceCode python"><span class="co"># dir/BUILD</span>

<span class="co"># ...</span>

genrule(
  name <span class="op">=</span> <span class="st">&quot;renamed_main&quot;</span>,
  srcs <span class="op">=</span> [<span class="st">&quot;copy_of_main.c&quot;</span>],
  outs <span class="op">=</span> [<span class="st">&quot;renamed_main.c&quot;</span>],
  tools <span class="op">=</span> [<span class="st">&quot;substitute.sh&quot;</span>],
  cmd <span class="op">=</span> <span class="st">&quot;$(location substitute.sh) &#39;Blaze&#39; &#39;Bazel&#39; $&lt; $@&quot;</span>,
)</code></pre></div>
<p><code>location</code> is Bazel’s helper function to resolve the location of the tool when this command is executed.</p>
<p>Then, create a file <code>substitute.sh</code> that calls out to <a href="https://linux.die.net/man/1/sed"><code>sed</code></a>:</p>
<div class="sourceCode"><pre class="sourceCode sh"><code class="sourceCode bash"><span class="co">#!/bin/bash</span>

<span class="fu">sed</span> <span class="st">&quot;s/</span><span class="va">$1</span><span class="st">/</span><span class="va">$2</span><span class="st">/&quot;</span> <span class="va">$3</span> <span class="op">&gt;</span> <span class="va">$4</span></code></pre></div>
<p>Don’t forget to make it executable with <code>chmod u+x substitute.sh</code>.</p>
<ol start="6" style="list-style-type: decimal">
<li>Build the target <code>//:renamed_main</code>.</li>
</ol>
<div class="sourceCode"><pre class="sourceCode sh"><code class="sourceCode bash"><span class="fu">dir</span> $ bazel build :renamed_main
<span class="ex">INFO</span>: Analysed target //:renamed_main (0 packages loaded)<span class="ex">.</span>
<span class="ex">INFO</span>: Found 1 target...
<span class="ex">Target</span> //:renamed_main up-to-date:
  <span class="ex">bazel-genfiles/renamed_main.c</span>
<span class="ex">INFO</span>: Elapsed time: 0.261s, Critical Path: 0.07s
<span class="ex">INFO</span>: Build completed successfully, 2 total actions

<span class="fu">dir</span> $ cat bazel-genfiles/renamed_main.c
<span class="co">#include &lt;stdio.h&gt;</span>

<span class="ex">int</span> main(int argc, char **argv) <span class="kw">{</span>
  <span class="bu">printf</span>(<span class="st">&quot;Hello Bazel.\n&quot;</span>);
  <span class="bu">return</span> 0<span class="kw">;</span>
<span class="kw">}</span></code></pre></div>
<p>We are now using the correct name.</p>
<ol start="7" style="list-style-type: decimal">
<li>To wrap it all up, let’s use <code>cc_binary</code> from <a href="../articles/bazel-in-5-minutes-c.html">Part 1</a>.</li>
</ol>
<div class="sourceCode"><pre class="sourceCode py"><code class="sourceCode python"><span class="co"># dir/BUILD</span>

cc_binary(
  name <span class="op">=</span> <span class="st">&quot;hello_bazel&quot;</span>,
  srcs <span class="op">=</span> [<span class="st">&quot;:renamed_main&quot;</span>],
)</code></pre></div>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="fu">dir</span> $ bazel run //:hello_bazel
<span class="ex">INFO</span>: Analysed target //:hello_bazel (3 packages loaded)<span class="ex">.</span>
<span class="ex">INFO</span>: Found 1 target...
<span class="ex">Target</span> //:hello_bazel up-to-date:
  <span class="ex">bazel-bin/hello_bazel</span>
<span class="ex">INFO</span>: Elapsed time: 5.817s, Critical Path: 0.52s
<span class="ex">INFO</span>: Build completed successfully, 5 total actions

<span class="ex">INFO</span>: Running command line: bazel-bin/hello_bazel
<span class="ex">Hello</span> Bazel.</code></pre></div>
<p>This is how we can use <code>genrule</code> to preprocess files before passing them in to other rules. It’s a simple and flexible way to create pipelines using Bazel.</p>
]]></summary>
</entry>
<entry>
    <title>5 minute guide to Bazel, Part 1: C and C++</title>
    <link href="http://jin.crypt.sg/articles/bazel-in-5-minutes-c.html" />
    <id>http://jin.crypt.sg/articles/bazel-in-5-minutes-c.html</id>
    <published>2018-02-18T00:01:00Z</published>
    <updated>2018-02-18T00:01:00Z</updated>
    <summary type="html"><![CDATA[<div class="info">
    Posted on February 18, 2018
    
</div>

<h1 id="minute-guide-to-bazel-part-1-c-c">5 minute guide to Bazel, Part 1: C &amp; C++</h1>
<p>The aim of this guide is to get you up and running with Bazel as fast as possible. The steps will assume <a href="https://docs.bazel.build/versions/master/install.html">you have Bazel installed</a>.</p>
<p>Some quick notes before we start: the most important idea about Bazel is that it is <strong>declarative</strong>.</p>
<p>You should <em>never</em> need to type out the intermediary build steps; that is the responsibility of the language/platform rule authors. The build steps are hidden away in the rule implementations so you can focus on just telling Bazel what sources to build.</p>
<p>Let’s get started. Each example here assumes that you’re in an empty directory called <code>dir</code>.</p>
<ol style="list-style-type: decimal">
<li>Create an empty <code>WORKSPACE</code> file.</li>
</ol>
<div class="sourceCode"><pre class="sourceCode sh"><code class="sourceCode bash"><span class="fu">dir</span> $ touch WORKSPACE</code></pre></div>
<ol start="2" style="list-style-type: decimal">
<li>Create a file called <code>main.c</code> and write some C in it.</li>
</ol>
<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">// dir/main.c</span>

<span class="pp">#include </span><span class="im">&lt;stdio.h&gt;</span>

<span class="dt">int</span> main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv) {
  printf(<span class="st">&quot;Hello Bazel.</span><span class="sc">\n</span><span class="st">&quot;</span>);
  <span class="cf">return</span> <span class="dv">0</span>;
}</code></pre></div>
<ol start="3" style="list-style-type: decimal">
<li>Write a <code>BUILD</code> file and tell Bazel you want an executable built from <code>main.c</code>.</li>
</ol>
<div class="sourceCode"><pre class="sourceCode py"><code class="sourceCode python"><span class="co"># dir/BUILD</span>

cc_binary(
  name <span class="op">=</span> <span class="st">&quot;hello_bazel&quot;</span>,
  srcs <span class="op">=</span> [<span class="st">&quot;main.c&quot;</span>],
)</code></pre></div>
<p>The <code>cc_binary</code> rule is all Bazel needs to know that you want to build C/C++ sources.</p>
<ol start="4" style="list-style-type: decimal">
<li>Build and run the <code>hello_bazel</code> target, <code>//:hello_bazel</code>.</li>
</ol>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="fu">dir</span> $ bazel run //:hello_bazel
<span class="ex">...............</span>
<span class="ex">INFO</span>: Analysed target //:hello_bazel (9 packages loaded)<span class="ex">.</span>
<span class="ex">INFO</span>: Found 1 target...
<span class="ex">Target</span> //:hello_bazel up-to-date:
  <span class="ex">bazel-bin/hello_bazel</span>
<span class="ex">INFO</span>: Elapsed time: 12.423s, Critical Path: 0.44s
<span class="ex">INFO</span>: Build completed successfully, 5 total actions

<span class="ex">INFO</span>: Running command line: bazel-bin/hello_bazel
<span class="ex">Hello</span> Bazel.</code></pre></div>
<p><code>//</code> refers to the directory level where the <code>WORKSPACE</code> is. <code>:</code> specifies a <a href="https://docs.bazel.build/versions/master/user-manual.html#target-patterns">target</a> in a <code>BUILD</code> file.</p>
<ol start="5" style="list-style-type: decimal">
<li>If you just want to build it, use <code>bazel build</code> instead of <code>bazel run</code>.</li>
</ol>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="fu">dir</span> $ bazel build //:hello_bazel
<span class="ex">INFO</span>: Analysed target //:hello_bazel (9 packages loaded)<span class="ex">.</span>
<span class="ex">INFO</span>: Found 1 target...
<span class="ex">Target</span> //:hello_bazel up-to-date:
  <span class="ex">bazel-bin/hello_bazel</span>
<span class="ex">INFO</span>: Elapsed time: 2.058s, Critical Path: 0.24s
<span class="ex">INFO</span>: Build completed successfully, 5 total actions</code></pre></div>
<p>The executable is in the <code>bazel-bin</code> symlink: <code>bazel-bin/hello_bazel</code>.</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="fu">dir</span> $ cp bazel-bin/hello_bazel hello_bazel
<span class="fu">dir</span> $ ./hello_bazel
<span class="ex">Hello</span> Bazel.</code></pre></div>
<p>That’s it!</p>
]]></summary>
</entry>
<entry>
    <title>Semantics | Notes on Types and Programming Languages</title>
    <link href="http://jin.crypt.sg/articles/semantics.html" />
    <id>http://jin.crypt.sg/articles/semantics.html</id>
    <published>2017-05-03T00:01:00Z</published>
    <updated>2017-05-03T00:01:00Z</updated>
    <summary type="html"><![CDATA[<div class="info">
    Posted on May  3, 2017
    
</div>

<h1 id="semantics">Semantics</h1>
<h5 id="notes-on-types-programming-languages-by-benjamin-pierce-2002">Notes on Types &amp; Programming Languages by Benjamin Pierce (2002)</h5>
<p>The design of a programming language can be divided into two parts: <strong>syntax</strong> and <strong>semantics</strong>.</p>
<p>The syntax describes <em>how it looks like</em>.</p>
<p>The semantics describes <em>what it should do</em>.</p>
<p>There are many ways a program can be written with valid syntax but turn nonsensical when evaluated. These nonsensical evaluations are known as <em>runtime errors</em>.</p>
<p>Semantics formally describes how programs should be evaluated. Programs that are well-formed according to its semantics do not get stuck.</p>
<p>There are three main styles of describing semantics: operational, denotational, and axiomatic.</p>
<h3 id="operational-semantics">Operational semantics</h3>
<p>Operational semantics uses the idea that languages are <em>abstract machines</em> and evaluation of a program is a series of state transitions from an initial to a final state.</p>
<p><em>Transition functions</em> define how states transit to the next, if there is one. If there is no such next state, the machine either completed its evaluation successfully or faced a runtime error and got stuck. The program halts in both cases.</p>
<p>Every term in the computer program has some <em>meaning</em>, and its form finalizes when the state transitions are complete. State transitions may be single or multi-step.</p>
<p>There are two major ways to write operational semantics: small-step or big-step.</p>
<p><em>Small-step semantics</em> breaks down behaviour into granular simplification steps. A simplication step might not guarantee evaluation to a finalized form; sometimes multiple steps are needed.</p>
<p><em>Big-step semantics</em> composes multiple small-step rules that evaluate into a finalized form into a single rule. Such a rule is equivalent with its multi-step counterpart.</p>
<p>Since operational semantics is styled after abstract machine behaviour, they’re useful as a reference for implementation.</p>
<p><em>Origins: John McCarthy on Semantics of Lisp (1960)</em></p>
<h3 id="denotational-semantics">Denotational semantics</h3>
<p>Denotational semantics uses the idea that languages are <em>mathematical objects</em>. Unlike operational semantics, evaluation and implementation details are abstracted away.</p>
<p>An <em>interpretation function</em> is defined to map terms in a program to elements in <em>semantic domains</em> (also known as its <em>denotation</em>), removing any occurrences of the original syntax.</p>
<p>Semantic domains are designed to model after specific language features and this study is called <em>domain theory</em>.</p>
<p>Checking whether two programs are the same is achievable by comparing their denotations.</p>
<p>Laws can be derived from the semantic domains and are used for language specifications to verify correctness of an implementation.</p>
<p>The properties of the semantic domains can be used to show impossible instances in a language.</p>
<p><em>Origins: Christopher Strachey, Dana Scott on “Toward a mathematical semantics for computer languages” (1970, 1971)</em></p>
<h3 id="axiomatic-semantics">Axiomatic semantics</h3>
<p>Intuitively related to <em>Hoare Logic</em>. Instead of deriving laws from operational or denotational behaviour definitions, the <em>laws themselves</em> define the semantics of the language.</p>
<p>This reversal simplifies reasoning about a program, leading to developments in software verification.</p>
<p>Two different program implementations with the same set of initial and final assertions (laws) are considered to have the same semantics.</p>
<p>The terms that happen between assertions are just used to prove the assertions themselves and do not contribute to the semantics.</p>
<p>Assertions define relationships between variables and other moving parts in a program, and some of these assertions remain invariant throughout execution. This is the important <em>invariance</em> concept that underlies axiomatic semantics.</p>
<p><em>Origins: Tony Hoare on Hoare Logic (1969)</em></p>
]]></summary>
</entry>
<entry>
    <title>A brief guide for potential NUS Computer Science undergraduates</title>
    <link href="http://jin.crypt.sg/articles/computer-science-undergrad-singapore.html" />
    <id>http://jin.crypt.sg/articles/computer-science-undergrad-singapore.html</id>
    <published>2017-02-26T00:00:00Z</published>
    <updated>2017-02-26T00:00:00Z</updated>
    <summary type="html"><![CDATA[<div class="info">
    Posted on February 26, 2017
    
</div>

<h1 id="a-brief-guide-for-potential-nus-computer-science-undergraduates"><strong>A brief guide for potential NUS Computer Science undergraduates</strong></h1>
<blockquote>
<p><sub><em>Update Dec 2017</em>: I’ve graduated from NUS. Specific references in this article about NUS and the computing faculty may be outdated - please <a href="mailto:jin@crypt.sg">contact me</a> if there’s information that should be updated.</sub></p>
</blockquote>
<p>As there has been growing interest in CS undergraduate courses over the past few years, I would like to share my experience as a CS major at National University of Singapore, and also shed light on the common misconceptions that people may have. This essay will also be focussed on National University of Singapore’s curriculum and programmes, because I’m most familiar with it.</p>
<p>My background: I’m a fourth year CS major. Prior to this, I graduated from Ngee Ann Polytechnic with a Diploma in Network Systems &amp; Security.</p>
<p>I made the decision to read CS upon realising the gaps in my knowledge of technology.</p>
<p>I felt confident in designing and implementing network systems, but never understood why network protocols were designed in that manner. A quick search on Wikipedia on a network protocol algorithm, Djikstra’s Shortest Path, inundated me with so much math that it quickly made me realize that a CS education will provide the foundational theoretical knowledge to understand these algorithms.</p>
<h2 id="should-i-study-cs"><strong>Should I study CS?</strong></h2>
<p>You know how to use computers as a tool to get things done. However, you’ve probably never learnt why and how they work behind the scenes.</p>
<p>Consider Google Search. Have you ever wondered why it seems to know everything and how it works behind the scenes? How did your search come back with millions of results in a fraction of a second? How did the information get from Google’s servers to your screen?</p>
<p>CS is the science of computational processes, like how Physics is the science of nature. It’s a foundational science that enables you to solve problems across disciplines and subfields.</p>
<p>It’s about taking problems, figuring out what needs to be solved, and providing a step-by-step solution to compute the solution. These problems come from other fields like healthcare, finance, environmental science, space exploration, game development, or something that you have an interest in. Anything.</p>
<p>If you’re a problem solver, CS will sharpen your mind to produce articulate and well-reasoned solutions, and to communicate them across domains.</p>
<p>If you’re not, CS will equip you with the mental toolbox to approach complex problems with confidence.</p>
<p>You’ll learn to break down complex problems into little problems that can be solved systematically. I recommend reading CS if you’ve enjoyed mathematical and logical challenges.</p>
<p>If this sounds interesting to you, then yes, go forth and study CS.</p>
<h2 id="computer-science-is-difficult."><strong>Computer Science is difficult.</strong></h2>
<p>CS is not a walk in the park.</p>
<p>No decent undergraduate degree program is a walk in the park.</p>
<p>A well-designed curriculum will begin with battle-tested fundamental courses. They will expand your mind and change the way you think about the world.</p>
<p>Don’t assume that you’re just going to learn how to program; you can do that in 2 weeks with an online course.</p>
<p>CS will flex your brain muscles and teach you how to reason rigorously in the various subfields, such as computer graphics, artificial intelligence and even programming languages themselves.</p>
<p>Wikipedia has a <a href="https://en.wikipedia.org/wiki/Outline_of_computer_science">good outline of the subfields</a> in CS.</p>
<h2 id="what-is-cs-at-national-university-of-singapore-like"><strong>What is CS at National University of Singapore like?</strong></h2>
<div class="figure">
<img src="http://jin.crypt.sg/images/soc.jpg" />

</div>
<p>CS is taught in the School of Computing (SoC).</p>
<p>There are about 1300 undergraduates in SoC (as of 2017) across CS, Information Systems, Information Security, Business Analytics and Computational Biology.</p>
<p>As a freshman, you’ll do lot of common modules, so the first year tend to be similar with other majors.</p>
<p>The full SoC CS curriculum is available on the <a href="http://www.comp.nus.edu.sg/programmes/ug/cs/curr/">website</a>.</p>
<p>The fundamental modules include:</p>
<ul>
<li>introductory programming methodologies (CS1010 and S, X, E variants, CS1101S, CS2030)</li>
<li>data structures and algorithms (CS2040, CS3230)</li>
<li>calculus (MA1521)</li>
<li>discrete mathematics (CS1231)</li>
<li>linear algebra (MA1101R)</li>
<li>software engineering (CS2103)</li>
</ul>
<p>After these, it’s generally assumed that you know how to code and are able to pick up the languages as needed.</p>
<p>For example, a parallel programming module will assume that you know how to code in C, or can pick it up in 1-2 weeks, since the syllabus is focussed on parallelism concepts.</p>
<p>The most hardware oriented module is CS2100, Computer Organisation. You’ll learn lower level concepts like logic, CPU design and basic assembly programming. Anything lower than that enters the realm of Computer Engineering, where modules are coded with CG instead of CS. CS students are not required to do electrical and electronic engineering modules.</p>
<p>From the second year onwards, you’ll specialize into a technical area of study called a Focus Area. There are <a href="http://www.comp.nus.edu.sg/programmes/ug/focus/">ten of them</a>.</p>
<p>Most students will spend their summer vacations on internships and exchanges. NUS Overseas Colleges is a popular choice for the entrepreneurial minded.</p>
<p>I <strong>highly</strong> recommend doing internships that are self-sourced, and not on the list provided in the faculty internship portal. Self-sourced internships usually result in more interesting companies and projects.</p>
<p>A SoC alumnus has compiled information on self-sourcing internships in <a href="https://ymichael.github.io/projectintern/">Project Intern</a>.</p>
<h2 id="dont-worry-about-a-lack-of-programming-background."><strong>Don’t worry about a lack of programming background.</strong></h2>
<p>Most come in fresh – I didn’t (I learnt programming in NP), but I didn’t feel advantaged at any point in time.</p>
<p>I felt challenged by the first programming module I took in SoC, CS1101S, which I highly recommend freshmen to take, if you have the opportunity. It replaces CS1010.</p>
<p>If you want to prepare yourself, start reading <a href="https://www.reddit.com/r/programming">/r/programming</a>, <a href="https://news.ycombinator.com">Hacker News</a>, and familiarize yourself with the idea that CS is not <strong>solely about programming</strong> but understanding how to compute things.</p>
<p>Programming is a tool to implement computations to solve a problem, like a hammer as the tool to drive nails into a piece of wood to create something.</p>
<p>However, disliking programming may lead to difficulty understanding CS materials, as they are intertwined.</p>
<p>Most NUS CS undergraduates will do Java at some point, especially in the Data Structures &amp; Algorithms module. While that is a good starting point, don’t be afraid to branch out to other languages once you feel that you know Java well enough.</p>
<p>A quick glance at <a href="http://learnxinyminutes.com/">http://learnxinyminutes.com</a> will show you the plethora of programming languages out there.</p>
<p>Popular programming languages are typically general purpose - meaning they can be used in many applications - but each language has its own niche area. For example, Python and Ruby are used for scripting languages, while Java is used for building enterprise systems. There are many guides on what language to learn first — I will not delve into that here.</p>
<p>Learning one language well makes learning successive languages easier.</p>
<h2 id="but-im-bad-at-mathematics"><strong>But I’m bad at mathematics!</strong></h2>
<p>CS has an enormous intersection with mathematics.</p>
<p>I disliked mathematics prior to University. The lack of interest and curiosity stemmed from rote learning formulas in secondary school and tuition classes. It just didn’t seem like an interesting subject and I associated it with boredom and dread.</p>
<p>However, mathematics pedagogy in University is on a whole other level. You will finally understand why certain things in math are the way they are, and maybe it’ll start to seem more interesting to you.</p>
<p>Your teachers are now passionate professors who are experts in their research fields, and are usually patient enough to explain concepts to you if you ask.</p>
<p>I’m still not great at mathematics, but NUS CS has made me see math in a different light. For example, matrices in linear algebra are used heavily in Computer Graphics and Game Development, and graph theory is used in databases and computer program analysis.</p>
<p>Both CS and mathematics force you to think in terms of abstractions. Improving in one domain helps in the other.</p>
<h2 id="do-grades-matter-in-cs"><strong>Do grades matter in CS?</strong></h2>
<p>The idea of studying for grades is probably ingrained deep into you after the 10-something years toiling through the Singapore education system. It’s time to get rid of that.</p>
<p>In CS, grades serve as your personal benchmark. Being able to score well in a module gives you a sense of confidence that you have understood the subject materials.</p>
<p>It does not mean you can mess school up and get away with it. Scoring consistent C’s and D’s is a signal that you have not understood the material intuitively, and will pose problems when you’re taking higher level modules.</p>
<p>Grades do not mean much when applying for industry roles, such as software engineering. No interviewers have ever asked me for grades.</p>
<p>Relevant internships and side-projects, on the other hand, are great ways to convey your skills to potential employers.</p>
<p>Potential employers can derive your willingness to learn and try new things, which translates to a potentially great attitude in the working environment. Self-directed learning is important in CS.</p>
<p>However, grades are still relatively important for graduate school applications, along with a research portfolio.</p>
<h2 id="what-are-my-job-prospects"><strong>What are my job prospects?</strong></h2>
<p>CS is one of the most versatile degrees to find work with.</p>
<p>It signifies that you’ve been through a rigorous curriculum and possess the ability to take on large and complex problems.</p>
<p>It is up to you to prove that you’re able to do it.</p>
<p>You can be a web developer, AI researcher, data scientist, software engineer, devops engineer, mobile app developer… the list goes on.</p>
<p>Each of those roles requires a specialized skill set, but CS forms the foundation of all of them.</p>
<p>Non-CS domains, like biology and finance, are <em>full</em> of problems that can be readily solved using CS techniques. See: DNA Editing with CRISPR, human genome project, anti-bank fraud systems and insider trading analysis.</p>
<h2 id="summary"><strong>Summary</strong></h2>
<p>CS is a field that has an ubiquitous nature.</p>
<p>It manifests itself in many different forms, and in many cases, it doesn’t even involve a computer.</p>
<p>To succeed in University, you’ll need to learn how to learn. That is, identify your gaps in knowledge and figure out how to fill them up efficiently.</p>
<p>The Singapore technology and research ecosystem is expanding rapidly with massive government support — there has never been a better time to pursue CS.</p>
<p>Feel free to ping me on <a href="https://twitter.com/jin_">Twitter</a> or <a href="mailto:jin@crypt.sg">Email</a> with questions or comments.</p>
<p>All the best!</p>
<h3 id="resources"><strong>Resources</strong></h3>
<p><a href="https://github.com/nushackers/notes-to-cs-freshmen-from-the-future">Notes to NUS CS Freshmen, from the future</a></p>
<p><a href="http://webuild.sg/">webuild.sg</a> - List of technology meetup groups in Singapore</p>
<p><a href="http://engineers.sg/">engineers.sg</a> - Meetup video recordings in Singapore</p>
<p><a href="http://matt.might.net/articles/what-cs-majors-should-know/">What every computer science major should know - Matt Might</a></p>
<h3 id="plug-nus-hackers"><strong>Plug: NUS Hackers</strong></h3>
<p>I’m part of the <a href="http://nushackers.org/">NUS Hackers</a> coreteam.</p>
<p>We’re a group of people who wants to spread the hacker culture.</p>
<p>The idea of not hesitating to build and break stuff for fun and knowledge, sharing and just being curious about how things work. Our weekly Friday Hacks have very different topics – the idea is to expose the NUS community to various technical topics they wouldn’t have otherwise learnt in class.</p>
<p>We also run a <a href="https://facebook.com/nushackerspace">hackerspace</a> in NUS.</p>
<h3 id="what-about-information-systems"><strong>What about Information Systems?</strong></h3>
<p>IS is a degree that sits in the intersection of business and IT, while CS is deeply grounded in mathematics and logic. Many CS graduates eventually exit academia into engineering roles though.</p>
<p>It’s easier to see the difference between the core modules of these majors:</p>
<ul>
<li><p>IS2101 Business and Technical Communication*</p></li>
<li><p>IS2102 Requirements Analysis and Design</p></li>
<li><p>IS2103 Enterprise Systems Development Concepts</p></li>
<li><p>IS2104 Software Team Dynamics</p></li>
<li><p>IS3101 Management of Information Systems</p></li>
<li><p>IS3102 Enterprise Systems Development Project</p></li>
<li><p>IS4100 IT Project Management</p></li>
</ul>
<hr />
<ul>
<li><p>CS2010 Data Structures and Algorithms II</p></li>
<li><p>CS2100 Computer Organisation</p></li>
<li><p>CS2103T Software Engineering</p></li>
<li><p>CS2105 Introduction to Computer Networks</p></li>
<li><p>CS2106 Introduction to Operating Systems</p></li>
<li><p>CS3230 Design and Analysis of Algorithms</p></li>
</ul>
]]></summary>
</entry>

</feed>
