Commit graph

83 commits

Author SHA1 Message Date
Colin Cross
de7afaaf74 Write ninja file directly to the output file
Writing the ninja file to a byte buffer causes a significant amount
of time to be spent in memmove when growing the byte slice.  Write
the file directly to disk instead.

This also fixes some unhandled error warnings, which become more
likely when doing disk IO instead of byte buffer writes.

Change-Id: I5094e4c45cab4012713037f60c5a4fb00718f92e
2019-01-23 13:26:42 -08:00
Dan Willemsen
dac90d33ca Add --empty-ninja-file for test usecases
In cases that we want to run blueprint-based builds in many
configurations to verify all of the logic works without errors, but
don't care about running the final ninja file, writing it out only
wastes time and disk space. So add a --empty-ninja-file option that
writes out an empty ninja file instead.

Our specific use case (Soong's build_test / multiproduct_kati) runs
Soong several hundred times for different configurations, and the ninja
files are around 1GB, which leads to several hundred gigabytes of disk
writes (and persistent use during incremental generation).

Change-Id: I0198dfb2f744ce22284c05d5214dac2ab5dc9700
2018-10-26 09:57:24 -07:00
Dan Willemsen
ab223a512b Run globs during earlier bootstrap phases
Instead of sometimes re-running minibp/the primary builder during the
next phase, run bpglob earlier to check dependencies.

We've run into issues where the environment is slightly different
between bootstrapping phase and the main build phase. It's also a
problem because our primary builder (Soong) exports information used by
another tool (Kati) that runs in between the bootstrapping phases and
the main phase. When Soong would run in the main phase, it could get out
of sync, and would require the build to be run again.

To do this, add a "subninja" include a build-globs.ninja file to each
build.ninja file. The first time, this will be an empty file, but we'll
always run minibp / the primary builder anyway. When the builder runs,
in addition to writing a dependency file, write out the
build-globs.ninja file with the rules to run bpglob.

Since bpglob may need to be run very early, before it would normally be
built, build it with microfactory.

Change-Id: I89fcd849a8729e892f163d40060ab90b5d4dfa5d
2018-07-06 10:39:38 -07:00
Colin Cross
28b2843b78 Allow primary builder to stop bootstrap early
Allow the primary builder to stop bootstrap between
ResolveDependencies and PrepareBuildActions so that it can
use the build graph to write customized documentation.

Change-Id: I67ee5e6e438a0c2c3ec844c4c453d223971e60a2
2017-12-11 16:31:41 -08:00
Colin Cross
92639f3fbb Refactor bpdoc
Separate the extraction of documentation-related info from writing
it out so that the primary builder can choose to write it out in
a customized format.

Change-Id: If2c91d6f13b8cea2e9e1cca75d8c2d684ad7f6df
2017-12-11 16:31:41 -08:00
Jeff Gaston
c3e2844dfe Support for a custom list of Blueprints files to parse
Bug: 64363847
Test: BLUEPRINT_LIST_FILE=out/.module_paths/Android.bp.list minibp

Change-Id: Id7f8cb1ab3a6684b3f8265d77bb32413957f1c93
2017-10-30 15:00:19 -07:00
Colin Cross
874a346904 Let mutators use ctx.AddNinjaFileDeps
Propagate extra ninja file deps through mutators so that they
can use ctx.AddNinjaFileDeps.

Test: blueprint tests
Change-Id: I299a0665c3f63b020ae345889fd78b91b91b215a
2017-08-01 15:12:12 -07:00
Dan Willemsen
cd4e0cebc9 Unify .ninja_log files
Having separate .ninja_log files doesn't work very well after
04d886b110
since the last successful timestamp is not recorded in the ninja log.
This was triggering the primary builder to be run twice on every build
since it was always considered out of date in the primary, then main
stages.

The two bootstrap stages already were unified when minibootstrap was
simplified, but this combines the main stage as well. This means that
we'll save some time running globs that are shared between minibp and
the primary builder as well (subdirs globs).

The cleanup code needed to be refactored, since the ninja_log will have
entries from the main stage as well. So instead of looking at everything
in the ninja log, take a string prefix to limit what we may clean.

Change-Id: I8d43168643aa8a0c6c3e48c6101eaa45d174bbe5
2017-07-24 14:02:51 -07:00
Dan Willemsen
af456eaae4 Define everything in both stages
Now that packages and binaries are only built when needed, they need to
be defined in both stages in case something building in the main stage
needs something that was defined, but didn't need to be built in the
earlier stage.

Change-Id: I67704fba1d670e82218eba5ce91f0c01896557a2
2017-07-24 14:02:51 -07:00
Dan Willemsen
1e72321e58 Use microfactory to build the bootstrap minibp
This duplicates building common blueprint go packages between minibp and
the primary builder, but drastically simplifies the first stage,
removing the need to check in a generated build.ninja.in.

Change-Id: I639a9637f1ed36d4210823ef276c0f7a064a83bd
2017-07-24 14:02:51 -07:00
Colin Cross
127d2eae8b Import globbing from Soong
Add globbing with dependency checking to blueprint.  Calling
ModuleContext.GlobWithDeps or SingletonContext.GlobWithDeps will return
a list of files that match the globs, while also adding efficient
dependencies to rerun the primary builder if a file that matches the
glob is added or removed.

Also use the globbing support for optional_subdirs=, subdirs= and build=
lines in blueprints files.  The globbing slightly changes the behavior
of subname= lines, it no longer falls back to looking for a file called
"Blueprints".  Blueprint files that need to include a subdirectory with
a different name can use build= instead of subdir= to directly include
them.  The Blueprints file is updated to reset subname="Blueprints" in
case we want to include subdirectories inside blueprint and the primary
builder has changed the subname.

Also adds a new test directory that contains a simple primary builder
tree to test regeneration for globbing, and runs the tests in travis.

Change-Id: I83ce525fd11e11579cc58ba5308d01ca8eea7bc6
2016-11-03 13:54:03 -07:00
colincross
53d4357592 Merge pull request #127 from colincross/memprofile
Add support for memory profiling
2016-10-12 11:16:42 -07:00
Colin Cross
2c62844274 Improve error reporting
Report module name and variant and property names in errors.

Change-Id: I747f840402497b2c92bf8c565d7c50af33e6ab0e
2016-10-12 11:14:18 -07:00
Colin Cross
2ecec57e47 Add support for memory profiling
Add -memprofile argument to support capturing a heap profile, and -nogc
to disable the garbage collector to see all allocations.

Change-Id: I0d4c5f2bf79786aed4b2af4be112ecf0a2810a91
2016-10-12 11:12:54 -07:00
Dan Willemsen
7d0dddd84d Simplify bootstrap
tl;dr: Read if you don't use the wrapper or use SKIP_NINJA

Previously, we were relying on the ninja behavior of restarting the
build when the build.ninja file was updated to switch between different
bootstrap stages. But that means that every step that could produce a
build.ninja must pass in order to switch to a different stage. That
wasn't a big problem when we had a two stage build -- there was very
little that could fail in the second stage before we chose to go back to
the first stage. But when we had a three stage build, it was possible to
get into a state (usually during development) where you were in the
second stage, but the build was failing because the first stage needed
to be run. This was fixed in d79f1af742
by adding a wrapper that always started building at the first stage.

But this kept all of the complexity of using ninja restarts without any
of the benefits, so this change removes that complexity and just runs
each stage sequentially in the wrapper. So the wrapper is now required.

Since we're no longer going through choosestage, we can also skip the
template parsing for the later stages that don't need to be templated --
this can save a couple of seconds for large files.

In addition to all of the above, this also lets Soong reduce the number
of times the main ninja file is loaded. We had been running the wrapper
once (3 stages), then running ninja again after combining the
Soong-generated build.ninja with the Kati-generated build.ninja. This
change lets us removing the intermediate parsing of Soong's build.ninja,
so that we only execute ninja 3 times per build. It also lets us have
dependencies on pools or rules from Kati in the primary builder, since
we're never executing the main build.ninja without the Kati build.ninja.

The wrapper has a new option, NINJA to provide the path to ninja. This
used to be hardcoded to `ninja`, and will still default to that. But
we'll be running the first two bootstrap stages with $NINJA even if
SKIP_NINJA is set.

The wrapper passes "-w dupbuild=err" to ninja now -- this really should
always be turned on if you care about reliable builds.

Change-Id: I6f656b74eb3d064b8b9e69d1d6dac1129d72b747
2016-08-30 17:26:56 -07:00
Colin Cross
aec881da86 Add option to trace goroutine execution
Passing -trace <file> on the command line produces a trace file that can
be used with go tool trace to examine concurrency.

Change-Id: I7d27bca64d0f0816cb4e518e947b70bc1c0573a3
2016-08-05 14:00:30 -07:00
Dan Willemsen
be275236ac Add blueprint_go_binary for user-run tools
Move these tools from $buildDir/.bootstrap/bin to $buildDir/bin
(configurable by the primary builder).

Also delay building them until the main stage, and give them a phony
target "blueprint_tools".
2016-05-26 10:09:35 -07:00
Colin Cross
ea5995439c Colorize errors
Prefix errors with "error:" or "internal error:" colored in red using
ANSI codes.  Ninja will strip the ANSI codes when build output is not
going to a terminal that can handle ANSI codes.
2016-01-07 17:24:15 -08:00
Colin Cross
6d529f0e16 Make removing abandoned files optional
Build logic can now implement a RemoveAbandonedFiles, and the bootstrap
logic will only remove abandoned files if that method returns true.
Leaving the method unimplemented will result in the existing behavior of
always removing abandoned files.
2015-11-18 15:29:12 -08:00
colincross
8282be78ee Merge pull request #49 from danw/plugins
Implement go bootstrap plugins
2015-09-14 16:01:46 -07:00
Dan Willemsen
fdeb724f74 Implement plugins for bootstrap go modules
Now that we have multi-stage bootstrapping, we can make the primary
builder build more dynamic. Add the concept of plugins that will be
linked and loaded into bootstrap_go_binary or bootstrap_go_package
modules. It's expected that the plugin's init() functions will do
whatever registration is necessary.

Example Blueprint definition:

    bootstrap_go_binary {
      name: "builder",
      ...
    }

    bootstrap_go_package {
      name: "plugin1",
      pluginFor: ["builder"],
    }

A package may specify more than one plugin if it will be inserted into
more than one go module.

Change-Id: I109835f444196b66fc4018c3fa36ba0875823184
2015-09-14 15:35:12 -07:00
George Kulakowski
4904c8ab3f Add new line to fatal error messages in bootstrap 2015-08-21 14:47:06 -07:00
Dan Willemsen
f0ca90124a Support a separate build directory
To provide a consistent __FILE__ behavior with cpp, we want to be able
to run with SRCDIR="." and the outputs be saved elsewhere. Other tools
within android also expect to be run from $TOP.

Change-Id: I572bce5c9086b0c3310b42065ae98cbf5a1c6399
2015-08-01 20:07:37 -07:00
Dan Willemsen
efd2de734d Use three stage builds
This splits the current bootstrap stage into two stages:

A bootstrap stage, which like today, a reference is checked into the
tree. It just builds the "core" blueprint binaries -- minibp,
gotestmain, and choosestage. Just enough to build the next stage's ninja
file.

A primary builder stage. This builds the primary builder, the main ninja
file, and any other bootstrap binaries (bpfmt, etc).

The main advantage here is that the checked in file really only contains
references to blueprint -- not the primary builder. This will allow us
to make the primary builder more dynamic, by loading more module types
that may or may not exist in all trees.

It's even possible to reuse the build.ninja.in in the blueprint repo
directly now. We don't currently do that, since we still want to turn on
tests.

Change-Id: I18683891ed7348b0d7af93084e3a68a04fbd5dbc
2015-07-29 17:14:00 -07:00
Dan Willemsen
91a657e219 Enhance bootstrap stage selection
This simplifies the bootstrap process while making it more flexible by
moving the stage selection into a go binary(choosestage). It will now be
possible to have more than two build stages.

Now each stage has a ninja template(main.ninja.in) and a timestamp
file(main.ninja.in.timestamp). The timestamp file may be updated by any
build stage that wishes to regenerate the ninja template. If the
choosestage binaries sees that the timestamp is newer than the template,
it will choose the prior stage.

The main stage no longer writes to the source tree to update the
build.ninja.in file. This was a problem for read-only source trees.
Instead, the choosestage binary first checks to see if that file is
newer than the last bootstrap.ninja.in, copies it in place, and starts
the boostrap stage.

The bootstrap stage regenerates it's own ninja template, but that
required a loop through the main stage to actually run it. The
choosestage binary now detects if the template has changed for the
current stage, and will restart the stage.

One change is that if dependencies do get messed up, instead of silently
failing, there's a higher chance that the bootstrap step will just
continue looping, doing nothing. This can happen if the main stage
has a dependency that triggers the bootstrap stage, but the bootstrap
stage doesn't see anything required to rebuild the main ninja file. A
side effect of this requirement is that changes to test code will now
rebuild the main ninja file.

Change-Id: I9965cfba79dc0dbbd3af05f5944f7653054455a2
2015-07-23 22:06:02 -07:00
Colin Cross
4572edddfa Add self-documenting support
The primary builder will now generate a rule to call itself with
--docs=.bootstrap/docs/<name>.html to produce an automatically
generated documentation file.

The documentation generation process is:
 - Call each factory once to get empty property structs associated
   with the module type
 - Use reflection to determine the names of the type of each property
   struct
 - Use the bootstrap_go_package modules from reading the Blueprints files
   to find the source files for each Go package used to build the primary
   builder
 - Use the go/parser module to find the type declaration for each
   property struct
 - Extract comments for the property struct and each property declaration
 - Format all the comments into HTML

Change-Id: Icae9307cc10549a30bfc14d6922824099de5a9b0
2015-06-26 10:51:44 -07:00
Dan Willemsen
87ba294ceb Add option to build and run tests during bootstrap
Users that want to enable this option can use the '-t' option to
bootstrap.bash when passing '-r'. Builders that want to enable this can
set the RUN_TESTS environment variable in their bootstrap.bash.

The gotestmain tools is needed to write the main functions for the test
binaries, since 'go test' doesn't work well in this environment.

Change-Id: Iec5c2b5c9c3f5e3ba0ac8677fb88f5e963f9bd3f
2015-06-25 11:45:54 -07:00
Dan Willemsen
30a80c3e5f Create internal bootstrap Config struct
Change-Id: If5c5ce3d5c46196cf9b77ff9f5c68b8849474823
2015-06-24 22:44:37 -07:00
Colin Cross
63d5d4d9e4 Fix formatting
gofmt -w .

Change-Id: If9cf0b7bd810f899edffcd2edf361fa83245bd2a
2015-04-20 16:41:55 -07:00
Colin Cross
5bdb4ca1a5 Set GOMAXPROCS to number of CPUs
Apparently Go only allows a single thread to be executing by default,
so the increase in performance seen when concurrency was added to
Blueprint was entirely due to scheduling goroutines while the
executing goroutine was blocked in a syscall.  Whoops.

Set GOMAXPROCS to the number of CPUs.  Reduces wall thime by >2x on
one workload.

Change-Id: Ib5fc7761c09a076fc5a1b7f08f5ccf034304477c
2015-04-15 11:03:17 -07:00
Jamie Gennis
6cafc2cddc Update import paths to include github 2015-03-21 01:03:36 -04:00
Colin Cross
8e0c51192a Add license headers and LICENSE file
Change-Id: I6f7c7374093c0745ee4aa677480376a06648b358
2015-01-23 14:23:27 -08:00
Colin Cross
3e8e74f276 Move blueprint/* up a directory
Make integrating with go tools easier by putting the blueprint package
files in the top level directory of the git project instead of in a
subdirectory called blueprint.

Change-Id: I35c144c5fe7ddf34e478d0c47c50b2f6c92c2a03
2015-01-23 14:23:27 -08:00
Renamed from blueprint/bootstrap/command.go (Browse further)