mirror of https://github.com/grpc/grpc.git
commit
97a678edb8
6 changed files with 358 additions and 2610 deletions
@ -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. |
Loading…
Reference in new issue