Integrating New Targets
In F´, targets are used to trigger various parts of the system to run. In v3.0.0, everything is a target. The build is a target, dictionaries are another target, etc. This guide will walk you through integrating a new target and the most common case: calling a new autocoder from that target.
Target CMake Structure
F´ targets have the option to run at any or all of the three following levels in the CMake setup: modules, deployments, and
globally. Module targets run on every module defining the <target>_register_fprime_module
functions. Deployment
targets run on deployments defined with the <target>_register_fprime_deployment
calls, and global targets run once.
Targets are CMake files that define three functions, one for each level, and are described below. The filename of this
CMake without the .cmake
extension determines the<target>
name. e.g. utility.cmake
will define the utility
target.
Targets stages are defined in the following order:
- Global targets are setup
- Pre-Module targets are setup
- Deployment targets are setup
This means that global targets are typically created without dependencies, and each module-level target will add itself as a dependency of the global target. Deployment targets are provided a full list of dependencies and thus can be set up with targets. This is done because the dependency tree cannot be known until after each module is set up.
Function <target>_add_global_target
This function must add a global target to be run. The target name is provided for convenience. Most of the time this is used to register a top-level target that will act as a trigger for all module-level targets.
This example adds an empty global target. We will attach module level targets during the <target>_add_module_target
call.
function(utility_add_global_target TARGET)
add_custom_target(${TARGET})
endfunction(utility_add_global_target)
Function <target>_add_module_target
This function adds a target per module. It is supplied the module, target, a list of source files supplied to the
module, and a list of dependencies supplied to the module (i.e. the MOD_DEPS
variable). Most commonly, this is done
to run autocoders on the module. The name of the target added should be: ${TARGET}_${MODULE}
.
Module targets often attach to the global target as dependencies such that all the module targets run before the global
target runs. An example is provided that runs my_autocoder
on each module.
include(autocoder/autocoder)
function(add_module_target MODULE TARGET SOURCE_FILES DEPENDENCIES)
# Run the autocoder setup
run_ac_set("${SOURCE_FILES}" autocoder/my-autocoder)
# Add the module target, and use DEPENDS to trigger generation of autocoder outputs
add_custom_target(${TARGET}_${MODULE} DEPENDS ${AC_GENERATED})
# Attach dependencies to global target
add_dependencies(${TARGET} ${TARGET}_${MODULE}) # Attach to the global target
endfunction(add_module_target)
Function add_deployment_target
This function must add a deployment level target. The target name, module or deployment name, module dependencies, and
the full dependency list are supplied. This function can be used to add targets to a deployment where it is helpful to
know all the needed dependencies. e.g. the install target is registered on a deployment and installs both the deployment
executable and all the archive/shared libraries. The name of the target added should be: ${TARGET}_${MODULE}
This example registers the deployment to the global target and depends on FULL_DEPENDENCIES
to ensure each dependent
module level target is run.
function(add_deployment_target MODULE TARGET SOURCES DEPENDENCIES FULL_DEPENDENCIES)
add_custom_target(${TARGET}_${MODULE} DEPENDS ${FULL_DEPENDENCIES})
add_dependencies(${TARGET} ${TARGET}_${MODULE})
endfunction(add_deployment_target)