diff --git a/rust/compiler.go b/rust/compiler.go
new file mode 100644
index 0000000..87cf08b
--- /dev/null
+++ b/rust/compiler.go
@@ -0,0 +1,193 @@
+// Copyright 2019 The Android Open Source Project
+//
+// 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 rust
+
+import (
+	"fmt"
+	"path/filepath"
+
+	"android/soong/android"
+	"android/soong/rust/config"
+)
+
+func NewBaseCompiler(dir, dir64 string) *baseCompiler {
+	return &baseCompiler{
+		Properties: BaseCompilerProperties{
+			Edition: &config.DefaultEdition,
+		},
+		dir:   dir,
+		dir64: dir64,
+	}
+}
+
+type BaseCompilerProperties struct {
+	// flags to pass to rustc
+	Flags []string `android:"path,arch_variant"`
+
+	// flags to pass to the linker
+	Ld_flags []string `android:"path,arch_variant"`
+
+	// list of rust rlib crate dependencies
+	Rlibs []string `android:"arch_variant"`
+
+	// list of rust dylib crate dependencies
+	Dylibs []string `android:"arch_variant"`
+
+	// list of rust proc_macro crate dependencies
+	Proc_macros []string `android:"arch_variant"`
+
+	// list of C shared library dependencies
+	Shared_libs []string `android:"arch_variant"`
+
+	// list of C static library dependencies
+	Static_libs []string `android:"arch_variant"`
+
+	// crate name (defaults to module name); if library, this must be the expected extern crate name
+	Crate_name string `android:"arch_variant"`
+
+	// list of features to enable for this crate
+	Features []string `android:"arch_variant"`
+
+	// specific rust edition that should be used if the default version is not desired
+	Edition *string `android:"arch_variant"`
+
+	// sets name of the output
+	Stem *string `android:"arch_variant"`
+
+	// append to name of output
+	Suffix *string `android:"arch_variant"`
+
+	// install to a subdirectory of the default install path for the module
+	Relative_install_path *string `android:"arch_variant"`
+}
+
+type baseCompiler struct {
+	Properties    BaseCompilerProperties
+	pathDeps      android.Paths
+	rustFlagsDeps android.Paths
+	linkFlagsDeps android.Paths
+	flags         string
+	linkFlags     string
+	depFlags      []string
+	linkDirs      []string
+	edition       string
+	src           android.Path //rustc takes a single src file
+
+	// Install related
+	dir      string
+	dir64    string
+	subDir   string
+	relative string
+	path     android.OutputPath
+}
+
+var _ compiler = (*baseCompiler)(nil)
+
+func (compiler *baseCompiler) compilerProps() []interface{} {
+	return []interface{}{&compiler.Properties}
+}
+
+func (compiler *baseCompiler) featuresToFlags(features []string) []string {
+	flags := []string{}
+	for _, feature := range features {
+		flags = append(flags, "--cfg 'feature=\""+feature+"\"'")
+	}
+	return flags
+}
+
+func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags) Flags {
+
+	flags.RustFlags = append(flags.RustFlags, compiler.Properties.Flags...)
+	flags.RustFlags = append(flags.RustFlags, compiler.featuresToFlags(compiler.Properties.Features)...)
+	flags.RustFlags = append(flags.RustFlags, "--edition="+*compiler.Properties.Edition)
+	flags.LinkFlags = append(flags.LinkFlags, compiler.Properties.Ld_flags...)
+	flags.GlobalFlags = append(flags.GlobalFlags, ctx.toolchain().ToolchainRustFlags())
+
+	if ctx.Host() && !ctx.Windows() {
+		rpath_prefix := `\$$ORIGIN/`
+		if ctx.Darwin() {
+			rpath_prefix = "@loader_path/"
+		}
+
+		var rpath string
+		if ctx.toolchain().Is64Bit() {
+			rpath = "lib64"
+		} else {
+			rpath = "lib"
+		}
+		flags.LinkFlags = append(flags.LinkFlags, "-Wl,-rpath,"+rpath_prefix+rpath)
+		flags.LinkFlags = append(flags.LinkFlags, "-Wl,-rpath,"+rpath_prefix+"../"+rpath)
+	}
+
+	return flags
+}
+
+func (compiler *baseCompiler) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path {
+	panic(fmt.Errorf("baseCrater doesn't know how to crate things!"))
+}
+
+func (compiler *baseCompiler) compilerDeps(ctx DepsContext, deps Deps) Deps {
+	deps.Rlibs = append(deps.Rlibs, compiler.Properties.Rlibs...)
+	deps.Dylibs = append(deps.Dylibs, compiler.Properties.Dylibs...)
+	deps.ProcMacros = append(deps.ProcMacros, compiler.Properties.Proc_macros...)
+	deps.StaticLibs = append(deps.StaticLibs, compiler.Properties.Static_libs...)
+	deps.SharedLibs = append(deps.SharedLibs, compiler.Properties.Shared_libs...)
+
+	return deps
+}
+
+func (compiler *baseCompiler) crateName() string {
+	return compiler.Properties.Crate_name
+}
+
+func (compiler *baseCompiler) installDir(ctx ModuleContext) android.OutputPath {
+	dir := compiler.dir
+	if ctx.toolchain().Is64Bit() && compiler.dir64 != "" {
+		dir = compiler.dir64
+	}
+	if (!ctx.Host() && !ctx.Arch().Native) || ctx.Target().NativeBridge == android.NativeBridgeEnabled {
+		dir = filepath.Join(dir, ctx.Arch().ArchType.String())
+	}
+	return android.PathForModuleInstall(ctx, dir, compiler.subDir,
+		compiler.relativeInstallPath(), compiler.relative)
+}
+
+func (compiler *baseCompiler) install(ctx ModuleContext, file android.Path) {
+	compiler.path = ctx.InstallFile(compiler.installDir(ctx), file.Base(), file)
+}
+
+func (compiler *baseCompiler) getStem(ctx ModuleContext) string {
+	return compiler.getStemWithoutSuffix(ctx) + String(compiler.Properties.Suffix)
+}
+
+func (compiler *baseCompiler) getStemWithoutSuffix(ctx BaseModuleContext) string {
+	stem := ctx.baseModuleName()
+	if String(compiler.Properties.Stem) != "" {
+		stem = String(compiler.Properties.Stem)
+	}
+
+	return stem
+}
+func (compiler *baseCompiler) relativeInstallPath() string {
+	return String(compiler.Properties.Relative_install_path)
+}
+
+func srcPathFromModuleSrcs(ctx ModuleContext, srcs []string) android.Path {
+	srcPaths := android.PathsForModuleSrc(ctx, srcs)
+	if len(srcPaths) != 1 {
+		ctx.PropertyErrorf("srcs", "srcs can only contain one path for rust modules")
+	}
+	return srcPaths[0]
+}
