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
|
---
layout: default
title: yotta Configuration System Reference
section: reference/buildsystem
---
# Build System Reference
yotta defines the way that software builds in order to make it easier for
separate modules to work together. It has both a simple automatic build system
that will build modules based on the source files discovered in the `source`
directory, and the capability to support building modules of any complexity
using [CMake](http://cmake.org).
## <a href="#info" name="info">#</a> Information Available To Builds
yotta makes some useful information available to the modules being compiled, which
can be embedded in the built binary or otherwise used at compile time. The
majority of this information is defined by yotta's [configuration
system](/reference/config.html), but some other information is also available.
### Information Always Available
The name of the library being built by the current module is available as
`YOTTA_MODULE_NAME`, as if it were defined:
```
#define YOTTA_MODULE_NAME modulename-unquoted
```
No header needs to be included for this definition to be available.
Use the [preprocessor stringification
trick](https://gcc.gnu.org/onlinedocs/cpp/Stringizing.html) to get the
module name as a string, if desired. Note that this definition is **not**
currently available when compiling tests, and there are other circumstances
where using custom CMake can make it unavailable.
### Information Available in the Build Info Header
If the yotta build information header is included, then you can also access
other information. Note that this header changes with every build (as it
includes a build timestamp and unique ID), so do not include it unnecessarily.
To include the yotta build information header:
```C
#include YOTTA_BUILD_INFO_HEADER
```
This header defines the following:
```C
#define YOTTA_BUILD_YEAR 2015 // the current year, UTC
#define YOTTA_BUILD_MONTH 9 // the current month, 1-12, UTC
#define YOTTA_BUILD_DAY 16 // the current day of the month, 1-31, UTC
#define YOTTA_BUILD_HOUR 18 // UTC hour 0-23
#define YOTTA_BUILD_MINUTE 16 // UTC minute 0-59
#define YOTTA_BUILD_SECOND 47 // UTC second 0-61 (1)
#define YOTTA_BUILD_UUID 1f37f267-f31b-48c0-bfdd-2a7a5449817b // a uuid representing the build (2)
```
If yotta finds a mercurial or git repository in the module or application being
built, then the following will also be defined in this header:
```C
#define YOTTA_BUILD_VCS_ID 0123456789abcdef // git or mercurial hash, variable length up to 40 characters
#define YOTTA_BUILD_VCS_CLEAN 1 // 1 if there were no uncommitted changes, else 0
#define YOTTA_BUILD_VCS_DESCRIPTION v0.5-57-gad36348 // git describe or mercurial equivalent
```
Corresponding definitions for all of the build information are always available
in CMake without including any files.
Notes:
* (1) Leap seconds will not currently occur in the _SECOND value, but they may do
in future, so allow for the possibility of values up to and including 61 here.
* (2) The build UUID changes every time that yotta build is invoked, even if the
build would otherwise be identical.
## <a href="#automatic" name="automatic">#</a> Automatic Build System
yotta will automatically build the contents of the `source` and `test`
subdirectories of a software module. If you wan to exclude files from being
picked up by this build system then you can add them to a
[`.yotta_ignore`](/reference/ignore.html) file placed at the top of the module.
Any files in the source directory, and any of its subdirectories, will be
compiled into a single static library (for normal modules), or into the
application (for an executable module).
Any source files at the top-level of the test directory will be compiled into
separate test executables, and the (recursive) contents of any subdirectories
will each be compiled into a single test executable. You can use the
`yotta test` subcommand to build and run these tests.
Files in any other directories are normally ignored by yotta. By convention,
public header files that a module exposes are placed in a subdirectory with the
same name as the module, and then should be included as:
```C
#include "modulename/headername.h"
```
## <a href="#custom-cmake" name="custom-cmake">#</a> Using Custom CMake to Control The Build
To override yotta's default build rules for the `source` and `test`
directories, place your own CMakeLists.txt file in these directories. yotta
will also ensure that any CMakeLists.txt file in any other top-level
subdirectory of your module is included in the build. The testing with yotta
guide explains how to make yotta aware of any tests you add manually so that
`yotta test` can run them.
yotta will also respect a CMakeLists.txt file at the top-level of your module.
If this file is detected, then yotta will not automatically generate any build
rules. This is useful if you're adding yotta support to a module with an
existing build system, especially if the build system already uses CMake.
To ensure that yotta can automatically link your module to other modules, make
sure you define exactly one library with the same name as your module. A custom
build system may also define other build artifacts. In this case take care to
ensure that you name them in a way that minimizes the likelihood of name
collisions with other modules.
### <a href="#cmakelists" name="cmakelists">#</a> Places CMake Rules Can be Defined
There are various places you can define CMake rules to control the build, these
each have different effects:
* **`./CMakeLists.txt` (in the module root)**: if you define a
`CMakeLists.txt` file in the root of your module or executable, then yotta
completely delegates building your module to this file.
* **`./source/CMakeLists.txt`**: defining a `CMakeLists.txt` file in the
source directory replaces yotta's default build rules for your library or
executable, but yotta will still generate default rules for yout test
directory (if any).
* **`./source/<anything>.cmake`**: any .cmake files found in the source
directory will be included at the *end* of the yotta-generated build rules
for the source directory. If you want to make a very simple modification
(such as definining a new preprocessor macro that your module needs), then
this is the best way to do it.
* **`./test/CMakeLists.txt`**: defining a `CMakeLists.txt` file in the
test directory replaces yotta's default build rules for your tests. yotta
will build your library or executable from the contents of the source
directory as normal.
* **`./<anything>/CMakeLists.txt`**: Any subdirectory with a `CMakeLists.txt`
file will be included in the build (unless it is ignored in the
.yotta_ignore file). There aren't very many good reasons to do this.
### <a href="#cmake-examples" name="cmake-examples">#</a> Custom CMake Examples
All the following examples are using standard [CMake](http://cmake.org) syntax.
For documentation on the commands used, pleas see the [CMake
docs](https://cmake.org/documentation/).
General tips for writing CMake:
* Always wrap expanded `"${VARIABLES}"` in quotes (or expand them inside a
quoted string), if they are unquoted then any spaces in the expanded
variable will cause it to be split into separate arguments
* Where possible, avoid overriding yotta's generated CMakeLists.txt, and use
the automatically included `.cmake` files to modify what yotta defined
instead.
#### <a href="#generating-files" name="generating-files">#</a> Generating Files
If you have a script `./scripts/munge.py <input> <output>` that you want to run on an input file
`./resources/input.data` to generate an output C file to include in the build,
you can use a custom CMake file like this:
`./source/CMakeLists.txt`
```cmake
# construct the output path for our generated file (in the build directory, so
# that it gets removed by `yotta clean`):
set(MYMODULE_GENERATED_FILES ${CMAKE_BINARY_DIR}/generated/mymodule)
# ensure that the directory for the generated file exists:
file(MAKE_DIRECTORY "${MYMODULE_GENERATED_FILES}")
# save the paths to the script, input and output files, for convenience:
set(MYMODULE_MUNGE_SCRIPT "${CMAKE_CURRENT_LIST_DIR}/../scripts/munge.py")
set(MYMODULE_MUNGE_INPUT "${CMAKE_CURRENT_LIST_DIR}/../resources/input.data")
set(MYMODULE_MUNGE_OUTPUT "${MYMODULE_GENERATED_FILES}/generated.c")
# define the command to generate this file
add_custom_command(
OUTPUT "${MYMODULE_GENERATED_FILES}/generated.c"
DEPENDS "${MYMODULE_MUNGE_SCRIPT}"
"${MYMODULE_MUNGE_INPUT}"
COMMAND python "${MYMODULE_MUNGE_SCRIPT}" "${MYMODULE_MUNGE_INPUT}" "${MYMODULE_MUNGE_OUTPUT}"
COMMENT "Munging input into generated.c"
)
# define the library for this module, using the generated file:
add_library(mymodule # your module must create a library with its own name
sourcefile1.c
sourcefile2.c
"${MYMODULE_GENERATED_FILES}/generated.c"
)
# link against the module's dependencies
target_link_libraries(mymodule
mydependency
myotherdependency
)
```
Note that as we're replacing the yotta-generated CMakeLists for the source
directory, you need to make sure you're still linking against all of your
module's dependencies
#### <a href="#changing-flags" name="changing-flags">#</a> Changing the Compilation Flags for a module
You can use a `.cmake` file to change the link flags of an existing target
without having to redefine the automatically generated build rules. For
example, if your module is called `mymodule`, you could add this:
`./source/override_flags.cmake`:
```CMake
# add -funroll loops to the compile commands used for the sources in this
# module... loops deserve some fun too!
set_target_properties(mymodule COMPILE_FLAGS "-funroll-loops")
```
Note that here "mymodule" is the name of the static library that your module is
generating (the CMake "target" that it defines – nothing to do with the yotta
target). By convention all yotta modules produce a static library with the same
name as the module
For documentation on the other things that you can set with
set_target_properties, including preprocessor definitions, see the [CMake
docs](https://cmake.org/cmake/help/v3.0/command/set_target_properties.html).
#### <a href="#linking-external" name="linking-external">#</a> Linking an External Library
`./source/link_foo.cmake`:
```CMake
# link ./precompiled/foo.a into mymodule, in addition to its yotta
# dependencies:
target_link_libraries(mymodule "${CMAKE_CURRENT_LIST_DIR}/../precompiled/foo.a")
```
### <a href="#cmake-definitions" name="cmake-definitions">#</a> Definitions Available in CMake Lists
yotta makes all the definitions which are available to the preprocessor
available to CMake scripts (including, for example, the path to the build
information header, and the definitions derived from the config information).
In addition, several other definitions are available, including:
* `YOTTA_CONFIG_MERGED_JSON_FILE`: This expands to the full path of a file
where the current yotta config information has been written. If you want to
use the config information for advanced pre-build steps (such as including
portions of it in the executable in a parseable form), then this is the file
you should read the config information from.
## <a href="#build-products" name="build-products">#</a> Build Products
Everything that yotta generates during the build is created within the `build`
subdirectory. Within this directory build products are further divided by the
name of the [target](tutorial/targets.html) being built. This makes it safe to
switch between building for different targets without cleaning.
|