blob: 573ff7be7cd7c06280e19cc19850c46eccca5085 [file] [log] [blame]
Colin Cross8e0c5112015-01-23 14:15:10 -08001// 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
Jamie Gennis7ab5f3c2014-06-11 15:51:08 -070015// 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 (
Jamie Gennis7ab5f3c2014-06-11 15:51:08 -070041// "flag"
Jamie Gennis6cafc2c2015-03-20 22:39:29 -040042// "github.com/google/blueprint"
43// "github.com/google/blueprint/bootstrap"
Jamie Gennis7ab5f3c2014-06-11 15:51:08 -070044// "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
Jamie Gennis0453c752014-06-12 14:00:10 -070099// 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.
Jamie Gennis7ab5f3c2014-06-11 15:51:08 -0700103//
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
Jamie Gennis0453c752014-06-12 14:00:10 -0700109// the build.ninja file with one that will perform the build actions for the
110// state.
Jamie Gennis7ab5f3c2014-06-11 15:51:08 -0700111//
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// @@GoOS@@ - The OS string for the Go toolchain
123// @@GoArch@@ - The CPU architecture for the Go toolchain
124// @@GoChar@@ - The CPU arch character for the Go toolchain
125// @@Bootstrap@@ - The path to the bootstrap script
126// @@BootstrapManifest@@ - The path to the source bootstrap Ninja file
127//
128// Once the script completes the build directory is initialized in the bootstrap
129// build state. In this state, running Ninja may perform the following build
130// actions. Each one but the last can be skipped if its output is determined to
131// be up-to-date.
132//
133// - Build the minibp binary
134// - Run minibp to generate .bootstrap/bootstrap.ninja.in
135// - Build the primary builder binary
136// - Run the primary builder to generate .bootstrap/main.ninja.in
137// - Run the bootstrap script to "copy" .bootstrap/main.ninja.in to build.ninja
138//
139// The last of these build actions results in transitioning the build directory
Jamie Gennis0453c752014-06-12 14:00:10 -0700140// to the main build state.
Jamie Gennis7ab5f3c2014-06-11 15:51:08 -0700141//
142// The main state (potentially) performs the following actions:
143// - Copy .bootstrap/bootstrap.ninja.in to the source bootstrap Ninja location
Jamie Gennis61e27fe2014-09-29 15:14:07 -0700144// - Run the bootstrap script to "copy" the source bootstrap Ninja file to
145// build.ninja
Jamie Gennis7ab5f3c2014-06-11 15:51:08 -0700146// - Build all the non-bootstrap modules defined in Blueprints files
147//
148// Updating the Bootstrap Ninja File Template
149//
150// The main purpose of the bootstrap state is to generate the Ninja file for the
151// main state. The one additional thing it does is generate a new bootstrap
152// Ninja file template at .bootstrap/bootstrap.ninja.in. When generating this
153// file, minibp will compare the new bootstrap Ninja file contents with the
154// original (in the source tree). If the contents match, the new file will be
155// created with a timestamp that matches that of the original, indicating that
156// the original file in the source tree is up-to-date.
157//
158// This is done so that in the main state if the bootstrap Ninja file template
159// in the source tree is out of date it can be automatically updated. Note,
160// however, that we can't have the main state generate the new bootstrap Ninja
161// file template contents itself, because it may be using an older minibp.
162// Recall that minibp is only built during the bootstrap state (to break a
163// circular dependence), so if a new bootstrap Ninja file template were
164// generated then it could replace a new file (from an updated source tree) with
165// one generated using an old minibp.
166//
167// This scheme ensures that updates to the source tree are always incorporated
168// into the build process and that changes that require a new bootstrap Ninja
169// file template automatically update the template in the source tree.
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700170package bootstrap