Target descriptions allow yotta
to compile the same code for different target
platforms (different desktop operating systems, or different embedded devices).
Each target description contains information both about how to run the compiler to compile (or cross-compile), and configuration information describing the hardware or environment that the target represents.
You can search for targets that people have published using yotta
search target "<search query>"
. For
mbed boards, you can find information about the targets that can be used on the
mbed board pages.
To view or change the current target, use the yotta target
subcommand:
# display the current target:
yotta target
# set the target to x86-osx-native
yotta target x86-osx-native
By default the target is set in the current directory only. To set it
globally, append ` -g to the second command. You can switch targets back and
forth to test building the same module for different targets without removing
the build directory or recompiling unnecessarily, as builds are carried out a
separate directory for each target:
./build/
The description contains information on:
And optionally provides information on:
yotta debug
support)yotta test
support)Each yotta target contains a target.json file, which describes where to find this other information.
Target descriptions usually inherit from an existing description. This allows you to extend the description that already exists instead of writing everything from scratch. With inheritance you override or add only the things that need changing.
For example, this is a simple target hierarchy from mbed OS:
If you were building a product derived from the FRDM-K64F development board schematic you would choose to inherit from the existing frdm-k64f target.
To make your target description inherit from an existing one define the
inherits
property in your target.json file:
...
"inherits": {
"some-base-target": "^1.2.3"
}
...
Note the version specification next to the name of the description you inherit
from. Target descriptions use semantic versioning just
like modules do: it’s normally a good idea to use the ^
version specification
which allows any compatible version to be used. Just like module version
specifications this can also be a github, git or mercurial reference if your
target inherits from another target that hasn’t been published yet.
yotta
uses the CMake build system, and targets
describe how the compiler should be run by providing a CMake Toolchain
File.
To use the system’s native compiler, the toolchain doesn’t need to do anything, but cross-compiling toolchain descriptions can get a lot more complicated, and must define every command necessary to compile programs.
By convention, the toolchain file is placed in a CMake subdirectory of the target:
.
├── CMake
│ └── toolchain.cmake
├── readme.md
└── target.json
Though the path is actually specified in the toolchain
property in target.json:
"toolchain": "CMake/toolchain.cmake"
In addition to the similarTo
data, your target can also define arbitrary JSON
configuration data that can be used as the basis for including dependencies and
providing configuration to the modules being built. See the config system
reference for details.
The similarTo list in a target description is the list of targets that the target should be considered “similar to”. This is defined by target.json:
"similarTo": <list of strings>,
This list is used (in addition to the config information) to choose which
dependencies to pick when a module has target-specific dependencies (defined by
the targetDependencies
property in module.json).
Target-specific dependencies can be used to depend on different implementations
of the functionality that a module needs on different target platforms, which
is especially useful when compiling for embedded hardware.
Note that now that config info can be defined by
target descriptions, and target descriptions inherit from other ones, the use
of similarTo
should generally be avoided.
When compiling, CMake variables and preprocessor definitions are defined by
yotta
for each thing in the similarTo list (and the name of the target
itself):
TARGET_LIKE_FOO
Where FOO
is the name in the similarTo list, converted to uppercase, and with
any non-alphanumeric characters converted to underscores.
yotta debug
SupportTargets can optionally provide a command that yotta will use to start a
debugger when the user runs yotta debug
. They do this by providing a
debug
script in target.json. This should be an array of commmand arguments,
and use $program for the name of the program that’s being debugged, for example:
"scripts": {
"debug": [
"lldb", "$program"
]
}
Debuggers that attach to embedded devices often need to run a debug server
program in the background before running the debugger itself. ARM mbed
compilation targets use the valinor
program to achieve this (valinor also detects which debugger is installed on the
local system, and chooses the preferred one).
yotta test
SupportTo support the yotta test
command, targets must provide a way of running
tests, to do this, implement scripts.test
in target.json. For native
compilation targets, this can simply run the program in question, for a
cross-compilation target it should be a wrapper script that loads the program
onto the target device, runs it, prints the program’s output to stdout, and
exits with the processes return code.
For example:
"scripts": {
"test": [
"mbed-test-wrapper", "-t", "K64F", "-i", 10, "$program"
]
}
To test a target locally, without publishing it, you can use
yotta link-target
to link it into an existing module, and use it for
compilation.
First run yotta link-target
in the directory in which you’re editing your
target:
cd path/to/my-target
yotta link-target
Then in the module that you want to compile, run
yotta link-target <targetname>
:
cd ../path/to/my/module
yotta link-target my-target
You should also select your new target from the module directory before attempting to build for it for the first time.
yotta target my-target
Now when you build, your new target description will be used. Note that currently you need to remove the build directory after editing the target’s toolchain file, as CMake does not add dependency rules on the toolchain:
rm -Rf build/my-target
yotta build
Once you’ve written your target you can publish it:
# change into the target's direcory:
cd path/to/my/target
# tag a new version:
yotta version minor
# publish!
yotta publish
After publishing, whenever someone sets the target to your target with the
yotta target <targetname>
command, your target description will be
automatically downloaded and used.