aboutsummaryrefslogtreecommitdiffhomepage
path: root/site/docs/tutorial
diff options
context:
space:
mode:
authorGravatar Damien Martin-Guillerez <dmarting@google.com>2016-07-28 12:47:11 +0000
committerGravatar Damien Martin-Guillerez <dmarting@google.com>2016-07-29 10:09:06 +0000
commit95a54b98368a1c680c14e13d841b14a27aba01ca (patch)
tree4a4f51e0d40ac2231b27054207ff838ef574a4fd /site/docs/tutorial
parentadc2d75bfb4bc7000b69183b6053a8ce6578748e (diff)
*** Reason for rollback *** Breaks design docs links *** Original change description *** Move Bazel docs into versioned directory. * Move all Bazel docs (excluding main page, search page, and blog) into versions/master directory. * Replace all original pages with redirects. * Add Jekyll config with default_version setting to specify the default version to redirect docs to. * Add Jekyll config with version_prefix setting specific to pages under each version directory. * Update layouts to generate links to pages for the same version with the version_prefix. * Update Blaze rel... *** -- MOS_MIGRATED_REVID=128690580
Diffstat (limited to 'site/docs/tutorial')
-rw-r--r--site/docs/tutorial/android-app.md280
-rw-r--r--site/docs/tutorial/app.md45
-rw-r--r--site/docs/tutorial/backend-server.md224
-rw-r--r--site/docs/tutorial/cpp.md360
-rw-r--r--site/docs/tutorial/environment.md91
-rw-r--r--site/docs/tutorial/ios-app.md206
-rw-r--r--site/docs/tutorial/java.md245
-rw-r--r--site/docs/tutorial/review.md29
-rw-r--r--site/docs/tutorial/workspace.md53
9 files changed, 1515 insertions, 18 deletions
diff --git a/site/docs/tutorial/android-app.md b/site/docs/tutorial/android-app.md
index ea52e3ef1d..31e86475cc 100644
--- a/site/docs/tutorial/android-app.md
+++ b/site/docs/tutorial/android-app.md
@@ -1,4 +1,280 @@
---
-layout: redirect
-redirect: docs/tutorial/android-app.html
+layout: documentation
+title: Tutorial - Build an Android App
---
+
+# Tutorial - Build an Android App
+
+The sample Android app in this tutorial is a very simple application that makes
+an HTTP connection to the [backend server](backend-server.md) and displays the
+resulting response.
+
+Here, you'll do the following:
+
+* Review the source files for the app
+* Update the `WORKSPACE` file
+* Create a `BUILD` file
+* Run the build
+* Find the build outputs
+* Run the app
+
+## Review the source files
+
+Let's take a look at the source files for the app. These are located in
+`$WORKSPACE/android/`.
+
+The key files and directories are:
+
+<table class="table table-condensed table-striped">
+<thead>
+<tr>
+<td>Name</td>
+<td>Location</td>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>Manifest file</td>
+<td><code>src/main/java/com/google/bazel/example/android/AndroidManifest.xml</code></td>
+</tr>
+<tr>
+<td>Activity source file</td>
+<td><code>src/main/java/com/google/bazel/example/android/activities/MainActivity.java</code></td>
+</tr>
+<tr>
+<td>Resource file directory</td>
+<td><code>src/main/java/com/google/bazel/example/android/res/</code></td>
+</tr>
+</tbody>
+</table>
+
+Note that you're just looking at these files now to become familiar with the
+structure of the app. You don't have to edit any of the source files to complete
+this tutorial.
+
+## Update the WORKSPACE file
+
+Bazel needs to run the Android SDK
+[build tools](https://developer.android.com/tools/revisions/build-tools.html)
+and uses the SDK libraries to build the app. This means that you need to add
+some information to your `WORKSPACE` file so that Bazel knows where to find
+them. Note that this step is not required when you build for other platforms.
+For example, Bazel automatically detects the location of Java, C++ and
+Objective-C compilers from settings in your environment.
+
+Add the following lines to your `WORKSPACE` file:
+
+```python
+android_sdk_repository(
+ name = "androidsdk",
+ # Replace with path to Android SDK on your system
+ path = "/Users/username/Library/Android/sdk",
+ # Replace with the Android SDK API level
+ api_level = 23,
+ # Replace with the version in sdk/build-tools/
+ build_tools_version="23.0.0"
+)
+```
+
+**Optional:** This is not required by this tutorial, but if you want to compile
+native code into your Android app, you also need to download the
+[Android NDK](https://developer.android.com/ndk/downloads/index.html) and
+tell Bazel where to find it by adding the following rule to your `WORKSPACE`
+file:
+
+```python
+android_ndk_repository(
+ name = "androidndk",
+ # Replace with path to Android NDK on your system
+ path = "/Users/username/Library/Android/ndk",
+ # Replace with the Android NDK API level
+ api_level = 21
+)
+```
+
+`api_level` is the version of the Android API the SDK and the NDK target
+(for example, 19 for Android K and 21 for Android L). It's not necessary to set
+the API levels to the same value for the SDK and NDK.
+[This web page](https://developer.android.com/ndk/guides/stable_apis.html)
+contains a map from Android releases to NDK-supported API levels.
+
+## Create a BUILD file
+
+A [`BUILD` file](/docs/build-ref.html#BUILD_files) is a text file that describes
+the relationship between a set of build outputs -- for example, compiled
+software libraries or executables -- and their dependencies. These dependencies
+may be source files in your workspace or other build outputs. `BUILD` files are
+written in the Bazel *build language*.
+
+`BUILD` files are part of concept in Bazel known as the *package hierarchy*.
+The package hierarchy is a logical structure that overlays the directory
+structure in your workspace. Each [package](/docs/build-ref.html#packages) is a
+directory (and its subdirectories) that contains a related set of source files
+and a `BUILD` file. The package also includes any subdirectories, excluding
+those that contain their own `BUILD` file. The *package name* is the name of the
+directory where the `BUILD` file is located.
+
+Note that this package hierarchy is distinct from, but coexists with, the Java
+package hierarchy for your Android app.
+
+For the simple Android app in this tutorial, we'll consider all the source files
+in `$WORKSPACE/android/` to comprise a single Bazel package. A more complex
+project may have many nested packages.
+
+At a command-line prompt, open your new `BUILD` file for editing:
+
+```bash
+$ vi $WORKSPACE/android/BUILD
+```
+
+### Add an android_library rule
+
+A `BUILD` file contains several different types of instructions for Bazel. The
+most important type is the [build rule](/docs/build-ref.html#funcs), which tells
+Bazel how to build an intermediate or final software output from a set of source
+files or other dependencies.
+
+Bazel provides two build rules, `android_library` and `android_binary`, that you
+can use to build an Android app. For this tutorial, you'll first use the
+[`android_library`](/docs/be/android.html#android_library) rule to tell
+Bazel how to build an
+[Android library module](http://developer.android.com/tools/projects/index.html#LibraryProjects)
+from the app source code and resource files. Then you'll use the
+`android_binary` rule to tell it how to build the Android application package.
+
+Add the following to your `BUILD` file:
+
+```python
+android_library(
+ name = "activities",
+ srcs = glob(["src/main/java/com/google/bazel/example/android/activities/*.java"]),
+ custom_package = "com.google.bazel.example.android.activities",
+ manifest = "src/main/java/com/google/bazel/example/android/activities/AndroidManifest.xml",
+ resource_files = glob(["src/main/java/com/google/bazel/example/android/activities/res/**"]),
+)
+```
+
+As you can see, the `android_library` build rule contains a set of attributes
+that specify the information that Bazel needs to build a library module from the
+source files. Note also that the name of the rule is `activities`. You'll
+reference the rule using this name as a dependency in the `android_binary` rule.
+
+### Add an android_binary rule
+
+The [`android_binary`](/docs/be/android.html#android_binary) rule builds
+the Android application package (`.apk` file) for your app.
+
+Add the following to your build file:
+
+```python
+android_binary(
+ name = "android",
+ custom_package = "com.google.bazel.example.android",
+ manifest = "src/main/java/com/google/bazel/example/android/AndroidManifest.xml",
+ resource_files = glob(["src/main/java/com/google/bazel/example/android/res/**"]),
+ deps = [":activities"],
+)
+```
+
+Here, the `deps` attribute references the output of the `activities` rule you
+added to the `BUILD` file above. This means that, when Bazel builds the output
+of this rule, it checks first to see if the output of the `activities` library
+rule has been built and is up-to-date. If not, it builds it and then uses that
+output to build the application package file.
+
+Now, save and close the file. You can compare your `BUILD` file to the
+[completed example](https://github.com/bazelbuild/examples/blob/master/tutorial/android/BUILD)
+in the `master` branch of the GitHub repo.
+
+## Run the build
+
+You use the
+[`bazel`](/docs/bazel-user-manual.html) command-line tool to run builds, execute
+unit tests and perform other operations in Bazel. This tool is located in the
+`output` subdirectory of the location where you installed Bazel. During
+[installation](/docs/install.md), you probably added this location to your
+path.
+
+Before you build the sample app, make sure that your current working directory
+is inside your Bazel workspace:
+
+```bash
+$ cd $WORKSPACE
+```
+
+Now, enter the following to build the sample app:
+
+```bash
+$ bazel build //android:android
+```
+
+The [`build`](/docs/bazel-user-manual.html#build) subcommand instructs Bazel to
+build the target that follows. The target is specified as the name of a build
+rule inside a `BUILD` file, with along with the package path relative to
+your workspace directory. Note that you can sometimes omit the package path
+or target name, depending on your current working directory at the command
+line and the name of the target. See [Labels](/docs/build-ref.html#labels) in
+*Bazel Concepts and Terminology* page for more information about target labels
+and paths.
+
+Bazel now launches and builds the sample app. During the build process, its
+output will appear similar to the following:
+
+```bash
+INFO: Found 1 target...
+Target //android:android up-to-date:
+ bazel-bin/android/android_deploy.jar
+ bazel-bin/android/android_unsigned.apk
+ bazel-bin/android/android.apk
+INFO: Elapsed time: 7.237s, Critical Path: 5.81s
+```
+
+## Find the build outputs
+
+Bazel stores the outputs of both intermediate and final build operations in
+a set of per-user, per-workspace output directories. These directories are
+symlinked from the following locations:
+
+* `$WORKSPACE/bazel-bin`, which stores binary executables and other runnable
+ build outputs
+* `$WORKSPACE/bazel-genfiles`, which stores intermediary source files that are
+ generated by Bazel rules
+* `$WORKSPACE/bazel-out`, which stores other types of build outputs
+
+Bazel stores the Android `.apk` file generated using the `android_binary` rule
+in the `bazel-bin/android/` directory, where the subdirectory name `android` is
+derived from the name of the Bazel package.
+
+At a command prompt, list the contents of this directory and find the
+`android.apk` file:
+
+```bash
+$ ls $WORKSPACE/bazel-bin/android
+```
+
+## Run the app
+
+You can now deploy the app to a connected Android device or emulator from the
+command line using the
+[`bazel mobile-install`](http://bazel.io/docs/bazel-user-manual.html#mobile-install)
+command. This command uses the Android Debug Bridge (`adb`) to communicate with
+the device. You must set up your device to use `adb` following the instructions
+in
+[Android Debug Bridge](http://developer.android.com/tools/help/adb.html) before
+deployment.
+
+Enter the following:
+
+```bash
+$ bazel mobile-install //android:android
+```
+
+Note that the `mobile-install` subcommand also supports the
+[`--incremental`](http://bazel.io/docs/bazel-user-manual.html#mobile-install)
+flag that can be used to deploy only those parts of the app that have changed
+since the last deployment.
+
+## What's next
+
+Now that you've built a sample app for Android, it's time to do the same for
+the [iOS app](ios-app.md).
diff --git a/site/docs/tutorial/app.md b/site/docs/tutorial/app.md
index d3c2872f6f..fdc33c5f83 100644
--- a/site/docs/tutorial/app.md
+++ b/site/docs/tutorial/app.md
@@ -1,4 +1,45 @@
---
-layout: redirect
-redirect: docs/tutorial/app.html
+layout: documentation
+title: Build Mobile Application
---
+
+# Build Mobile Application
+
+You can use Bazel to build a variety of software outputs, including
+Linux and Mac OS X applications written in Java, C++ and Objective-C. You can
+also use Bazel to build software for other platforms or written in other
+languages.
+
+This tutorial shows how to use Bazel to build the following:
+
+* An Android app
+* An iOS app
+* A mobile backend server running on App Engine
+
+In this tutorial, you'll learn how to:
+
+* Set up a Bazel workspace and create a `WORKSPACE` file
+* Create `BUILD` files that contain the instructions used by Bazel to build
+ the software
+* Run builds using the Bazel command line tool
+
+## Requirements
+
+You can follow the steps in this tutorial on either a Linux or Mac OS X system.
+However, you can only build the iOS app if you are running Bazel on OS X. If
+you are using Linux, you can skip the iOS instructions and still complete
+the rest of the tutorial steps.
+
+## Sample project
+
+You don't have to write your own mobile apps and backend server to use this
+tutorial. Instead, you'll use a sample project hosted on GitHub. The sample
+project is hosted at the following location:
+
+[https://github.com/bazelbuild/examples/](https://github.com/bazelbuild/examples/)
+
+You'll grab the sample project files in the next step in this tutorial.
+
+## What's next
+
+Let's start off by [setting up](environment.md) the tutorial environment.
diff --git a/site/docs/tutorial/backend-server.md b/site/docs/tutorial/backend-server.md
index 150f9152ec..ad668a0d3b 100644
--- a/site/docs/tutorial/backend-server.md
+++ b/site/docs/tutorial/backend-server.md
@@ -1,4 +1,224 @@
---
-layout: redirect
-redirect: docs/tutorial/backend-server.html
+layout: documentation
+title: Tutorial - Build the Backend Server
---
+
+# Tutorial - Build the Backend Server
+
+The backend server is a simple web application that runs on Google App Engine
+and responds to incoming HTTP requests from the sample Android and iOS apps.
+
+Here, you'll do the following:
+
+* Review the source files for the app
+* Update the `WORKSPACE` file
+* Create the `appengine.BUILD` file
+* Create a `BUILD` file
+* Run the build
+* Find the build outputs
+* Deploy to a local development server
+* Deploy to Google App Engine
+
+Bazel provides a set of [App Engine build rules](/docs/be/appengine.html)
+written using the [Skylark](/docs/skylark/index.html) framework. You'll use
+these in the steps below to build the application.
+
+## Review the source files
+
+The source files for the backend server are located in `$WORKSPACE/backend/`.
+
+The key files and directories are:
+
+<table class="table table-condensed table-striped">
+<thead>
+<tr>
+<td>Name</td>
+<td>Location</td>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>Source file directory</td>
+<td><code>src/main/java/com/google/bazel/example/app/</code></td>
+</tr>
+<tr>
+<td>Web application metadata directory</td>
+<td><code>webapp/WEB-INF/</code></td>
+</tr>
+</tbody>
+</table>
+
+## Update the WORKSPACE file
+
+As with the Android app, you must add references to
+[external dependencies](http://bazel.io/docs/external.html) to your `WORKSPACE`
+file. For the backend server, these are references to the App Engine SDK,
+the Java Servlet SDK and other libraries needed to build the App Engine
+applications.
+
+### Add a new\_http\_archive rule
+
+When you built the Android app, you added a reference to the location on your
+filesystem where you downloaded and installed the Android SDK. For the
+backend server, however, you'll give Bazel instructions for downloading the
+required App Engine SDK package from a remote server. This is optional. You
+can also download and install the SDK manually on your filesystem and reference
+it from that location as described in the
+[App Engine rule documentation](/docs/be/appengine.html).
+
+Add the following to your `WORKSPACE` file:
+
+```python
+git_repository(
+ name = "io_bazel_rules_appengine",
+ remote = "https://github.com/bazelbuild/rules_appengine.git",
+ tag = "0.0.2",
+)
+load("@io_bazel_rules_appengine//appengine:appengine.bzl", "appengine_repositories")
+appengine_repositories()
+```
+
+[`git_repository`](/docs/be/workspace.html#git_repository) downloads the
+AppEngine rules from GitHub, then the next two lines use the
+`appengine_repositories` function defined in these rules to download the
+libraries and SDK needed to build AppEngine applications.
+
+Now, save and close the file. You can compare your `WORKSPACE` file to the
+[completed example](https://github.com/bazelbuild/examples//blob/master/tutorial/WORKSPACE)
+in the `master` branch of the GitHub repo.
+
+## Create a BUILD file
+
+Now that you have set up the external dependencies, you can go ahead and create
+the `BUILD` file for the backend server, as you did previously for the sample
+Android and iOS apps.
+
+Open your new `BUILD` file for editing:
+
+```bash
+$ vi $WORKSPACE/backend/BUILD
+```
+
+### Add a java_binary rule
+
+Add the following to your `BUILD` file:
+
+```python
+java_binary(
+ name = "app",
+ srcs = glob(["src/main/java/**/*.java"]),
+ main_class = "does.not.exist",
+ deps = [
+ "@io_bazel_rules_appengine//appengine:javax.servlet.api",
+ ],
+)
+```
+
+The [`java_binary`](/docs/be/java.html#java_binary) tells Bazel
+how to build a Java `.jar` library for your application, plus a wrapper shell
+script that launches the application code from the specified main class. Here,
+we're using this rule instead of the
+[`java_library`](/docs/be/java.html#java_library) because we need
+the `.jar` file to contain all the dependencies required to build the final
+App Engine `.war` file. For this reason, we specify a bogus class name
+for the `main_class` attribute.
+
+### Add an appengine_war rule
+
+Add the following to your `BUILD` file:
+
+```python
+load("@io_bazel_rules_appengine//appengine:appengine.bzl", "appengine_war")
+
+appengine_war(
+ name = "backend",
+ data = [":webapp"],
+ data_path = "/backend/webapp",
+ jars = [":app_deploy.jar"],
+)
+
+filegroup(
+ name = "webapp",
+ srcs = glob(["webapp/**/*"]),
+)
+```
+
+The [`appengine_war`](/docs/be/appengine.html#appengine_war)
+rule builds the final App Engine `war` file from the library `.jar` file and web
+application metadata files in the `webapp` directory.
+
+Save and close the file. Again, the
+[completed example](https://github.com/google/bazel-examples/blob/master/tutorial/backend/BUILD)
+is in the `master` branch of the GitHub repo.
+
+## Run the build
+
+Make sure that your current working directory is inside your Bazel workspace:
+
+```bash
+$ cd $WORKSPACE
+```
+
+Now, enter the following to build the sample app:
+
+```bash
+$ bazel build //backend:backend
+```
+
+Bazel now launches and builds the sample app. During the build process, its
+output will appear similar to the following:
+
+```bash
+INFO: Found 1 target...
+Target //backend:backend up-to-date:
+ bazel-bin/backend/backend.war
+ bazel-bin/backend/backend.deploy
+ bazel-bin/backend/backend
+INFO: Elapsed time: 56.867s, Critical Path: 2.72s
+```
+
+## Find the build outputs
+
+The `.war` file and other outputs are located in the
+`$WORKSPACE/bazel-bin/backend` directory.
+
+## Deploy to a local development server
+
+The `appengine_war` rule generates an upload script that you can use to deploy
+your backend server on Google App Engine. Here, you'll start a local App Engine
+development server in your environment and deploy your application there.
+
+To deploy the application, enter the following:
+
+```bash
+$ bazel-bin/backend/backend --port=12345
+```
+
+Your application URL will be `http://localhost:12345`
+
+## Deploy to Google App Engine
+
+You can also deploy the application to the live App Engine serving
+environment on Google Cloud Platform. For this scenario, you must first create
+a project in the
+[Google Developers Console](https://console.developers.google.com).
+
+To deploy the application, enter the following:
+
+```bash
+$ $WORKSPACE/bazel-bin/backend/backend.deploy <project-id>
+```
+
+The deployment script prompts you to authorize access to Google Cloud Platform.
+After you have authorized access the first time, you can deploy the application
+using the `bazel` command and the following rule target:
+
+```bash
+$ bazel run //backend:backend.deploy <project-id>
+```
+
+Your application URL will be `http://<project-id>.appspot.com`.
+
+## What's next
+
+Now let's [review](review.md) the tutorial steps.
diff --git a/site/docs/tutorial/cpp.md b/site/docs/tutorial/cpp.md
index 6ec737f93d..3d6effbd68 100644
--- a/site/docs/tutorial/cpp.md
+++ b/site/docs/tutorial/cpp.md
@@ -1,4 +1,360 @@
---
-layout: redirect
-redirect: docs/tutorial/cpp.html
+layout: documentation
+title: Build C++
---
+
+Build C++
+=========
+
+You can use Bazel to build your C++ application. In this tutorial you'll learn how to:
+
+* Build your first C++ target
+* Use external libraries
+* Write and run C++ tests
+* Use precompiled libraries
+
+## Setting up your workspace
+
+Suppose that you have an existing project in a directory, say,
+`~/gitroot/my-project/`. Create an empty file at
+`~/gitroot/my-project/WORKSPACE` to show Bazel where your project's root is.
+We are going to create a small hello world project with the following directory structure:
+{% highlight bash %}
+└── my-project
+ ├── lib
+ │   ├── BUILD
+ │   ├── hello-greet.cc
+ │   └── hello-greet.h
+ ├── main
+ │   ├── BUILD
+ │   ├── hello-time.cc
+ │   ├── hello-time.h
+ │   └── hello-world.cc
+ └── WORKSPACE
+{% endhighlight %}
+
+## Creating source files
+
+Using the following commands to create the necessary source files:
+{% highlight bash %}
+$ # If you're not already there, move to your workspace directory.
+$ cd ~/gitroot/my-project
+$ mkdir ./main
+$ cat > main/hello-world.cc <<'EOF'
+#include "lib/hello-greet.h"
+#include "main/hello-time.h"
+#include <iostream>
+#include <string>
+
+int main(int argc, char** argv) {
+ std::string who = "world";
+ if (argc > 1) {
+ who = argv[1];
+ }
+ std::cout << get_greet(who) <<std::endl;
+ print_localtime();
+ return 0;
+}
+EOF
+$ cat > main/hello-time.h <<'EOF'
+#ifndef MAIN_HELLO_TIME_H_
+#define MAIN_HELLO_TIME_H_
+
+void print_localtime();
+
+#endif
+EOF
+$ cat > main/hello-time.cc <<'EOF'
+#include "main/hello-time.h"
+#include <ctime>
+#include <iostream>
+
+void print_localtime() {
+ std::time_t result = std::time(nullptr);
+ std::cout << std::asctime(std::localtime(&result));
+}
+EOF
+$ mkdir ./lib
+$ cat > lib/hello-greet.h <<'EOF'
+#ifndef LIB_HELLO_GREET_H_
+#define LIB_HELLO_GREET_H_
+
+#include <string>
+
+std::string get_greet(const std::string &thing);
+
+#endif
+EOF
+$ cat > lib/hello-greet.cc <<'EOF'
+#include "lib/hello-greet.h"
+#include <string>
+
+std::string get_greet(const std::string& who) {
+ return "Hello " + who;
+}
+EOF
+{% endhighlight %}
+
+## Adding BUILD files
+
+As you can see from the source code, `main/hello-world.cc` needs to include both `lib/hello-greet.h` and `main/hello-time.h`.
+First we create `lib/BUILD` for hello-greet.cc:
+
+{% highlight python %}
+cc_library(
+ name = "hello-greet",
+ srcs = ["hello-greet.cc"],
+ hdrs = ["hello-greet.h"],
+ visibility = ["//main:__pkg__"],
+)
+{% endhighlight %}
+
+Note that `visibility = ["//main:__pkg__"]` indicates `hello-greet` is visible from `main/BUILD`.
+Then we'd create the following `main/BUILD` file:
+
+{% highlight python %}
+cc_library(
+ name = "hello-time",
+ srcs = ["hello-time.cc"],
+ hdrs = ["hello-time.h"],
+)
+
+cc_binary(
+ name = "hello-world",
+ srcs = ["hello-world.cc"],
+ deps = [
+ ":hello-time",
+ "//lib:hello-greet",
+ ],
+)
+{% endhighlight %}
+
+Note when depending on a target in the same package, we can just use `:hello-time`.
+When the target is in other package, a full path from root should be used, like `//lib:hello-greet`.
+
+Now you are ready to build your hello world C++ binary:
+
+{% highlight bash %}
+$ bazel build main:hello-world
+INFO: Found 1 target...
+Target //main:hello-world up-to-date:
+ bazel-bin/main/hello-world
+INFO: Elapsed time: 2.869s, Critical Path: 1.00s
+$ ./bazel-bin/main/hello-world
+Hello world
+Thu Jun 23 18:51:46 2016
+$ ./bazel-bin/main/hello-world Bazel
+Hello Bazel
+Thu Jun 23 18:52:10 2016
+{% endhighlight %}
+
+Congratulations, you've just built your first Bazel target!
+
+## Transitive includes
+
+If a file includes a header, then the file's rule should depend on that header's
+library. Conversely, only direct dependencies need to be specified as
+dependencies. For example, suppose `sandwich.h` includes `bread.h` and
+`bread.h` includes `flour.h`. `sandwich.h` doesn't include `flour.h` (who wants
+flour in their sandwich?), so the BUILD file would look like:
+
+```python
+cc_library(
+ name = "sandwich",
+ srcs = ["sandwich.cc"],
+ hdrs = ["sandwich.h"],
+ deps = [":bread"],
+)
+
+cc_library(
+ name = "bread",
+ srcs = ["bread.cc"],
+ hdrs = ["bread.h"],
+ deps = [":flour"],
+)
+
+cc_library(
+ name = "flour",
+ srcs = ["flour.cc"],
+ hdrs = ["flour.h"],
+)
+```
+
+Here, the `sandwich` library depends on the `bread` library, which depends
+on the `flour` library.
+
+## Adding include paths
+
+Sometimes you cannot (or do not want to) base include paths at the workspace
+root. Existing libraries might already have a include directory that doesn't
+match its path in your workspace. For example, suppose you have the following
+directory structure:
+
+```
+└── my-project
+ ├── third_party
+ │   └── some_lib
+ │   ├── BUILD
+ │   ├── include
+ │   │   └── some_lib.h
+ │   └── some_lib.cc
+ └── WORKSPACE
+```
+
+Bazel will expect `some_lib.h` to be included as
+`third_party/some_lib/include/some_lib.h`, but suppose `some_lib.cc` includes
+`"include/some_lib.h"`. To make that include path valid,
+`third_party/some_lib/BUILD` will need to specify that the `some_lib/`
+directory is an include directory:
+
+```python
+cc_library(
+ name = "some_lib",
+ srcs = ["some_lib.cc"],
+ hdrs = ["some_lib.h"],
+ copts = ["-Ithird_party/some_lib"],
+)
+```
+
+This is especially useful for external dependencies, as their header files
+must otherwise be included with an `external/[repository-name]/` prefix.
+
+## Including external libraries
+
+Suppose you are using [Google Test](https://code.google.com/p/googletest/). You
+can use one of the `new_` repository functions in the `WORKSPACE` file to
+download Google Test and make it available in your repository:
+
+```python
+new_http_archive(
+ name = "gtest",
+ url = "https://googletest.googlecode.com/files/gtest-1.7.0.zip",
+ sha256 = "247ca18dd83f53deb1328be17e4b1be31514cedfc1e3424f672bf11fd7e0d60d",
+ build_file = "gtest.BUILD",
+)
+```
+
+Then create `gtest.BUILD`, a BUILD file to use to compile Google Test.
+Google Test has several "special" requirements that make its `cc_library` rule
+more complicated:
+
+* `gtest-1.7.0/src/gtest-all.cc` `#include`s all of the other files in
+ `gtest-1.7.0/src/`, so we need to exclude it from the compile or we'll get
+ link errors for duplicate symbols.
+* It uses header files that relative to the `gtest-1.7.0/include/` directory
+ (`"gtest/gtest.h"`), so we must add that directory the include paths.
+* It needs to link in pthread, so we add that as a `linkopt`.
+
+The final rule looks like this:
+
+```python
+cc_library(
+ name = "main",
+ srcs = glob(
+ ["gtest-1.7.0/src/*.cc"],
+ exclude = ["gtest-1.7.0/src/gtest-all.cc"]
+ ),
+ hdrs = glob([
+ "gtest-1.7.0/include/**/*.h",
+ "gtest-1.7.0/src/*.h"
+ ]),
+ copts = [
+ "-Iexternal/gtest/gtest-1.7.0/include"
+ ],
+ linkopts = ["-pthread"],
+ visibility = ["//visibility:public"],
+)
+```
+
+This is somewhat messy: everything is prefixed with gtest-1.7.0 as a byproduct
+of the archive's structure. You can make `new_http_archive` strip this prefix by
+adding the `strip_prefix` attribute:
+
+```python
+new_http_archive(
+ name = "gtest",
+ url = "https://googletest.googlecode.com/files/gtest-1.7.0.zip",
+ sha256 = "247ca18dd83f53deb1328be17e4b1be31514cedfc1e3424f672bf11fd7e0d60d",
+ build_file = "gtest.BUILD",
+ strip_prefix = "gtest-1.7.0",
+)
+```
+
+Then `gtest.BUILD` would look like this:
+
+```python
+cc_library(
+ name = "main",
+ srcs = glob(
+ ["src/*.cc"],
+ exclude = ["src/gtest-all.cc"]
+ ),
+ hdrs = glob([
+ "include/**/*.h",
+ "src/*.h"
+ ]),
+ copts = ["-Iexternal/gtest/include"],
+ linkopts = ["-pthread"],
+ visibility = ["//visibility:public"],
+)
+```
+
+Now `cc_` rules can depend on `//external:gtest/main`.
+
+## Writing and running C++ tests
+
+For example, we could create a test `./test/hello-test.cc` such as:
+
+```cpp
+#include "gtest/gtest.h"
+#include "lib/hello-greet.h"
+
+TEST(FactorialTest, Negative) {
+ EXPECT_EQ(get_greet("Bazel"), "Hello Bazel");
+}
+```
+
+Then create `./test/BUILD` file for your tests:
+
+```python
+cc_test(
+ name = "hello-test",
+ srcs = ["hello-test.cc"],
+ copts = ["-Iexternal/gtest/include"],
+ deps = [
+ "@gtest//:main",
+ "//lib:hello-greet",
+ ],
+)
+```
+
+Note in order to make `hello-greet` visible to `hello-test`, we have to add `"//test:__pkg__",` to `visibility` attribute in `./lib/BUILD`.
+
+Now you can use `bazel test` to run the test.
+
+{% highlight bash %}
+$ bazel test test:hello-test
+INFO: Found 1 test target...
+Target //test:hello-test up-to-date:
+ bazel-bin/test/hello-test
+INFO: Elapsed time: 4.497s, Critical Path: 2.53s
+//test:hello-test PASSED in 0.3s
+
+Executed 1 out of 1 tests: 1 test passes.
+{% endhighlight %}
+
+
+## Adding dependencies on precompiled libraries
+
+If you want to use a library that you only have a compiled version of (e.g.,
+headers and a .so) wrap it in a `cc_library` rule:
+
+```python
+cc_library(
+ name = "mylib",
+ srcs = ["mylib.so"],
+ hdrs = ["mylib.h"],
+)
+```
+
+Then other C++ targets in your workspace can depend on this rule.
diff --git a/site/docs/tutorial/environment.md b/site/docs/tutorial/environment.md
index 8ce35d68a2..219060de7c 100644
--- a/site/docs/tutorial/environment.md
+++ b/site/docs/tutorial/environment.md
@@ -1,4 +1,91 @@
---
-layout: redirect
-redirect: docs/tutorial/environment.html
+layout: documentation
+title: Tutorial - Set Up Your Environment
---
+
+# Tutorial - Set Up Your Environment
+
+The first step in this tutorial is to set up your environment.
+
+Here, you'll do the following:
+
+* Install Bazel
+* Install Android Studio and the Android SDK
+* Install Xcode (OS X only)
+* Get the sample project from the GitHub repo
+
+## Install Bazel
+
+Follow the [installation instructions](/docs/install.md) to install Bazel and
+its dependencies.
+
+## Install the Android SDK tools
+
+Do the following:
+
+1. Download and install the
+ [Android SDK Tools](https://developer.android.com/sdk/index.html#Other).
+
+2. Run the Android SDK Manager and install the following packages:
+
+ <table class="table table-condensed table-striped">
+ <thead>
+ <tr>
+ <td>Package</td>
+ <td>SDK directory</td>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>Android SDK Platform Tools</td>
+ <td><code>platform-tools</code></td>
+ </tr>
+ <tr>
+ <td>Android SDK Build Tools</td>
+ <td><code>build-tools</code></td>
+ </tr>
+ <tr>
+ <td>Android SDK Platform</td>
+ <td><code>platform</code></td>
+ </tr>
+ </tbody>
+ </table>
+
+ The SDK Manager is an executable named `android` located in the `tools`
+ directory.
+
+## Install Xcode (OS X only)
+
+If you are following the steps in this tutorial on Mac OS X, download and
+install [Xcode](https://developer.apple.com/xcode/downloads/). The Xcode
+download contains the iOS libraries, Objective-C compiler other tools
+required by Bazel to build the iOS app.
+
+## Get the sample project
+
+You also need to get the sample project for the tutorial from GitHub:
+
+[https://github.com/bazelbuild/examples/](https://github.com/bazelbuild/examples/)
+
+The GitHub repo has two branches: `source-only` and `master`. The `source-only`
+branch contains the source files for the project only. You'll use the files in
+this branch in this tutorial. The `master` branch contains both the source files
+and completed Bazel `WORKSPACE` and `BUILD` files. You can use the files in this
+branch to check your work when you've completed the tutorial steps.
+
+Enter the following at the command line to get the files in the `source-only`
+branch:
+
+```bash
+$ cd $HOME
+$ git clone -b source-only https://github.com/bazelbuild/examples
+```
+
+The `git clone` command creates a directory named `$HOME/examples/`. This
+directory contains several sample projects for Bazel. The project files for this
+tutorial are in `$HOME/examples/tutorial`.
+
+## What's next
+
+Now that you have set up your environment, you can
+[set up a Bazel workspace](workspace.md).
diff --git a/site/docs/tutorial/ios-app.md b/site/docs/tutorial/ios-app.md
index e77b36907e..51774e9312 100644
--- a/site/docs/tutorial/ios-app.md
+++ b/site/docs/tutorial/ios-app.md
@@ -1,4 +1,206 @@
---
-layout: redirect
-redirect: docs/tutorial/ios-app.html
+layout: documentation
+title: Tutorial - Build an iOS App
---
+
+# Tutorial - Build an iOS App
+
+Like the [Android app](android-app.md) you built in the previous step, the iOS
+app is a simple mobile app that communicates with the
+[backend server](backend-server.md).
+
+Here, you'll do the following:
+
+* Review the source files for the app
+* Create a `BUILD` file
+* Build the app for the simulator
+* Find the build outputs
+* Run/Debug the app on the simulator
+* Build the app for a device
+* Install the app on a device
+
+Note that, unlike with the Android app, you don't have to modify your
+`WORKSPACE` file to add iOS-specific external dependencies.
+
+If you're following the steps in this tutorial on Mac OS X, you can go ahead
+and build the sample iOS app as described below. If you are on Linux, skip ahead
+to the [next step](backend-server.md).
+
+## Review the source files
+
+Let's take a look at the source files for the app. These are located in
+`$WORKSPACE/ios-app/UrlGet`. Again, you're just looking at these files now to
+become familiar with the structure of the app. You don't have to edit any of the
+source files to complete this tutorial.
+
+## Create a BUILD file
+
+At a command-line prompt, open your new `BUILD` file for editing:
+
+```bash
+$ vi $WORKSPACE/ios-app/BUILD
+```
+
+## Add an objc_library rule
+
+Bazel provides several build rules that you can use to build an app for the
+iOS platform. For this tutorial, you'll first use the
+[`objc_library`](/docs/be/objective-c.html#objc_library) rule to tell Bazel
+how to build an
+[static library](https://developer.apple.com/library/ios/technotes/iOSStaticLibraries/Introduction.html)
+from the app source code and Xib files. Then you'll use the
+`objc_binary` rule to tell it how to bundle the iOS application. (Note that
+this is a minimal use case of the Objective-C rules in Bazel. For example, you
+have to use the `ios_application` rule to build multi-architecture iOS
+apps.)
+
+Add the following to your `BUILD` file:
+
+```python
+objc_library(
+ name = "UrlGetClasses",
+ srcs = [
+ "UrlGet/AppDelegate.m",
+ "UrlGet/UrlGetViewController.m",
+ ],
+ hdrs = glob(["UrlGet/*.h"]),
+ xibs = ["UrlGet/UrlGetViewController.xib"],
+)
+```
+
+Note the name of the rule, `UrlGetClasses`.
+
+## Add an objc_binary rule
+
+The [`objc_binary`](/docs/be/objective-c.html#objc_binary) rule creates a
+binary to be bundled in the application.
+
+Add the following to your `BUILD` file:
+
+```python
+objc_binary(
+ name = "ios-app-binary",
+ srcs = [
+ "UrlGet/main.m",
+ ],
+ deps = [
+ ":UrlGetClasses",
+ ],
+)
+
+```
+Note how the `deps` attribute references the output of the
+`UrlGetClasses` rule you added to the `BUILD` file above.
+
+## Add an ios_application rule
+
+The [`ios_application`](/docs/be/objective-c.html#ios_application) rule
+creates the bundled `.ipa` archive file for the application and also generates
+an Xcode project file.
+
+Add the following to your `BUILD` file:
+
+```python
+ios_application(
+ name = "ios-app",
+ binary = ":ios-app-binary",
+ infoplist = "UrlGet/UrlGet-Info.plist",
+)
+```
+
+Now, save and close the file. You can compare your `BUILD` file to the
+[completed example](https://github.com/bazelbuild/examples/blob/master/tutorial/ios-app/BUILD)
+in the `master` branch of the GitHub repo.
+
+## Build the app for the simulator
+
+Make sure that your current working directory is inside your Bazel workspace:
+
+```bash
+$ cd $WORKSPACE
+```
+
+Now, enter the following to build the sample app:
+
+```bash
+$ bazel build //ios-app:ios-app
+```
+
+Bazel now launches and builds the sample app. During the build process, its
+output will appear similar to the following:
+
+```bash
+INFO: Found 1 target...
+Target //ios-app:ios-app up-to-date:
+ bazel-bin/ios-app/ios-app.ipa
+ bazel-bin/ios-app/ios-app.xcodeproj/project.pbxproj
+INFO: Elapsed time: 3.765s, Critical Path: 3.44s
+```
+
+## Find the build outputs
+
+The `.ipa` file and other outputs are located in the
+`$WORKSPACE/bazel-bin/ios-app` directory.
+
+## Run/Debug the app on the simulator
+
+You can now run the app from Xcode using the iOS Simulator. To run the app,
+open the project directory `$WORKSPACE/bazel-bin/ios-app/ios-app.xcodeproj` in
+Xcode, choose an iOS Simulator as the runtime scheme and then click the **Run**
+button.
+
+**Note:** If you change anything about the project file set in Xcode (for
+example, if you add or remove a file, or add or change a dependency), you must
+rebuild the app using Bazel and then re-open the project.
+
+## Build the app for a device
+
+You need to set up bazel so that it can find the appropriate provisioning
+profile for the device you want to build for. To set up the "default"
+provisioning profile for all bazel builds:
+
+ 1. Go to [Apple Profiles](https://developer.apple.com/account/ios/profile/profileList.action)
+ and download the appropriate provisioning profile for your device.
+ If this is confusing, please refer to [Apple's documentation](https://developer.apple.com/library/ios/documentation/IDEs/Conceptual/AppDistributionGuide/MaintainingProfiles/MaintainingProfiles.html).
+ 1. Move your profile into `$WORKSPACE/tools/objc`.
+ 1. Optional - You may want to add your profile to your `.gitignore`.
+ 1. Edit `$WORKSPACE/tools/objc/BUILD` and add:
+
+ ```python
+ filegroup(
+ name = "default_provisioning_profile",
+ srcs = ["<NAME OF YOUR PROFILE>.mobileprovision"],
+ )
+ ```
+
+Now you should be able to build the app for your device:
+
+```bash
+$ bazel build //ios-app:ios-app --ios_multi_cpus=armv7,arm64
+```
+
+This will build the app "fat". If you would prefer just to build for
+your specific device architecture you can designate a single architecture.
+
+If you would like to select a specific Xcode version/SDK version you can do so
+with the `--xcode_version=7.2 --ios_sdk_version=9.2` options. Make sure that
+the Xcode version that you select has the appropriate SDK installed in it.
+
+If you would like to specify a minimum version of iOS to run against, you can
+do so with the `--ios_minimum_os=7.0` option.
+
+## Install the app on a device
+
+The easiest way to install the app on the device is to launch Xcode and use the
+`Windows > Devices` command. Select your plugged in device from the list on the
+left, and then add the app by clicking on the "plus" sign under installed apps
+and selecting the `.ipa` that you built.
+
+If your app does not launch, please make sure that your device was on your
+provisioning profile. The `View Device Logs` button on the `Devices` screen in
+Xcode may provide other information as to what has gone wrong.
+
+## What's next
+
+The next step is to build a [backend server](backend-server.md) for the two
+mobile apps you built in this tutorial.
diff --git a/site/docs/tutorial/java.md b/site/docs/tutorial/java.md
index aeeac5483a..ce916667e1 100644
--- a/site/docs/tutorial/java.md
+++ b/site/docs/tutorial/java.md
@@ -1,4 +1,245 @@
---
-layout: redirect
-redirect: docs/tutorial/java.html
+layout: documentation
+title: Build Java
---
+
+Build Java
+==========
+
+You can use Bazel to build your Java application. In this tutorial you'll learn how to:
+
+* Build your first Java target
+* Add dependencies to your target
+* Use multiple packages
+* Deploy your target
+
+## Setting up your workspace
+
+Suppose that you have an existing project in a directory, say,
+`~/gitroot/my-project/`. Create an empty file at
+`~/gitroot/my-project/WORKSPACE` to show Bazel where your project's root is.
+
+## Creating Your Own Build File
+
+Use the following commands to make a small Java project for this example:
+
+{% highlight bash %}
+$ # If you're not already there, move to your workspace directory.
+$ cd ~/gitroot/my-project
+$ mkdir -p src/main/java/com/example
+$ cat > src/main/java/com/example/ProjectRunner.java <<'EOF'
+package com.example;
+
+public class ProjectRunner {
+ public static void main(String args[]) {
+ Greeting.sayHi();
+ }
+}
+EOF
+$ cat > src/main/java/com/example/Greeting.java <<'EOF'
+package com.example;
+
+public class Greeting {
+ public static void sayHi() {
+ System.out.println("Hi!");
+ }
+}
+EOF
+{% endhighlight %}
+
+Bazel figures out what to build by looking for files named `BUILD` in your
+workspace, so we'll create a `BUILD` file in the `~/gitroot/my-project`
+directory. Add the following lines to this BUILD file:
+
+{% highlight python %}
+# ~/gitroot/my-project/BUILD
+java_binary(
+ name = "my-runner",
+ srcs = glob(["**/*.java"]),
+ main_class = "com.example.ProjectRunner",
+)
+{% endhighlight %}
+
+`java_binary` is the type of thing this rule will build.
+`glob(["**/*.java"])` is a handy shorthand for "recursively include every file
+that ends with .java" (see the
+[build encyclopedia](be/functions.html#glob) for more information about
+globbing). `com.example.ProjectRunner` specifies the class that contains the
+main method.
+
+Now you are ready to build your Java binary:
+
+{% highlight bash %}
+$ cd ~/gitroot/my-project
+$ bazel build //:my-runner
+INFO: Found 1 target...
+Target //:my-runner up-to-date:
+ bazel-bin/my-runner.jar
+ bazel-bin/my-runner
+INFO: Elapsed time: 1.021s, Critical Path: 0.83s
+$ bazel-bin/my-runner
+Hi!
+{% endhighlight %}
+
+Congratulations, you've just built your first Bazel target!
+
+## Adding Dependencies
+
+Creating one rule to build your entire project may be sufficient for small
+projects, but as projects get larger it's important to break up the build into
+self-contained libraries that can be assembled into a final product. This way
+the entire world doesn't need to be rebuilt on small changes and Bazel can
+parallelize more of the build steps.
+
+To break up a project, create separate rules for each subcomponent and then
+make them depend on each other. For the example above, add the following rules
+to the `BUILD` file:
+
+{% highlight python %}
+java_binary(
+ name = "my-other-runner",
+ srcs = ["src/main/java/com/example/ProjectRunner.java"],
+ main_class = "com.example.ProjectRunner",
+ deps = [":greeter"],
+)
+
+java_library(
+ name = "greeter",
+ srcs = ["src/main/java/com/example/Greeting.java"],
+)
+{% endhighlight %}
+
+This builds the same files as before, but in a different way: now Bazel will
+build the `greeter` library first and then build `my-other-runner`. Try building
+and running `//:my-other-runner`:
+
+{% highlight bash %}
+$ bazel run //:my-other-runner
+INFO: Found 1 target...
+Target //:my-other-runner up-to-date:
+ bazel-bin/my-other-runner.jar
+ bazel-bin/my-other-runner
+INFO: Elapsed time: 2.454s, Critical Path: 1.58s
+
+INFO: Running command line: bazel-bin/my-other-runner
+Hi!
+{% endhighlight %}
+
+Now if you edit `ProjectRunner.java` and rebuild `my-other-runner`,
+`Greeting.java` will not need to be recompiled.
+
+## Using Multiple Packages
+
+For larger projects, you will often be dealing with several directories. You
+can refer to targets defined in other BUILD files using the syntax
+`//path/to/directory:target-name`. For example, suppose
+`src/main/java/com/example/` has a `cmdline/` subdirectory with the following
+file:
+
+{% highlight bash %}
+$ mkdir -p src/main/java/com/example/cmdline
+$ cat > src/main/java/com/example/cmdline/Runner.java <<'EOF'
+package com.example.cmdline;
+
+import com.example.Greeting;
+
+public class Runner {
+ public static void main(String args[]) {
+ Greeting.sayHi();
+ }
+}
+EOF
+{% endhighlight %}
+
+`Runner.java` depends on `com.example.Greeting`, so we could add a `BUILD` file
+at `src/main/java/com/example/cmdline/BUILD` that contained the following rule:
+
+{% highlight python %}
+# ~/gitroot/my-project/src/main/java/com/example/cmdline/BUILD
+java_binary(
+ name = "runner",
+ srcs = ["Runner.java"],
+ main_class = "com.example.cmdline.Runner",
+ deps = ["//:greeter"]
+)
+{% endhighlight %}
+
+However, by default, build rules are _private_. This means that they can only be
+referred to by rules in the same BUILD file. This prevents libraries that are
+implementation details from leaking into public APIs, but it also means that you
+must explicitly allow `runner` to depend on `//:greeter`. As is, if we
+build `runner` we'll get a permissions error:
+
+{% highlight bash %}
+$ bazel build //src/main/java/com/example/cmdline:runner
+ERROR: /home/user/gitroot/my-project/src/main/java/com/example/cmdline/BUILD:2:1:
+ Target '//:greeter' is not visible from target '//src/main/java/com/example/cmdline:runner'.
+ Check the visibility declaration of the former target if you think the dependency is legitimate.
+ERROR: Analysis of target '//src/main/java/com/example/cmdline:runner' failed; build aborted.
+INFO: Elapsed time: 0.091s
+{% endhighlight %}
+
+You can make a rule visible to rules in other BUILD files by adding a
+`visibility = level` attribute. Change the `greeter` rule in
+`~/gitroot/my-project/BUILD` to be visible to our new rule:
+
+{% highlight python %}
+java_library(
+ name = "greeter",
+ srcs = ["src/main/java/com/example/Greeting.java"],
+ visibility = ["//src/main/java/com/example/cmdline:__pkg__"],
+)
+{% endhighlight %}
+
+This makes `//:greeter` visible to any rule in the
+`//src/main/java/com/example/cmdline` package. Now we can build and
+run the `runner` binary:
+
+{% highlight bash %}
+$ bazel run //src/main/java/com/example/cmdline:runner
+INFO: Found 1 target...
+Target //src/main/java/com/example/cmdline:runner up-to-date:
+ bazel-bin/src/main/java/com/example/cmdline/runner.jar
+ bazel-bin/src/main/java/com/example/cmdline/runner
+INFO: Elapsed time: 1.576s, Critical Path: 0.81s
+
+INFO: Running command line: bazel-bin/src/main/java/com/example/cmdline/runner
+Hi!
+{% endhighlight %}
+
+See the [build encyclopedia](be/common-definitions.html#common.visibility) for more
+visibility options.
+
+## Deploying
+
+If you look at the contents of
+_bazel-bin/src/main/java/com/example/cmdline/runner.jar_, you can see that it
+only contains `Runner.class`, not its dependencies (`Greeting.class`):
+
+{% highlight bash %}
+$ jar tf bazel-bin/src/main/java/com/example/cmdline/runner.jar
+META-INF/
+META-INF/MANIFEST.MF
+com/
+com/example/
+com/example/cmdline/
+com/example/cmdline/Runner.class
+{% endhighlight %}
+
+This works for running locally (the `runner` script Bazel generates adds the
+greeter jar to the classpath) but will not work if we want to copy `runner.jar`
+to another machine and use it as a standalone binary. To build a self-contained
+jar that can be deployed, build `runner_deploy.jar` (or, more generally,
+`<target-name>_deploy.jar`):
+
+{% highlight bash %}
+$ bazel build //src/main/java/com/example/cmdline:runner_deploy.jar
+INFO: Found 1 target...
+Target //src/main/java/com/example/cmdline:runner_deploy.jar up-to-date:
+ bazel-bin/src/main/java/com/example/cmdline/runner_deploy.jar
+INFO: Elapsed time: 1.700s, Critical Path: 0.23s
+{% endhighlight %}
+
+`runner_deploy.jar` will contain all of its dependencies.
+
+
diff --git a/site/docs/tutorial/review.md b/site/docs/tutorial/review.md
index 16557f7527..62d4501ad4 100644
--- a/site/docs/tutorial/review.md
+++ b/site/docs/tutorial/review.md
@@ -1,4 +1,29 @@
---
-layout: redirect
-redirect: docs/tutorial/review.html
+layout: documentation
+title: Tutorial - Review
---
+
+# Tutorial - Review
+
+In this tutorial, you used Bazel to build an [Android app](android-app.md),
+an [iOS app](ios-app.md) and a [backend server](backend-server.md) that runs on
+Google App Engine.
+
+To build these software outputs, you:
+
+* Set up a Bazel [workspace](workspace.md) that contained the source code
+ for the components and a `WORKSPACE` that identifies the top level of the
+ workspace directory
+* Created a `BUILD` file for each component
+* Updated the `WORKSPACE` file to contain references to the required
+ external dependencies
+* Ran Bazel to build the software components
+
+The built mobile apps and backend server application files are located in the
+`$WORKSPACE/bazel-bin` directory.
+
+Note that completed `WORKSPACE` and `BUILD` files for this tutorial are located
+in the
+[master branch](https://github.com/bazelbuild/examples/tree/master/tutorial)
+of the GitHub repo. You can compare your work to the completed files for
+additional help or troubleshooting.
diff --git a/site/docs/tutorial/workspace.md b/site/docs/tutorial/workspace.md
index 76a2a7cd14..ff3f6da510 100644
--- a/site/docs/tutorial/workspace.md
+++ b/site/docs/tutorial/workspace.md
@@ -1,4 +1,53 @@
---
-layout: redirect
-redirect: docs/tutorial/workspace.html
+layout: documentation
+title: Tutorial - Set Up a Workspace
---
+
+# Tutorial - Set Up a Workspace
+
+A [workspace](/docs/build-ref.html#workspaces) is a directory that contains the
+source files for one or more software projects, as well as a `WORKSPACE` file
+and `BUILD` files that contain the instructions that Bazel uses to build
+the software. It also contains symbolic links to output directories in the
+Bazel home directory.
+
+A workspace directory can be located anywhere on your filesystem. In this
+tutorial, your workspace directory is `$HOME/examples/tutorial/`, which
+contains the sample project files you cloned from the GitHub repo in the
+previous step.
+
+Note that Bazel itself doesn't make any requirements about how you organize
+source files in your workspace. The sample source files in this tutorial are
+organized according to common conventions for Android apps, iOS apps and App
+Engine applications.
+
+For your convenience, set the `$WORKSPACE` environment variable now to refer to
+your workspace directory. At the command line, enter:
+
+```bash
+$ export WORKSPACE=$HOME/examples/tutorial
+```
+
+## Create a WORKSPACE file
+
+Every workspace must have a text file named `WORKSPACE` located in the top-level
+workspace directory. This file may be empty or it may contain references
+to [external dependencies](/docs/external.html) required to build the
+software.
+
+For now, you'll create an empty `WORKSPACE` file, which simply serves to
+identify the workspace directory. In later steps, you'll update the file to add
+external dependency information.
+
+Enter the following at the command line:
+
+```bash
+$ touch $WORKSPACE/WORKSPACE
+```
+
+This creates the empty `WORKSPACE` file.
+
+## What's next
+
+Now that you've set up your workspace, you can
+[build the Android app](android-app.md).