README.md
1 # Regenerating project files
2
3 Prerequisites: `python`, `pip install mako`, `go`
4
5 ```
6 # Regenerate the projects files using templates
7 tools/buildgen/generate_projects.sh
8 ```
9
10 # Quick justification
11
12 We've approached the problem of the build system from a lot of different
13 angles. The main issue was that there isn't a single build system that
14 was going to single handedly cover all of our usage cases.
15
16 So instead we decided to work the following way:
17
18 * A `build.yaml` file at the root is the source of truth for listing all the
19 targets and files needed to build grpc and its tests, as well as a basic system
20 for dependency description.
21
22 * Each project file (Makefile, Visual Studio project files, Bazel's BUILD) is
23 a [YAML](http://yaml.org) file used by the `build.yaml` file to generate the
24 final output file.
25
26 This way we can maintain as many project system as we see fit, without having
27 to manually maintain them when we add or remove new code to the repository.
28 Only the structure of the project file is relevant to the template. The actual
29 list of source code and targets isn't.
30
31 We currently have template files for GNU Make, Visual Studio 2013,
32 [Bazel](http://bazel.io) and [gyp](https://gyp.gsrc.io/) (albeit only for
33 Node.js). In the future, we
34 would like to expand to also generate [cmake](https://cmake.org)
35 project files, XCode project files, and an Android.mk file allowing to compile
36 gRPC using Android's NDK.
37
38 We'll gladly accept contribution that'd create additional project files
39 using that system.
40
41 # Structure of `build.yaml`
42
43 The `build.yaml` file has the following structure:
44
45 ```
46 settings: # global settings, such as version number
47 ...
48 filegroups: # groups of files that are automatically expanded
49 ...
50 libs: # list of libraries to build
51 ...
52 target: # list of targets to build
53 ...
54 ```
55
56 The `filegroups` are helpful to re-use a subset of files in multiple targets.
57 One `filegroups` entry has the following structure:
58
59 ```
60 - name: "arbitrary string", # the name of the filegroup
61 public_headers: # list of public headers defined in that filegroup
62 - ...
63 headers: # list of headers defined in that filegroup
64 - ...
65 src: # list of source files defined in that filegroup
66 - ...
67 ```
68
69 The `libs` collection contains the list of all the libraries we describe. Some may be
70 helper libraries for the tests. Some may be installable libraries. Some may be
71 helper libraries for installable binaries.
72
73 The `targets` array contains the list of all the binary targets we describe. Some may
74 be installable binaries.
75
76 One `libs` or `targets` entry has the following structure (see below for
77 details):
78
79 ```
80 name: "arbitrary string", # the name of the library
81 build: "build type", # in which situation we want that library to be
82 # built and potentially installed (see below).
83 language: "...", # the language tag; "c" or "c++"
84 public_headers: # list of public headers to install
85 headers: # list of headers used by that target
86 src: # list of files to compile
87 secure: boolean, # see below
88 baselib: boolean, # this is a low level library that has system
89 # dependencies
90 vs_project_guid: '{...}', # Visual Studio's unique guid for that project
91 filegroups: # list of filegroups to merge to that project
92 # note that this will be expanded automatically
93 deps: # list of libraries this target depends on
94 deps_linkage: "..." # "static" or "dynamic". Used by the Makefile only to
95 # determine the way dependencies are linkned. Defaults
96 # to "dynamic".
97 dll: "..." # see below.
98 dll_def: "..." # Visual Studio's dll definition file.
99 vs_props: # List of property sheets to attach to that project.
100 vs_config_type: "..." # DynamicLibrary/StaticLibrary. Used only when
101 # creating a library. Specifies if we're building a
102 # static library or a dll. Use in conjunction with `dll_def`.
103 vs_packages: # List of nuget packages this project depends on.
104 ```
105
106 ## The `"build"` tag
107
108 Currently, the "`build`" tag have these meanings:
109
110 * `"all"`: library to build on `"make all"`, and install on the system.
111 * `"protoc"`: a protoc plugin to build on `"make all"` and install on the system.
112 * `"private"`: a library to only build for tests.
113 * `"test"`: a test binary to run on `"make test"`.
114 * `"tool"`: a binary to be built upon `"make tools"`.
115
116 All of the targets should always be present in the generated project file, if
117 possible and applicable. But the build tag is what should group the targets
118 together in a single build command.
119
120
121 ## The `"secure"` tag
122
123 This means this target requires OpenSSL one way or another. The values can be
124 `"yes"`, `"no"` and `"check"`. The default value is `"check"`. It means that
125 the target requires OpenSSL, but that since the target depends on another one
126 that is supposed to also import OpenSSL, the import should then be implicitely
127 transitive. `"check"` should then only disable that target if OpenSSL hasn't
128 been found or is unavailable.
129
130 ## The `"baselib"` boolean
131
132 This means this is a library that will provide most of the features for gRPC.
133 In particular, if we're locally building OpenSSL, protobuf or zlib, then we
134 should merge OpenSSL, protobuf or zlib inside that library. That effect depends
135 on the `"language"` tag. OpenSSL and zlib are for `"c"` libraries, while
136 protobuf is for `"c++"` ones.
137
138 ## The `"dll"` tag
139
140 Used only by Visual Studio's project files. "true" means the project will be
141 built with both static and dynamic runtimes. "false" means it'll only be built
142 with static runtime. "only" means it'll only be built with the dll runtime.
143
144 ## The `"dll_def"` tag
145
146 Specifies the visual studio's dll definition file. When creating a DLL, you
147 sometimes (not always) need a def file (see grpc.def).
148
149
150 # The template system
151
152 We're currently using the [mako templates](http://www.makotemplates.org/)
153 renderer. That choice enables us to simply render text files without dragging
154 with us a lot of other features. Feel free to explore the current templates
155 in that directory. The simplest one is probably [BUILD.template](BUILD.template)
156 which is used to create the [Bazel](http://bazel.io/) project file.
157
158 ## The renderer engine
159
160 As mentioned, the renderer is using [mako templates](http://www.makotemplates.org/),
161 but some glue is needed to process all of that. See the [buildgen folder](../tools/buildgen)
162 for more details. We're mainly loading the build.json file, and massaging it,
163 in order to get the list of properties we need, into a Python dictionary, that
164 is then passed to the template while rending it.
165
166 ## The plugins
167
168 The file build.json itself isn't passed straight to the template files. It is
169 first processed and modified by a few plugins. For example, the `filegroups`
170 expander is [a plugin](../tools/buildgen/plugins/expand_filegroups.py).
171
172 The structure of a plugin is simple. The plugin must defined the function
173 `mako_plugin` that takes a Python dictionary. That dictionary represents the
174 current state of the build.json contents. The plugin can alter it to whatever
175 feature it needs to add.
176