From 21faffa6f85ef09a0d1baecbcce5fa8c729d4708 Mon Sep 17 00:00:00 2001 From: M Starch Date: Tue, 5 Aug 2025 16:52:14 -0700 Subject: [PATCH] CMake documentation refactor (#3981) * CMake documentation refactor * sp * Update cmake-implementations.md --- cmake/docs/sdd.md | 246 ++++-------------- .../build-system/01-cmake-intro.md | 29 +-- .../build-system/cmake-advanced.md | 102 -------- .../build-system/cmake-customization.md | 34 +-- ...mentations.md => cmake-implementations.md} | 24 +- .../build-system/cmake-platforms.md | 13 +- .../user-manual/build-system/cmake-targets.md | 3 - .../build-system/cmake-toolchains.md | 10 +- docs/user-manual/build-system/settings.md | 2 +- 9 files changed, 93 insertions(+), 370 deletions(-) delete mode 100644 docs/user-manual/build-system/cmake-advanced.md rename docs/user-manual/build-system/{package-implementations.md => cmake-implementations.md} (51%) diff --git a/cmake/docs/sdd.md b/cmake/docs/sdd.md index df2e5c3442..083e01595c 100644 --- a/cmake/docs/sdd.md +++ b/cmake/docs/sdd.md @@ -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 /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 -mkdir build_config1 -cd build_config1 -cmake ../ -D -``` - -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 /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 -git clean -xdf . #WARNING, this clobbers *all* untracked files -cmake ../ -D -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. ![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,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. diff --git a/docs/user-manual/build-system/01-cmake-intro.md b/docs/user-manual/build-system/01-cmake-intro.md index 574dab398a..c25442b0f0 100644 --- a/docs/user-manual/build-system/01-cmake-intro.md +++ b/docs/user-manual/build-system/01-cmake-intro.md @@ -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`. diff --git a/docs/user-manual/build-system/cmake-advanced.md b/docs/user-manual/build-system/cmake-advanced.md deleted file mode 100644 index 92035777bc..0000000000 --- a/docs/user-manual/build-system/cmake-advanced.md +++ /dev/null @@ -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 -DCMAKE_BUILD_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= -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) diff --git a/docs/user-manual/build-system/cmake-customization.md b/docs/user-manual/build-system/cmake-customization.md index 965b4122c4..9567315d3b 100644 --- a/docs/user-manual/build-system/cmake-customization.md +++ b/docs/user-manual/build-system/cmake-customization.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 - `_add_global_target`, `_add_module_target`, and `_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). \ No newline at end of file diff --git a/docs/user-manual/build-system/package-implementations.md b/docs/user-manual/build-system/cmake-implementations.md similarity index 51% rename from docs/user-manual/build-system/package-implementations.md rename to docs/user-manual/build-system/cmake-implementations.md index 977efc1ad7..7f195aa663 100644 --- a/docs/user-manual/build-system/package-implementations.md +++ b/docs/user-manual/build-system/cmake-implementations.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. diff --git a/docs/user-manual/build-system/cmake-platforms.md b/docs/user-manual/build-system/cmake-platforms.md index 15d9e95e52..ed35324520 100644 --- a/docs/user-manual/build-system/cmake-platforms.md +++ b/docs/user-manual/build-system/cmake-platforms.md @@ -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). diff --git a/docs/user-manual/build-system/cmake-targets.md b/docs/user-manual/build-system/cmake-targets.md index d9dbdce190..f4a906befb 100644 --- a/docs/user-manual/build-system/cmake-targets.md +++ b/docs/user-manual/build-system/cmake-targets.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 `_count` to count the files of a given module. -For projects generating GNU make files, these targets can be executed with the `make ` and -`make _` 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 diff --git a/docs/user-manual/build-system/cmake-toolchains.md b/docs/user-manual/build-system/cmake-toolchains.md index 1a55ae6a96..8a9cdc45ba 100644 --- a/docs/user-manual/build-system/cmake-toolchains.md +++ b/docs/user-manual/build-system/cmake-toolchains.md @@ -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) \ No newline at end of file +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) \ No newline at end of file diff --git a/docs/user-manual/build-system/settings.md b/docs/user-manual/build-system/settings.md index 42a2a679b5..3a1b9c37bd 100644 --- a/docs/user-manual/build-system/settings.md +++ b/docs/user-manual/build-system/settings.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