diff --git a/ui/build/Android.bp b/ui/build/Android.bp
index 8f5250b..25520da 100644
--- a/ui/build/Android.bp
+++ b/ui/build/Android.bp
@@ -30,6 +30,7 @@
         "kati.go",
         "make.go",
         "ninja.go",
+        "proc_sync.go",
         "signal.go",
         "soong.go",
         "util.go",
@@ -37,6 +38,7 @@
     testSrcs: [
         "environment_test.go",
         "util_test.go",
+        "proc_sync_test.go",
     ],
     darwin: {
         srcs: [
diff --git a/ui/build/build.go b/ui/build/build.go
index 51dce05..83dbcb6 100644
--- a/ui/build/build.go
+++ b/ui/build/build.go
@@ -117,6 +117,10 @@
 	// Start getting java version as early as possible
 	getJavaVersions(ctx, config)
 
+	// Make sure that no other Soong process is running with the same output directory
+	buildLock := BecomeSingletonOrFail(ctx, config)
+	defer buildLock.Unlock()
+
 	SetupOutDir(ctx, config)
 
 	checkCaseSensitivity(ctx, config)
diff --git a/ui/build/proc_sync.go b/ui/build/proc_sync.go
new file mode 100644
index 0000000..857786d
--- /dev/null
+++ b/ui/build/proc_sync.go
@@ -0,0 +1,143 @@
+// Copyright 2017 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package build
+
+import (
+	"errors"
+	"fmt"
+	"math"
+	"os"
+	"path/filepath"
+	"syscall"
+	"time"
+
+	"android/soong/ui/logger"
+)
+
+// This file provides cross-process synchronization methods
+// i.e. making sure only one Soong process is running for a given output directory
+
+func BecomeSingletonOrFail(ctx Context, config Config) (lock *fileLock) {
+	lockingInfo, err := newLock(config.OutDir())
+	if err != nil {
+		ctx.Logger.Fatal(err)
+	}
+	err = lockSynchronous(*lockingInfo, newSleepWaiter(lockfilePollDuration, lockfileTimeout), ctx.Logger)
+	if err != nil {
+		ctx.Logger.Fatal(err)
+	}
+	return lockingInfo
+}
+
+var lockfileTimeout = time.Second * 10
+var lockfilePollDuration = time.Second
+
+type lockable interface {
+	tryLock() error
+	Unlock() error
+	description() string
+}
+
+var _ lockable = (*fileLock)(nil)
+
+type fileLock struct {
+	File *os.File
+}
+
+func (l fileLock) description() (path string) {
+	return l.File.Name()
+}
+func (l fileLock) tryLock() (err error) {
+	return syscall.Flock(int(l.File.Fd()), syscall.LOCK_EX|syscall.LOCK_NB)
+}
+func (l fileLock) Unlock() (err error) {
+	return l.File.Close()
+}
+
+func lockSynchronous(lock lockable, waiter waiter, logger logger.Logger) (err error) {
+
+	waited := false
+
+	for {
+		err = lock.tryLock()
+		if err == nil {
+			if waited {
+				// If we had to wait at all, then when the wait is done, we inform the user
+				logger.Printf("Acquired lock on %v; previous Soong process must have completed. Continuing...\n", lock.description())
+			}
+			return nil
+		}
+
+		waited = true
+
+		done, description := waiter.checkDeadline()
+
+		if done {
+			return fmt.Errorf("Tried to lock %s, but timed out %s . Make sure no other Soong process is using it",
+				lock.description(), waiter.summarize())
+		} else {
+			logger.Printf("Waiting up to %s to lock %v to ensure no other Soong process is running in the same output directory\n", description, lock.description())
+			waiter.wait()
+		}
+	}
+}
+
+func newLock(basedir string) (lock *fileLock, err error) {
+	lockPath := filepath.Join(basedir, ".lock")
+
+	os.MkdirAll(basedir, 0777)
+	lockfileDescriptor, err := os.OpenFile(lockPath, os.O_RDWR|os.O_CREATE, 0666)
+	if err != nil {
+		return nil, errors.New("failed to open " + lockPath)
+	}
+	lockingInfo := &fileLock{File: lockfileDescriptor}
+
+	return lockingInfo, nil
+}
+
+type waiter interface {
+	wait()
+	checkDeadline() (done bool, remainder string)
+	summarize() (summary string)
+}
+
+type sleepWaiter struct {
+	sleepInterval time.Duration
+	deadline      time.Time
+
+	totalWait time.Duration
+}
+
+var _ waiter = (*sleepWaiter)(nil)
+
+func newSleepWaiter(interval time.Duration, duration time.Duration) (waiter *sleepWaiter) {
+	return &sleepWaiter{interval, time.Now().Add(duration), duration}
+}
+
+func (s sleepWaiter) wait() {
+	time.Sleep(s.sleepInterval)
+}
+func (s *sleepWaiter) checkDeadline() (done bool, remainder string) {
+	remainingSleep := s.deadline.Sub(time.Now())
+	numSecondsRounded := math.Floor(remainingSleep.Seconds()*10+0.5) / 10
+	if remainingSleep > 0 {
+		return false, fmt.Sprintf("%vs", numSecondsRounded)
+	} else {
+		return true, ""
+	}
+}
+func (s sleepWaiter) summarize() (summary string) {
+	return fmt.Sprintf("polling every %v until %v", s.sleepInterval, s.totalWait)
+}
diff --git a/ui/build/proc_sync_test.go b/ui/build/proc_sync_test.go
new file mode 100644
index 0000000..857bea3
--- /dev/null
+++ b/ui/build/proc_sync_test.go
@@ -0,0 +1,241 @@
+// Copyright 2017 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package build
+
+import (
+	"fmt"
+	"io/ioutil"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"syscall"
+	"testing"
+
+	"android/soong/ui/logger"
+)
+
+// some util methods and data structures that aren't directly part of a test
+func makeLockDir() (path string, err error) {
+	return ioutil.TempDir("", "soong_lock_test")
+}
+func lockOrFail(t *testing.T) (lock fileLock) {
+	lockDir, err := makeLockDir()
+	var lockPointer *fileLock
+	if err == nil {
+		lockPointer, err = newLock(lockDir)
+	}
+	if err != nil {
+		os.RemoveAll(lockDir)
+		t.Fatalf("Failed to create lock: %v", err)
+	}
+
+	return *lockPointer
+}
+func removeTestLock(fileLock fileLock) {
+	lockdir := filepath.Dir(fileLock.File.Name())
+	os.RemoveAll(lockdir)
+}
+
+// countWaiter only exists for the purposes of testing lockSynchronous
+type countWaiter struct {
+	numWaitsElapsed int
+	maxNumWaits     int
+}
+
+func newCountWaiter(count int) (waiter *countWaiter) {
+	return &countWaiter{0, count}
+}
+
+func (c *countWaiter) wait() {
+	c.numWaitsElapsed++
+}
+func (c *countWaiter) checkDeadline() (done bool, remainder string) {
+	numWaitsRemaining := c.maxNumWaits - c.numWaitsElapsed
+	if numWaitsRemaining < 1 {
+		return true, ""
+	}
+	return false, fmt.Sprintf("%v waits remain", numWaitsRemaining)
+}
+func (c countWaiter) summarize() (summary string) {
+	return fmt.Sprintf("waiting %v times", c.maxNumWaits)
+}
+
+// countLock only exists for the purposes of testing lockSynchronous
+type countLock struct {
+	nextIndex    int
+	successIndex int
+}
+
+var _ lockable = (*countLock)(nil)
+
+// returns a countLock that succeeds on iteration <index>
+func testLockCountingTo(index int) (lock *countLock) {
+	return &countLock{nextIndex: 0, successIndex: index}
+}
+func (c *countLock) description() (message string) {
+	return fmt.Sprintf("counter that counts from %v to %v", c.nextIndex, c.successIndex)
+}
+func (c *countLock) tryLock() (err error) {
+	currentIndex := c.nextIndex
+	c.nextIndex++
+	if currentIndex == c.successIndex {
+		return nil
+	}
+	return fmt.Errorf("Lock busy: %s", c.description())
+}
+func (c *countLock) Unlock() (err error) {
+	if c.nextIndex == c.successIndex {
+		return nil
+	}
+	return fmt.Errorf("Not locked: %s", c.description())
+}
+
+// end of util methods
+
+// start of tests
+
+// simple test
+func TestGetLock(t *testing.T) {
+	lockfile := lockOrFail(t)
+	defer removeTestLock(lockfile)
+}
+
+// a more complicated test that spans multiple processes
+var lockPathVariable = "LOCK_PATH"
+var successStatus = 0
+var unexpectedError = 1
+var busyStatus = 2
+
+func TestTrylock(t *testing.T) {
+	lockpath := os.Getenv(lockPathVariable)
+	if len(lockpath) < 1 {
+		checkTrylockMainProcess(t)
+	} else {
+		getLockAndExit(lockpath)
+	}
+}
+
+// the portion of TestTrylock that runs in the main process
+func checkTrylockMainProcess(t *testing.T) {
+	var err error
+	lockfile := lockOrFail(t)
+	defer removeTestLock(lockfile)
+	lockdir := filepath.Dir(lockfile.File.Name())
+	otherAcquired, message, err := forkAndGetLock(lockdir)
+	if err != nil {
+		t.Fatalf("Unexpected error in subprocess trying to lock uncontested fileLock: %v. Subprocess output: %q", err, message)
+	}
+	if !otherAcquired {
+		t.Fatalf("Subprocess failed to lock uncontested fileLock. Subprocess output: %q", message)
+	}
+
+	err = lockfile.tryLock()
+	if err != nil {
+		t.Fatalf("Failed to lock fileLock: %v", err)
+	}
+
+	reacquired, message, err := forkAndGetLock(filepath.Dir(lockfile.File.Name()))
+	if err != nil {
+		t.Fatal(err)
+	}
+	if reacquired {
+		t.Fatalf("Permitted locking fileLock twice. Subprocess output: %q", message)
+	}
+
+	err = lockfile.Unlock()
+	if err != nil {
+		t.Fatalf("Error unlocking fileLock: %v", err)
+	}
+
+	reacquired, message, err = forkAndGetLock(filepath.Dir(lockfile.File.Name()))
+	if err != nil {
+		t.Fatal(err)
+	}
+	if !reacquired {
+		t.Fatalf("Subprocess failed to acquire lock after it was released by the main process. Subprocess output: %q", message)
+	}
+}
+func forkAndGetLock(lockDir string) (acquired bool, subprocessOutput []byte, err error) {
+	cmd := exec.Command(os.Args[0], "-test.run=TestTrylock")
+	cmd.Env = append(os.Environ(), fmt.Sprintf("%s=%s", lockPathVariable, lockDir))
+	subprocessOutput, err = cmd.CombinedOutput()
+	exitStatus := successStatus
+	if exitError, ok := err.(*exec.ExitError); ok {
+		if waitStatus, ok := exitError.Sys().(syscall.WaitStatus); ok {
+			exitStatus = waitStatus.ExitStatus()
+		}
+	}
+	if exitStatus == successStatus {
+		return true, subprocessOutput, nil
+	} else if exitStatus == busyStatus {
+		return false, subprocessOutput, nil
+	} else {
+		return false, subprocessOutput, fmt.Errorf("Unexpected status %v", exitStatus)
+	}
+}
+
+// This function runs in a different process. See TestTrylock
+func getLockAndExit(lockpath string) {
+	fmt.Printf("Will lock path %q\n", lockpath)
+	lockfile, err := newLock(lockpath)
+	exitStatus := unexpectedError
+	if err == nil {
+		err = lockfile.tryLock()
+		if err == nil {
+			exitStatus = successStatus
+		} else {
+			exitStatus = busyStatus
+		}
+	}
+	fmt.Printf("Tried to lock path %s. Received error %v. Exiting with status %v\n", lockpath, err, exitStatus)
+	os.Exit(exitStatus)
+}
+
+func TestLockFirstTrySucceeds(t *testing.T) {
+	noopLogger := logger.New(ioutil.Discard)
+	lock := testLockCountingTo(0)
+	waiter := newCountWaiter(0)
+	err := lockSynchronous(lock, waiter, noopLogger)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if waiter.numWaitsElapsed != 0 {
+		t.Fatalf("Incorrect number of waits elapsed; expected 0, got %v", waiter.numWaitsElapsed)
+	}
+}
+func TestLockThirdTrySucceeds(t *testing.T) {
+	noopLogger := logger.New(ioutil.Discard)
+	lock := testLockCountingTo(2)
+	waiter := newCountWaiter(2)
+	err := lockSynchronous(lock, waiter, noopLogger)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if waiter.numWaitsElapsed != 2 {
+		t.Fatalf("Incorrect number of waits elapsed; expected 2, got %v", waiter.numWaitsElapsed)
+	}
+}
+func TestLockTimedOut(t *testing.T) {
+	noopLogger := logger.New(ioutil.Discard)
+	lock := testLockCountingTo(3)
+	waiter := newCountWaiter(2)
+	err := lockSynchronous(lock, waiter, noopLogger)
+	if err == nil {
+		t.Fatalf("Appeared to have acquired lock on iteration %v which should not be available until iteration %v", waiter.numWaitsElapsed, lock.successIndex)
+	}
+	if waiter.numWaitsElapsed != waiter.maxNumWaits {
+		t.Fatalf("Waited an incorrect number of times; expected %v, got %v", waiter.maxNumWaits, waiter.numWaitsElapsed)
+	}
+}
