Skip to content
This repository was archived by the owner on Jan 15, 2021. It is now read-only.

Commit 85d8424

Browse files
committed
Merge pull request #327 from autopulated/app-config
Implement app-specific config
2 parents 7343db2 + c03535a commit 85d8424

File tree

11 files changed

+603
-46
lines changed

11 files changed

+603
-46
lines changed

docs/_layouts/default.html

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
<li data-section="reference/module"><a href="{{ site.github.url }}/reference/module.html">module.json</a></li>
4848
<li data-section="reference/target"><a href="{{ site.github.url }}/reference/target.html">target.json</a></li>
4949
<li data-section="reference/ignore"><a href="{{ site.github.url }}/reference/ignore.html">.yotta_ignore</a></li>
50+
<li data-section="reference/config"><a href="{{ site.github.url }}/reference/config.html">Config System</a></li>
5051
</ul>
5152
</div>
5253
<div class="col-sm-9">

docs/assets/css/docs.css

+5-5
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,14 @@ p{
4545

4646
#menu {
4747
min-height: 800px;
48-
width: 200px;
48+
width: 180px;
4949
}
5050
@media (min-width: 1200px) {
51-
width: 200px;
51+
width: 180px;
5252
}
5353
@media (max-width: 979px) and (min-width: 768px) {
5454
#menu {
55-
width: 200px;
55+
width: 180px;
5656
}
5757
}
5858
@media (max-width: 768px) {
@@ -74,8 +74,8 @@ p{
7474
margin-bottom: 7px;
7575
}
7676
#menu li a {
77-
padding-top: 8px;
78-
padding-bottom: 8px;
77+
padding-top: 6px;
78+
padding-bottom: 6px;
7979
}
8080
#menu li a {
8181
color: #999;

docs/reference/commands.md

+30-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
layout: default
3-
title: Yotta Command Reference
3+
title: yotta Command Reference
44
section: reference/commands
55
---
66

