CMake documentation refactor (#3981)

* CMake documentation refactor

* sp

* Update cmake-implementations.md
This commit is contained in:
M Starch 2025-08-05 16:52:14 -07:00 committed by GitHub
parent dfaf496263
commit 21faffa6f8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 93 additions and 370 deletions

View File

@ -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
![https://cmake.org/](https://cmake.org/). 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´.
![Combined F´ and Adaptations](img/CMake%20Ops%20-%20Traditional.png "Combined F´ and Adaptations")
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.
![Old Style F´Build](img/CMake%20Ops%20-%20Old%20Style.png "Old Style F´Build")
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
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,7 +205,7 @@ 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.
@ -347,8 +213,8 @@ custom components of their own.
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.
![F´ CMake Lists Hierarchy](img/CMake%20Lists%20Hierarchy.png "F´ CMake File Organization")
@ -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,7 +256,7 @@ 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.
@ -402,16 +267,9 @@ complete F´ system is not explicitly built. This makes the build more efficien
### 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.

View File

@ -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`.

View File

@ -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)

View File

@ -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).

View File

@ -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.

View File

@ -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).

View File

@ -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

View File

@ -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)

View File

@ -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