diff --git a/cmd/release_config/main.go b/cmd/release_config/main.go
new file mode 100644
index 0000000..3bb6b3d
--- /dev/null
+++ b/cmd/release_config/main.go
@@ -0,0 +1,691 @@
+// Copyright 2024 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 main
+
+import (
+	"cmp"
+	"encoding/json"
+	"flag"
+	"fmt"
+	"io/fs"
+	"os"
+	"path/filepath"
+	"slices"
+	"strings"
+
+	"android/soong/cmd/release_config/release_config_proto"
+
+	"google.golang.org/protobuf/encoding/prototext"
+	"google.golang.org/protobuf/proto"
+)
+
+var verboseFlag bool
+
+type StringList []string
+
+func (l *StringList) Set(v string) error {
+	*l = append(*l, v)
+	return nil
+}
+
+func (l *StringList) String() string {
+	return fmt.Sprintf("%v", *l)
+}
+
+var releaseConfigMapPaths StringList
+
+func DumpProtos(outDir string, message proto.Message) error {
+	basePath := filepath.Join(outDir, "all_release_configs")
+	writer := func(suffix string, marshal func() ([]byte, error)) error {
+		data, err := marshal()
+		if err != nil {
+			return err
+		}
+		return os.WriteFile(fmt.Sprintf("%s.%s", basePath, suffix), data, 0644)
+	}
+	err := writer("textproto", func() ([]byte, error) { return prototext.MarshalOptions{Multiline: true}.Marshal(message) })
+	if err != nil {
+		return err
+	}
+
+	err = writer("pb", func() ([]byte, error) { return proto.Marshal(message) })
+	if err != nil {
+		return err
+	}
+
+	return writer("json", func() ([]byte, error) { return json.MarshalIndent(message, "", "  ") })
+}
+
+func LoadTextproto(path string, message proto.Message) error {
+	data, err := os.ReadFile(path)
+	if err != nil {
+		return err
+	}
+	ret := prototext.Unmarshal(data, message)
+	if verboseFlag {
+		debug, _ := prototext.Marshal(message)
+		fmt.Printf("%s: %s\n", path, debug)
+	}
+	return ret
+}
+
+func WalkTextprotoFiles(root string, subdir string, Func fs.WalkDirFunc) error {
+	path := filepath.Join(root, subdir)
+	if _, err := os.Stat(path); err != nil {
+		// Missing subdirs are not an error.
+		return nil
+	}
+	return filepath.WalkDir(path, func(path string, d fs.DirEntry, err error) error {
+		if err != nil {
+			return err
+		}
+		if strings.HasSuffix(d.Name(), ".textproto") && d.Type().IsRegular() {
+			return Func(path, d, err)
+		}
+		return nil
+	})
+}
+
+type FlagValue struct {
+	// The path providing this value.
+	path string
+
+	// Protobuf
+	proto release_config_proto.FlagValue
+}
+
+func FlagValueFactory(protoPath string) (fv *FlagValue) {
+	fv = &FlagValue{path: protoPath}
+	if protoPath != "" {
+		LoadTextproto(protoPath, &fv.proto)
+	}
+	return fv
+}
+
+// One directory's contribution to the a release config.
+type ReleaseConfigContribution struct {
+	// Paths to files providing this config.
+	path string
+
+	// The index of the config directory where this release config
+	// contribution was declared.
+	// Flag values cannot be set in a location with a lower index.
+	DeclarationIndex int
+
+	// Protobufs relevant to the config.
+	proto release_config_proto.ReleaseConfig
+
+	FlagValues []*FlagValue
+}
+
+// A single release_config_map.textproto and its associated data.
+// Used primarily for debugging.
+type ReleaseConfigMap struct {
+	// The path to this release_config_map file.
+	path string
+
+	// Data received
+	proto release_config_proto.ReleaseConfigMap
+
+	ReleaseConfigContributions map[string]*ReleaseConfigContribution
+	FlagDeclarations           []release_config_proto.FlagDeclaration
+}
+
+// A generated release config.
+type ReleaseConfig struct {
+	// the Name of the release config
+	Name string
+
+	// The index of the config directory where this release config was
+	// first declared.
+	// Flag values cannot be set in a location with a lower index.
+	DeclarationIndex int
+
+	// What contributes to this config.
+	Contributions []*ReleaseConfigContribution
+
+	// Aliases for this release
+	OtherNames []string
+
+	// The names of release configs that we inherit
+	InheritNames []string
+
+	// Unmarshalled flag artifacts
+	FlagArtifacts FlagArtifacts
+
+	// Generated release config
+	ReleaseConfigArtifact *release_config_proto.ReleaseConfigArtifact
+
+	// We have begun compiling this release config.
+	compileInProgress bool
+}
+
+type FlagArtifact struct {
+	FlagDeclaration *release_config_proto.FlagDeclaration
+
+	// The index of the config directory where this flag was declared.
+	// Flag values cannot be set in a location with a lower index.
+	DeclarationIndex int
+
+	Traces []*release_config_proto.Tracepoint
+
+	// Assigned value
+	Value *release_config_proto.Value
+}
+
+// Key is flag name.
+type FlagArtifacts map[string]*FlagArtifact
+
+type ReleaseConfigDirMap map[string]int
+
+// The generated release configs.
+type ReleaseConfigs struct {
+	// Ordered list of release config maps processed.
+	ReleaseConfigMaps []*ReleaseConfigMap
+
+	// Aliases
+	Aliases map[string]*string
+
+	// Dictionary of flag_name:FlagDeclaration, with no overrides applied.
+	FlagArtifacts FlagArtifacts
+
+	// Dictionary of name:ReleaseConfig
+	ReleaseConfigs map[string]*ReleaseConfig
+
+	// Generated release configs
+	Artifact release_config_proto.ReleaseConfigsArtifact
+
+	// The list of config directories used.
+	ConfigDirs []string
+
+	// A map from the config directory to its order in the list of config
+	// directories.
+	ConfigDirIndexes ReleaseConfigDirMap
+}
+
+func (src *FlagArtifact) Clone() *FlagArtifact {
+	value := &release_config_proto.Value{}
+	proto.Merge(value, src.Value)
+	return &FlagArtifact{
+		FlagDeclaration: src.FlagDeclaration,
+		Traces:          src.Traces,
+		Value:           value,
+	}
+}
+
+func (src FlagArtifacts) Clone() (dst FlagArtifacts) {
+	if dst == nil {
+		dst = make(FlagArtifacts)
+	}
+	for k, v := range src {
+		dst[k] = v.Clone()
+	}
+	return
+}
+
+func ReleaseConfigFactory(name string, index int) (c *ReleaseConfig) {
+	return &ReleaseConfig{Name: name, DeclarationIndex: index}
+}
+
+func ReleaseConfigsFactory() (c *ReleaseConfigs) {
+	return &ReleaseConfigs{
+		Aliases:          make(map[string]*string),
+		FlagArtifacts:    make(map[string]*FlagArtifact),
+		ReleaseConfigs:   make(map[string]*ReleaseConfig),
+		ConfigDirs:       []string{},
+		ConfigDirIndexes: make(ReleaseConfigDirMap),
+	}
+}
+
+func ReleaseConfigMapFactory(protoPath string) (m *ReleaseConfigMap) {
+	m = &ReleaseConfigMap{
+		path:                       protoPath,
+		ReleaseConfigContributions: make(map[string]*ReleaseConfigContribution),
+	}
+	if protoPath != "" {
+		LoadTextproto(protoPath, &m.proto)
+	}
+	return m
+}
+
+func FlagDeclarationFactory(protoPath string) (fd *release_config_proto.FlagDeclaration) {
+	fd = &release_config_proto.FlagDeclaration{}
+	if protoPath != "" {
+		LoadTextproto(protoPath, fd)
+	}
+	return fd
+}
+
+func (configs *ReleaseConfigs) LoadReleaseConfigMap(path string, ConfigDirIndex int) error {
+	m := ReleaseConfigMapFactory(path)
+	if m.proto.Origin == nil || *m.proto.Origin == "" {
+		return fmt.Errorf("Release config map %s lacks origin", path)
+	}
+	if m.proto.DefaultContainer == nil {
+		return fmt.Errorf("Release config map %s lacks default_container", path)
+	}
+	dir := filepath.Dir(path)
+	// Record any aliases, checking for duplicates.
+	for _, alias := range m.proto.Aliases {
+		name := *alias.Name
+		oldTarget, ok := configs.Aliases[name]
+		if ok {
+			if *oldTarget != *alias.Target {
+				return fmt.Errorf("Conflicting alias declarations: %s vs %s",
+					*oldTarget, *alias.Target)
+			}
+		}
+		configs.Aliases[name] = alias.Target
+	}
+	var err error
+	err = WalkTextprotoFiles(dir, "flag_declarations", func(path string, d fs.DirEntry, err error) error {
+		flagDeclaration := FlagDeclarationFactory(path)
+		// Container must be specified.
+		if flagDeclaration.Container == nil {
+			flagDeclaration.Container = m.proto.DefaultContainer
+		}
+		// TODO: drop flag_declaration.origin from the proto.
+		if flagDeclaration.Origin == nil {
+			flagDeclaration.Origin = m.proto.Origin
+		}
+		// There is always a default value.
+		if flagDeclaration.Value == nil {
+			flagDeclaration.Value = &release_config_proto.Value{Val: &release_config_proto.Value_UnspecifiedValue{true}}
+		}
+		m.FlagDeclarations = append(m.FlagDeclarations, *flagDeclaration)
+		name := *flagDeclaration.Name
+		if def, ok := configs.FlagArtifacts[name]; !ok {
+			configs.FlagArtifacts[name] = &FlagArtifact{FlagDeclaration: flagDeclaration, DeclarationIndex: ConfigDirIndex}
+		} else if !proto.Equal(def.FlagDeclaration, flagDeclaration) {
+			return fmt.Errorf("Duplicate definition of %s", *flagDeclaration.Name)
+		}
+		// Set the initial value in the flag artifact.
+		configs.FlagArtifacts[name].UpdateValue(
+			FlagValue{path: path, proto: release_config_proto.FlagValue{
+				Name: proto.String(name), Value: flagDeclaration.Value}})
+		return nil
+	})
+	if err != nil {
+		return err
+	}
+
+	err = WalkTextprotoFiles(dir, "release_configs", func(path string, d fs.DirEntry, err error) error {
+		releaseConfigContribution := &ReleaseConfigContribution{path: path, DeclarationIndex: ConfigDirIndex}
+		LoadTextproto(path, &releaseConfigContribution.proto)
+		name := *releaseConfigContribution.proto.Name
+		if fmt.Sprintf("%s.textproto", name) != filepath.Base(path) {
+			return fmt.Errorf("%s incorrectly declares release config %s", path, name)
+		}
+		if _, ok := configs.ReleaseConfigs[name]; !ok {
+			configs.ReleaseConfigs[name] = ReleaseConfigFactory(name, ConfigDirIndex)
+		}
+		config := configs.ReleaseConfigs[name]
+		config.InheritNames = append(config.InheritNames, releaseConfigContribution.proto.Inherits...)
+
+		// Only walk flag_values/{RELEASE} for defined releases.
+		err2 := WalkTextprotoFiles(dir, filepath.Join("flag_values", name), func(path string, d fs.DirEntry, err error) error {
+			flagValue := FlagValueFactory(path)
+			if fmt.Sprintf("%s.textproto", *flagValue.proto.Name) != filepath.Base(path) {
+				return fmt.Errorf("%s incorrectly sets value for flag %s", path, *flagValue.proto.Name)
+			}
+			releaseConfigContribution.FlagValues = append(releaseConfigContribution.FlagValues, flagValue)
+			return nil
+		})
+		if err2 != nil {
+			return err2
+		}
+		m.ReleaseConfigContributions[name] = releaseConfigContribution
+		config.Contributions = append(config.Contributions, releaseConfigContribution)
+		return nil
+	})
+	if err != nil {
+		return err
+	}
+	configs.ReleaseConfigMaps = append(configs.ReleaseConfigMaps, m)
+	return nil
+}
+
+func (configs *ReleaseConfigs) GetReleaseConfig(name string) (*ReleaseConfig, error) {
+	trace := []string{name}
+	for target, ok := configs.Aliases[name]; ok; target, ok = configs.Aliases[name] {
+		name = *target
+		trace = append(trace, name)
+	}
+	if config, ok := configs.ReleaseConfigs[name]; ok {
+		return config, nil
+	}
+	return nil, fmt.Errorf("Missing config %s.  Trace=%v", name, trace)
+}
+
+func (configs *ReleaseConfigs) DumpMakefile(outDir, targetRelease string) error {
+	outFile := filepath.Join(outDir, "release_config.mk")
+	makeVars := make(map[string]string)
+	config, err := configs.GetReleaseConfig(targetRelease)
+	if err != nil {
+		return err
+	}
+	// Sort the flags by name first.
+	names := []string{}
+	for k, _ := range config.FlagArtifacts {
+		names = append(names, k)
+	}
+	slices.SortFunc(names, func(a, b string) int {
+		return cmp.Compare(a, b)
+	})
+	partitions := make(map[string][]string)
+
+	vNames := []string{}
+	addVar := func(name, suffix, value string) {
+		fullName := fmt.Sprintf("_ALL_RELEASE_FLAGS.%s.%s", name, suffix)
+		vNames = append(vNames, fullName)
+		makeVars[fullName] = value
+	}
+
+	for _, name := range names {
+		flag := config.FlagArtifacts[name]
+		decl := flag.FlagDeclaration
+
+		// cName := strings.ToLower(release_config_proto.Container_name[decl.GetContainer()])
+		cName := strings.ToLower(decl.Container.String())
+		if cName == strings.ToLower(release_config_proto.Container_ALL.String()) {
+			partitions["product"] = append(partitions["product"], name)
+			partitions["system"] = append(partitions["system"], name)
+			partitions["system_ext"] = append(partitions["system_ext"], name)
+			partitions["vendor"] = append(partitions["vendor"], name)
+		} else {
+			partitions[cName] = append(partitions[cName], name)
+		}
+		value := MarshalValue(flag.Value)
+		makeVars[name] = value
+		addVar(name, "PARTITIONS", cName)
+		addVar(name, "DEFAULT", MarshalValue(decl.Value))
+		addVar(name, "VALUE", value)
+		addVar(name, "DECLARED_IN", *flag.Traces[0].Source)
+		addVar(name, "SET_IN", *flag.Traces[len(flag.Traces)-1].Source)
+		addVar(name, "ORIGIN", *decl.Origin)
+	}
+	pNames := []string{}
+	for k, _ := range partitions {
+		pNames = append(pNames, k)
+	}
+	slices.SortFunc(pNames, func(a, b string) int {
+		return cmp.Compare(a, b)
+	})
+
+	// Now sort the make variables, and output them.
+	slices.SortFunc(vNames, func(a, b string) int {
+		return cmp.Compare(a, b)
+	})
+
+	// Write the flags as:
+	//   _ALL_RELELASE_FLAGS
+	//   _ALL_RELEASE_FLAGS.PARTITIONS.*
+	//   all _ALL_RELEASE_FLAGS.*, sorted by name
+	//   Final flag values, sorted by name.
+	data := fmt.Sprintf("_ALL_RELEASE_FLAGS :=$= %s\n", strings.Join(names, " "))
+	for _, pName := range pNames {
+		data += fmt.Sprintf("_ALL_RELEASE_FLAGS.PARTITIONS.%s :=$= %s\n", pName, strings.Join(partitions[pName], " "))
+	}
+	for _, vName := range vNames {
+		data += fmt.Sprintf("%s :=$= %s\n", vName, makeVars[vName])
+	}
+	data += "\n\n# Values for all build flags\n"
+	data += fmt.Sprintf("RELEASE_ACONFIG_VALUE_SETS :=$= %s\n",
+		strings.Join(config.ReleaseConfigArtifact.AconfigValueSets, " "))
+	for _, name := range names {
+		data += fmt.Sprintf("%s :=$= %s\n", name, makeVars[name])
+	}
+	return os.WriteFile(outFile, []byte(data), 0644)
+}
+
+func (configs *ReleaseConfigs) GenerateReleaseConfigs(targetRelease string) error {
+	otherNames := make(map[string][]string)
+	for aliasName, aliasTarget := range configs.Aliases {
+		if _, ok := configs.ReleaseConfigs[aliasName]; ok {
+			return fmt.Errorf("Alias %s is a declared release config", aliasName)
+		}
+		if _, ok := configs.ReleaseConfigs[*aliasTarget]; !ok {
+			if _, ok2 := configs.Aliases[*aliasTarget]; !ok2 {
+				return fmt.Errorf("Alias %s points to non-existing config %s", aliasName, *aliasTarget)
+			}
+		}
+		otherNames[*aliasTarget] = append(otherNames[*aliasTarget], aliasName)
+	}
+	for name, aliases := range otherNames {
+		configs.ReleaseConfigs[name].OtherNames = aliases
+	}
+
+	for _, config := range configs.ReleaseConfigs {
+		err := config.GenerateReleaseConfig(configs)
+		if err != nil {
+			return err
+		}
+	}
+
+	releaseConfig, err := configs.GetReleaseConfig(targetRelease)
+	if err != nil {
+		return err
+	}
+	configs.Artifact = release_config_proto.ReleaseConfigsArtifact{
+		ReleaseConfig: releaseConfig.ReleaseConfigArtifact,
+		OtherReleaseConfigs: func() []*release_config_proto.ReleaseConfigArtifact {
+			orc := []*release_config_proto.ReleaseConfigArtifact{}
+			for name, config := range configs.ReleaseConfigs {
+				if name != releaseConfig.Name {
+					orc = append(orc, config.ReleaseConfigArtifact)
+				}
+			}
+			return orc
+		}(),
+	}
+	return nil
+}
+
+func MarshalValue(value *release_config_proto.Value) string {
+	switch val := value.Val.(type) {
+	case *release_config_proto.Value_UnspecifiedValue:
+		// Value was never set.
+		return ""
+	case *release_config_proto.Value_StringValue:
+		return val.StringValue
+	case *release_config_proto.Value_BoolValue:
+		if val.BoolValue {
+			return "true"
+		}
+		// False ==> empty string
+		return ""
+	case *release_config_proto.Value_Obsolete:
+		return " #OBSOLETE"
+	default:
+		// Flagged as error elsewhere, so return empty string here.
+		return ""
+	}
+}
+
+func (fa *FlagArtifact) UpdateValue(flagValue FlagValue) error {
+	name := *flagValue.proto.Name
+	fa.Traces = append(fa.Traces, &release_config_proto.Tracepoint{Source: proto.String(flagValue.path), Value: flagValue.proto.Value})
+	if fa.Value.GetObsolete() {
+		return fmt.Errorf("Attempting to set obsolete flag %s. Trace=%v", name, fa.Traces)
+	}
+	switch val := flagValue.proto.Value.Val.(type) {
+	case *release_config_proto.Value_StringValue:
+		fa.Value = &release_config_proto.Value{Val: &release_config_proto.Value_StringValue{val.StringValue}}
+	case *release_config_proto.Value_BoolValue:
+		fa.Value = &release_config_proto.Value{Val: &release_config_proto.Value_BoolValue{val.BoolValue}}
+	case *release_config_proto.Value_Obsolete:
+		if !val.Obsolete {
+			return fmt.Errorf("%s: Cannot set obsolete=false.  Trace=%v", name, fa.Traces)
+		}
+		fa.Value = &release_config_proto.Value{Val: &release_config_proto.Value_Obsolete{true}}
+	default:
+		return fmt.Errorf("Invalid type for flag_value: %T.  Trace=%v", val, fa.Traces)
+	}
+	return nil
+}
+
+func (fa *FlagArtifact) Marshal() (*release_config_proto.FlagArtifact, error) {
+	return &release_config_proto.FlagArtifact{
+		FlagDeclaration: fa.FlagDeclaration,
+		Value:           fa.Value,
+		Traces:          fa.Traces,
+	}, nil
+}
+
+func (config *ReleaseConfig) GenerateReleaseConfig(configs *ReleaseConfigs) error {
+	if config.ReleaseConfigArtifact != nil {
+		return nil
+	}
+	if config.compileInProgress {
+		return fmt.Errorf("Loop detected for release config %s", config.Name)
+	}
+	config.compileInProgress = true
+
+	// Generate any configs we need to inherit.  This will detect loops in
+	// the config.
+	contributionsToApply := []*ReleaseConfigContribution{}
+	myInherits := []string{}
+	myInheritsSet := make(map[string]bool)
+	for _, inherit := range config.InheritNames {
+		if _, ok := myInheritsSet[inherit]; ok {
+			continue
+		}
+		myInherits = append(myInherits, inherit)
+		myInheritsSet[inherit] = true
+		iConfig, err := configs.GetReleaseConfig(inherit)
+		if err != nil {
+			return err
+		}
+		iConfig.GenerateReleaseConfig(configs)
+		contributionsToApply = append(contributionsToApply, iConfig.Contributions...)
+	}
+	contributionsToApply = append(contributionsToApply, config.Contributions...)
+
+	myAconfigValueSets := []string{}
+	myFlags := configs.FlagArtifacts.Clone()
+	myDirsMap := make(map[int]bool)
+	for _, contrib := range contributionsToApply {
+		myAconfigValueSets = append(myAconfigValueSets, contrib.proto.AconfigValueSets...)
+		myDirsMap[contrib.DeclarationIndex] = true
+		for _, value := range contrib.FlagValues {
+			fa, ok := myFlags[*value.proto.Name]
+			if !ok {
+				return fmt.Errorf("Setting value for undefined flag %s in %s\n", *value.proto.Name, value.path)
+			}
+			myDirsMap[fa.DeclarationIndex] = true
+			if fa.DeclarationIndex > contrib.DeclarationIndex {
+				// Setting location is to the left of declaration.
+				return fmt.Errorf("Setting value for flag %s not allowed in %s\n", *value.proto.Name, value.path)
+			}
+			if err := fa.UpdateValue(*value); err != nil {
+				return err
+			}
+		}
+	}
+
+	directories := []string{}
+	for idx, confDir := range configs.ConfigDirs {
+		if _, ok := myDirsMap[idx]; ok {
+			directories = append(directories, confDir)
+		}
+	}
+
+	config.FlagArtifacts = myFlags
+	config.ReleaseConfigArtifact = &release_config_proto.ReleaseConfigArtifact{
+		Name:       proto.String(config.Name),
+		OtherNames: config.OtherNames,
+		FlagArtifacts: func() []*release_config_proto.FlagArtifact {
+			ret := []*release_config_proto.FlagArtifact{}
+			for _, flag := range myFlags {
+				ret = append(ret, &release_config_proto.FlagArtifact{
+					FlagDeclaration: flag.FlagDeclaration,
+					Traces:          flag.Traces,
+					Value:           flag.Value,
+				})
+			}
+			return ret
+		}(),
+		AconfigValueSets: myAconfigValueSets,
+		Inherits:         myInherits,
+		Directories:      directories,
+	}
+
+	config.compileInProgress = false
+	return nil
+}
+
+func main() {
+	var targetRelease string
+	var outputDir string
+
+	outEnv := os.Getenv("OUT_DIR")
+	if outEnv == "" {
+		outEnv = "out"
+	}
+	defaultOutputDir := filepath.Join(outEnv, "soong", "release-config")
+	var defaultMapPaths StringList
+	defaultLocations := StringList{
+		"build/release/release_config_map.textproto",
+		"vendor/google_shared/build/release/release_config_map.textproto",
+		"vendor/google/release/release_config_map.textproto",
+	}
+	for _, path := range defaultLocations {
+		if _, err := os.Stat(path); err == nil {
+			defaultMapPaths = append(defaultMapPaths, path)
+		}
+	}
+	prodMaps := os.Getenv("PRODUCT_RELEASE_CONFIG_MAPS")
+	if prodMaps != "" {
+		defaultMapPaths = append(defaultMapPaths, strings.Split(prodMaps, " ")...)
+	}
+
+	flag.BoolVar(&verboseFlag, "debug", false, "print debugging information")
+	flag.Var(&releaseConfigMapPaths, "map", "path to a release_config_map.textproto. may be repeated")
+	flag.StringVar(&targetRelease, "release", "trunk_staging", "TARGET_RELEASE for this build")
+	flag.StringVar(&outputDir, "out_dir", defaultOutputDir, "basepath for the output. Multiple formats are created")
+	flag.Parse()
+
+	if len(releaseConfigMapPaths) == 0 {
+		releaseConfigMapPaths = defaultMapPaths
+		fmt.Printf("No --map argument provided.  Using: --map %s\n", strings.Join(releaseConfigMapPaths, " --map "))
+	}
+
+	configs := ReleaseConfigsFactory()
+	for idx, releaseConfigMapPath := range releaseConfigMapPaths {
+		// Maintain an ordered list of release config directories.
+		configDir := filepath.Dir(releaseConfigMapPath)
+		configs.ConfigDirIndexes[configDir] = idx
+		configs.ConfigDirs = append(configs.ConfigDirs, configDir)
+		err := configs.LoadReleaseConfigMap(releaseConfigMapPath, idx)
+		if err != nil {
+			panic(err)
+		}
+	}
+
+	// Now that we have all of the release config maps, can meld them and generate the artifacts.
+	err := configs.GenerateReleaseConfigs(targetRelease)
+	if err != nil {
+		panic(err)
+	}
+	err = os.MkdirAll(outputDir, 0775)
+	if err != nil {
+		panic(err)
+	}
+	err = configs.DumpMakefile(outputDir, targetRelease)
+	if err != nil {
+		panic(err)
+	}
+	DumpProtos(outputDir, &configs.Artifact)
+}
