Component Generator

The main goal of this tool is to speed up the process of generating a component from scratch with its source files and testing files.

  • Important note: this tool requires a GAP SDK up to date and properly set up.

  • If you’re using a virtual environment, make sure to use Python 3.10 or above and install all the requirements for all the GAP SDK tools. For more details, see how how to get started with the GAP SDK in the documentation.

Getting started

The first step is to set up your Python environment properly. For this, you must run the setup.sh script from the component_generator directory. It will install and update the necessary Python packages.

With this done, you can get started creating a simple component using the script component_generator/test_gen_component.sh You can begin by copying it to your desired location and editing it’s content. For example, you can change the name of the generated component by changing the variable

component=my_component

The script will execute the command of the line:

$GAP_AUDIO_FRAMEWORK_HOME/utils/component_generator/gen_component.py -n $component -i gap9_fc -P 1
By default, this will generate a component with an implementation called gap9_fc_my_component, a parameter and a single input and output.
If you want to edit the description file (.comp) of the component to generate a new component from there, you can comment the previous line and uncomment the next one:
$GAP_AUDIO_FRAMEWORK_HOME/utils/component_generator/gen_component.py -d $component/$component.comp

From there you can iterate as much as needed from the description file or by changing the arguments in the calls of the gen_component.py script. You can find the list of commands and their usage detailed below.

Build and compile a model

All components are generated with their CMake files completed and ready to use. To build the code of your freshly generated component, you have to run the following commands:

cd my_component/scr
cmake -B ../build # This will create all the building files required for CMake.
cmake --build ../build --target my_component # This will build the code using the previously created build files for our component.

Once the code has been built, to compile the built code you just have to run the non regression test:

cd ../test
./nonreg.sh # Test build files, compiles the code

Build and compile implementations

The build and compilation of implementations differ from models by one step: the parameters have to be built and compiled before the implementation.

For this, we have to build, compile and run the gen_param tool. To achieve that we have to run the following commands:

cd my_component/gap9_fc_my_component/test/gen_param
cmake -B ../build # CMake generates required building files.
cmake --build ../build --target gen_param # CMake builds the gen_param code.
./nonreg.sh # This tests the build and runs the gen_param tool.

Note: here our implementation is called gap9_fc_my_component so you have to replace it by the name of your implementation in order for these commands to work.

Once our parameters have been built properly, we can build, compile and run our implementation. All that process is handled by a single non-regression script:

cd my_component/gap9_fc_my_component/test
./nonreg.sh

or, if you’re still in the gen_param directory:

cd ../../test
./nonreg.sh

Using commands

They allow to generate components directly from a terminal with commands through the construction of the CommandProcessor class. The list of commands is visible when adding the -h or --help when calling your script. For example:

$GAP_AUDIO_FRAMEWORK_HOME/utils/component_generator/gen_component.py -h

In that case the list would appear as follows:

usage: gen_component.py [-h] [-n NAME [NAME ...]] [-i IMPLEMENTATION [IMPLEMENTATION ...]] [-d DESCRIPTION [DESCRIPTION ...]]
                        [-I INPUTS] [-O OUTPUTS] [-P PARAMETERS] [-p PATH] [-t] [-f]

Generates components from commands. Multiple I/O not supported yet.

options:
  -h, --help            show this help message and exit
  -n NAME [NAME ...], --name NAME [NAME ...]
                        Generates components with the specified names. Standalone behaviour: generate a pass through filter. Usage:
                        -n component1 component2...
  -i IMPLEMENTATION [IMPLEMENTATION ...], --implementation IMPLEMENTATION [IMPLEMENTATION ...]
                        Includes the prefixes as implementations to the components. Usage: -i prefix1 prefix2...
  -d DESCRIPTION [DESCRIPTION ...], --description DESCRIPTION [DESCRIPTION ...]
                        Create component from component description (.comp).
  -I INPUTS, --inputs INPUTS
                        Adds the provided number of inputs to the components.
  -O OUTPUTS, --outputs OUTPUTS
                        Adds the provided number of outputs to the components.
  -P PARAMETERS, --parameters PARAMETERS
                        Adds the provided number of parameters to the components.
  -p PATH, --path PATH  Sets the destination folder for the generated component files.
  -t, --template        Generates only a component template (.comp) instead of its files.
  -f, --force           Force overwrite of existing components.

There are some implicit use cases may not be obvious at first glance, so here are some examples:

Generate multiple component with the same characteristics

$GAP_AUDIO_FRAMEWORK_HOME/utils/component_generator/gen_component.py -n comp1 comp2 comp3 -i gap9_fc -P 2

This will generate 3 components (comp1, comp2, comp3), each with one implementation with the prefix “gap9_fc” and two parameters.

Generate component at specific location

Generating a component in another directory other than the CWD (Current Working Directory) can be achieved in two ways when the generation is done through the --name or -n commands:

$GAP_AUDIO_FRAMEWORK_HOME/utils/component_generator/gen_component.py -n amplifier -p home/user/my_folder

or

$GAP_AUDIO_FRAMEWORK_HOME/utils/component_generator/gen_component.py -n my_folder/amplifier

Both commands will generate a component called “amplifier” in the directory “~/my_folder”.

Note that this path is relative to your CWD. This can be changed by specifying the directory you want to use as root with the command -p or --path.

With the same logic as before we can also do the following command to generate multiple components with the same characteristics at different locations:

$GAP_AUDIO_FRAMEWORK_HOME/utils/component_generator/gen_component.py -n comp1 output/comp2 output/my_folder/comp3 -i gap9_fc gap9_sfu -P 1

This command will generate the components comp1, comp2 and comp3 at the CWD, CWD/output and CWD/output/my_folder/ respectively. It will also add the implementations with the prefixes gap9_fc and gap9_sfu.

__init__.py

Allows the use of component_generator as a package by other scripts.

tools.py

Contains useful constants and a set of methods for text formating, reading templates and custom files management.
Can be useful when filling out CMCore components with for checking names with special characters, formating long descriptions or even generating entire directory trees from custom dict.

gen_component.py

It’s the central script of the Component Generator, the one to call even for running commands. It uses tools.py for all text formatting and constructs a CommandProcessor on launch allowing to run commands when calling the script.

Generating a component skeleton mainly requires a CMCore component object populated with all the desired characteristics beforehand. Then, to begin the generation process with python we need a ComponentGenerator object that requires the Component object or the component name and the output directory:

import component_generator.gen_component as gen

my_generator = gen.ComponentGenerator("my_component", "~/output")

Note: if the directory is not specified, the CWD, in this case the script location, will be used.

From there, you can manipulate the CMCore component of the generator by it’s attribute component (my_generator.component) or simply generate all files with the method:

my_generator.gen_all_files()

If you want to generate all files and overwrite any other directory with named as the component it is also possible to generate all files with overwriting:

my_generator.restart_gen()

Changing the Signature content

Changing the content of the file header involves mainly two parts: 1. The Banner. 1. The Tags.

Changing the Banner

To change the Banner, one has to replace the content of the file: templates/banner.c.template. The banner is made out of comments in C language, and it’s recommended to keep the same convention used. The file header will automatically adapt to the banners dimensions.

Testing

To run all tests, run the following command from the component_generator parent folder: python -m unittest discover.

Note: Since Warnings are tested too, it is normal to see some “WARNING” messages during unit testing.

Upcoming features

  • Support multiple inputs.

  • Support multiple outputs.

  • Support non scalar parameters.

For now, all operations involving the previously mentioned features require human intervention.