diff --git a/.gitignore b/.gitignore index 0e79ef1..b10ca45 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ BUILD cmake_build mbed-os +definitions.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 785405e..4133f33 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,9 @@ cmake_minimum_required(VERSION 3.19.0 FATAL_ERROR) +# Create definitions.h, a header file with definitions generated from setup.yml and tests.yml +execute_process(COMMAND ./parseConfigs.py + COMMAND_ERROR_IS_FATAL ANY) + set(MBED_PATH ${CMAKE_CURRENT_SOURCE_DIR}/mbed-os CACHE INTERNAL "") set(MBED_CONFIG_PATH ${CMAKE_CURRENT_BINARY_DIR} CACHE INTERNAL "") set(APP_TARGET embedded-mbed) @@ -12,6 +16,12 @@ add_subdirectory(${MBED_PATH}) add_executable(${APP_TARGET} testRunner.cpp) +# Precompile the definitions header. The generated header will be force included in all source files, so they don't need `#include "definitions.h"` +target_precompile_headers(${APP_TARGET} + PRIVATE + definitions.h +) + target_sources(${APP_TARGET} PRIVATE testRunner.cpp diff --git a/parseConfigs.py b/parseConfigs.py new file mode 100755 index 0000000..ea0e9ee --- /dev/null +++ b/parseConfigs.py @@ -0,0 +1,55 @@ +#!/bin/python3 + +import yaml + + +# Get information from configuration files +with open('tests.yml', 'r') as testFile, open('setup.yml', 'r') as setupFile: + testCfg = yaml.safe_load(testFile) + setupCfg = yaml.safe_load(setupFile) + + +# Get target and ensure that it is consistent across the configuration files +target = setupCfg['setup']['target'] +assert target == list(testCfg.keys())[0], "Target in setup.yml ({}) does not match the root key in tests.yml ({})".format(target, list(testCfg.keys())[0]) + + +# Stores lines of generated definitions header file +definitions=[] +lineNum = 1 + + +# Insert definitions for devices and drivers macros +# These macros will be used throughout the project whenever test setup-related info is needed +for setupCat in ['devices', 'drivers']: + if isinstance(setupCfg['setup'][setupCat], dict): + definitions.insert(lineNum, '{}// Define macros for {}\n'.format('\n' if setupCat != 'devices' else '', setupCat)) + lineNum += 1 + for setup, setupInfo in setupCfg['setup'][setupCat].items(): + for attr, val in setupInfo.items(): + # If val is a list, make it a string and reformat it as a C array (i.e. {...} instead of [...]) + if isinstance(val, list): + val = '{' + str(val)[1:-1] + '}' + definitions.insert(lineNum, '#define {}_{} {}\n'.format(setup.upper(), attr.upper(), val)) + lineNum += 1 + +# Insert definitions for test macros +# These macros will be used in testRunner.cpp to determine what tests should be run, +# as well as in any source files that have test-dependent configurations +if isinstance(testCfg[target], dict): + definitions.insert(lineNum, '\n// Define macros for tests\n') + lineNum += 1 + for testCat, tests in testCfg[target].items(): + startLine=lineNum + for test, testType in tests.items(): + if testType != 'disabled': + definitions.insert(lineNum, '#define {}_{} \"{}\"\n'.format(testCat.upper(), test.upper(), testType.upper())) + lineNum += 1 + # Only insert the TEST_ line if one or more of the tests within that category are not disabled + if startLine < lineNum: + definitions.insert(startLine - 1, '// Start {} test definitions\n#define TEST_{}\n'.format(testCat, testCat.upper())) + lineNum += 1 + +# Create/Replace the contents of definitions.h with the generated lines +with open('definitions.h', 'w') as definitionsFile: + definitionsFile.writelines(definitions)