Skip to content

Draft: Add uVision Generator

Viktor Wallner requested to merge vik_wallner/cmake:uvision into master

A KEIL uVision generator has already been discussed several times (e.g. #19357) and there have been a couple of implementation attempts (!3356 (closed)). But no final generator has been implemented, so this is my shot at this.

Motivation

KEIL uVision (https://www2.keil.com/mdk5/uvision/) is one of the default IDEs for the KEIL/ARM MDKs, but in many ways cumbersome. So CMake to the rescue! While compiling a simple project can be done with a toolchain file using the ArmCC or ArmClang compilers, provided by KEIL uVision, there are some things (Software Packs, Debuggers, Third-Party SDKs) which require the IDE. Thus a uVision generator might be a better approach.

Implementation Approaches

Creating the project file from scratch

The project format is kind of odd and has its quirks. Even though uVision uses xerces, sometimes even valid XML breaks the project. Also there is a lot of device information (CPU information, device specific defines etc.), which is not that easy to generate.

Using import functionality of uVision (-i command line flag)

uVision provides an XML scheme for the import files. Looks nice at first glance, but lacks a lot of functionality. For example you can only add compiler flags and definitions globally, not for single files

Using the project creation functionality of uVision (-n command line flag)

uVision can create an empty project for a specific device from the command line. This file has all device specific things in place and is a good starting point for generating the rest of the project file.

So this is the approach I choose for the generator.

Generator Implementation

As mentioned above, the generator utilizes the -n command line flag to generate a new project. This project is then loaded with a new class cmXMLEditor, which combines cmXMLParser and cmXMLWriter to modify XML files with a very basic subset of the XPath syntax.

For converting compile flags etc. to project settings, it uses json based flag tables, similar to the VS generator (maybe there is some synergy potential?).

State of the generator

  • Library targets
  • Executable targets
  • Multi-Project Workspaces
  • Building with CMake
    • uVision does not pipe the build log to StdOut (because even when calling it from the command line, they start a gui application)
    • So the build has to wait till the end of the build to read the build log file and print it to StdOut
    • A better solution might be the usage of named pipes (in a VS generator a similar approach is mentioned, but I think never pursued)
  • Software Packs
    • Realized as imported module libraries with special target properties
  • Custom targets
    • Realized as executable targets, which skip the linking step (couldn't find a way to skip the archiver step for library targets)
  • Custom commands
  • Special CMake targets (ALL_BUILD, ZERO_CHECK)
  • Project dependencies in the IDE
    • uVision does not support dependencies between projects in a multi-project workspace. The current approach is to sort them the right way in the multi-project workspace, so a batch build builds them in the correct order.
    • Building with CMake is not affected by this.
    • Maybe some kind of prebuild actions could simulate project dependencies.

Testing

Currently I'm preparing a test machine for running nightly tests, which has uVision installed. Is there a way to run the tests for a specific pull request using the CMake dashboards scripts?

Further support and maintenance

I developed the generator mainly for my current customer Infineon (https://en.wikipedia.org/wiki/Infineon_Technologies), where an earlier version of this generator is already used in a well sized project. There is serious interest from Infineon in supporting (test machines) and maintaining this generator.

Merge request reports