diff --git a/bpfix/cmd-lib/bpfix.go b/bpfix/cmd-lib/bpfix.go
new file mode 100644
index 0000000..98122f2
--- /dev/null
+++ b/bpfix/cmd-lib/bpfix.go
@@ -0,0 +1,189 @@
+// 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.
+
+// This file provides a bpfix command-line library
+
+// TODO(jeffrygaston) should this file be consolidated with bpfmt.go?
+
+package cmd
+
+import (
+	"bytes"
+	"flag"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"os"
+	"os/exec"
+	"path/filepath"
+
+	"github.com/google/blueprint/parser"
+
+	"android/soong/bpfix/bpfix"
+)
+
+var (
+	// main operation modes
+	list   = flag.Bool("l", false, "list files whose formatting differs from bpfmt's")
+	write  = flag.Bool("w", false, "write result to (source) file instead of stdout")
+	doDiff = flag.Bool("d", false, "display diffs instead of rewriting files")
+)
+
+var (
+	exitCode = 0
+)
+
+func report(err error) {
+	fmt.Fprintln(os.Stderr, err)
+	exitCode = 2
+}
+
+func openAndProcess(filename string, out io.Writer, fixRequest bpfix.FixRequest) error {
+	f, err := os.Open(filename)
+	if err != nil {
+		return err
+	}
+	defer f.Close()
+	return processFile(filename, f, out, fixRequest)
+}
+
+// If in == nil, the source is the contents of the file with the given filename.
+func processFile(filename string, in io.Reader, out io.Writer, fixRequest bpfix.FixRequest) error {
+	// load the input file
+	src, err := ioutil.ReadAll(in)
+	if err != nil {
+		return err
+	}
+	r := bytes.NewBuffer(append([]byte(nil), src...))
+	file, errs := parser.Parse(filename, r, parser.NewScope(nil))
+	if len(errs) > 0 {
+		for _, err := range errs {
+			fmt.Fprintln(os.Stderr, err)
+		}
+		return fmt.Errorf("%d parsing errors", len(errs))
+	}
+
+	// compute and apply any requested fixes
+	fixer := bpfix.NewFixer(file)
+	file, err = fixer.Fix(fixRequest)
+	if err != nil {
+		return err
+	}
+
+	// output the results
+	res, err := parser.Print(file)
+	if err != nil {
+		return err
+	}
+	if !bytes.Equal(src, res) {
+		// contents have changed
+		if *list {
+			fmt.Fprintln(out, filename)
+		}
+		if *write {
+			err = ioutil.WriteFile(filename, res, 0644)
+			if err != nil {
+				return err
+			}
+		}
+		if *doDiff {
+			data, err := diff(src, res)
+			if err != nil {
+				return fmt.Errorf("computing diff: %s", err)
+			}
+			fmt.Printf("diff %s bpfix/%s\n", filename, filename)
+			out.Write(data)
+		}
+	}
+	if !*list && !*write && !*doDiff {
+		_, err = out.Write(res)
+	}
+	return err
+}
+
+func makeFileVisitor(fixRequest bpfix.FixRequest) func(string, os.FileInfo, error) error {
+	return func(path string, f os.FileInfo, err error) error {
+		if err == nil && (f.Name() == "Blueprints" || f.Name() == "Android.bp") {
+			err = openAndProcess(path, os.Stdout, fixRequest)
+		}
+		if err != nil {
+			report(err)
+		}
+		return nil
+	}
+}
+
+func walkDir(path string, fixRequest bpfix.FixRequest) {
+	filepath.Walk(path, makeFileVisitor(fixRequest))
+}
+
+func Run() {
+	flag.Parse()
+
+	fixRequest := bpfix.NewFixRequest().AddAll()
+
+	if flag.NArg() == 0 {
+		if *write {
+			fmt.Fprintln(os.Stderr, "error: cannot use -w with standard input")
+			exitCode = 2
+			return
+		}
+		if err := processFile("<standard input>", os.Stdin, os.Stdout, fixRequest); err != nil {
+			report(err)
+		}
+		return
+	}
+
+	for i := 0; i < flag.NArg(); i++ {
+		path := flag.Arg(i)
+		switch dir, err := os.Stat(path); {
+		case err != nil:
+			report(err)
+		case dir.IsDir():
+			walkDir(path, fixRequest)
+		default:
+			if err := openAndProcess(path, os.Stdout, fixRequest); err != nil {
+				report(err)
+			}
+		}
+	}
+}
+
+func diff(b1, b2 []byte) (data []byte, err error) {
+	f1, err := ioutil.TempFile("", "bpfix")
+	if err != nil {
+		return
+	}
+	defer os.Remove(f1.Name())
+	defer f1.Close()
+
+	f2, err := ioutil.TempFile("", "bpfix")
+	if err != nil {
+		return
+	}
+	defer os.Remove(f2.Name())
+	defer f2.Close()
+
+	f1.Write(b1)
+	f2.Write(b2)
+
+	data, err = exec.Command("diff", "-u", f1.Name(), f2.Name()).CombinedOutput()
+	if len(data) > 0 {
+		// diff exits with a non-zero status when the files don't match.
+		// Ignore that failure as long as we get output.
+		err = nil
+	}
+	return
+
+}
