-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding some documentation about the build/template system.
- Loading branch information
1 parent
e00bd9c
commit 8512fba
Showing
3 changed files
with
144 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
# Quick justification | ||
|
||
We've approached the problem of the build system from a lot of different | ||
angles. The main issue was that there isn't a single build system that | ||
was going to single handedly cover all of our usage cases. | ||
|
||
So instead we decided to work the following way: | ||
|
||
* A build.json file at the root is the source of truth for listing all of the | ||
target and files needed to build grpc and its tests, as well as basic system | ||
dependencies description. | ||
|
||
* Each project file (Makefile, Visual Studio project files, Bazel's BUILD) is | ||
a plain-text template that uses the build.json file to generate the final | ||
output file. | ||
|
||
This way we can maintain as many project system as we see fit, without having | ||
to manually maintain them when we add or remove new code to the repository. | ||
Only the structure of the project file is relevant to the template. The actual | ||
list of source code and targets isn't. | ||
|
||
We currently have template files for GNU Make, Visual Studio 2010 to 2015, | ||
and Bazel. In the future, we would like to expand to generating gyp or cmake | ||
project files (or potentially both), XCode project files, and an Android.mk | ||
file to be able to compile gRPC using Android's NDK. | ||
|
||
We'll gladly accept contribution that'd create additional project files | ||
using that system. | ||
|
||
# Structure of build.json | ||
|
||
The build.json file has the following structure: | ||
|
||
``` | ||
{ | ||
"settings": { ... }, # global settings, such as version number | ||
"filegroups": [ ... ], # groups of file that is automatically expanded | ||
"libs": [ ... ], # list of libraries to build | ||
"targets": [ ... ], # list of targets to build | ||
} | ||
``` | ||
|
||
The `filegroups` are helpful to re-use a subset of files in multiple targets. | ||
One `filegroups` entry has the following structure: | ||
|
||
``` | ||
{ | ||
"name": "arbitrary string", # the name of the filegroup | ||
"public_headers": [ ... ], # list of public headers defined in that filegroup | ||
"headers": [ ... ], # list of headers defined in that filegroup | ||
"src": [ ... ], # list of source files defined in that filegroup | ||
} | ||
``` | ||
|
||
The `libs` array contains the list of all the libraries we describe. Some may be | ||
helper libraries for the tests. Some may be installable libraries. Some may be | ||
helper libraries for installable binaries. | ||
|
||
The `targets` array contains the list of all the binary targets we describe. Some may | ||
be installable binaries. | ||
|
||
One `libs` or `targets` entry has the following structure: | ||
|
||
``` | ||
{ | ||
"name": "arbitrary string", # the name of the library | ||
"build": "build type", # in which situation we want that library to be | ||
# built and potentially installed | ||
"language": "...", # the language tag; "c" or "c++" | ||
"public_headers": [ ... ], # list of public headers to install | ||
"headers": [ ... ], # list of headers used by that target | ||
"src": [ ... ], # list of files to compile | ||
"secure": "...", # "yes", "no" or "check" | ||
"baselib": boolean, # this is a low level library that has system | ||
# dependencies | ||
"vs_project_guid: "...", # Visual Studio's unique guid for that project | ||
"filegroups": [ ... ], # list of filegroups to merge to that project | ||
# note that this will be expanded automatically | ||
"deps": [ ... ], # list of libraries this target depends on | ||
} | ||
``` | ||
|
||
## The `"build"` tag | ||
|
||
Currently, the "`build`" tag have these meanings: | ||
|
||
* `"all"`: library to build on `"make all"`, and install on the system. | ||
* `"protoc"`: a protoc plugin to build on `"make all"` and install on the system. | ||
* `"priviate"`: a library to only build for tests. | ||
* `"test"`: a test binary to run on `"make test"`. | ||
|
||
All of the targets should always be present in the generated project file, if | ||
possible and applicable. But the build tag is what should group the targets | ||
together in a single build command. | ||
|
||
|
||
## The `"secure"` tag | ||
|
||
This means this target requires OpenSSL one way or another. The values can be | ||
`"yes"`, `"no"` and `"check"`. The default value is `"check"`. It means that | ||
the target requires OpenSSL, but that since the target depends on another one | ||
that is supposed to also import OpenSSL, the import should then be implicitely | ||
transitive. `"check"` should then only disable that target if OpenSSL hasn't | ||
been found or is unavailable. | ||
|
||
## The `"baselib"` boolean | ||
|
||
This means this is a library that will provide most of the features for gRPC. | ||
In particular, if we're locally building OpenSSL, protobuf or zlib, then we | ||
should merge OpenSSL, protobuf or zlib inside that library. That effect depends | ||
on the `"language"` tag. OpenSSL and zlib are for `"c"` libraries, while | ||
protobuf is for `"c++"` ones. | ||
|
||
# The template system | ||
|
||
We're currently using the [mako templates](http://www.makotemplates.org/) | ||
renderer. That choice enables us to simply render text files without dragging | ||
with us a lot of other features. Feel free to explore the current templates | ||
in that directory. The simplest one is probably [BUILD.template](BUILD.template) | ||
which is used to create the [Bazel](http://bazel.io/) project file. | ||
|
||
## The renderer engine | ||
|
||
As mentioned, the renderer is using [mako templates](http://www.makotemplates.org/), | ||
but some glue is needed to process all of that. See the [buildgen folder](../tools/buildgen) | ||
for more details. We're mainly loading the build.json file, and massaging it, | ||
in order to get the list of properties we need, into a Python dictionary, that | ||
is then passed to the template while rending it. | ||
|
||
## The plugins | ||
|
||
The file build.json itself isn't passed straight to the template files. It is | ||
first processed and modified by a few plugins. For example, the `filegroups` | ||
expander is [a plugin](../tools/buildgen/plugins/expand_filegroups.py). | ||
|
||
The structure of a plugin is simple. The plugin must defined the function | ||
`mako_plugin` that takes a Python dictionary. That dictionary represents the | ||
current state of the build.json contents. The plugin can alter it to whatever | ||
feature it needs to add. |