Skip to content

Application Build system

Ludwig Schreier edited this page Feb 27, 2017 · 9 revisions

A new build system using python has been added recently. It is based on a Python script written by Pierre Molinaro. It will coexist with the system using make for some time and will replace it eventually. Currently the new build system works with the cortex targets and PowerPC targets only. It will be extended to the other targets soon.

How to use the new build system

Using the new system is quite simple. Locate the BUILD object in the OS object of your OIL file. You should have something like that (example taken from examples/cortex/armv7/stm32f407/stm32f4discovery/readbutton_isr):

    BUILD = TRUE {
      TRAMPOLINE_BASE_PATH = "../../../../../..";
      APP_SRC = "readbutton_isr.c";
      APP_NAME = "readbutton_isr_exe";
      CFLAGS  = "-O0"; 
      LDFLAGS = "-Map=readbutton_isr.map";
      COMPILER = "arm-none-eabi-gcc";
      ASSEMBLER = "arm-none-eabi-as";
      LINKER = "arm-none-eabi-ld";
      COPIER = "arm-none-eabi-objcopy";
      SYSTEM = PYTHON;
    };

Attribute SYSTEM = PYTHON; inside the BUILD object set the build system to Python.

Run goil

Run goil on the OIL file: goil --target=cortex/armv7/stm32f407/stm32f4discovery --templates=../../../../../../goil/templates readbutton_isr.oil.

Two files related to the build system are generated: make.py and build.py. make.py contains the rules and the build commands used to compile the OIL file itself. Dependencies are set on the OIL file and on all the included OIL files. build.py contains the rules and the build commands used to compile the C files of the application, of the OS and those that have been generated by the OIL compilation. make.py calls build.py so it is not needed to launch build.py directly, use only make.py.

Build the application

The application is now built by executing make.py: ./make.py. 2 build goals are provided by default: all and clean. Launching ./make.py without any argument or with argument all are equivalent. ./make.py clean cleans up all the files.

Additional build goal

On some target platform, additional build goals may be available. For instance on thumb2/cortex-m4/STM32F4-Discovery the goal burn allow to burn the flash with the application.

How to configure the build system for a target

Adding a target to the build system consists in specifying the target specific files needed. When compiling for a target goil includes the config.oil files, if available, along the target path starting at the goil/templates/config directory. For instance for the thumb2/cortex-m4/STM32F4-Discovery target, goil includes:

  • goil/templates/config/config.oil
  • goil/templates/config/cortex/config.oil
  • goil/templates/config/cortex/armv7/config.oil
  • goil/templates/config/cortex/armv7/stm32f407/config.oil
  • and goil/templates/config/cortex/armv7/stm32f407/stm32f4discovery/config.oil

Adding target specific machines/ files

For each depth in the hierarchy, the config.oil file should define what files in the machines corrresponding path should be compiled along with the operating system and application source files. This definition is done by using the PLATFORM_FILES OIL object. Each PLATFORM_FILES object has an attribute, PATH, to give the relative path (from machines/) where the files are located and as many as needed CFILE (for C source file) and ASFILE (for assembly source file) attributes. For instance, the following PLATFORM_FILES object lists the files needed for the STM32F4-Discovery target:

  PLATFORM_FILES stm32f4discovery {
    PATH = "cortex/armv7/stm32f407/stm32f4discovery";
    CFILE = "stm32f4_discovery.c";
    CFILE = "tp.c";
  };

Adding target specific generated files

Additional files may be generated for a target: interrupt handlers, macros to acknowledge interrupts and so on. To have these files taken into account by the build system, they have to be listed in the config.oil files by using the GENERATED_FILES OIL object. For instance the following declaration lists the files generated for the cortex/armv7 target and located in goil/templates/config/cortex/armv7/config.oil file:

  GENERATED_FILES cortex_m4 {
    CFILE = "tpl_first_stage_irq.S";
    CFILE = "tpl_second_stage_irq.S";
    CFILE = "tpl_vectors.c";
  };

These files will be generated in the project directory.

Adding libraries as sources

Libraries are supported as long as libraries dependancies. A library is described by a LIBRARY OIL object. These objects are defined in the config.oil files along the target path. A LIBRARY object has the name of the library and the following attributes:

  • PATH sets the relative path of the library from the machines/ directory;
  • CHEADER gives the name of the C Header files to be included to use the library. A #includefor this file is added in the tpl_os.h generated file. More than one can be set;
  • CPPHEADER gives the name of the C++ Header files to be included to use the library. A #includefor this file is added in the tpl_os.h generated file and protected by a #ifdef __cplusplus. More than one can be set;
  • CFILE gives the name of a C file to be compiled. More than one can be set;
  • CPPFILE gives the name of a C++ file to be compiled. More than one can be set;
  • ASFILE gives the name of a assembly source file to be assembled. More than one can be set;
  • NEEDS gives the name of a library. More than one can be set. These are libraries the current library depends on.

