// Copyright 2015 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.

// Blueprint is a meta-build system that reads in Blueprints files that describe
// modules that need to be built, and produces a Ninja
// (https://ninja-build.org/) manifest describing the commands that need
// to be run and their dependencies.  Where most build systems use built-in
// rules or a domain-specific language to describe the logic how modules are
// converted to build rules, Blueprint delegates this to per-project build logic
// written in Go.  For large, heterogenous projects this allows the inherent
// complexity of the build logic to be maintained in a high-level language,
// while still allowing simple changes to individual modules by modifying easy
// to understand Blueprints files.
//
// Blueprint uses a bootstrapping process to allow the code for Blueprint,
// the code for the build logic, and the code for the project being compiled
// to all live in the project.  Dependencies between the layers are fully
// tracked - a change to the logic code will cause the logic to be recompiled,
// regenerate the project build manifest, and run modified project rules.  A
// change to Blueprint itself will cause Blueprint to rebuild, and then rebuild
// the logic, etc.
//
// A Blueprints file is a list of modules in a pseudo-python data format, where
// the module type looks like a function call, and the properties of the module
// look like optional arguments.  For example, a simple module might look like:
//
//   cc_library {
//       name: "cmd",
//       srcs: [
//           "main.c",
//       ],
//       deps: [
//           "libc",
//       ],
//   }
//
//   subdirs = ["subdir1", "subdir2"]
//
// The modules from the top level Blueprints file and recursively through any
// subdirectories listed by the "subdirs" variable are read by Blueprint, and
// their properties are stored into property structs by module type.  Once
// all modules are read, Blueprint calls any registered Mutators, in
// registration order.  Mutators can visit each module top-down or bottom-up,
// and modify them as necessary.  Common modifications include setting
// properties on modules to propagate information down from dependers to
// dependees (for example, telling a module what kinds of parents depend on it),
// or splitting a module into multiple variants (for example, one per
// architecture being compiled).  After all Mutators have run, each module is
// asked to generate build rules based on property values, and then singletons
// can generate any build rules from the output of all modules.
//
// The per-project build logic defines a top level command, referred to in the
// documentation as the "primary builder".  This command is responsible for
// registering the module types needed for the project, as well as any
// singletons or mutators, and then calling into Blueprint with the path of the
// root Blueprint file.
package blueprint
