• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2014 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// The Blueprint bootstrapping mechanism is intended to enable building a source
16// tree using a Blueprint-based build system that is embedded (as source) in
17// that source tree.  The only prerequisites for performing such a build are:
18//
19//   1. A Ninja binary
20//   2. A script interpreter (e.g. Bash or Python)
21//   3. A Go toolchain
22//
23// The Primary Builder
24//
25// As part of the bootstrapping process, a binary called the "primary builder"
26// is created.  This primary builder is the binary that includes both the core
27// Blueprint library and the build logic specific to the source tree.  It is
28// used to generate the Ninja file that describes how to build the entire source
29// tree.
30//
31// The primary builder must be a pure Go (i.e. no cgo) module built with the
32// module type 'bootstrap_go_binary'.  It should have the 'primaryBuilder'
33// module property set to true in its Blueprints file.  If more than one module
34// sets primaryBuilder to true the build will fail.
35//
36// The primary builder main function should look something like:
37//
38//   package main
39//
40//   import (
41//       "flag"
42//       "github.com/google/blueprint"
43//       "github.com/google/blueprint/bootstrap"
44//       "path/filepath"
45//
46//       "my/custom/build/logic"
47//   )
48//
49//   func main() {
50//       // The primary builder should use the global flag set because the
51//       // bootstrap package registers its own flags there.
52//       flag.Parse()
53//
54//       // The top-level Blueprints file is passed as the first argument.
55//       srcDir := filepath.Dir(flag.Arg(0))
56//
57//       // Create the build context.
58//       ctx := blueprint.NewContext()
59//
60//       // Register custom module types
61//       ctx.RegisterModuleType("foo", logic.FooModule)
62//       ctx.RegisterModuleType("bar", logic.BarModule)
63//
64//       // Register custom singletons
65//       ctx.RegisterSingleton("baz", logic.NewBazSingleton())
66//
67//       // Create and initialize the custom Config object.
68//       config := logic.NewConfig(srcDir)
69//
70//       // This call never returns
71//       bootstrap.Main(ctx, config)
72//   }
73//
74// Required Source Files
75//
76// There are three files that must be included in the source tree to facilitate
77// the build bootstrapping:
78//
79//   1. The top-level Blueprints file
80//   2. The bootstrap Ninja file template
81//   3. The bootstrap script
82//
83// The top-level Blueprints file describes how the entire source tree should be
84// built.  It must have a 'subdirs' assignment that includes both the core
85// Blueprint library and the custom build logic for the source tree.  It should
86// also include (either directly or through a subdirs entry) describe all the
87// modules to be built in the source tree.
88//
89// The bootstrap Ninja file template describes the build actions necessary to
90// build the primary builder for the source tree.  This template contains a set
91// of placeholder Ninja variable values that get filled in by the bootstrap
92// script to create a usable Ninja file.  It can be created by running the
93// minibp binary that gets created as part of the standalone Blueprint build.
94// Passing minibp the path to the top-level Blueprints file will cause it to
95// create a bootstrap Ninja file template named 'build.ninja.in'.
96//
97// The bootstrap script is a small script (or theoretically a compiled binary)
98// that is included in the source tree to begin the bootstrapping process.  It
99// is responsible for filling in the bootstrap Ninja file template with some
100// basic information about the Go build environemnt and the path to the root
101// source directory.  It does this by performing a simple string substitution on
102// the template file to produce a usable build.ninja file.
103//
104// The Bootstrapping Process
105//
106// A bootstrap-enabled build directory has two states, each with a corresponding
107// Ninja file. The states are referred to as the "bootstrap" state and the
108// "main" state. Changing the directory to a particular state means replacing
109// the build.ninja file with one that will perform the build actions for the
110// state.
111//
112// The bootstrapping process begins with the user running the bootstrap script
113// to initialize a new build directory.  The script is run from the build
114// directory, and when run with no arguments it copies the source bootstrap
115// Ninja file into the build directory as "build.ninja".  It also performs a set
116// of string substitutions on the file to configure it for the user's build
117// environment. Specifically, the following strings are substituted in the file:
118//
119//   @@SrcDir@@            - The path to the root source directory (either
120//                           absolute or relative to the build dir)
121//   @@GoRoot@@            - The path to the root directory of the Go toolchain
122//   @@GoCompile@@         - The path to the Go compiler (6g or compile)
123//   @@GoLink@@            - The path to the Go linker (6l or link)
124//   @@Bootstrap@@         - The path to the bootstrap script
125//   @@BootstrapManifest@@ - The path to the source bootstrap Ninja file
126//
127// Once the script completes the build directory is initialized in the bootstrap
128// build state.  In this state, running Ninja may perform the following build
129// actions.  Each one but the last can be skipped if its output is determined to
130// be up-to-date.
131//
132// 	- Build the minibp binary
133// 	- Run minibp to generate .bootstrap/bootstrap.ninja.in
134// 	- Build the primary builder binary
135// 	- Run the primary builder to generate .bootstrap/main.ninja.in
136// 	- Run the bootstrap script to "copy" .bootstrap/main.ninja.in to build.ninja
137//
138// The last of these build actions results in transitioning the build directory
139// to the main build state.
140//
141// The main state (potentially) performs the following actions:
142//   - Copy .bootstrap/bootstrap.ninja.in to the source bootstrap Ninja location
143//   - Run the bootstrap script to "copy" the source bootstrap Ninja file to
144//     build.ninja
145//   - Build all the non-bootstrap modules defined in Blueprints files
146//
147// Updating the Bootstrap Ninja File Template
148//
149// The main purpose of the bootstrap state is to generate the Ninja file for the
150// main state.  The one additional thing it does is generate a new bootstrap
151// Ninja file template at .bootstrap/bootstrap.ninja.in.  When generating this
152// file, minibp will compare the new bootstrap Ninja file contents with the
153// original (in the source tree).  If the contents match, the new file will be
154// created with a timestamp that matches that of the original, indicating that
155// the original file in the source tree is up-to-date.
156//
157// This is done so that in the main state if the bootstrap Ninja file template
158// in the source tree is out of date it can be automatically updated.  Note,
159// however, that we can't have the main state generate the new bootstrap Ninja
160// file template contents itself, because it may be using an older minibp.
161// Recall that minibp is only built during the bootstrap state (to break a
162// circular dependence), so if a new bootstrap Ninja file template were
163// generated then it could replace a new file (from an updated source tree) with
164// one generated using an old minibp.
165//
166// This scheme ensures that updates to the source tree are always incorporated
167// into the build process and that changes that require a new bootstrap Ninja
168// file template automatically update the template in the source tree.
169package bootstrap
170