For instance, library LiquidCrystalFast depends on library Print and library Print depends on library WString. These library are declared as follow:

  LIBRARY WString {
    PATH = "cortex/armv7/mk20dx256/teensy31/libraries/WString";
    CPPHEADER = "WString.h";
    CPPFILE = "WString.cpp";
  };

  LIBRARY Print {
    NEEDS = WString; /* Print depends on WString */
    PATH = "cortex/armv7/mk20dx256/teensy31/libraries/Print";
    CPPHEADER = "Print.h";
    CPPFILE = "Print.cpp";
  };

  LIBRARY LiquidCrystalFast {
    NEEDS = Print;  /* LiquidCrystalFast depends on Print */
    PATH = "cortex/armv7/mk20dx256/teensy31/libraries/LiquidCrystalFast";
    CPPHEADER = "LiquidCrystalFast.h";
    CPPFILE = "LiquidCrystalFast.cpp";
  };

Putting a LIBRARY = LiquidCrystalFast; in the build object of an application to use the LCD leads to the following:

  • Since LiquidCrystalFast depends on Print and Print depends on WString, LiquidCrystalFast, Print and WString sources files are added to the project;
  • LiquidCrystalFast.h is included in tpl_os.h.

Adding post-build command to a goal

Additional commands may be applied to a goal. For instance, after generating the executable, it has to be transformed to another format in order to be downloaded to the board. This is done by using the POSTBUILD OIL object with the COMMAND attribute. The name of the POSTBUILD object is the goal where the command are added. The following sub-attributes of COMMAND are available:

  • TYPE gives the command. Predefined commands are available:
    • COMPILER uses the compiler defined in the application OIL file;
    • ASSEMBLER uses the assembler defined in the application OIL file;
    • LINKER uses the linker defined in the application OIL file;
    • COPIER uses the copier defined in the application OIL file;
    • CUSTOM uses a custom command. In this case, 2 sub-attributes must be provided:
      • MESSAGE: the message o be displayed when the command is run:
      • NAME: the name of the command.
  • INPUT gives the input file of the command. Values are as follow:
    • TARGET: the input is the target of the goal.
    • INTERMEDIATE: the input is an arbitrary file. In this case a sub-attribute, SOURCE gives the name of the file.
  • OUTPUT gives the extension that will be added to INPUT to build the output file name. It can be omitted. In this case the command is not supposed to output any file;
  • PREOPTION gives the options that will be put in the command line before the input and output file names;
  • POSTOPTION gives the options that will be put in the command line after the input and output file names.

For instance, the following declaration adds a post-build command to goal all:

POSTBUILD all {
  COMMAND buildbin {
    TYPE = COPIER;
    INPUT = TARGET;
    OUTPUT = ".bin";
    PREOPTION = "-O binary";
  };
};

If COPIER is defined as arm-eabi-objcopy and the target of all is readbutton_isr_exe, this declaration will run command:

arm-eabi-objcopy -O binary readbutton_isr_exe readbutton_isr_exe.bin

Adding post-command to the build process

Additional commands may be run at the end of the build process. Such a command is added by using the POSTCOMMAND OIL object with the COMMAND attribute. The name of the object defines the goal for which the post command should be run. If the name is not all or clean, a corresponding sub-goal of all is defined. Using this sub-goal builds the goal all and executes the post-commands. The following sub-attributes of COMMAND are available:

  • MESSAGE: unused at that moment;
  • COMMAND: name of the command
  • INPUT gives the input file of the command. Values are as follow:
    • TARGET: the input is the target of the goal. In this case a sub-attribute, EXT gives a file extension.
    • INTERMEDIATE: the input is an arbitrary file. In this case a sub-attribute, SOURCE gives the name of the file.
  • OUTPUT gives the extension that will be added to INPUT to build the output file name. It can be omitted. In this case the command is not supposed to output any file;
  • PREOPTION gives the options that will be put in the command line before the input and output file names;
  • POSTOPTION gives the options that will be put in the command line after the input and output file names.

For instance, the following declaration adds a post-command to goal all:

POSTCOMMAND burn {
  COMMAND flash {
    MESSAGE = "Flashing";
    COMMAND = "st-flash";
    INPUT = TARGET { EXT = ".bin"; };
    PREOPTION = "write";
    POSTOPTION = "0x8000000";
  };
};

This declaration adds a sub-goal burn. Typing ./make.py burn with target being readbutton_isr_exe runs goal all then apply the post-command:

st-flash write readbutton_isr_exe.bin 0x8000000

This command flashes the readbutton_isr_exe.bin using the stlink software.