@@ -327,7 +327,7 @@ To link a module you need to perform two steps. First, in the directory of the d
327327
yotta link
328328
```
329329

330-
This will ensure it has all of its own dependencies installed, and then create a symlink from the global modules directory to the current module.
330+
This will create a symlink from the global modules directory to the current module.
331331

332332
Then, in the module that you would like to use the linked version of the dependency, run:
333333

@@ -344,9 +344,10 @@ When you run `yotta link`, links are created in a system-wide directory under
344344
`YOTTA_PREFIX`, and the links in that directory are then picked up by
345345
subsequent `yotta link <modulename>` commands.
346346

347-
On linux this defaults to `/usr/local`, and on windows to
348-
`%PROGRAMFILES/yotta`. To change this directory (e.g. to make yotta link things
349-
into your home directory), set the `YOTTA_PREFIX` environment variable.
347+
On linux this defaults to `/usr/local`, and on windows to the python
348+
installation directory (normally `c:\Python27`). To change this directory (e.g.
349+
to make yotta link things into your home directory), set the `YOTTA_PREFIX`
350+
environment variable.
350351

351352

352353
<a name="yotta-link-target"></a>
@@ -436,3 +437,27 @@ occurs in, instead of just once.
436437
`module.json` files, it can make no warranties about whether modules contain
437438
code under other licenses that have not been declared.
438439

440+
<a name="yotta-config"></a>
441+
## yotta config
442+
443+
#### Synopsis
444+
445+
```
446+
yotta config
447+
```
448+
449+
#### Description
450+
Display the merged [config data](/reference/config.html) for the current target
451+
(and application, if the current module defines an executable application).
452+
453+
The config data is produced by merging the json config data defined by the
454+
application, the current target, and any targets the current target inherits
455+
from recursively. Values defined by the application will override those defined
456+
at the same path by targets, and values defined in targets will override values
457+
defined by targets they inherit from.
458+
459+
The config data displayed is identical to the data that will be available to
460+
modules when they are built.
461+
462+
See the [config system reference](/reference/config.html) for more details.
463+

docs/reference/config.md

+255
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,255 @@
1+
---
2+
layout: default
3+
title: yotta Configuration System Reference
4+
section: reference/config
5+
---
6+
7+
# Configuration System Reference
8+
9+
**NOTE: The configuration system is currently experimental. Some of the
10+
behaviour described below may change in backwards-icompatible ways with minor
11+
updates to yotta.**
12+
13+
yotta provides a flexible configuration system that can be used to control how
14+
modules are built based on information provided by [target
15+
descriptions](/tutorial/targets.html), optionally extended by a `config.json`
16+
file in the application.
17+
18+
This configuration information can be used to control a module's dependencies,
19+
and is also made available to code.
20+
21+
<a name="defining"></a>
22+
## Defining Configuration Data
23+
Configuration data is defined in two places: [target descriptions](/tutorial/targets.html), and
24+
[executable applications](/tutorial/tutorial.html#Creating%20an%20Executable).
25+
26+
27+
### Target Config Data
28+
The config data defined by targets can be used to make software modules compile
29+
across a wide range of different target hardware. For example, it might
30+
describe things like the frequency of a
31+
[UART](https://en.wikipedia.org/wiki/Universal_asynchronous_receiver/transmitter)
32+
serial bus that the target hardware might have for communication.
33+
34+
Software that uses this hardware can then run on different targets, choosing
35+
the correct frequency to use for the UART communication by reading it from the
36+
configuration data.
37+
38+
#### Config Data in target.json
39+
To define config data in a target's target.json file, use the `"config":`
40+
property, for example:
41+
42+
```json
43+
{
44+
"name":"mytarget",
45+
"version":"1.2.3",
46+
"license":"Apache-2",
47+
"config":{
48+
"devices":{
49+
"foobar":"value",
50+
"volume":11
51+
}
52+
}
53+
}
54+
```
55+
56+
#### Overriding Config Data in Derived Targets
57+
If a target [inherits](/tutorial/targets.html#inheriting) from a more generic
58+
target, then the config data in the more-derived target overrides data
59+
inherited from the base target.
60+
61+
For example, given a base target with config data:
62+
63+
```json
64+
{
65+
"a":{
66+
"foo": true,
67+
"bar": 123
68+
}
69+
}
70+
```
71+
72+
And a derived target with config data:
73+
74+
```json
75+
{
76+
"a":{
77+
"bar": 456
78+
},
79+
"b":{
80+
"baz": "<whatever>"
81+
}
82+
}
83+
```
84+
85+
The merged config data (which you can display with the [`yotta
86+
config`](/reference/commands.html#yotta-config) subcommand), would be:
87+
88+
```json
89+
{
90+
"a":{
91+
"foo": true,
92+
"bar": 456
93+
},
94+
"b":{
95+
"baz": "<whatever>"
96+
}
97+
}
98+
```
99+
100+
### Application Config Data
101+
An executable application may define additional config data to that provided by
102+
the selected target. To do this, the application should include a file called
103+
`config.json` alongside its `module.json` file.
104+
105+
The application's configuration data takes highest precedence, so can be used
106+
to override any values defined by the target data. This is useful for defining
107+
application-specific configuration, and when developing an application for
108+
one-off target hardware which is derived from a supported platform (it can
109+
eliminate the need to define your own target description just for one
110+
application).
111+
112+
If you find yourself copying & pasting `config.json` data between many
113+
applications, consider if deriving and publishing [your own
114+
target](/tutorial/targets.html) would be preferable.
115+
116+
117+
### Config Data Syntax
118+
The yotta config system accepts almost any JSON data, apart from Array objects.
119+
Array objects are not supported due to the ambiguity of merging inherited array
120+
objects.
121+
122+
123+
<a name="using"></a>
124+
## Using Configuration Data
125+
Modules can use the configuration data that has been defined to change their
126+
behaviour. In general it is best to minimise the amount of configuration that
127+
your module requires to the absolute minimum possible. This makes it easier
128+
for people to re-use your module in different applications, and to use it on
129+
different target hardware, without having to define a lot of configuration.
130+
131+
By convention, modules should only read configuration data from their own
132+
namespace in the config data, for example a module called `simplelog` might
133+
read a logging level set in the `simplelog` section of the config data:
134+
135+
```json
136+
{
137+
"mbed":{
138+
...
139+
},
140+
"simplelog":{
141+
"level":1
142+
},
143+
...
144+
}
145+
```
146+
147+
It would be possible for any other module (say a `betterlog` logging module),
148+
to read this data and use it to configure itself, but doing so could cause
149+
things to break if `simplelog` directs its users to do something different with
150+
the config data than what `betterlog` expects.
151+
152+
**NOTE: support for modules to define schemas on parts of the config data is
153+
currently being considered. This would formalise the constraints modules have
154+
on what configuration may be defined.**
155+
156+
### Controlling Dependencies
157+
158+
Config data can be used in the [targetDependencies
159+
section](/reference/module.html#targetDependencies) of `module.json` files.
160+
161+
If a path in the config data matches the values defined on the left-hand side
162+
of the targetDependencies hash, then the dependencies declared in the object on
163+
the right-hand side will be used.
164+
165+
For example, given the config data:
166+
167+
```json
168+
{
169+
"a": {
170+
"enable": true
171+
},
172+
"b": {
173+
"foobar": 123
174+
},
175+
"c": {
176+
"baz": {
177+
178+
}
179+
},
180+
"d": {
181+
"etc": "astring"
182+
},
183+
"e": {
184+
"supported": null,
185+
"also-falsey": false
186+
}
187+
}
188+
```
189+
190+
And the targetDependencies:
191+
192+
```json
193+
"targetDependencies": {
194+
"a.enable": {
195+
"module-1": "^1.2.3"
196+
},
197+
"b.foobar": {
198+
"module-2": "^1.2.3"
199+
},
200+
"c.baz": {
201+
"module-3": "^1.2.3"
202+
},
203+
"d.etc": {
204+
"module-4": "^1.2.3"
205+
},
206+
"e.supported": {
207+
"module-5": "^1.2.3"
208+
}
209+
}
210+
```
211+
212+
Then modules 1, 2, 3 and 4 will be included as dependencies, but `module-5` will not.
213+
214+
### Using Configuration In Code
215+
216+
The config data is made available as preprocessor definitions, so that it can
217+
be tested at compile-time.
218+
219+
For the config data in the above dependencies example, the following
220+
definitions will be produced:
221+
222+
```C
223+
#define YOTTA_CFG
224+
#define YOTTA_CFG_A
225+
#define YOTTA_CFG_A_ENABLE 1
226+
#define YOTTA_CFG_B
227+
#define YOTTA_CFG_B_FOOBAR 123
228+
#define YOTTA_CFG_C
229+
#define YOTTA_CFG_C_BAZ
230+
#define YOTTA_CFG_D
231+
#define YOTTA_CFG_D_ETC astring
232+
#define YOTTA_CFG_E
233+
#define YOTTA_CFG_E_SUPPORTED NULL
234+
#define YOTTA_CFG_E_ALSO_FALSEY 0
235+
```
236+
237+
Note that string values are not quoted. If you want a quoted string,
238+
either embed escaped quotes (`\"`) in the string value, or use the preprocessor
239+
[stringification
240+
trick](https://gcc.gnu.org/onlinedocs/cpp/Stringification.html).
241+
242+
JSON boolean values are converted to 1 or 0, and `null` values are converted to `NULL`.
243+
244+
These definitions are defined through a pre-include file called
245+
`yotta_config.h` which is generated in the root of the build directory.
246+
247+
### Using Configuration in CMakeLists
248+
249+
The config data is also made accessible to any custom CMakeLists.txt that have
250+
been written to control the build of a module. The CMake definitions are nearly
251+
the same as the C preprocessor definitions, except that empty definitions, and
252+
`null` definitions are converted to `set(YOTTA_CFG_<property> "")`, and no
253+
conversion is performed for boolean values.
254+
255+

docs/reference/module.md

+29-2
Original file line numberDiff line numberDiff line change
@@ -220,9 +220,33 @@ The `targetDependencies` property makes this possible.
220220
Each value in the `targetDependencies` is a target identifier defining a set of
221221
dependencies with the same format as the [`dependencies`](#dependencies) property.
222222

223-
When calculating the dependencies to install, `yotta` uses the first section
223+
When calculating the dependencies to install, `yotta` uses all sections
224224
from `targetDependencies` that matches one of the identifiers in the current
225-
target's [`similarTo` list](../tutorial/targets.html#similarto).
225+
target's [`similarTo` list](../tutorial/targets.html#similarto), or which match
226+
properties that are defined to a truthy value in the [configuration
227+
data](/reference/config.html).
228+
229+
To test nested values from config data, use dot-syntax,
230+
`"mbed.meshing.supported"` in the following example tests that the "supported"
231+
value is truthy in config data that looks like this:
232+
233+
```json
234+
{
235+
"mbed":{
236+
"meshing":{
237+
"supported":true
238+
}
239+
}
240+
}
241+
```
242+
243+
A "truthy" json config value is any object or string, or non-zero numbers, or a
244+
literal `true` boolean value.
245+
246+
**NOTE: in the future support for evaluating simple expressions on config
247+
values may be added, but this is not currently possible. To choose which
248+
one-of-n dependencies to use you must define N config values that are either
249+
true or false, and require that they are set appropriately.**
226250

227251
Example:
228252

@@ -231,6 +255,9 @@ Example:
231255
"k64f": {
232256
"mbed-hal-freescale": "^3.0.0",
233257
"mbed": "^3.0.0"
258+
},
259+
"mbed.meshing.supported": {
260+
"mbed-meshing": "^1.2.3"
234261
}
235262
}
236263
```

0 commit comments

Comments
 (0)