From 72230b6e501e2b47b821b685d03702c735e256b7 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 11 Oct 2021 13:34:57 +0200 Subject: [PATCH] added build scripts --- README.md | 11 +- cmake/cmake-build-cfg.py | 254 ++++++++++++++++++++++++++++++++ cmake/scripts/make-debug-cfg.sh | 34 +++++ 3 files changed, 291 insertions(+), 8 deletions(-) create mode 100755 cmake/cmake-build-cfg.py create mode 100755 cmake/scripts/make-debug-cfg.sh diff --git a/README.md b/README.md index c92f58d..8e374a3 100644 --- a/README.md +++ b/README.md @@ -106,18 +106,13 @@ related steps. On Linux, run the following command: ```sh - cmake -G "Unix Makefiles" -DOS_FSFW=rtems -DCMAKE_BUILD_TYPE=Debug -DTGT_BSP=arm/stm32h743zi-nucleo .. - ``` - - On Windows, use the following command: - - ```sh - cmake -G "MinGW Makefiles" -DOS_FSFW=rtems -DCMAKE_BUILD_TYPE=Debug -DTGT_BSP=arm/stm32h743zi-nucleo .. + cmake -G "Ninja" -DFSFW_OSAL=rtems -DCMAKE_BUILD_TYPE=Debug .. ``` The build configuration can also be performed with the shell scripts located inside `cmake/scripts/RTEMS` or the Python helper script `cmake_build_config.py` inside - `cmake/scripts`. + `cmake/scripts`. You can also use Make by using `-G "Unix Makefiles"` or `-G "MinGW Makefiles"` + as the build generator. 5. Build the application diff --git a/cmake/cmake-build-cfg.py b/cmake/cmake-build-cfg.py new file mode 100755 index 0000000..98f0df4 --- /dev/null +++ b/cmake/cmake-build-cfg.py @@ -0,0 +1,254 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -* +""" +@brief CMake configuration helper +@details +This script was written to have a portable way to perform the CMake configuration with various +parameters on different OSes. It was first written for the FSFW Example, but could be adapted to +be more generic in the future. + +Run cmake_build_config.py --help to get more information. +""" +import os +import platform +import sys +import argparse +import shutil + + +def main(): + print("-- Python CMake build configurator utility --") + + print("Parsing command line arguments..") + parser = argparse.ArgumentParser( + description="Processing arguments for CMake build configuration." + ) + parser.add_argument( + "-o", "--osal", type=str, choices=["rtems"], + help="FSFW OSAL. Valid arguments: rtems" + ) + parser.add_argument( + "-b", "--buildtype", type=str, choices=["debug", "release", "size", "reldeb"], + help="CMake build type. Valid arguments: debug, release, size, reldeb " + "(Release with Debug Information)", default="debug" + ) + parser.add_argument("-l", "--builddir", type=str, help="Specify build directory.") + parser.add_argument( + "-g", "--generator", type=str, help="CMake Generator", + choices=["ninja", "make"] + ) + parser.add_argument( + "-d", "--defines", + help="Additional custom defines passed to CMake (supply without -D prefix!)", + nargs="*", type=str + ) + + args = parser.parse_args() + + print("Determining source location..") + source_location = determine_source_location() + print(f"Determined source location: {source_location}") + + print("Building cmake configuration command..") + + if args.generator is None: + generator = determine_build_generator() + generator_cmake_arg = f"-G \"{generator}\"" + else: + if args.generator == "ninja": + generator_cmake_arg = "-G \"Ninja\"" + elif args.generator == "make": + if sys.platform == 'win32': + generator_cmake_arg = "-G \"MinGW Makefiles\"" + else: + generator_cmake_arg = "-G \"Unix Makefiles\"" + + + define_string = "" + if args.defines is not None: + define_list = args.defines[0].split() + for define in define_list: + define_string += f"-D{define} " + cmake_build_folder = args.builddir + cmake_fsfw_osal = args.osal + + if args.buildtype == "debug": + cmake_build_type = "Debug" + elif args.buildtype == "release": + cmake_build_type = "Release" + elif args.buildtype == "reldeb": + cmake_build_type = "RelWithDebInfo" + else: + cmake_build_type = "MinSizeRel" + os_set = False + set_freertos = False + + build_path = source_location + os.path.sep + cmake_build_folder + if os.path.isdir(build_path): + remove_old_dir = input( + f"{cmake_build_folder} folder already exists. " + f"Remove old directory? [y/n]: " + ) + if str(remove_old_dir).lower() in ["yes", "y", 1]: + remove_old_dir = True + else: + cmake_build_folder = determine_new_folder() + build_path = source_location + os.path.sep + cmake_build_folder + remove_old_dir = False + if remove_old_dir: + try: + shutil.rmtree(build_path) + except PermissionError as error: + print(error) + print("File might still be opened!") + sys.exit(0) + os.chdir(source_location) + os.mkdir(cmake_build_folder) + print(f"Navigating into build directory: {build_path}") + os.chdir(cmake_build_folder) + + cmake_command = \ + f"cmake {generator_cmake_arg} -DFSFW_OSAL=\"{cmake_fsfw_osal}\" " \ + f"-DCMAKE_BUILD_TYPE=\"{cmake_build_type}\" {define_string} {source_location}" + # Remove redundant spaces + cmake_command = ' '.join(cmake_command.split()) + print("Running CMake command (without +): ") + print(f"+ {cmake_command}") + os.system(cmake_command) + print("-- CMake configuration done. --") + + +def determine_build_generator() -> str: + print("No generator specified. ") + print("Please select from the following list of build types or type " + "in desired system directly [h for help]: ") + while True: + user_input = input("Enter your selection: ") + if user_input == "h": + os.system("cmake --help") + else: + build_generator = user_input + confirmation = input(f"Confirm your generator: {build_generator} [y/n]: ") + if confirmation in ["y", "yes", 1]: + break + return build_generator + + +def determine_build_folder(cmake_build_type: str) -> str: + confirm = input(f"No build folder specified. Set to build type name {cmake_build_type}? [y/n]: ") + if confirm in ["yes", "y", 1]: + return cmake_build_type + else: + new_folder_name = input("Please enter folder name, will be created in source folder: ") + return new_folder_name + + +def determine_source_location() -> str: + index = 0 + while not os.path.isdir("fsfw"): + index += 1 + os.chdir("..") + if index >= 5: + print("Error: Could not find source directory (determined by looking for fsfw folder!)") + sys.exit(1) + return os.getcwd() + + +def determine_fsfw_osal() -> str: + select_dict = dict({ + 1: "host", + 2: "linux", + 3: "freertos", + 4: "rtems" + }) + print("No build type specified. Please select from the following list of build types: ") + for key, item in select_dict.items(): + print(f"{key}: {item}") + select = input("Enter your selection: ") + while True: + if select.isdigit(): + select_num = int(select) + if select_num >= 1 or select_num <= 4: + return select_dict[select_num] + else: + print("Input digit is invalid!") + else: + print("Input is not a digit!") + + +def determine_build_type(build_type_arg) -> str: + if build_type_arg is None: + select_dict = dict({ + 1: "Debug", + 2: "Release", + 3: "Release with Debug Information", + 4: "Size" + }) + print("No build type specified. Please select from the following list of build types") + for key, item in select_dict.items(): + print(f"{key}: {item}") + select = input("Enter your selection: ") + while True: + if select.isdigit(): + select_num = int(select) + if select_num >= 1 or select_num <= 4: + cmake_build_type = select_dict[select_num] + break + else: + print("Input digit is invalid!") + else: + print("Input is not a digit!") + else: + if build_type_arg == "debug": + cmake_build_type = "Debug" + elif build_type_arg == "release": + cmake_build_type = "Release" + elif build_type_arg == "size": + cmake_build_type = "MinSizeRel" + elif build_type_arg == "reldeb": + cmake_build_type = "RelWithDebInfo" + else: + print("Unknown buildtype.") + cmake_build_type = determine_build_type(None) + return cmake_build_type + + +def determine_new_folder() -> str: + new_folder = input(f"Use different folder name? [y/n]: ") + if str(new_folder).lower() in ["yes", "y", 1]: + new_folder_name = input("New folder name: ") + return new_folder_name + else: + print("Aborting configuration.") + sys.exit(0) + + +""" +def determine_tgt_bsp(osal: str) -> str: + if osal == "freertos": + print("Target BSP set to arm/stm32h743zi-nucleo") + osal = "arm/stm32h743zi-nucleo" + elif osal == "linux": + print("No target BSP specified. Please select from the following list of build types.") + select_dict = dict({ + 1: "arm/raspberrypi", + 2: "none/hosted" + }) + for key, item in select_dict.items(): + print(f"{key}: {item}") + select = input("Enter your selection: ") + while True: + if select.isdigit(): + select_num = int(select) + if select_num >= 1 or select_num <= 2: + osal = select_dict[select_num] + break + else: + print("Input digit is invalid!") + else: + print("Input is not a digit!") + return osal +""" + +if __name__ == "__main__": + main() diff --git a/cmake/scripts/make-debug-cfg.sh b/cmake/scripts/make-debug-cfg.sh new file mode 100755 index 0000000..a5c3084 --- /dev/null +++ b/cmake/scripts/make-debug-cfg.sh @@ -0,0 +1,34 @@ +#!/bin/sh +counter=0 +cfg_script_name="cmake-build-cfg.py" +while [ ${counter} -lt 5 ] +do + cd .. + if [ -f ${cfg_script_name} ];then + break + fi + counter=$((counter=counter + 1)) +done + +if [ "${counter}" -ge 5 ];then + echo "${cfg_script_name} not found in upper directories!" + exit 1 +fi + +build_generator="ninja" +os_fsfw="rtems" +builddir="build-Debug" +build_type="debug" +if [ "${OS}" = "Windows_NT" ]; then + python="py" +# Could be other OS but this works for now. +else + python="python3" +fi + +echo "Running command (without the leading +):" +set -x # Print command +${python} ${cfg_script_name} -o "${os_fsfw}" -g "${build_generator}" -l "${builddir}" \ + -b "${build_type}" +# Use this if commands are added which should not be printed +# set +x