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