Spruce up the documentation for Buck. Summary: * Update the home page to note that Buck is both an Android and a Java build tool. * Document the `buck quickstart` and `buck query` commands. * Rewrite the Quick Start page to use `buck quickstart`. * Migrate the old Quick Start page to the "Manual Quick Start" page. * Create some new macros for inserting hyperlinks in `__common.soy`. * Wrote up an article titled "What Makes Buck so Fast?" Test Plan: Inspected locally on http://localhost:9811/.
diff --git a/docs/__common.soy b/docs/__common.soy index e6d4a58..ea14e53 100644 --- a/docs/__common.soy +++ b/docs/__common.soy
@@ -123,9 +123,15 @@ <li><span class="{css toc_header}">Getting Started</span> <ul> <li><a href="{ROOT}">Overview</a> - <li><a href="{ROOT}setup/quickstart.html">Quick Start</a> + <li><a href="{ROOT}setup/quick_start.html">Quick Start</a> <li><a href="{ROOT}setup/install.html">Downloading and Installing Buck</a> </ul> + <li><span class="{css toc_header}">About</span> + <ul> + <li><a href="{ROOT}concept/what_makes_buck_so_fast.html">What Makes Buck so Fast?</a> + <li><a href="{ROOT}concept/troubleshooting.html">Troubleshooting</a> + <li><a href="{ROOT}concept/faq.html">FAQ</a> + </ul> <li><span class="{css toc_header}">Concepts</span> <ul> <li><a href="{ROOT}concept/build_rule.html">Build Rule</a> @@ -136,8 +142,6 @@ <li><a href="{ROOT}concept/buckconfig.html">.buckconfig</a> <li><a href="{ROOT}concept/build_target_pattern.html">Build Target Pattern</a> <li><a href="{ROOT}concept/visibility.html">Visibility</a> - <li><a href="{ROOT}concept/troubleshooting.html">Troubleshooting</a> - <li><a href="{ROOT}concept/faq.html">FAQ</a> </ul> <li><span class="{css toc_header}">Build Rules</span> <ul> @@ -180,6 +184,8 @@ 'clean', 'install', 'project', + 'query', + 'quickstart', 'targets', 'test', 'uninstall', @@ -413,6 +419,33 @@ {call .ruleLink}{param name : 'project_config' /}{/call} {/template} +/** + * @param name + */ +{template .cmd_link} +<a href="{ROOT}command/{$name}.html"><code>buck {$name}</code></a> +{/template} + +/***/ +{template .cmd_clean} +{call .cmd_link}{param name : 'clean' /}{/call} +{/template} + +/***/ +{template .cmd_project} +{call .cmd_link}{param name : 'project' /}{/call} +{/template} + +/***/ +{template .cmd_quickstart} +{call .cmd_link}{param name : 'quickstart' /}{/call} +{/template} + +/***/ +{template .concept_buckconfig} +<a href="{ROOT}concept/buckconfig.html"><code>.buckconfig</code></a> +{/template} + /***/ {template .visibility_arg} {call buck.arg}
diff --git a/docs/command/query.soy b/docs/command/query.soy new file mode 100644 index 0000000..18beb0f --- /dev/null +++ b/docs/command/query.soy
@@ -0,0 +1,39 @@ +{namespace buck.query} + +/***/ +{template .soyweb} + {call buck.page} + {param title: 'buck query' /} + {param content} + + +{call buck.command} +{param overview} +Queries the build dependency graph. + +<p> + +This can be used to find a path from one dependency to another in the build graph. +The format of the query is <code><em>source</em> -> <em>sink</em></code> as follows: + +<pre>buck query "//apps/myapp:app -> //res/com/example/activity:res"</pre> + +It can also be used to find the set of transitive dependencies for a build rule by omitting the +sink in the query expression. + +<pre>buck query "//apps/myapp:app -> "</pre> + +This can be useful in untangling your dependencies, or for general scripting against +the build graph. + +{/param} + +{param params} +None. +{/param} + +{/call} + + {/param} // content + {/call} // buck.page +{/template}
diff --git a/docs/command/quickstart.soy b/docs/command/quickstart.soy new file mode 100644 index 0000000..41b4056 --- /dev/null +++ b/docs/command/quickstart.soy
@@ -0,0 +1,51 @@ +{namespace buck.quickstart} + +/***/ +{template .soyweb} + {call buck.page} + {param title: 'buck quickstart' /} + {param content} + + +{call buck.command} +{param overview} +Generates a new Android project that can be built with Buck. + +<p> + +Running: + +<pre>buck quickstart</pre> + +will prompt you for the necessary inputs, or you can specify them using the flags below. +See the <a href="{ROOT}setup/quick_start.html">Quick Start</a> instructions for an example +of <code>buck quickstart</code> in action. + +{/param} + +{param params} + +{call buck.param} + {param name: 'dest-dir' /} + {param desc} +The path to the directory where the project should be generated. This can be either +an absolute or a relative path. + {/param} +{/call} + +{call buck.param} + {param name: 'android-sdk' /} + {param desc} +The path to the directory where the Android SDK is installed locally. This can be either +an absolute or a relative path. + {/param} +{/call} + + +{/param} + +{/call} + + {/param} // content + {/call} // buck.page +{/template}
diff --git a/docs/concept/buckconfig.soy b/docs/concept/buckconfig.soy index 80179f5..48cdc9f 100644 --- a/docs/concept/buckconfig.soy +++ b/docs/concept/buckconfig.soy
@@ -24,7 +24,7 @@ <h2>[alias]</h2> -As demonstrated in the <a href="{ROOT}setup/quickstart.html">Quick Start</a>{sp} +As demonstrated in the <a href="{ROOT}setup/quick_start.html">Quick Start</a>{sp} instructions, aliases for build targets can be defined in {sp}<code>.buckconfig</code>:
diff --git a/docs/concept/what_makes_buck_so_fast.soy b/docs/concept/what_makes_buck_so_fast.soy new file mode 100644 index 0000000..22a6ff7 --- /dev/null +++ b/docs/concept/what_makes_buck_so_fast.soy
@@ -0,0 +1,104 @@ +{namespace buck.what_makes_buck_so_fast} + +/***/ +{template .soyweb} + {call buck.page} + {param title: 'What Makes Buck so Fast?' /} + {param content} + +Buck exploits a number of strategies to reduce build times. + +<h2>A build rule knows all of the inputs that can affect its output</h2> + +Buck is designed so that anything that can affect the output of a build rule must be specified +as an input to the build rule: hidden state is not allowed. (This is also important for ensuring that +results are consistent and reproducible for all developers.) Therefore, we can be sure that once a +rule's <code>deps</code> are satisfied, the rule itself can be built. This gives us confidence that +the <a href="http://en.wikipedia.org/wiki/Directed_acyclic_graph">DAG</a> that results from build +rules and their <code>deps</code> is true: all dependencies are captured in the graph. + +<p> + +Having a DAG makes it straightforward for rules to be built in parallel, which can dramatically reduce +build times. The execution model for Buck is very simple: starting with the leaf nodes +of the graph, add them to a queue of rules to be built. When a thread is available, a rule is removed +from the queue, and built. Assuming it is built successfully, it notifies all of the rules that depend +on it that it is done. When a rule gets such a notification, it checks whether all its dependencies have +been satisfied, and if so, it gets added to the queue. Computation proceeds in this manner until all of +the nodes in the graph have gone through the queue. +Therefore, breaking modules into finer dependencies creates opportunities for increased +parallelism, improving throughput. + +<h2>Buck can store the outputs it generates in a cache</h2> + +A build rule knows all of the inputs that can affect its output, and therefore it can combine that +information into a hash that represents the total input. This hash is used as +a <em>cache key</em> where the associated value in the cache is the output produced by the rule. +(See {call buck.concept_buckconfig /} for information on how to set up a cache.) +The following information contributes to the cache key for a build rule: + +<ul> + <li>The values of the arguments used to define the build rule in the build file. + <li>The contents of any file arguments for the build rule. + <li>The version of Buck being used to build the rule. (This means that upgrading Buck to a new + version invalidates all of the cache keys generated by the old version.) + <li>The cache key for each of the rule's <code>deps</code>. +</ul> + +<p> + +When Buck begins to build a build rule, the first thing it does is compute the <em>cache key</em> for +the rule. If there is a hit in any of the caches specified in <code>.buckconfig</code>, then it will +fetch the rule's output from the cache instead of building the rule locally. For outputs that are +expensive to compute, this is a substantial savings. It also makes it fast to rebuild when switching +between branches in a <a href="http://en.wikipedia.org/wiki/Distributed_version_control_system">DVCS</a> such as Git or Mercurial. + +<p> + +Because Buck uses the cache key to determine whether to rebuild a rule, you should never have to run {call buck.cmd_clean /}. +If anything that could affect the output of the rule changes, then the cache key should change, as well. +Because the change in input will cause a cache miss, Buck will rebuild the rule, overwriting its old outputs. +Since out-of-date outputs are guaranteed to be overwritten, there is no reason to clean the build. + +<p> + +If you are using some sort of <a href="http://en.wikipedia.org/wiki/Continuous_integration">continuous +integration (CI)</a> system, you will likely want your CI builds to populate a cache that can be read by your local builds. +That way, when a developer syncs to a revision that has already been built on your CI system, running <code>buck +build</code> should not build anything locally, as all outputs should be able to be pulled from the cache. +This works because the cache key computed by Buck when run on the CI system should match the key computed by Buck +on your local machine. + +<h2>A Java rule computes its ABI when it is built</h2> + +Oftentimes, a developer will modify Java code in a way that does not affect its interface. For example, adding +or removing private methods, as well as modifying the implementation of existing methods (regardless of their visibility), +does not change the <a href="http://en.wikipedia.org/wiki/Application_binary_interface">ABI</a> of a Java file. + +<p> + +When Buck builds a {call buck.java_library /} rule, it also computes its ABI<sup><a href="#footnote-abi">1</a></sup>. +Normally, modifying a private method +in a {call buck.java_library /} would cause it and all rules that depend on it to be rebuilt because the change in +cache keys would propagate up the DAG. However, Buck has special logic for a {call buck.java_library /} where, +if the <code>.java</code> input files have not changed since the previous build, and the ABI for each of its Java +dependencies has not changed since the previous build, then the {call buck.java_library /} will not be recompiled. +This is valid because we know that neither the input <code>.java</code> files nor the ABI against which they +would be compiled has changed, so the result would be the same if the rule were rebuilt. This localizes how much +Java code needs to be recompiled in response to a change, again reducing build times. + +<hr> + +<p> + +<sup id="footnote-abi">1</sup>The ABI computed by Buck is stricter +than <a href="http://docs.oracle.com/javase/specs/jls/se7/html/jls-13.html">what the Java Language Specification (JLS) +uses to define binary compatibility</a>. +In Buck, the ABI defines an equivalence relationship, whereas in the JLS, it does not. This is primarily done +because the ABI is represented as a SHA-1 hash, which is cheap to compare. However, this does mean that adding a +new method to a class results in a new ABI for a {call buck.java_library /} in Buck, which triggers a rebuild in dependent rules. +By comparison, the JLS would consider the old and new versions of the library binary compatible, thereby determining +recompilation of dependent rules unnecessary. + {/param} + {/call} +{/template}
diff --git a/docs/index.soy b/docs/index.soy index 8ca9f34..6bf997e 100644 --- a/docs/index.soy +++ b/docs/index.soy
@@ -3,10 +3,13 @@ /***/ {template .soyweb} {call buck.page} - {param title: 'An Android build tool' /} + {param title: 'An Android (and Java!) build tool' /} {param content} Buck is a build system for Android that encourages the creation of -small, reusable modules consisting of code and resources. +small, reusable modules consisting of code and resources. Because Android +applications are predominantly written in Java, Buck also functions as a +Java build system. <a href="{ROOT}concept/what_makes_buck_so_fast.html">Learn more</a> about +the strategies Buck uses to build Java code so quickly. <h2>Features</h2> @@ -15,8 +18,8 @@ <ul> <li>Speed up your Android builds. Buck builds independent artifacts in parallel to take advantage of multiple cores. Further, it reduces incremental - build times by keeping track of unchanged resources so that the minimal set - of resources is rebuilt. + build times by keeping track of unchanged modules so that the minimal set + of modules is rebuilt. <li>Introduce ad-hoc build steps for building artifacts that are not supported out-of-the-box using the standard Ant build scripts for Android. <li>Keep the logic for generating build rules in the build system instead of @@ -73,7 +76,7 @@ If you build multiple applications, or if even if you ship one application but use several sample applications for development, then Buck is definitely for you. -Give the <a href="{ROOT}setup/quickstart.html">Quick Start</a> a try and see how +Give the <a href="{ROOT}setup/quick_start.html">Quick Start</a> a try and see how Buck can help you organize your Android project and build it faster than ever before. {/param} {/call}
diff --git a/docs/rule/android_binary.soy b/docs/rule/android_binary.soy index fc7605f..be378ea 100644 --- a/docs/rule/android_binary.soy +++ b/docs/rule/android_binary.soy
@@ -48,7 +48,7 @@ A build target that identifies a {call buck.keystore /} to use to sign the APK. - See <a href="{ROOT}setup/quickstart.html">Quick Start</a> for more + See <a href="{ROOT}setup/quick_start.html">Quick Start</a> for more details. {/param} {/call}
diff --git a/docs/setup/quickstart.soy b/docs/setup/manual_quick_start.soy similarity index 98% rename from docs/setup/quickstart.soy rename to docs/setup/manual_quick_start.soy index 92d07ba..94d06a6 100644 --- a/docs/setup/quickstart.soy +++ b/docs/setup/manual_quick_start.soy
@@ -1,10 +1,10 @@ -{namespace buck.quickstart} +{namespace buck.manual_quick_start} /***/ {template .soyweb} {call buck.header} - {param title: 'Quick Start' /} + {param title: 'Manual Quick Start' /} {/call} <div class="{css overview}">
diff --git a/docs/setup/quick_start.soy b/docs/setup/quick_start.soy new file mode 100644 index 0000000..c67bffa --- /dev/null +++ b/docs/setup/quick_start.soy
@@ -0,0 +1,145 @@ +{namespace buck.quick_start} + +/***/ +{template .soyweb} + +{call buck.header} + {param title: 'Quick Start' /} +{/call} + +<div class="{css overview}"> + +{call buck.platformWarning /} + +This is a quick start guide for getting up and running with Buck. +To make it easy to get started, Buck provides a command, {call buck.cmd_quickstart /}, +which creates a simple Android project that is configured to be built with Buck +out of the box. +<p> +If you are uncomfortable using a command to generate a project for you, +then you may want to go through the <a href="manual_quick_start.html">manual quick start guide</a>, +which provides step-by-step instructions for creating your first project. +The contents and purpose of each file needed to bootstrap the project are explained in the guide. + +<h2>Step 1: Install Buck</h2> + +As these are the "Quick Start" instructions, we assume that you already have tools +such as Ant and the Android SDK installed on your machine. If you are not sure, +then you may want to follow the more detailed instructions for installing Buck in{sp} +<a href="install.html">Downloading and Installing Buck</a>. + +<p> + +Run the following commands to checkout Buck from GitHub, build it, and add it to your <code>$PATH</code>: +{call buck.installationInstructions}{param withAlias : true /}{/call} + +While there, you may also want to set up <a href="{ROOT}command/buckd.html"><code>buckd</code></a>: + +<pre>sudo ln -s ${lb}PWD{rb}/bin/buckd /usr/bin/buckd</pre> + +<em>Currently, there is no way to download a precompiled binary for Buck.</em> + +<h2>Step 2: Run "buck quickstart"</h2> + +Now that you have Buck installed on your machine, +let's use it to build a sample Android application. + +<p> + +We should start our project in an empty directory, +so create a new directory, navigate to it, and run: + +{literal}<pre> +buck quickstart +</pre>{/literal} + +You will get prompted for the directory where you would like to create the project, +as well as the location of your Android SDK. Assuming you would like to create the +project in the current directory and your Android SDK is installed +at <code>~/android-sdk-macosx</code>, then you would respond to the prompts as follows: + +<pre> +Enter the directory where you would like to create the project: .<br> +Enter your Android SDK's location: ~/android-sdk-macosx +</pre> + +Alternatively, you could specify these arguments via flags to avoid the prompts: + +<pre> +buck quickstart --dest-dir . --android-sdk ~/android-sdk-macosx +</pre> + +If the command succeeds, then you should see the following output: + +{literal}<pre style="font-size:80%"> +Thanks for installing Buck! + +In this quickstart project, the file apps/myapp/BUCK defines the build rules. + +At this point, you should move into the project directory and try running: + + buck build //apps/myapp:app + +or: + + buck build app + +See .buckconfig for a full list of aliases. + +If you have an Android device connected to your computer, you can also try: + + buck install app + +This information is located in the file README.md if you need to access it +later. +</pre>{/literal} + +<h2>Step 3: Build and Install Your App</h2> + +As explained in the instructions that were printed to the console, you can +run the following to build your application: + +<pre>buck build app</pre> + +Or if you have an Android emulator running or a device connected via a +USB cable (you can verify this by running <code>adb devices</code>), +then you can install and start up the app by running: + +<pre>buck install app</pre> + +The name <code>app</code> is an alias for the <a href="{ROOT}concept/build_target.html">build +target</a> that identifies the <a href="{ROOT}concept/build_rule.html">build +rule</a> that is responsible for building your app. You can change this mapping in the{sp} +<a href="{ROOT}concept/buckconfig.html"><code>.buckconfig</code></a> file that was created in +the root of your project directory. + +<h2>Step 4: Modifying the App</h2> + +Now that you know how to run Buck to build an APK, you are probably interested in modifying +the boilerplate code to build the app of your dreams. Java code goes under the <code>java/</code> directory, +and it is recommended that the directory structure match the package structure, as is the convention in Java. + +<p> + +By comparision, Android resources should go under the <code>res/</code> directory. Just as you can have +multiple Java packages in the <code>java/</code> directory, you are encouraged to declare +multiple {call buck.android_resource /} rules under the <code>res/</code> directory. This makes it easier +to create a mapping between directories of Android resources and the Java code that requires them. + +<p> + +Now you should have everything that you need to get started! You will likely want to come back to +start exploring more of Buck's documentation as your app becomes more complex and you want to leverage +more of the sophisticated features of Buck. + +<p> + +<em>Currently, the IntelliJ project generated by running {call buck.cmd_project /} does not import +cleanly into IntelliJ. We are working to get <a href="http://stackoverflow.com/questions/19326675/how-do-i-fix-or-debug-error-android-packager-app-cannot-create-new-key-or-k"> +answers to our questions</a> to help debug this. + +</div> // close overview + +{call buck.footer /} + +{/template}
diff --git a/docs/setup/quickstart.html b/docs/setup/quickstart.html new file mode 100644 index 0000000..229dd78 --- /dev/null +++ b/docs/setup/quickstart.html
@@ -0,0 +1,7 @@ +<!doctype> +<html> +<head> + <!-- Original file was renamed, so preserve the URL. --> + <meta http-equiv="refresh" content="0; url=quick_start.html"> +</head> +</html>
diff --git a/docs/soy2html.py b/docs/soy2html.py index 079179a..6f7c854 100644 --- a/docs/soy2html.py +++ b/docs/soy2html.py
@@ -50,7 +50,8 @@ copy_to_output_dir(html_file, output_dir, html) elif (file_name.endswith('.css') or file_name.endswith('.js') or - file_name.endswith('.png')): + file_name.endswith('.png') or + file_name.endswith('.html')): # Copy the static resource to output_dir. relative_path = os.path.join(root, file_name) with open(relative_path) as resource_file: