|
|
SBS (_Skyward Build System_) is the build system used to compile boardcore's entrypoints, which are written for Miosix and need to be compiled for a specific target board.
|
|
|
SBS (_Skyward Build System_) is the build system used in _Skyward Experimental Rocketry_ to compile its firmwares, which are written for _Miosix_ (the in-house OS) and need to be built for specific boards.
|
|
|
|
|
|
SBS lets you specify the target board and custom includes and defines for each entrypoint, as well as grouping useful drivers in a library to reuse them in different entrypoints.
|
|
|
SBS is based on CMake: it is made of CMake modules that include the necessary dependencies and define functions that allow to specify SBS targets and their respective target boards.
|
|
|
|
|
|
## SBS
|
|
|
## Creating a new SBS project
|
|
|
|
|
|
An SBS project is first of all a CMake project, therefore you need to create a file `CMakeLists.txt` in the project root folder.
|
|
|
|
|
|
#### Building
|
|
|
In order to use SBS in the CMake project, you need to add Skyward Boardcore as a recursive Git submodule:
|
|
|
|
|
|
SBS's standard usage is building a board's firmware, which can be done with:
|
|
|
```sh
|
|
|
./sbs -b <entrypoint_name>
|
|
|
git clone --recursive https://git.skywarder.eu/scs/skyward-boardcore.git <skyward_boardcore_path>
|
|
|
```
|
|
|
|
|
|
> The placeholder `<skyward_boardcore_path>` refers to the relative path of the folder of Skyward Boardcore. It is common practice to place Skyward Boardcore into the subfolder `libs` of the project root folder.
|
|
|
|
|
|
Once you cloned Skyward Boardcore, you need to include the SBS CMake module `sbs.cmake`, located in the folder `cmake` of Skyward Boardcore, in the file `CMakeLists.txt` of your project:
|
|
|
|
|
|
```cmake
|
|
|
include(<skyward_boardcore_path>/cmake/sbs.cmake)
|
|
|
```
|
|
|
If you omit the `-b` option all entrypoints will be compiled.
|
|
|
|
|
|
#### Other options
|
|
|
In order to get a list of all the possible entrypoints you can use the `-l` option.
|
|
|
You can also use the `-v` option (verbose output log).
|
|
|
|
|
|
Prompting `./sbs --help` will print the options menu.
|
|
|
> As a reference for how to structure the file `CMakeLists.txt`, you can take a look at the file used for Skyward Boardcore.
|
|
|
|
|
|
## SBS.conf
|
|
|
#### cmake/dependencies.cmake
|
|
|
|
|
|
#### Project Configuration
|
|
|
An optional file `dependencies.cmake` can be added into the subfolder `cmake` of the project root folder in order to define variables and targets on which the targets of the project depend. Module `sbs.cmake` first includes `dependencies.cmake` inside Skyward Boardcore and then it automatically includes `dependencies.cmake` in the subfolder `cmake` of the project root folder, if it exists.
|
|
|
|
|
|
Whenever it is executed, SBS looks for a `sbs.conf` file in the current folder to know how to compile each entrypoint. The current folder could be the boardcore repository as well as another project which includes boardcore. For this reason, we have to define a `[PROJECT_CONF]` section with the following information, that will be valid for all entrypoints listed in the file:
|
|
|
In CMake you use `add_subdirectory()` to load a CMake-based external library:
|
|
|
|
|
|
```conf
|
|
|
ENTRY_PATH: entrypoints folder relative path, e.g. src/entrypoints
|
|
|
TESTS_PATH: tests folder relative path, e.g. src/tests
|
|
|
SRC_PATH: shared sources folder relative path, e.g. src/shared
|
|
|
SBS_BASE: boardcore folder relative path, e.g. libs/skyward-boardcore
|
|
|
PROJECT_INCLUDES: Optional additional include directories, preceded by -I (eg: -Ilibs/mxgui)
|
|
|
PROJECT_SUBDIRS: Optional subfolders which contains additional makefiles (eg: libs/mxgui)
|
|
|
PROJECT_LIBS: Optional static libraries. (eg: libs/mxgui/mxgui.a)
|
|
|
```cmake
|
|
|
add_subdirectory(<lib_directory> EXCLUDE_FROM_ALL)
|
|
|
```
|
|
|
|
|
|
#### SrcFiles
|
|
|
> It is common practice to add libraries as Git submodules into the subfolder `libs` of the project root folder.
|
|
|
|
|
|
The *srcfiles* are used for grouping together sources that refer to a common device/purpose,
|
|
|
so that they can be referred to when building entrypoints by simply using `%name`. Note that SBS first imports the srcfiles from the sbs.conf inside the boardcore's folder, and then it will include any other srcfiles that are defined in higher level sbs.conf files.
|
|
|
You can use CMake variables to define groups of sources that refer to a common purpose, so that they can be referred to when defining targets:
|
|
|
|
|
|
```conf
|
|
|
[name]
|
|
|
Type: srcfiles
|
|
|
Files: a '\n'-separated list of files
|
|
|
```cmake
|
|
|
set(<NAME_OF_THE_GROUP>_SOURCES
|
|
|
file1
|
|
|
file2
|
|
|
...
|
|
|
)
|
|
|
```
|
|
|
|
|
|
#### Boards and Tests
|
|
|
|
|
|
Sections of type `board` and `test` define how to compile the entrypoints.
|
|
|
|
|
|
```conf
|
|
|
[board-name]:
|
|
|
Type: board
|
|
|
BoardId: which board to compile for
|
|
|
BinName: name of the final binary (without extension!)
|
|
|
Include: a space-separated list of files, %something will be substituted
|
|
|
with the corresponding 'srcfiles'
|
|
|
Defines: a space-separated list of flags, each starting with '-D' (e.g. -DDEBUG)
|
|
|
Main: name of the main file (e.g. 'foo' -> ENTRY_PATH/foo.cpp)
|
|
|
|
|
|
[test-name]:
|
|
|
Type: test
|
|
|
BoardId: which board to compile for
|
|
|
BinName: name of the final binary (without extension!)
|
|
|
Include: a space-separated list of files, %something will be substituted
|
|
|
with the corresponding 'srcfiles'
|
|
|
Defines: a space-separated list of flags, each starting with '-D' (e.g. -DDEBUG)
|
|
|
Main: name of the main file (e.g. 'foo' -> TEST_PATH/foo.cpp)
|
|
|
#### CMakeLists.txt
|
|
|
|
|
|
The file `CMakeLists.txt` in the project root folder defines how to compile each target.
|
|
|
|
|
|
In CMake you use:
|
|
|
|
|
|
- `add_executable()` to define an executable target
|
|
|
- `target_include_directories()` to specify its include directories
|
|
|
- `target_link_libraries()` to specify the libraries to which to link it
|
|
|
- `target_compile_definitions()` to specify its compile definitions
|
|
|
|
|
|
SBS adds the function `sbs_target()` that defines an executable as SBS target, i.e. a board firmware linked to Skyward Boardcore (and recursively to Miosix and its other dependencies).
|
|
|
|
|
|
```cmake
|
|
|
add_executable(<executable_name> <sources...>)
|
|
|
target_include_directories(<executable_name> PRIVATE <directories...>)
|
|
|
target_link_libraries(<executable_name> PRIVATE <libraries...>)
|
|
|
target_compile_definitions(<executable_name> PRIVATE <definitions...>)
|
|
|
sbs_target(<executable_name> <board_id>)
|
|
|
```
|
|
|
|
|
|
## Creating a new SBS project
|
|
|
> It is common practice to categorize SBS targets as either *entrypoints* (located in `src/entrypoints`) or *tests* (located in `src/tests`).
|
|
|
|
|
|
##### Note
|
|
|
A typical folder structure for an SBS project is:
|
|
|
|
|
|
```
|
|
|
your-project/
|
|
|
|_ build/
|
|
|
|_ libs/
|
|
|
| |_ skyward-boardcore/
|
|
|
|_ src/
|
|
|
| |_ entrypoints/
|
|
|
| |_ tests/
|
|
|
|_ CMakeLists.txt
|
|
|
```
|
|
|
|
|
|
## Building
|
|
|
|
|
|
To build the targets of an SBS project, you use CMake:
|
|
|
|
|
|
```sh
|
|
|
mkdir build
|
|
|
cd build
|
|
|
cmake -DCMAKE_TOOLCHAIN_FILE=<skyward_boardcore_path>/libs/miosix-kernel/miosix/_tools/toolchain.cmake ..
|
|
|
cmake --build .
|
|
|
```
|
|
|
|
|
|
To simplify the steps necessary to build the targets and lint the code, an SBS script written in Bash is provided that wraps the CMake commands.
|
|
|
|
|
|
Prompting `./sbs -h` will print the help message.
|
|
|
|
|
|
To build all the targets with the SBS script, you just need to do:
|
|
|
|
|
|
Typically when you want to develop the software for a new board or system, you want to include `skyward-boardcore` in your project and develop specific components using the ones provided by boardcore. To do this:
|
|
|
```sh
|
|
|
./sbs
|
|
|
```
|
|
|
|
|
|
To build a specific target (not necessarily a board firmware) you can do:
|
|
|
|
|
|
1. include `skyward-boardcore` as a submodule of your project.
|
|
|
```sh
|
|
|
./sbs -b <target>
|
|
|
```
|
|
|
|
|
|
2. create a `sbs.conf` file in your project directory, specifying the relative path of the boardcore folder (e.g. libs/skyward-boardcore) and where the sources are located ( typically `modules`, `entrypoints` and `tests`).
|
|
|
The SBS script automatically looks for Ccache and Ninja and in case it finds them it sets the appropriate options of the CMake configure command to use them, speeding up the build phase.
|
|
|
|
|
|
A typical file structure for your project could be:
|
|
|
To get a list of the available *entrypoints* you can use the `-l` option. To get a list of the available *boards* you can use the `-r` option.
|
|
|
|
|
|
```
|
|
|
YourProject/
|
|
|
|_ src/
|
|
|
| |_ modules/
|
|
|
| |_ entrypoints/
|
|
|
| |_ tests/
|
|
|
|_ libs/
|
|
|
| |_ skyward-boardcore/
|
|
|
|_ sbs.conf
|
|
|
|_ bin/ <-- binaries will be generated here
|
|
|
|_ build/ <-- Makefiles will be generated here
|
|
|
```
|
|
|
----
|
|
|
|
|
|
## SBS Internals
|
... | ... | @@ -109,60 +130,84 @@ Since in boardcore we have many entrypoints to build, and we don't want to write |
|
|
graph TD;
|
|
|
|
|
|
subgraph miosix-kernel
|
|
|
Makefile -- execute --> miosixMakefile
|
|
|
Makefile -- include --> configMakefile.inc
|
|
|
|
|
|
subgraph miosix
|
|
|
miosixMakefile[Makefile]
|
|
|
|
|
|
subgraph config
|
|
|
configMakefile.inc[Makefile.inc]
|
|
|
end
|
|
|
|
|
|
end
|
|
|
|
|
|
subgraph miosix
|
|
|
miosixMakefile[Makefile]
|
|
|
subgraph config
|
|
|
configMakefile.inc[Makefile.inc]
|
|
|
end
|
|
|
end
|
|
|
Makefile -- execute --> miosixMakefile
|
|
|
Makefile -- include --> configMakefile.inc
|
|
|
end
|
|
|
```
|
|
|
|
|
|
#### SBS Build
|
|
|
|
|
|
The SBS build works as follows:
|
|
|
1. from your project folder, you execute `<BOARDCORE_FOLDER>/sbs`
|
|
|
2. SBS will then search for an sbs.conf in the directory from which it has been executed, loading configurations for all the entrypoints
|
|
|
3. SBS then imports the srcfiles from the `<BOARDCORE_FOLDER>/sbs.conf` (to reuse source groups that come from boardcore)
|
|
|
4. For each entrypoint, SBS fills in the `Makefile.template` creating a MIOSIX Makefile
|
|
|
5. Each Makefile is then executed to compile a binary
|
|
|
1. From your project folder, you execute the SBS script `<skyward_boardcore_path>/sbs` (or a calling script `./sbs`)
|
|
|
2. The SBS script executes `cmake` specifying the Miosix Toolchain File and the appropriate options
|
|
|
3. CMake configures the project by loading `CMakeLists.txt`
|
|
|
4. `CMakeLists.txt` includes `<skyward_boardcore_path>/cmake/sbs.cmake`, which recursively configures the project of Skyward Boardcore by loading its file `CMakeLists.txt`
|
|
|
5. The project of Skyward Boardcore includes `<skyward_boardcore_path>/cmake/boardcore.cmake`, which includes `<skyward_boardcore_path>/cmake/dependencies.cmake`
|
|
|
6. `<skyward_boardcore_path>/cmake/dependencies.cmake` recursively configures the project of Miosix by loading its file `CMakeLists.txt` and other external libraries
|
|
|
7. The project of Miosix configures a library for each board, by loading the options defined in `<skyward_boardcore_path>/libs/miosix-kernel/miosix/config/options.cmake`
|
|
|
8. `<skyward_boardcore_path>/cmake/sbs.cmake` includes `cmake/dependencies.cmake` in the root project folder
|
|
|
9. CMake builds each target of the project, including the entrypoints and the tests defined with `sbs_target()`
|
|
|
|
|
|
```mermaid
|
|
|
graph TD;
|
|
|
|
|
|
subgraph "Project Folder"
|
|
|
sbs.sh[.]
|
|
|
sbs.conf
|
|
|
subgraph "build"
|
|
|
buildBOARD1[BOARD1]
|
|
|
buildBOARD2[BOARD2]
|
|
|
build...[...]
|
|
|
end
|
|
|
subgraph "bin"
|
|
|
binBOARD1[BOARD1.bin]
|
|
|
binBOARD2[BOARD2.bin]
|
|
|
bin...[...]
|
|
|
end
|
|
|
subgraph CMake
|
|
|
cmake
|
|
|
end
|
|
|
|
|
|
sbs.sh -- 1. execute --> boardcoresbs.py
|
|
|
boardcoresbs.py -- 2. read --> sbs.conf
|
|
|
boardcoresbs.py -- 3. import srcfiles --> boardcoresbs.conf
|
|
|
boardcoresbs.py -- 4. read template --> Makefile.template
|
|
|
Makefile.template -- 5. create makefile --> buildBOARD1
|
|
|
buildBOARD1 -- 6. make --> binBOARD1
|
|
|
Makefile.template -- 5. create makefile --> buildBOARD2
|
|
|
buildBOARD2 -- 6. make --> binBOARD2
|
|
|
|
|
|
subgraph "skyward-boardcore"
|
|
|
boardcoresbs.conf[sbs.conf]
|
|
|
boardcoresbs.py[sbs]
|
|
|
Makefile.template
|
|
|
subgraph Project
|
|
|
sbs
|
|
|
CMakeLists.txt
|
|
|
subgraph proj/cmake[cmake]
|
|
|
dependencies.cmake
|
|
|
end
|
|
|
subgraph src
|
|
|
entrypoint1
|
|
|
entrypoint2
|
|
|
src...[...]
|
|
|
end
|
|
|
subgraph build
|
|
|
entrypoint1.bin
|
|
|
entrypoint2.bin
|
|
|
build...[...]
|
|
|
end
|
|
|
subgraph libs/skyward-boardcore
|
|
|
b/sbs[sbs]
|
|
|
b/CMakeLists.txt[CMakeLists.txt]
|
|
|
subgraph b/cmake[cmake]
|
|
|
b/boardcore.cmake[boardcore.cmake]
|
|
|
b/dependencies.cmake[dependencies.cmake]
|
|
|
b/sbs.cmake[sbs.cmake]
|
|
|
end
|
|
|
subgraph libs/miosix-kernel/miosix
|
|
|
m/CMakeLists.txt[CMakeLists.txt]
|
|
|
m/options.cmake[config/options.cmake]
|
|
|
m/toolchain.cmake[_tools/toolchain.cmake]
|
|
|
end
|
|
|
end
|
|
|
end
|
|
|
|
|
|
sbs -- execute --> b/sbs
|
|
|
b/sbs -- execute --> cmake
|
|
|
cmake -- use --> m/toolchain.cmake
|
|
|
cmake -- configure --> CMakeLists.txt
|
|
|
CMakeLists.txt -- include --> b/sbs.cmake
|
|
|
b/sbs.cmake -- add_subdirectory --> b/CMakeLists.txt
|
|
|
b/CMakeLists.txt -- include --> b/boardcore.cmake
|
|
|
b/boardcore.cmake -- include --> b/dependencies.cmake
|
|
|
b/dependencies.cmake -- add_subdirectory --> m/CMakeLists.txt
|
|
|
m/CMakeLists.txt -- ... for each board ... --> m/options.cmake
|
|
|
b/sbs.cmake -- include --> dependencies.cmake
|
|
|
CMakeLists.txt -- sbs_target --> entrypoint1
|
|
|
CMakeLists.txt -- sbs_target --> entrypoint2
|
|
|
cmake -- build --> entrypoint1
|
|
|
entrypoint1 --> entrypoint1.bin
|
|
|
cmake -- build --> entrypoint2
|
|
|
entrypoint2 --> entrypoint2.bin
|
|
|
``` |
|
|
\ No newline at end of file |