Skip to content

Design_document

Martin Kojtal edited this page Dec 3, 2019 · 6 revisions

Progen design document

** This is under construction **

If you want to contribute or use progen via its classes, this is the place to start.

Classes

Generator

This class is an abstraction on top of projects.

from project_generator.generate import Generator

# projects.yaml is a main record file
generator = Generator('projects.yaml')
# get a project named project_name_1
project1 = next(Generator(projects_yaml).generate('project_name_1'))

# generate a project for IAR
project1.generate('iar')

Project

The most important class is the project.

# get default project settings
project_settings = ProjectSettings()
# create a new project
project = Project('project_name', [project_dicts], project_settings)
project.generate('iar')

project_dicts can be either YAML files or python dictionaries. If YAML files are passed, then they are parsed and project_dict are formed.

The project dictionaries are defined via ProjectTemplate classes. For a user, there's ProjectTemplate. To get a project template:

from project_generator.project import ProjectTemplate

# create project data
project_data = {'common': {}}
project_data['common'] = ProjectTemplate.get_project_template()

# we can now fill in our project details
project_data['common']['name'] = my_name
project_data['common']['sources'] = source_files

Settings

It contains the progen settings. It's required to be passed for main progen classes, as it defines the user settings.

from project_generator.settings import ProjectSettings

project_settings = ProjectSettings()

Tools

The main tool classes are Tool and Exporter, any tool class should inherit from these, and implement their methods. The Tool defines API for tools (toolchain, tool name). The Exporter defines API for generating projects.

This is the boilerplate for a new tool, which any tool should implement (building is an optional):

from project_generator.tools.tool import Tool, Exporter

class MyNewTool(Tool, Exporter):
    def __init__(self, workspace, env_settings):
        # workspace or project
        self.workspace = workspace
        self.env_settings = env_settings

    @staticmethod
    def get_toolnames():
        return ['toolname']

    @staticmethod
    def get_toolchain():
        return 'toolchain'

    def export_workspace(self):
        # might be empty if not supported

    def export_project(self):
        # export a project here
        return generated_files_dict
Tool templates

In the early versions of progen we used to have only jinja2 templates. They are easy to define to work with. Therefore is recommended to start with jinja2, and fill in the template with progen data. However, when tool is a bit more complicated (let's take an example uvision), means it provides many options, it becomes harder to implement all those options via jinja2 templates.

Therefore various tools have no template file, the template is a python dictionary (parsed project file via python), which then is changed according to a user's template file or user's data. This requires some reverse engineering the project files. As result, it can provide 100 percent tool options coverage using not much code, as many of those options have some common patterns (one method can cover all debug/linker options for instance). For better understanding, look at how uvision is implemented.