Pull in native_client and build tests.

NaCl has not been added to the default developer workflow, yet.  You must point
your .gclient file at DEPS.nacl and pass --nacl to mojob.py.

BUG=https://code.google.com/p/chromium/issues/detail?id=401761
R=jamesr@chromium.org

Review URL: https://codereview.chromium.org/840653003
diff --git a/.gitignore b/.gitignore
index 17cec23..41c17be 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,6 +22,7 @@
 /c
 /dart/
 /mojo/public/tools/prebuilt/
+/native_client/
 /out/
 /out_*/
 /sdch/open-vcdiff/
diff --git a/DEPS.nacl b/DEPS.nacl
new file mode 100644
index 0000000..37dc80d
--- /dev/null
+++ b/DEPS.nacl
@@ -0,0 +1,29 @@
+import gclient_utils
+import os
+
+path = gclient_utils.FindGclientRoot(os.getcwd())
+execfile(os.path.join(path, 'src', 'DEPS'))  # Include proper Mojo DEPS.
+
+# Now we need to add in NaCl.
+
+vars.update({
+  'nacl_revision': 'c71d65ffcb0e7a1f35eacfd37c327ca5edfa647e', # from svn revision r14268
+})
+
+deps.update({
+  'src/native_client':
+    Var('chromium_git') + '/native_client/src/native_client.git' + '@' + Var('nacl_revision'),
+})
+
+hooks.append({
+  # This downloads binaries for Native Client's newlib toolchain.
+  # Done in lieu of building the toolchain from scratch as it can take
+  # anywhere from 30 minutes to 4 hours depending on platform to build.
+  'name': 'nacltools',
+  'pattern': '.',
+  'action': [
+      'python', 'src/build/download_nacl_toolchains.py',
+      '--packages', 'pnacl_newlib',
+      'sync', '--extract',
+  ],
+})
diff --git a/mojo/BUILD.gn b/mojo/BUILD.gn
index ab86729..2299f4f 100644
--- a/mojo/BUILD.gn
+++ b/mojo/BUILD.gn
@@ -11,6 +11,7 @@
   testonly = true
   declare_args() {
     mojo_use_go = false
+    mojo_use_nacl = false
   }
   deps = [
     ":tests",
@@ -34,6 +35,13 @@
   if (is_linux) {
     deps += [ "//mojo/python" ]
   }
+
+  if (mojo_use_nacl) {
+    deps += [
+      "//mojo/nacl:mojo_nacl",
+      "//mojo/nacl:mojo_nacl_tests",
+    ]
+  }
 }
 
 group("tests") {
diff --git a/mojo/nacl/BUILD.gn b/mojo/nacl/BUILD.gn
new file mode 100644
index 0000000..4315245
--- /dev/null
+++ b/mojo/nacl/BUILD.gn
@@ -0,0 +1,103 @@
+# All toolchains use the same generated code.
+gen_dir = "$root_build_dir/gen/mojo/nacl"
+
+# Only allow the generator to be run by one toolchain.
+if (current_toolchain == default_toolchain) {
+  # Generate the code to plumb the Mojo public API into the NaCl sandbox.
+  action("mojo_nacl_codegen") {
+    script = "generator/generate_nacl_bindings.py"
+    args = [
+      "-d",
+      rebase_path(gen_dir, root_build_dir),
+    ]
+    inputs = [
+      script,
+      "generator/interface.py",
+      "generator/interface_dsl.py",
+      "generator/mojo_syscall.cc.tmpl",
+      "generator/libmojo.cc.tmpl",
+    ]
+    outputs = [
+      "$gen_dir/mojo_syscall.cc",
+      "$gen_dir/libmojo.cc",
+    ]
+  }
+}
+
+# Trusted code
+if (!is_nacl) {
+  # A library for launching a NaCl sandbox connected to a Mojo embedder.
+  static_library("monacl_sel") {
+    sources = [
+      "mojo_syscall_internal.h",
+      "$gen_dir/mojo_syscall.cc",
+      "monacl_sel_main.cc",
+    ]
+    deps = [
+      # This target makes sure we have all the pre-processor defines needed to
+      # use NaCl's headers.
+      "//native_client/build/config/nacl:nacl_base",
+      "//native_client/src/trusted/desc:nrd_xfer",
+      "//native_client/src/trusted/service_runtime:sel_main_chrome",
+      ":mojo_nacl_codegen($default_toolchain)",
+    ]
+  }
+
+  # A simple shell for running untrusted binaries that talk to the Mojo
+  # embedder. (No services.)
+  executable("monacl_shell") {
+    testonly = true
+    sources = [
+      "monacl_shell.cc",
+    ]
+    deps = [
+      "//base:base",
+      "//mojo/edk/system:system",
+      ":monacl_sel",
+    ]
+  }
+}
+
+# Untrusted code
+if (is_nacl) {
+  # Thunk mapping the Mojo public API onto NaCl syscalls.
+  static_library("mojo") {
+    sources = [
+      "$gen_dir/libmojo.cc",
+    ]
+    deps = [
+      ":mojo_nacl_codegen($default_toolchain)",
+    ]
+  }
+
+  # Unit test for the Mojo public API.
+  executable("monacl_test") {
+    testonly = true
+    sources = [
+      "//mojo/public/cpp/system/tests/core_unittest.cc",
+      "//mojo/public/cpp/system/tests/macros_unittest.cc",
+    ]
+    deps = [
+      "//native_client/src/untrusted/nacl:imc_syscalls",
+      "//mojo/public/c/system/tests:tests",
+      "//mojo/public/cpp/system:system",
+      "//testing/gtest:gtest",
+      "//testing/gtest:gtest_main",
+      ":mojo",
+    ]
+  }
+}
+
+group("mojo_nacl") {
+  deps = [
+    "//native_client/src/untrusted/irt:irt_core(//native_client/build/toolchain/nacl:irt_${cpu_arch})",
+  ]
+}
+
+group("mojo_nacl_tests") {
+  testonly = true
+  deps = [
+    ":monacl_shell",
+    ":monacl_test(//native_client/build/toolchain/nacl:clang_newlib_${cpu_arch})",
+  ]
+}
diff --git a/mojo/tools/mojob.py b/mojo/tools/mojob.py
index 9419ce5..ff1cb28 100755
--- a/mojo/tools/mojob.py
+++ b/mojo/tools/mojob.py
@@ -52,6 +52,9 @@
   if 'with_dart' in args:
     additional_args['with_dart'] = args.with_dart
 
+  if 'nacl' in args:
+    additional_args['use_nacl'] = args.nacl
+
   if 'dry_run' in args:
     additional_args['dry_run'] = args.dry_run
 
@@ -100,6 +103,9 @@
   if config.values['with_dart']:
     gn_args.append('mojo_use_dart=true')
 
+  if config.values['use_nacl']:
+    gn_args.append('mojo_use_nacl=true')
+
   if config.target_os == Config.OS_ANDROID:
     gn_args.append(r'''os=\"android\" cpu_arch=\"arm\"''')
   elif config.target_os == Config.OS_CHROMEOS:
@@ -216,6 +222,7 @@
   gn_parser.set_defaults(func=gn)
   gn_parser.add_argument('--with-dart', help='Configure the Dart bindings',
                          action='store_true')
+  gn_parser.add_argument('--nacl', help='Add in NaCl', action='store_true')
   clang_group = gn_parser.add_mutually_exclusive_group()
   clang_group.add_argument('--clang', help='Use Clang (default)', default=None,
                            action='store_true')