mirror of
https://github.com/nasa/fprime.git
synced 2025-12-10 00:44:37 -06:00
CMake documentation refactor (#3981)
* CMake documentation refactor * sp * Update cmake-implementations.md
This commit is contained in:
parent
dfaf496263
commit
21faffa6f8
@ -2,11 +2,11 @@
|
||||
|
||||
## 1 Introduction
|
||||
|
||||
This document describes a new build system based on the popular open source tool cmake
|
||||
This document describes the build system based on the popular open source tool CMake
|
||||
. The software design document will present a set of
|
||||
requirements for the build system, some operational concepts, and the candidate build system design.
|
||||
This build system is intended to replace the legacy F´ build system which is difficult to enhance
|
||||
and maintain. The legacy F´ build system had was inherited from the JPL Mars Science Laboratory
|
||||
and maintain. The legacy F´ build system was inherited from the JPL Mars Science Laboratory
|
||||
mission and created over 10 years ago.
|
||||
|
||||
## 1.1 Definitions
|
||||
@ -18,8 +18,7 @@ These terms have specific meaning in this SDD. This table gives a quick referenc
|
||||
| **Host** | Machine or architecture used to build the code. |
|
||||
| **Target** | Machine or architecture for which the code is built. |
|
||||
| **Build Commands** | Commands run through the make system. |
|
||||
| **In-Source Build** | Generate build artifacts along-side source code. |
|
||||
| **Out-Of-Source Build** | Generate build artifacts in a separate directory source code. |
|
||||
| **Out-Of-Source Build** | Generate build artifacts in a separate directory from source code. |
|
||||
| **Build Configurations** | Different build setups, like different targets, debug flags, different deployments. Typically these are isolated from one another. |
|
||||
| **F´ Module** | Super set of F´ components and F´ ports. |
|
||||
| **Deployments** | F´ binary/executable containing framework intended to run as F´. |
|
||||
@ -27,68 +26,35 @@ These terms have specific meaning in this SDD. This table gives a quick referenc
|
||||
|
||||
## 2 Requirements
|
||||
|
||||
Requirement | Description | Rationale | Verification Method | Status |
|
||||
---- | ---- | ---- | ---- | ----
|
||||
BUILD-01 | The build system shall support native F´ builds and installations on Linux, and Mac OS. | F´ development at JPL takes place on Linux and Mac OS machines | Inspection | Done |
|
||||
BUILD-02 | The build system shall provide templates for supporting other host OSes. | Templates make adding hosts easier. | Inspection | Done |
|
||||
BUILD-03 | The build system shall provide templates for supporting other targets. | Templates make adding new targets easier. | Inspection | Done |
|
||||
BUILD-05 | The build system shall provide a cross-compiled target example. | Cross-compilation is common at JPL and must be provided as an example. | Inspection | Done |
|
||||
BUILD-06 | The build system shall support custom build commands. | Custom build commands allow for extension of the build system. | Inspection | Done |
|
||||
BUILD-07 | The build system shall support individual component, port, and topology builds. | Compiling a specific component can speed-up development. | Unit Test | Done |
|
||||
BUILD-08 | The build system shall support unit test building and running system checks. | Unit testing is critical for proper development. | Unit Test | Done |
|
||||
BUILD-09 | The build system shall support building deployments. | Deployments must build properly | Unit Test | Done |
|
||||
BUILD-10 | The build system shall support integration with other build systems. | Some libraries come with other make systems. | Included within CMake | Done |
|
||||
BUILD-11 | The build system shall not require specific ordering of all modules to build properly. | Ordering of all F´ is difficult when it must be explicit | Inspection | Done |
|
||||
BUILD-12 | The build system shall support separate out-of-source building of F´ | Build artifacts are commonly kept separate from source code. | Inspection | Done |
|
||||
BUILD-13 | The build system shall support executable and tool building | Not all of F´ is a deployment | Inspection | Done |
|
||||
BUILD-14 | The build system shall support installation and distribution of outputs, headers, and libraries | Shipping of binary outputs is important for projects. | Inspection | **Needed** |
|
||||
BUILD-15 | The build system shall support user-configurable builds i.e. debug, release, etc. | F´ may need access to different build variants for debugging purposes | Inspection | **Work-Around** |
|
||||
BUILD-16 | The build system shall be easy to use including adding new components | F´'s current build system has a steep learning curve | Inspection | Done |
|
||||
BUILD-17 | The build system shall not be explicitly slow. | Compilation times are non-trivial | Inspection | Done |
|
||||
BUILD_18 | Deployments shall configure dependencies independently. | Current F´ has issues with global make config directory | Inspection | Done |
|
||||
BUILD_19 | The build system shall not be difficult to set up and configure. | Porting existing F´ deployments to the new make system should not require massive efforts | Inspection | Done |
|
||||
BUILD_20 | The build system shall support treating F´ as a library, sub-repo, and sub-directory even if F is read-only | Future F´ usage should treat core as an input | Inspection | Done |
|
||||
BUILD_21 | The build system shall support Windows hosts. | Windows build are desired to be supported in the future. | Inspection | **Needed** |
|
||||
~~BUILD_22~~ | ~~The build system shall support building sub topologies.~~ | ~~Sub topologies are desired in the future.~~ | ~~Inspection~~ | **Removed** Note: Autocoder function support needed |
|
||||
BUILD_23 | The build system shall support building F´ core as a set of shared libraries. | Some future missions may benefit from shared F´ core. | Inspection | Done |
|
||||
BUILD_24 | The build system shall support UT and validation stage hooks. | Validation and additions to Unit Testing support better project development. | Inspection | **Needed** |
|
||||
BUILD_26 | The build system shall support execution of individual, sets, or all gtest based unit tests. | | | Done |
|
||||
BUILD_27 | The build system shall support explicit and implicit execution of the F´ Autocoder. | | | Done |
|
||||
BUILD_28 | The build system shall verify that required compilers, linkers, libraries, etc. are installed on host where build is being executed. | | | DONE |
|
||||
BUILD_29 | The build system shall implement all user targets of the legacy F´ build system. | | | **Deferred** separate build commands needed. |
|
||||
~~BUILD_30~~ | ~~The build system shall support execution of individual, sets, or all GSE based integration tests.~~ | | | Note: this is a GDS/GSE process, not a build process. Easily accomplished w/ fprime-gds |
|
||||
BUILD_31 | The build system shall support execution of individual, sets, or all F´ Autocoder and associated tooling tests. | | | Done |
|
||||
Requirement | Description | Rationale | Verification Method |
|
||||
---- | ---- | ---- | ----
|
||||
BUILD-01 | The build system shall support native F´ builds on Linux, and Mac OS. | F´ development at JPL takes place on Linux and Mac OS machines | Unit-Test |
|
||||
BUILD-02 | The build system shall provide templates for supporting various targets. | Templates make adding new targets easier. | Inspection |
|
||||
BUILD-03 | The build system shall provide a cross-compiled target example. | Cross-compilation is common at JPL and must be provided as an example. | Inspection |
|
||||
BUILD-04 | The build system shall support custom build commands. | Custom build commands allow for extension of the build system. | Unit-Test |
|
||||
BUILD-05 | The build system shall support individual component, port, and topology builds. | Compiling a specific component can speed-up development. | Unit Test |
|
||||
BUILD-06 | The build system shall support unit test building and running system checks. | Unit testing is critical for proper development. | Unit Test |
|
||||
BUILD-07 | The build system shall support building deployments. | Deployments must build properly | Unit Test |
|
||||
BUILD-08 | The build system shall not require specific ordering of all modules to build properly. | Ordering of all F´ is difficult when it must be explicit. Note: deployments are exempt. | Unit-Test |
|
||||
BUILD-09 | The build system shall support separate out-of-source building of F´ | Build artifacts are commonly kept separate from source code. | Inspection |
|
||||
BUILD-10 | The build system shall support executable and tool building | Not all of F´ is a deployment | Inspection |
|
||||
BUILD-11 | The build system shall support installation and distribution of outputs, headers, and libraries | Shipping of binary outputs is important for projects. | Inspection |
|
||||
BUILD-12 | The build system shall support user-configurable builds i.e. debug, release, etc. | F´ may need access to different build variants for debugging purposes | Inspection |
|
||||
BUILD-13 | The build system shall be easy to use including adding new components | F´'s current build system has a steep learning curve | Inspection |
|
||||
BUILD-14 | The build system shall not be explicitly slow. | Compilation times are non-trivial | Inspection |
|
||||
BUILD_15 | Deployments shall configure dependencies independently. | Current F´ has issues with global make config directory | Inspection |
|
||||
BUILD_16 | The build system shall not be difficult to set up and configure. | Porting existing F´ deployments to the new make system should not require massive efforts | Inspection |
|
||||
BUILD_17 | The build system shall support treating F´ as a sub-repo, and sub-directory even if F is read-only | Future F´ usage should treat core as an input | Inspection |
|
||||
BUILD_18 | The build system shall support building F´ core as a set of shared libraries. | Some future missions may benefit from shared F´ core. | Unit-Test |
|
||||
BUILD_19 | The build system shall support execution of individual, sets, or all gtest based unit tests. | | |
|
||||
BUILD_20 | The build system shall support execution of the F´ Autocoder. | | Unit-Test |
|
||||
BUILD_21 | The build system shall verify that required compilers, linkers, libraries, etc. are installed on host where build is being executed. | | Unit-Test |
|
||||
BUILD_22 | The build system shall support execution of individual, sets, or all F´ Autocoder and associated tooling tests. | | |
|
||||
BUILD_24 | The build system shall support execution of custom Autocoders. | | Unit-Test |
|
||||
|
||||
## 3 Operations Concepts
|
||||
|
||||
The CMake can be run in three different ways. These represent different paradigms of using F´.
|
||||
Primarily, there are two choices of where to place build artifacts (objects, libraries, archives,
|
||||
makefiles, and sometimes auto-generated code). *Out-of-source* builds place the artifacts into a
|
||||
separate directory from the source files. *In-source* builds place these same files along-side
|
||||
source. Modern build systems either strongly discourage or forbid *in-source* builds, as content
|
||||
management, build configuration, version control, and development all become more difficult when
|
||||
using *in-source* builds.
|
||||
|
||||
The CMake system will allow *in-source* builds, but only when operating precisely as the old make
|
||||
system is running. Thus there are three paradigms of operation for the CMake system. These
|
||||
paradigms are described below. They are:
|
||||
|
||||
1. (Recommended) Treating F´ as a library. Builds are performed out-of-source.
|
||||
2. Adding project code directly to F´. Builds are still performed out-of-source.
|
||||
3. (Highly Discouraged) Adding code to F´, building is done in-source. **Note:** this will not
|
||||
work when running with the old make system in-place.
|
||||
|
||||
Separate build configurations (different targets, different cmake options set, different
|
||||
deployments, debug builds, etc.) would normally be placed in separate build directories (i.e.
|
||||
build_raspi_debug). This keeps all of that configuration, and all of the outputs fully isolated.
|
||||
There is not a change of linking confusion, or build collisions. Nor is there a chance that the
|
||||
state is forgotten and something "wrong" is built. This is easily supported by options 1 and 2 as
|
||||
they use *out-of-source* builds. Options 3, performing *in-source* builds becomes very difficult
|
||||
as any and all build artifacts must be purged. Thus, this option specifically is discouraged.
|
||||
|
||||
### 3.1 (Recommended) Treating F´As a Library w/ Out-Of-Source Builds
|
||||
|
||||
In this design, F´is included as a sub directory to the project. All adaptations are kept out of
|
||||
In the build system, F´ is included as a sub directory to the project. All adaptations are kept out of
|
||||
the F´ directory, allowing for streamlined F´ update, patching, and freezing of the F´ core
|
||||
components. This could easily be extended to treat F´ as a library and link against it. Here builds
|
||||
are performed in user supplied directories. The user creates a named directory to build into, and
|
||||
@ -116,44 +82,11 @@ cd <project>/build_config1
|
||||
make
|
||||
```
|
||||
|
||||
For building individual components, please see section "3.3, *out-of-source* building of individual
|
||||
For building individual components, please see section "3.1, *out-of-source* building of individual
|
||||
components".
|
||||
|
||||
### 3.2 Traditional F´Organization w/ Out-Of-Source Builds
|
||||
|
||||
In this design, F´ core and adaptations are kept in the F´ directory. This is the traditional
|
||||
way of using F´. It is less easy to use F´ as a library, and can be somewhat difficult to update
|
||||
F´, if needed, but is otherwise a stable approach. Here a user uses a named directory to build
|
||||
into, and then supplies cmake the configuration arguments to setup the build properly, just like
|
||||
in section 3.1. The only difference is that all code is in the F´ checkout. This forces a full
|
||||
fork of F´.
|
||||
|
||||

|
||||
|
||||
As can be seen here, the adaptations and core code live in the same directory. The builds go into
|
||||
separate build directories, one for each configuration. This can be setup with the following
|
||||
commands. Setup needs to be done once and only once for each build type. After that, one can call
|
||||
make over-and-over.
|
||||
|
||||
```
|
||||
cd <fprime>
|
||||
mkdir build_config1
|
||||
cd build_config1
|
||||
cmake ../<path-to-deployment> -D<configuration settings>
|
||||
```
|
||||
|
||||
Then when code or make changes occur, this configuration can easily be rebuilt by performing the
|
||||
following commands (as many times as needed during development iteration).
|
||||
|
||||
```
|
||||
cd <project>/build_config1
|
||||
make
|
||||
```
|
||||
|
||||
For building individual components, please see section "3.3, *out-of-source* building of individual
|
||||
components".
|
||||
|
||||
### 3.3 *Out-of-Source* Building of Individual Components
|
||||
### 3.1 Building of Individual Components
|
||||
|
||||
In order to build individual components inside F´ when using out-of-source builds, one must change
|
||||
into the parallel build structure to find the components build directory. F´ core components live in
|
||||
@ -175,68 +108,27 @@ cd build_config1/Ref/PingReceiver/
|
||||
make
|
||||
```
|
||||
|
||||
### 3.4 (Highly Discouraged) Old Style *In-Source* Builds
|
||||
|
||||
This style is strongly discouraged. It is supported simply to not break the old F´ workflow style.
|
||||
This paradigm comes with some caveats:
|
||||
|
||||
1. It cannot be run alongside the old make system. It *will* clobber the old make system.
|
||||
2. Reconfiguring build settings *will* require removal of all build and CMake artifacts
|
||||
3. Linking and building errors can arise when switching build configurations.
|
||||
|
||||
If at all possible, *do not* use this paradigm without understanding the above caveats and having
|
||||
safety mechanisms to combat the negative consequences of this pattern.
|
||||
|
||||

|
||||
|
||||
Here the adaptations are combined and the builds land in the same directory as the source. To use
|
||||
this system, the following commands can be run:
|
||||
|
||||
```
|
||||
cd <fprime>
|
||||
git clean -xdf . #WARNING, this clobbers *all* untracked files
|
||||
cmake ../<path-to-deployment> -D<configuration settings>
|
||||
make
|
||||
```
|
||||
|
||||
Each time the build it run it, the above commands **must** be run to prevent errors and
|
||||
unpredictable builds. However, it is heavy handed to purge all artifacts of the build system.
|
||||
Configurations are lost or pollute new builds. Hence the discouraging tone used in this section.
|
||||
|
||||
### 3.5 Adding in New Components and Topologies
|
||||
### 3.2 Adding in New Components and Topologies
|
||||
|
||||
New components can be added by creating a `CMakeLists.txt` file in the directory of that component.
|
||||
This file is required to set two CMake variables:
|
||||
This file is required to call one of the `register_fprime_*` functions passing in directives to control
|
||||
the source list.
|
||||
|
||||
1. **SOURCE_FILES**: a list of files that act as source or autocoding source files.
|
||||
2. **MOD_DEPS**: (optional) a list of module and link dependencies.
|
||||
|
||||
These are set using the CMake set() function, as shown below. Finally, this file must call
|
||||
`register_fprime_module`, a F´ CMake support function used to setup the auto coding step and ensure
|
||||
this component is built as an F´ module. This call passes in the above variables.
|
||||
|
||||
**Module CMakeList.txt**
|
||||
**Module CMakeLists.txt**
|
||||
|
||||
```
|
||||
# Default module cmake file
|
||||
# SOURCE_FILES: Handcoded C++ source files
|
||||
|
||||
set(SOURCE_FILES
|
||||
"${CMAKE_CURRENT_LIST_DIR}/PingReceiver.fpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/PingReceiver.cpp"
|
||||
register_fprime_module(
|
||||
AUTOCODER_INPUTS
|
||||
"${CMAKE_CURRENT_LIST_DIR}/PingReceiver.fpp"
|
||||
SOURCES
|
||||
"${CMAKE_CURRENT_LIST_DIR}/PingReceiver.cpp"
|
||||
)
|
||||
|
||||
# Note: no MOD_DEPS needed.
|
||||
|
||||
register_fprime_module()
|
||||
```
|
||||
|
||||
This file must be added to some parent CMakeLists.txt file using the add_subdirectory file. If it
|
||||
is a new F´ component this is typically added to `CMakeLists.txt` in the top-level directory this
|
||||
component goes in. i.e. `fprime/Svc/CMakeLists.txt`. These sub-CMakeLists.txt are there as a
|
||||
convenience and are included themselves in FPrime.cmake. If there is no convenient sub list file,
|
||||
the component may be added directly to `fprime/cmake/FPrime.cmake`. Non-core components must be
|
||||
added to the deployment `CMakeLists.txt` file, or to some child included from there.
|
||||
convenience and are included themselves in FPrime.cmake.
|
||||
|
||||
**Example Add Subdirectory**
|
||||
|
||||
@ -244,32 +136,6 @@ added to the deployment `CMakeLists.txt` file, or to some child included from th
|
||||
add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/PingReceiver/")
|
||||
```
|
||||
|
||||
Topology `CMakeLists.txt` follow the same format as the Module files with two deviations. First,
|
||||
`MOD_DEPS` is usually defined as some dependencies cannot be auto-detected must be chosen and
|
||||
`register_fprime_executable` is called as an executable will be generated.
|
||||
|
||||
**Topology CMakeList.txt**
|
||||
|
||||
```
|
||||
# Default deployment cmake file
|
||||
# SOURCE_FILES: Handcoded C++ source files
|
||||
# MOD_DEPS: Modules needed by this deployment
|
||||
|
||||
set(SOURCE_FILES
|
||||
"${CMAKE_CURRENT_LIST_DIR}/RefTopology.fpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/Topology.cpp"
|
||||
)
|
||||
|
||||
set(MOD_DEPS
|
||||
Svc/PosixTime
|
||||
Svc/PassiveConsoleTextLogger
|
||||
)
|
||||
|
||||
register_fprime_executable()
|
||||
```
|
||||
|
||||
These files must also be added to entry-point `CMakeList.txt` or a child therein.
|
||||
|
||||
## 4 CMake Build Organization
|
||||
|
||||
The CMake system is organized into three pieces. There are the entry-point files supplied by the
|
||||
@ -339,16 +205,16 @@ with the `Ref` prefix.
|
||||
These files provide the core CMake functions used to make components, deployments, and modules.
|
||||
In addition `FPrime-Code.cmake` includes the sub directories that compose F´ core components. In
|
||||
that way deployments need only include the one CMake file to import all of F´. Functions that
|
||||
automate the auto-code function, module dependencies, and various other utilities are included to.
|
||||
automate the autocoder function, module dependencies, and various other utilities are included as well.
|
||||
Thus deployments and executables can follow the same pattern as core F´ components when adding
|
||||
custom components of their own.
|
||||
|
||||
### 4.3 F´Core and Adaptation CMakeLists.txt Files
|
||||
### 4.3 F´ Core and Adaptation CMakeLists.txt Files
|
||||
|
||||
These files are used to specify the build layout of the F´ components, ports, and topologies. They
|
||||
are composed in a hierarchy as shown below. These files call the F´ module and deployment functions
|
||||
to generate the expected build files. The file format is described in section *3.5 Adding in New
|
||||
Components and Topologies*. These files link source files, and auto-coder inputs to the generate
|
||||
to generate the expected build files. The file format is described in section *3.2 Adding in New
|
||||
Components and Topologies*. These files link source files, and autocoder inputs to the generate
|
||||
functions. These functions assemble F´ from those constituents.
|
||||
|
||||

|
||||
@ -374,10 +240,9 @@ represent execution steps.
|
||||
Module functions are designed to create a library (static or shared) out of an F´ directory. The
|
||||
module name is determined from the directory path relative to the root of the repository.
|
||||
i.e. `Fw/Comp` becomes *Fw_Comp* and yields `libFw_Comp.a`. This library is added as an output of
|
||||
the CMake system. This library is built from `SOURCE_FILES`, which are split into inputs to the
|
||||
autocoder (*.fpp and/or *.txt) and normal source files. Specific dependencies can be supplied using
|
||||
the `MOD_DEPS` variable, but is only required when the dependencies are not detected via a recursive
|
||||
search of all *.fpp includes in the autocoder files. The autocoder generation steps are registered
|
||||
the CMake system. This library is built from `SOURCES` and `AUTOCODER_INPUTS`. Specific dependencies can be supplied using
|
||||
the `DEPENDS` directive, but is only required when the dependencies are not detected via the model
|
||||
dependency tree. The autocoder generation steps are registered
|
||||
for each of the autocoder input files. These autocoder input files are also used to detect all
|
||||
dependencies of the given module. The normal source files are supplied to the build directory.
|
||||
|
||||
@ -391,27 +256,20 @@ stage and register it with CMake so it can be used with the global dependency ro
|
||||
Executable functions are designed to create an executable. These executables have some concrete
|
||||
sources and roll-up all dependencies into a global ordered list of dependencies automatically. The
|
||||
executable name comes from the defined "${PROJECT_NAME}" when creating the CMake project, or a
|
||||
separate name must be supplied. The executable may supply `SOURCE_FILES` and `MOD_DEPS`, use
|
||||
separate name must be supplied. The executable may supply `SOURCES` and `DEPENDS`, use
|
||||
autocoding, and otherwise acts similar to the above module with the exception that an executable
|
||||
output is the result of the build.
|
||||
|
||||
**Note:** deployments specify one or more executables, and these executables become the root of the
|
||||
dependency tree. Thus, only the needed executables, libraries, and outputs are generated and the
|
||||
complete F´ system is not explicitly built. This makes the build more efficient.
|
||||
complete F´ system is not explicitly built. This makes the build more efficient.
|
||||
|
||||
### 5.3 Unit Test Functions: register_fprime_ut
|
||||
|
||||
Registering unit tests uses the same process as above with the exception that the variables
|
||||
`UT_SOURCE_FILES` and `UT_MOD_DEPS`. This allows the same file to define both a module or
|
||||
`SOURCES` and `DEPENDS`. This allows the same file to define both a module or
|
||||
executable and unit test without overriding previously used variables.
|
||||
|
||||
Unit tests must be built with a cmake build type of "TESTING". This allows for the building of the
|
||||
unit-tests and setting up the `make check` target. This prevents the
|
||||
unit-tests from bogging down a normal build, and allows for specialized compilation flags for UTs.
|
||||
They are registered with a `make check` target to allow them to be run at once. Individual UTs can
|
||||
be run from the `bin` directory if needed. It is advised that the user build from top-level F´ as
|
||||
this will pull in every unit-test. Building from a deployment is useful when running that
|
||||
deployment's unit-tests.
|
||||
|
||||
**Example UT Build**
|
||||
|
||||
@ -422,7 +280,7 @@ cmake .. -DBUILD_TESTING=ON
|
||||
make -j32
|
||||
```
|
||||
|
||||
### 5.3 Adding New Platforms
|
||||
### 5.4 Adding New Platforms
|
||||
|
||||
CMake allows you to specify the toolchain as part of the initial CMake step, so at its core,
|
||||
compiling for a new target OS should be as simple as doing the following step.
|
||||
|
||||
@ -2,13 +2,6 @@
|
||||
|
||||
F´ leverages CMake as its underlying build system, adding an [API layer](../../reference/api/cmake/API.md) for ease of use.
|
||||
|
||||
Since this F´ CMake system is designed to follow CMake norms, certain caveats must be understood before beginning to use CMake. These are described below:
|
||||
|
||||
1. CMake should not be used in tandem with the original make system. If it is needed to switch
|
||||
between make systems, perform a `git clean -xdf` command or otherwise remove **all** generated files.
|
||||
2. CMake in-source builds are dangerous. Use CMake out-of-source builds.
|
||||
|
||||
|
||||
Installation guides for CMake can be found here: [https://cmake.org/install/](https://cmake.org/install/).
|
||||
|
||||
A Basic CMake tutorial can be found here: [https://cmake.org/cmake/help/latest/guide/tutorial/index.html](https://cmake.org/cmake/help/latest/guide/tutorial/index.html).
|
||||
@ -16,13 +9,13 @@ Although fprime tries to simplify CMake usage for fprime-specific tasks, an unde
|
||||
|
||||
## Getting Started with CMake and F´
|
||||
|
||||
CMake as a system auto-generates OS-specific make files for building F´. Once these file are generated, standard make tools can be run to perform the compiling, assembling, linking, etc. In other words, CMake is a high-level build system that defers low-level build systems to build. It generates the inputs to these low-level systems in a straightforward way.
|
||||
CMake as a system auto-generates OS-specific build files for building F´. Once these files are generated, standard build tools can be run to perform the compiling, assembling, linking, etc. In other words, CMake is a high-level build system that defers low-level build systems to build. It generates the inputs to these low-level systems in a straightforward way.
|
||||
|
||||
fprime sets up CMake in such a way that adding a module (component, port, deployment) is easy and automatically takes
|
||||
F´ sets up CMake in such a way that adding a module (component, port, deployment) is easy and automatically takes
|
||||
advantage of the autocoding capabilities of fprime. To add new modules to the CMake system, users need to perform the following steps:
|
||||
|
||||
1. Define a `CMakeLists.txt` file to define the module's source files and dependencies
|
||||
2. Ensure that `register_fprime_module` or `register_fprime_executable` is called in that `CMakeLists.txt`
|
||||
2. Ensure that `register_fprime_module` or `register_fprime_deployment` is called in that `CMakeLists.txt`
|
||||
3. Make sure this new directory defining the `CMakeLists.txt` is added to the deployment `CMakeLists.txt` using
|
||||
`add_fprime_subdirectory`.
|
||||
|
||||
@ -33,22 +26,14 @@ steps can be found in [API](./cmake-api.md). This document will explain the usag
|
||||
|
||||
The CMakeList.txt file defines the steps needed to build **something** in CMake. In fprime, we use this file to define the source, autocoder, and module dependencies for modules in fprime. A `register_` function is called to tie into the fprime autocoder environment. This keeps fprime modules simple, although all of CMake's power can be used when needed.
|
||||
|
||||
Users need only set the `SOURCE_FILES` variable to a list of autocoder and code sources and then call
|
||||
`register_fprime_module` to setup a module for fprime (Port/Component). Deployments are done similarly, but since these
|
||||
`CMakeLists.txt` files are the entry point to a build, more setup is needed. Deployments should also call
|
||||
`register_fprime_executable` as a binary output is desired. `add_fprime_subdirectory` is also used in deployments to
|
||||
link to all the other modules they use.
|
||||
Users need only set the `AUTOCODER_INPUTS` and `SOURCES` directives to a list of autocoder and code sources as part of the
|
||||
`register_fprime_module` call to setup a module for fprime (Port/Component). Deployments are done similarly but use the
|
||||
`register_fprime_deployment` call instead.
|
||||
|
||||
`add_fprime_subdirectory`, `register_fprime_module`, `register_fprime_executable` docs are here: [API](./cmake-api.md).
|
||||
|
||||
A template module `CMakeLists.txt` is documented: [module-CMakeLists.txt-template.md](../../../cmake/module-CMakeLists.txt.template)
|
||||
Remember it should be renamed to `CMakeLists.txt` in your module's folder.
|
||||
|
||||
A template deployment `CMakeLists.txt` is documented: [deployment-CMakeLists.txt-template.md](../../../cmake/deployment-CMakeLists.txt.template).
|
||||
Remember it should be renamed to `CMakeLists.txt` in your deployments folder.
|
||||
|
||||
When building a module, ensure it at least calls `register_fprime_module`. Deployments may call
|
||||
`register_fprime_executable` in the deployment `CMakeLists.txt` or in any child (usually Top/CMakeLists.txt).
|
||||
When defining a module, ensure it at least calls `register_fprime_module`, or `register_fprime_deployment`.
|
||||
|
||||
When building a module, remember to add it to the deployment by adding a line `add_fprime_subdirectory(path/module/dir)`
|
||||
to the deployment `CMakeLists.txt`.
|
||||
|
||||
@ -1,102 +0,0 @@
|
||||
# Advanced F´ CMake Usage
|
||||
|
||||
The CMake system has several advanced usages, described here. This document walks through the CMake usage and settings
|
||||
for users ignoring `fprime-util` and trying to run the CMake system directly.
|
||||
|
||||
**Note:** `fprime-util` was designed to ease use of the F´ cmake system by wrapping all of the developer-level processes
|
||||
freeing users from running these steps directly. This automatically handles the two build types using the
|
||||
developer's action to choose the correct one.
|
||||
|
||||
## CMake Build Types
|
||||
|
||||
fprime allows for two different CMAKE_BUILD_TYPE settings (specified using -DCMAKE_BUILD_TYPE when generating a build
|
||||
cache). These two types are: Release used to build a flight-like executable, and Testing enabling debugging and unit
|
||||
test features. These are split such that testing can be done on a more permissive executable.
|
||||
|
||||
Running CMake directly (by hand) amounts to generating a build cache and running make (assuming GNU make output):
|
||||
|
||||
1. Make and change to a directory to build in: `mkdir build_dir; cd build_dir`
|
||||
2. Call CMake to generate make-files: `cmake <path to deployment CMakeLists.txt> -DCMAKE_BUILD_TYPE=<some type>`
|
||||
3. Engage OS-specific make system: `make`
|
||||
4. Run unit tests: `make check`. Note: `check` is only available in the `Testing` CMAKE_BUILD_TYPE
|
||||
|
||||
Further information on each step is provided below.
|
||||
|
||||
### Make Build Directory and Generate CMake Files (Run Once Per Configuration)
|
||||
|
||||
When building F´ using the CMake system, each build type should be separated into its own directory.
|
||||
Any time a different platform, toolchain, or option set are used, a new directory should be created.
|
||||
However, each of these directories are independent, and can be built independently without cleaning
|
||||
or removing the others.
|
||||
|
||||
The following commands will create a new build directory and generate CMake files. Separate builds
|
||||
should be isolated in their own build-directories. These directories can be achieved as
|
||||
build-artifacts, but are typically not added to source management (Git).
|
||||
|
||||
Below, a user-provided deployment directory could be substituted for `Ref` below in-order to build a
|
||||
different deployment. More on deployments below.
|
||||
|
||||
**Build Setup Commands**
|
||||
|
||||
```
|
||||
# Make a build directory and change directory into it
|
||||
mkdir fprime/build-dir
|
||||
cd fprime/build-dir
|
||||
# Run CMake to generate CMake Files (Specifically for the Ref App)
|
||||
cmake ../Ref/
|
||||
```
|
||||
|
||||
### Building Deployments (Iterated On Change)
|
||||
|
||||
Once generated by CMake, the cmake files typically do not need to be re-generated. If a new configuration is needed, a separate (new) build directory should be used. If changes occur to the
|
||||
CMake system, running the following steps will rerun the CMake file generation. Thus, the above
|
||||
step can be run one time. Rebuilding and iteration can be done with the following simple steps:
|
||||
|
||||
**Build Commands(Linux, Mac OS X)**
|
||||
|
||||
```
|
||||
# Build the application (Will regenerate CMake if necessary)
|
||||
make
|
||||
# Build and run the UTs (if desired)
|
||||
make check # Only if CMAKE_BUILD_TYPE=Testing was used when generating the build cache
|
||||
```
|
||||
|
||||
|
||||
## Adding in New CMake Components and Deployments
|
||||
|
||||
The core of a cmake build is the `CMakeLists.txt` file. This file specifies the files needed to
|
||||
build the current directory of the system. In F prime each Component, Port, and Topology get a
|
||||
`CMakeList.txt` along with the top-level deployment directory.
|
||||
|
||||
Two templates for these CMakeLists.txt files are provided as part of the CMake system. One for
|
||||
Modules that result in the creation of a library, executable, or both. The other for Deployments,
|
||||
which setup the CMake for a deployment and include a number of Modules.
|
||||
|
||||
Components, Ports, and Topologies (`Top` folders) all use the Module template. These modules
|
||||
provide libraries and executables to the system.
|
||||
|
||||
Top-level deployment directories (`Ref` folder) use the deployment templates. It is there to setup
|
||||
the entry point to the build system.
|
||||
|
||||
|
||||
## Cross-Compiling With CMake
|
||||
|
||||
In order to cross-compile F´ with the cmake system to some new target platform, two files are
|
||||
required. These two files are a cmake toolchain file, and an F´ platform file. Once these files
|
||||
have been created, a cross-compile can be set up and run with the following commands:
|
||||
|
||||
```
|
||||
mkdir build-cross
|
||||
cd build-cross
|
||||
cmake -DCMAKE_TOOLCHAIN_FILE=<path/to/toolchain/file> <path/to/deployment>
|
||||
make
|
||||
```
|
||||
|
||||
## CMake Customization
|
||||
|
||||
Sometimes users need to crack open the CMake structure in order to do things like adding an external
|
||||
library/build system, adding custom make targets, building utilities, etc. These issues are described
|
||||
here: [Customization](./cmake-customization.md)
|
||||
|
||||
|
||||
Further documentation can be found in the CMake SDD: [SDD.md](https://github.com/nasa/fprime/blob/devel/cmake/docs/sdd.md)
|
||||
@ -11,43 +11,25 @@ cannot be found herein.
|
||||
## Build F Prime Utilities
|
||||
|
||||
Adding a utility executable that depends on F prime code is easy. Just perform a standard call to
|
||||
`register_fprime_executable`. Care should be taken to set the variable `EXECUTABLE_NAME` before
|
||||
making this call in order to set the utility's name. This executable will then be output as part
|
||||
of the deployment's build. A separate tools deployment may be used to build only utilities.
|
||||
`register_fprime_executable`. Care should be taken to set the executable name as the first argument to that
|
||||
call. This executable will then be output as part of the deployment's build and may be built directly by name.
|
||||
A separate tools deployment may be used to build only utilities.
|
||||
|
||||
See: [API](cmake-api.md)
|
||||
|
||||
## Custom Build-System Commands (Make Targets)
|
||||
|
||||
Custom build targets that need to be built against modules and global targets can be generated
|
||||
using the hook pattern. This pattern involves creating a file with two functions - `add_global_target` and `add_module_target`. These functions are called to add targets to the top level and each module respectively.
|
||||
using the hook pattern. This pattern involves creating a file with three functions - `<target>_add_global_target`, `<target>_add_module_target`, and `<target>_add_deployment_target`. These functions are called to add targets to the top level and each module respectively.
|
||||
Then this file is registered with `register_fprime_target`.
|
||||
|
||||
In the two add functions, the user is expected to call the `add_custom_target` CMake command in order to compose the target itself. **Note:** the user may simply call this function directly to
|
||||
add targets that don't have both per-module and global steps.
|
||||
These functions can have any code the target needs, but typically uses `add_custom_target` to register the actual target.
|
||||
|
||||
See:
|
||||
- [add_custom_target](https://cmake.org/cmake/help/latest/command/add_custom_target.html) to view
|
||||
information on CMake targets.
|
||||
- [API](cmake-api.md) for the syntax of the register call
|
||||
- [Targets](cmake-targets.md) for information on the built-in targets
|
||||
- [F´ standard targets](https://github.com/nasa/fprime/tree/devel/cmake/target) as an example of adding targets
|
||||
|
||||
**Example (Raw Global Target):**
|
||||
|
||||
```
|
||||
add_custom_target(
|
||||
dict
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_BINARY_DIR}/dict/serializable ${CMAKE_SOURCE_DIR}/py_dict/serializable
|
||||
COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_SOURCE_DIR}/py_dict/serializable/__init__.py
|
||||
)
|
||||
```
|
||||
**Running Example:**
|
||||
|
||||
```
|
||||
cmake ../Ref
|
||||
make dict
|
||||
```
|
||||
|
||||
## Custom External Libraries With Other Build Systems
|
||||
|
||||
@ -60,7 +42,5 @@ dependency, and `add_custom_command` is used when the system needs access to the
|
||||
Alternatively, `ExternalProject_Add` can be used if the external library requires download,
|
||||
version control, and building steps.
|
||||
|
||||
**Supporting Documentation:**
|
||||
1. [https://cmake.org/cmake/help/latest/command/add_custom_target.html](https://cmake.org/cmake/help/latest/command/add_custom_target.html)
|
||||
2. [https://cmake.org/cmake/help/latest/command/add_custom_command.html](https://cmake.org/cmake/help/latest/command/add_custom_command.html)
|
||||
3. [https://cmake.org/cmake/help/latest/module/ExternalProject.html](https://cmake.org/cmake/help/latest/module/ExternalProject.html)
|
||||
For a guide on integrating with another build system see:
|
||||
[How To: Integrate External Libraries](../../how-to/integrate-external-libraries.md).
|
||||
@ -1,4 +1,4 @@
|
||||
# Package Implementations
|
||||
# CMake Implementations
|
||||
|
||||
Certain parts of F´ have different implementations that a project may choose from. The canonical example of this is a file system implementation. Projects may wish to use the stubbed implementation of the file system, the platform supplied standard implementation, or something project-specific like a flash chip or SD card.
|
||||
|
||||
@ -6,28 +6,38 @@ These packages must be fully specified. Thus, every platform must specify a spec
|
||||
|
||||
## Requiring an Implementation
|
||||
|
||||
Modules that require an implementation should call the CMake API function `require_fprime_implementation()` to declare a requirement on a specific implementation. For example, the Os module `require_fprime_implementation(Os/Task)` declares that some implementation of `Os/Task` is required.
|
||||
Modules that require an implementation should use the directive `REQUIRES_IMPLEMENTATIONS` in the `register_fprime_module` call.
|
||||
|
||||
> [!NOTE]
|
||||
> Only `Os` requires an implementation of `Os/Task` as users of the `Os` package get the implementation through `Os` and should not specify it directly.
|
||||
> `REQUIRES_IMPLEMENTATIONS` is only needed for modules that have a direct dependency on the implementation, not on their dependents.
|
||||
|
||||
## Choosing an Implementation
|
||||
|
||||
Platform developers *must* specify an implementation of every package used in the system. Failing to do so means that a given functionality is undefined and impossible to link. Stub implementations are provided in the case that a platform does not support a given package's functionality.
|
||||
|
||||
Choosing an implementation is done with a series of `choose_fprime_implementation` calls. One for each required implementation defined in the system. These calls are put in a platform CMake file.
|
||||
Choosing an implementation is done with the `CHOOSES_IMPLEMENTATIONS` directive available to `register_fprime_config`. Platform developers should choose implementations as part of the platform definition.
|
||||
|
||||
https://github.com/nasa/fprime/blob/dfaf496263bdfff04461179eb99fb3f906a10009/cmake/platform/Linux.cmake#L15-L17
|
||||
|
||||
## Overriding an Implementation Choice
|
||||
|
||||
Some executables, unit tests, and deployments may wish to use a different implementation than that specified by the platform. This can be done by a `choose_fprime_implementation` call in the deployment, executable, or unit test's module. For example, a unit test may wish to choose `Os_File_Stub` as an implementation of `Os_File` to disable platform file system support for the given unit test.
|
||||
Executables, unit tests, and deployments may wish to use a different implementation than that specified by the platform. This can be done by using `CHOOSES_IMPLEMENTATIONS` directive call in the deployment, executable, or unit test's registration. For example, a unit test may wish to choose `Os_File_Stub` as an implementation of `Os_File` to disable platform file system support for the given unit test:
|
||||
|
||||
```
|
||||
register_fprime_ut(
|
||||
...
|
||||
CHOOSES_IMPLEMENTATIONS
|
||||
Os_File_Stub
|
||||
)
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> A CMake target with the name of the chosen implementor *must* be defined somewhere in F´, an F´ library used by the project, or by the project itself.
|
||||
|
||||
## Defining an Implementation
|
||||
|
||||
To define an implementation, developers should declare an F´ module (using `register_fprime_module`) that implements the needed interface of the package. Then call `register_fprime_implementation` to specify this module is an implementation.
|
||||
To define an implementation, developers should declare an F´ module (using `register_fprime_module`) that implements the needed interface of the package and supply the `IMPLEMENTS` directive to that call.
|
||||
|
||||
## Conclusion
|
||||
|
||||
F´ provides for various implementations for certain packages needed by the framework. See `cmake/API` and `Os` for API descriptions and Os implementations.
|
||||
F´ provides for various implementations for certain packages needed by the framework.
|
||||
@ -1,12 +1,11 @@
|
||||
# F´ and CMake Platforms
|
||||
|
||||
Users can create platform-specific build files for the purposes of tailoring fprime
|
||||
for given platform targets. Any CMake toolchain file should work, but it will require a platform file created here to add target-specific configuration using the name "${CMAKE_SYSTEM_NAME}.cmake".
|
||||
for given platform targets. Any CMake toolchain file should work, but it will require a platform file created here to add target-specific configuration using the name "${FPRIME_PLATFORM}.cmake".
|
||||
|
||||
At minimum, this file can be blank, but more commonly there are included paths for "StandardTypes.hpp" to support.
|
||||
Build flags and other includes can be added in to support different compile-time options. In addition, these files can define CMake option flags specific to the build.
|
||||
Platforms should register a configuration module using `register_fprime_config` that sets the `AUTOCODER_INPUTS`, `HEADERS` and
|
||||
`CHOOSES_IMPLEMENTATIONS` directives.
|
||||
|
||||
In order to create a new platform from scratch, the user can copy "platform.cmake.template" and fill it out to generate the new platform file. It will guide the user through the setup of this piece.
|
||||
|
||||
To understand the platform template: [Platform Template File](https://github.com/nasa/fprime/blob/docs/auto-documentation/docs/UsersGuide/api/cmake/platform/platform-template.md)
|
||||
To use the template: [fprime Platform Template](https://github.com/nasa/fprime/blob/devel/cmake/platform/platform.cmake.template)
|
||||
`AUTOCODER_INPUTS`: must include one .fpp file defining the platform's [platform types](../../reference/numerical-types.md#platform-configured-types)
|
||||
`HEADERS`: lists the `PlatformTypes.h` header defining `PlatformPointerCastType`
|
||||
`CHOOSES_IMPLEMENTATIONS`: lists all implementations chosen for the current platform. See: [CMake Implementations](./cmake-implementations.md).
|
||||
|
||||
@ -8,9 +8,6 @@ and have it available to the build system.
|
||||
|
||||
Targets are applied both at the global scope and per-module scope. Thus each target can provide a set of build targets (one per registered module) and a global build target. For example, a counting target might provide a `count` global target to count all files, and a `<MODULE>_count` to count the files of a given module.
|
||||
|
||||
For projects generating GNU make files, these targets can be executed with the `make <target>` and
|
||||
`make <MODULE>_<target>` commands. i.e. `make Svc_CmdDispatcher_coverage`.
|
||||
|
||||
## Built-In Targets
|
||||
|
||||
The CMake system supplies several targets that are useful for all projects and thus are included
|
||||
|
||||
@ -4,12 +4,8 @@ CMake defines the location, arguments, and properties of build tools using toolc
|
||||
specify what configuration of tools to use to build the CMake project. Since CMake toolchain files can be shared between
|
||||
projects, F´ mostly uses them as-is. To set platform-specific fprime settings a parallel Platform file may be created in order to keep those settings out of this more generic file.
|
||||
|
||||
See: [fprime Platform Files](./cmake-platforms.md)
|
||||
|
||||
See: [https://cmake.org/cmake/help/v3.12/manual/cmake-toolchains.7.html](https://cmake.org/cmake/help/v3.12/manual/cmake-toolchains.7.html)
|
||||
|
||||
To create a new toolchain, copy the toolchain.template.cmake file and fill it out. Then create a platform file in the
|
||||
platform directory. Other CMake toolchains (from CMake, other CMake-based projects, etc) can be used. The appropriate
|
||||
platform file must be created if it does not exist.
|
||||
|
||||
To understand the toolchain template: [Toolchain Template File](../../reference/api/cmake/toolchain/toolchain-template.md)
|
||||
To use the template: [fprime Toolchain Template](https://github.com/nasa/fprime/blob/devel/cmake/toolchain/toolchain.cmake.template)
|
||||
CMake toolchains are often adapted from vendor-supplied toolchains, or from one F´ provides. Users should set the variable
|
||||
`FPRIME_PLATFORM` in their toolchain to specify the F Prime platform file. See: [fprime Platform Files](./cmake-platforms.md)
|
||||
@ -18,7 +18,7 @@ In this document:
|
||||
## `settings.ini` Settings
|
||||
|
||||
The `settings.ini` file is written in the INI format as interpreted by the default settings of the
|
||||
Python `configparser` module. Should a user were to reference another key, the `%(other key)s` syntax should be used. The full format description is available here:
|
||||
Python `configparser` module. Should a user wish to reference another key, the `%(other key)s` syntax should be used. The full format description is available here:
|
||||
|
||||
https://docs.python.org/3/library/configparser.html#supported-ini-file-structure
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user