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