diff --git a/.clang-format b/.clang-format index 177e4491..7eab3168 100644 --- a/.clang-format +++ b/.clang-format @@ -1,5 +1,122 @@ --- -BasedOnStyle: Google -ColumnLimit: 100 -IndentWidth: '4' +Language: Cpp +AlignAfterOpenBracket: Align +AlignConsecutiveMacros: true +AlignConsecutiveAssignments: true +AlignConsecutiveDeclarations: true +AlignEscapedNewlines: Left +AlignOperands: true +AlignTrailingComments: true +AllowAllArgumentsOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: Never +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: None +AllowShortLambdasOnASingleLine: All +AllowShortIfStatementsOnASingleLine: Never +AllowShortLoopsOnASingleLine: false +AlwaysBreakBeforeMultilineStrings: true +AlwaysBreakTemplateDeclarations: Yes +BinPackArguments: false +BinPackParameters: false +BreakBeforeBinaryOperators: NonAssignment +BreakBeforeBraces: Attach # Our guideline prefers Attach style +BreakBeforeInheritanceComma: false +BreakInheritanceList: AfterColon +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeColon +BreakAfterJavaFieldAnnotations: true +BreakStringLiterals: true +ColumnLimit: 100 # BARR C requires 80, but 100 is more presentable +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: false +DeriveLineEnding: true +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: false +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IncludeBlocks: Preserve +IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + SortPriority: 0 + - Regex: '^(<|"(gtest|gmock|isl|json)/)' + Priority: 3 + SortPriority: 0 + - Regex: '.*' + Priority: 1 + SortPriority: 0 +IncludeIsMainRegex: '(Test)?$' +IncludeIsMainSourceRegex: '' +IndentCaseLabels: true +IndentCaseBlocks: true +IndentGotoLabels: true +IndentPPDirectives: None +IndentWidth: 4 +IndentWrappedFunctionNames: false +InsertBraces: true +IndentAccessModifiers: true +AccessModifierOffset: 0 +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: true +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBinPackProtocolList: Auto +ObjCBlockIndentWidth: 4 +ObjCSpaceAfterProperty: true +ObjCSpaceBeforeProtocolList: false +PackConstructorInitializers: CurrentLine +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 200 +PointerAlignment: Right +ReflowComments: true +SortIncludes: false +SortUsingDeclarations: false +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeCpp11BracedList: true +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: Custom +SpaceBeforeParensOptions: + AfterControlStatements: true + AfterFunctionDefinitionName: true +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyBlock: false +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInConditionalStatement: false +SpacesInContainerLiterals: false +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +SpaceBeforeSquareBrackets: false +Standard: Latest +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TabWidth: 8 +UseCRLF: false +UseTab: Never ... diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 00000000..e240a9e9 --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,164 @@ +--- +Checks: + - bugprone-assignment-in-if-condition + - bugprone-bool-pointer-implicit-conversion + - bugprone-branch-clone + - bugprone-empty-catch + - bugprone-inc-dec-in-conditions + - bugprone-incorrect-roundings + - bugprone-infinite-loop + - bugprone-integer-division + - bugprone-macro-parentheses + - bugprone-parent-virtual-call + - bugprone-redundant-branch-condition + - bugprone-shared-ptr-array-mismatch + - bugprone-sizeof-container + - bugprone-sizeof-expression + - bugprone-swapped-arguments + - bugprone-switch-missing-default-case + - bugprone-unique-ptr-array-mismatch + - bugprone-virtual-near-miss + - cppcoreguidelines-avoid-do-while + - cppcoreguidelines-avoid-goto + - cppcoreguidelines-avoid-non-const-global-variables + - cppcoreguidelines-init-variables + - cppcoreguidelines-narrowing-conversions + - cppcoreguidelines-no-malloc + - cppcoreguidelines-prefer-member-initializer + - cppcoreguidelines-pro-type-member-init + - cppcoreguidelines-virtual-class-destructor + - misc-definitions-in-headers + - misc-header-include-cycle + - misc-no-recursion + - misc-non-private-member-variables-in-classes + - misc-redundant-expression + - modernize-use-equals-default + - modernize-use-equals-delete + - modernize-use-nullptr + - modernize-use-override + - readability-avoid-const-params-in-decls + - readability-avoid-unconditional-preprocessor-if + - readability-braces-around-statements + - readability-const-return-type + - readability-delete-null-pointer + - readability-duplicate-include + - readability-else-after-return + - readability-identifier-naming + - readability-implicit-bool-conversion + - readability-inconsistent-declaration-parameter-name + - readability-misleading-indentation + - readability-redundant-access-specifiers + - readability-redundant-control-flow + - readability-redundant-declaration + - readability-redundant-function-ptr-dereference + - readability-redundant-member-init + - readability-redundant-preprocessor + - readability-simplify-boolean-expr + - readability-static-accessed-through-instance + - readability-static-definition-in-anonymous-namespace + - performance-type-promotion-in-math-fn + - performance-unnecessary-value-param +WarningsAsErrors: '' +HeaderFileExtensions: + - '' + - h + - hh + - hpp + - hxx +ImplementationFileExtensions: + - c + - cc + - cpp + - cxx +HeaderFilterRegex: '' +FormatStyle: none +CheckOptions: + bugprone-empty-catch.AllowEmptyCatchForExceptions: '' + bugprone-empty-catch.IgnoreCatchWithKeywords: '@TODO;@FIXME' + bugprone-sizeof-expression.WarnOnSizeOfCompareToConstant: 'true' + bugprone-sizeof-expression.WarnOnSizeOfConstant: 'true' + bugprone-sizeof-expression.WarnOnSizeOfIntegerExpression: 'false' + bugprone-sizeof-expression.WarnOnSizeOfPointerToAggregate: 'true' + bugprone-sizeof-expression.WarnOnSizeOfThis: 'true' + cert-dcl16-c.NewSuffixes: 'L;LL;LU;LLU' + cert-err33-c.AllowCastToVoid: 'true' + cert-err33-c.CheckedFunctions: '::aligned_alloc;::asctime_s;::at_quick_exit;::atexit;::bsearch;::bsearch_s;::btowc;::c16rtomb;::c32rtomb;::calloc;::clock;::cnd_broadcast;::cnd_init;::cnd_signal;::cnd_timedwait;::cnd_wait;::ctime_s;::fclose;::fflush;::fgetc;::fgetpos;::fgets;::fgetwc;::fopen;::fopen_s;::fprintf;::fprintf_s;::fputc;::fputs;::fputwc;::fputws;::fread;::freopen;::freopen_s;::fscanf;::fscanf_s;::fseek;::fsetpos;::ftell;::fwprintf;::fwprintf_s;::fwrite;::fwscanf;::fwscanf_s;::getc;::getchar;::getenv;::getenv_s;::gets_s;::getwc;::getwchar;::gmtime;::gmtime_s;::localtime;::localtime_s;::malloc;::mbrtoc16;::mbrtoc32;::mbsrtowcs;::mbsrtowcs_s;::mbstowcs;::mbstowcs_s;::memchr;::mktime;::mtx_init;::mtx_lock;::mtx_timedlock;::mtx_trylock;::mtx_unlock;::printf_s;::putc;::putwc;::raise;::realloc;::remove;::rename;::scanf;::scanf_s;::setlocale;::setvbuf;::signal;::snprintf;::snprintf_s;::sprintf;::sprintf_s;::sscanf;::sscanf_s;::strchr;::strerror_s;::strftime;::strpbrk;::strrchr;::strstr;::strtod;::strtof;::strtoimax;::strtok;::strtok_s;::strtol;::strtold;::strtoll;::strtoul;::strtoull;::strtoumax;::strxfrm;::swprintf;::swprintf_s;::swscanf;::swscanf_s;::thrd_create;::thrd_detach;::thrd_join;::thrd_sleep;::time;::timespec_get;::tmpfile;::tmpfile_s;::tmpnam;::tmpnam_s;::tss_create;::tss_get;::tss_set;::ungetc;::ungetwc;::vfprintf;::vfprintf_s;::vfscanf;::vfscanf_s;::vfwprintf;::vfwprintf_s;::vfwscanf;::vfwscanf_s;::vprintf_s;::vscanf;::vscanf_s;::vsnprintf;::vsnprintf_s;::vsprintf;::vsprintf_s;::vsscanf;::vsscanf_s;::vswprintf;::vswprintf_s;::vswscanf;::vswscanf_s;::vwprintf_s;::vwscanf;::vwscanf_s;::wcrtomb;::wcschr;::wcsftime;::wcspbrk;::wcsrchr;::wcsrtombs;::wcsrtombs_s;::wcsstr;::wcstod;::wcstof;::wcstoimax;::wcstok;::wcstok_s;::wcstol;::wcstold;::wcstoll;::wcstombs;::wcstombs_s;::wcstoul;::wcstoull;::wcstoumax;::wcsxfrm;::wctob;::wctrans;::wctype;::wmemchr;::wprintf_s;::wscanf;::wscanf_s;' + cert-oop54-cpp.WarnOnlyIfThisHasSuspiciousField: 'false' + cert-str34-c.DiagnoseSignedUnsignedCharComparisons: 'false' + cppcoreguidelines-avoid-do-while.IgnoreMacros: 'false' + cppcoreguidelines-init-variables.IncludeStyle: llvm + cppcoreguidelines-init-variables.MathHeader: '' + cppcoreguidelines-narrowing-conversions.IgnoreConversionFromTypes: '' + cppcoreguidelines-narrowing-conversions.PedanticMode: 'false' + cppcoreguidelines-narrowing-conversions.WarnOnEquivalentBitWidth: 'true' + cppcoreguidelines-narrowing-conversions.WarnOnFloatingPointNarrowingConversion: 'true' + cppcoreguidelines-narrowing-conversions.WarnOnIntegerNarrowingConversion: 'true' + cppcoreguidelines-narrowing-conversions.WarnOnIntegerToFloatingPointNarrowingConversion: 'true' + cppcoreguidelines-narrowing-conversions.WarnWithinTemplateInstantiation: 'false' + cppcoreguidelines-no-malloc.Allocations: '::malloc;::calloc' + cppcoreguidelines-no-malloc.Deallocations: '::free' + cppcoreguidelines-no-malloc.Reallocations: '::realloc' + cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic: 'true' + cppcoreguidelines-prefer-member-initializer.UseAssignment: 'false' + cppcoreguidelines-pro-type-member-init.IgnoreArrays: 'false' + cppcoreguidelines-pro-type-member-init.UseAssignment: 'false' + google-readability-braces-around-statements.ShortStatementLines: '1' + google-readability-function-size.StatementThreshold: '800' + google-readability-namespace-comments.ShortNamespaceLines: '10' + google-readability-namespace-comments.SpacesBeforeComments: '2' + llvm-else-after-return.WarnOnConditionVariables: 'false' + llvm-else-after-return.WarnOnUnfixable: 'false' + llvm-qualified-auto.AddConstToQualified: 'false' + misc-definitions-in-headers.HeaderFileExtensions: ';h;hh;hpp;hxx' + misc-definitions-in-headers.UseHeaderFileExtension: 'true' + misc-header-include-cycle.IgnoredFilesList: '' + misc-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic: 'false' + misc-non-private-member-variables-in-classes.IgnorePublicMemberVariables: 'false' + modernize-use-equals-default.IgnoreMacros: 'true' + modernize-use-equals-delete.IgnoreMacros: 'true' + modernize-use-nullptr.IgnoredTypes: 'std::_CmpUnspecifiedParam::;^std::__cmp_cat::__unspec' + modernize-use-nullptr.NullMacros: 'NULL' + modernize-use-override.AllowOverrideAndFinal: 'false' + modernize-use-override.FinalSpelling: final + modernize-use-override.IgnoreDestructors: 'false' + modernize-use-override.IgnoreTemplateInstantiations: 'false' + modernize-use-override.OverrideSpelling: override + performance-type-promotion-in-math-fn.IncludeStyle: llvm + readability-avoid-const-params-in-decls.IgnoreMacros: 'true' + readability-braces-around-statements.ShortStatementLines: '0' + readability-const-return-type.IgnoreMacros: 'true' + readability-else-after-return.WarnOnConditionVariables: 'true' + readability-else-after-return.WarnOnUnfixable: 'true' + readability-identifier-naming.AggressiveDependentMemberLookup: 'false' + readability-identifier-naming.CheckAnonFieldInParent: 'false' + readability-identifier-naming.GetConfigPerFile: 'true' + readability-identifier-naming.IgnoreFailedSplit: 'false' + readability-identifier-naming.IgnoreMainLikeFunctions: 'false' + readability-identifier-naming.MacroDefinitionCase: 'UPPER_CASE' + readability-identifier-naming.VariableCase: 'camelBack' + readability-identifier-naming.StaticVariablePreffix: '_' + readability-identifier-naming.ConstantCase: 'UPPER_CASE' + readability-identifier-naming.ClassCase: 'CamelCase' + readability-identifier-naming.FunctionCase: 'camelBack' + readability-identifier-naming.MemberCase: 'camelBack' + readability-identifier-naming.MemberSuffix: '_' + readability-identifier-naming.StructCase: 'CamelCase' + readability-identifier-naming.TypedefCase: 'CamelCase' + readability-identifier-naming.TypedefSuffix: '_t' + readability-identifier-naming.EnumCase: 'CamelCase' + readability-identifier-naming.EnumSuffix: '_e' + readability-implicit-bool-conversion.AllowIntegerConditions: 'false' + readability-implicit-bool-conversion.AllowPointerConditions: 'false' + readability-inconsistent-declaration-parameter-name.IgnoreMacros: 'true' + readability-inconsistent-declaration-parameter-name.Strict: 'false' + readability-redundant-declaration.IgnoreMacros: 'true' + readability-redundant-member-init.IgnoreBaseInCopyConstructors: 'false' + readability-simplify-boolean-expr.ChainedConditionalAssignment: 'false' + readability-simplify-boolean-expr.ChainedConditionalReturn: 'false' + readability-simplify-boolean-expr.IgnoreMacros: 'false' + readability-simplify-boolean-expr.SimplifyDeMorgan: 'true' + readability-simplify-boolean-expr.SimplifyDeMorganRelaxed: 'false' + readability-static-accessed-through-instance.NameSpecifierNestingThreshold: '3' +SystemHeaders: false +... + diff --git a/.github/workflows/compile_test.yaml b/.github/workflows/compile_test.yaml index 2cdae680..f689321a 100644 --- a/.github/workflows/compile_test.yaml +++ b/.github/workflows/compile_test.yaml @@ -7,24 +7,12 @@ on: jobs: compile_test: runs-on: ubuntu-latest - - env: - URL: developer.arm.com/-/media/Files/downloads/gnu/12.2.mpacbti-rel1/binrel - TOOLCHAIN_NAME: arm-gnu-toolchain-12.2.mpacbti-rel1-x86_64-arm-none-eabi - steps: - - name: Install CMake, make, and wget - run: sudo apt-get -y install cmake make wget - - - name: Install Arm Toolchain - working-directory: /opt - run: | - wget -nv $URL/$TOOLCHAIN_NAME.tar.xz - tar -xf $TOOLCHAIN_NAME.tar.xz && rm -f $TOOLCHAIN_NAME.tar.xz - ln -s $(pwd)/$TOOLCHAIN_NAME/bin/arm-none-eabi-* /usr/local/bin - - name: Checkout the repo uses: actions/checkout@v3 + - name: Initialize Docker + run: bash ./tools/run_docker.bash init + - name: Build project - run: bash ./Tools/tools.bash compile -t Firmware -c + run: bash ./tools/run_docker.bash compile diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml new file mode 100644 index 00000000..ba0ac9e1 --- /dev/null +++ b/.github/workflows/lint.yaml @@ -0,0 +1,27 @@ +name: Lint + +on: + pull_request: + type: [opened, synchronize] + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - name: Checkout the repo + uses: actions/checkout@v3 + + - name: Initialize Docker + run: bash ./tools/run_docker.bash init + + - name: Build project + run: bash ./tools/run_docker.bash compile + + - name: Run clang-tidy + run: bash ./tools/run_docker.bash clang-tidy + + - name: Run clang-format + run: bash ./tools/run_docker.bash clang-format + + - name: Run cppcheck + run: bash ./tools/run_docker.bash cppcheck diff --git a/.github/workflows/unit_test.yaml b/.github/workflows/unit_test.yaml index 452d18cf..39673742 100644 --- a/.github/workflows/unit_test.yaml +++ b/.github/workflows/unit_test.yaml @@ -6,29 +6,13 @@ on: jobs: unit_test: - runs-on: ubuntu-latest - - env: - URL: https://github.com/google/googletest.git - TAG: v1.13.0 - - steps: - - name: Install CMake, make, and git - run: sudo apt-get -y install cmake make git - - - name: Install GoogleTest - working-directory: /home/runner/work - run: | - git clone $URL -b $TAG - mkdir googletest/build && cd googletest/build - cmake -G "Unix Makefiles" .. - cmake --build . && sudo cmake --install . - - - name: Checkout repo + runs-on: ubuntu-latest + steps: + - name: Checkout the repo uses: actions/checkout@v3 - - name: Build tests - run: bash ./Tools/tools.bash compile -t Testing -c + - name: Initialize Docker + run: bash ./tools/run_docker.bash init - - name: Run tests - run: bash ./Tools/tools.bash run + - name: Build and run tests + run: bash ./tools/run_docker.bash test diff --git a/.gitignore b/.gitignore index a9ec751a..3bbebef1 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,8 @@ .idea/ .vscode/ -Tools/*/build/ +.DS_Store/ +tools/*/build +tools/lint_output Debug/ /.metadata/ diff --git a/README.md b/README.md index 270a1a13..434a38ec 100644 --- a/README.md +++ b/README.md @@ -1,56 +1,81 @@ -# ZeroPilot 3.5 Compile Commands +# ZeroPilot 3.5 Docker -- A powershell script is provided for Windows +Docker is our recommended way of compiling, linting and testing code, since it's cross platform and easy to use. -- A bash script is provided for Linux and Mac +To get started, install Docker from their [official website](https://docs.docker.com/get-docker/) and run our docker script. It will take some time to build the Docker image and container when you run it for the first time. -- Once compiled, binaries for flashing can be found under *./Tools/Firmware/build* +## Instructions for Macs with M-series chips +You can identify the processor you have by running the following command in the terminal: +`sysctl -n machdep.cpu.brand_string` -- Once compiled, a testing executable can be found under *./Tools/Testing/build* +If you're on Mac with an M-series chip, you'll have to install `gcc-arm-embedded` – the ARM GNU toolchain for development. This can be done by running: +`brew install gcc-arm-embedded` +Note that you'll be prompted to provide sudo privileges. +## Docker Scripts +- Windows: `run_docker.ps1` +- Linux and MacOS: `run_docker.bash` -## Syntax +To compile the code, simply run with the `compile` option: +``` +./run_docker.ps1 compile # Windows +./run_docker.bash compile # Linux and MacOS +``` -### Windows -./Tools/tools.ps1 \[function\] \[options\] -
+Run with the `help` option to see more options such as linting and Docker container shell +``` +./run_docker.ps1 help # Windows +./run_docker.bash help # Linux and MacOS +``` -### Linux and Mac +# ZeroPilot 3.5 Compile Commands -./Tools/tools.bash \[function\] \[options\] +`./tools/scripts/build.bash` is used to build the project in the Docker container (although you can run this on your local Linux system as well). You may manually run this script in the container using the Docker script `shell` option to do custom builds. -## Function +- Once compiled, binaries for flashing can be found under `./tools/firmware/build` -The function is a mandatory parameter that specifies script action: *compile* or *run* -- Set to *compile* to build the project for either flashing or testing -- Set to *run* to execute an existing test executable +- Once compiled, a testing executable can be found under `./tools/testing/build` -## Options +## Syntax -Options are nonmandatory parameters which are used to override the default configurations specified in *./Tools/default_config.txt* +``` +./tools/scripts/build.bash [options] +``` -### Compile Only Options +## Options + +`options` are nonmandatory parameters which are used to override the default configurations specified in `./tools/configs/compile_config.txt` -- -t
    Specifies the build type. Set to either *Firmware* or *Testing* +- -t
    Specifies the build type. Set to either `firmware` or `testing` - -p
    Specifies the platform to build for (i.e. nucleol552zeq) - -c
    A clean build will be conducted if and only if this flag is present -### Run Only Options +## Examples -- -f
    Specifies a filter to selectively run tests in the GoogleTest executable +- Compile with default settings, no clean
    `./tools/scripts/build.bash` -## Examples +- Compile with default settings, clean
    `./tools/scripts/build.bash -c` + +- Compile with default settings except for compile type, clean
    `./tools/scripts/build.bash -t testing -c` -- Compile with default settings, no clean
    ./Tools/tools.ps1 compile +# ZeroPilot 3.5 Test Commands -- Compile with default settings, clean
    ./Tools/tools.ps1 compile -c +`./tools/scripts/test.bash` is used to run tests in the Docker container (although you can run this on your local Linux system as well). You may manually run this script in the container using the Docker script `shell` option to do custom testing. -- Compile with default settings except for compile type, clean
    ./Tools/tools.ps1 compile -t Testing -c +## Syntax -- Run with default filter
    ./Tools/tools.ps1 run +``` +./tools/scripts/test.bash [options] +``` + +## Options + +- -f
    Specifies a filter to selectively run tests in the GoogleTest executable + +## Examples -- Run with custom filter
    ./Tools/tools.ps1 run -f \ +- Run with default filter
    `./tools/scripts/test.bash` -- Note: The bash version of these examples have the same structure, just replace *.ps1* with *.bash* +- Run with custom filter
    `./tools/scripts/test.bash -f ` diff --git a/Tools/default_config.txt b/Tools/default_config.txt deleted file mode 100644 index 6a84b1c6..00000000 --- a/Tools/default_config.txt +++ /dev/null @@ -1,14 +0,0 @@ -# --- Compile settings begin --- - -COMPILE_TYPE="Firmware" -PLATFORM="nucleol552zeq" -MODEL_NAME="example_model" - -# --- Compile settings end --- - - -# --- Testing settings begin --- - -TEST_FILTER="*" - -# --- Testing settings end --- diff --git a/Tools/tools.bash b/Tools/tools.bash deleted file mode 100755 index 35400b43..00000000 --- a/Tools/tools.bash +++ /dev/null @@ -1,174 +0,0 @@ -#!/usr/bin/env bash - - -# ==================== -# --- script setup --- -# ==================== - -# exit on attempt to use undeclared variable -set -o nounset -# enable error tracing -set -o errtrace -# define path to this bash script -SCRIPT_PATH=$(dirname -- "$0") - -# display error message -throw_error() { - echo "" - echo $1 - exit 1 -} - - -# ==================== -# --- var declare --- -# ==================== - -# read default configurations -while read -r line -do - # skip comment lines and blank lines - if [[ $line =~ ^\s*#.*$ ]] || [[ -z $(echo $line | tr -d '[:space:]') ]]; then - continue - fi - - # split line at "=" into a key-value pair - IFS="=" read -r key value <<< "$line" - - # strip extra spaces - key=$(echo $key) - value=$(echo $value) - - # declare variables - declare $key="${value//\"/}" -done < "$SCRIPT_PATH/default_config.txt" - -# read user inputs -# missing function -if [[ $# -eq 0 ]]; then - throw_error "Error: No function supplied." -# compile settings -elif [[ $1 == "compile" ]]; then - RUN_TEST=false - CLEAN=false - shift 1 && while getopts :t:p:m:c opt - do - case ${opt} in - t) - COMPILE_TYPE=${OPTARG} - ;; - p) - PLATFORM=${OPTARG} - ;; - m) - MODEL_NAME=${OPTARG} - ;; - c) - CLEAN=true - ;; - \?) - throw_error "Error: Flag -$OPTARG is undefined for compile." - ;; - esac - done -# run setting -elif [[ $1 == "run" ]]; then - RUN_TEST=true - shift 1 && while getopts :f: opt - do - case "${opt}" in - f) - TEST_FILTER=${OPTARG} - ;; - \?) - throw_error "Error: Flag -$OPTARG is undefined for run." - ;; - esac - done -# bad function -else - throw_error "Error: Function $1 is undefined." -fi - - -# ==================== -# --- compile/run--- -# ==================== - -# compile project -if [[ $RUN_TEST == false ]]; then - # validate build type - if [[ $COMPILE_TYPE != "Firmware" ]] && [[ $COMPILE_TYPE != "Testing" ]]; then - throw_error "Error: Build type $COMPILE_TYPE is undefined." - fi - - # select generator - if command -v ninja >/dev/null 2>&1; then - GENERATOR="Ninja" - elif command -v make >/dev/null 2>&1; then - GENERATOR="Unix Makefiles" - elif command -v mingw32-make >/dev/null 2>&1; then - GENERATOR="MinGW Makefiles" - else - throw_error "Error: No cmake generator found." - fi - - # compile setup - echo "Building ZeroPilot for $(echo $COMPILE_TYPE | tr '[:upper:]' '[:lower:]')." - COMPILE_DIR="$SCRIPT_PATH/$COMPILE_TYPE/build" - if [[ $COMPILE_TYPE == "Firmware" ]]; then - echo "Building for platform $PLATFORM and model $MODEL_NAME." - fi - if [[ $CLEAN == true ]]; then - echo "Cleaning old $(echo $COMPILE_TYPE | tr '[:upper:]' '[:lower:]') build environment." - cmake -E rm -rf $COMPILE_DIR - fi - - # create build system - echo "" - echo "Creating $GENERATOR build system..." - cmake -E make_directory $COMPILE_DIR - if [[ $COMPILE_TYPE == "Firmware" ]]; then - cmake -E chdir $COMPILE_DIR \ - cmake \ - -G "${GENERATOR}" \ - -DCMAKE_BUILD_TYPE="Debug" \ - -DCMAKE_TOOLCHAIN_FILE="../../../Boardfiles/$PLATFORM/$PLATFORM.cmake" \ - -DMODEL_NAME="$MODEL_NAME" \ - -Wdev \ - -Wdeprecated \ - ../ - else - cmake -E chdir $COMPILE_DIR \ - cmake \ - -G "${GENERATOR}" \ - ../ - fi - if [[ ! $? -eq 0 ]]; then - throw_error "Error: Failed to create $GENERATOR build system." - fi - - # compile project - echo "" - echo "Compiling project..." - cmake --build $COMPILE_DIR - if [[ ! $? -eq 0 ]]; then - throw_error "Error: Failed to compile project." - fi - - # compile done - echo "" - echo "ZeroPilot $(echo $COMPILE_TYPE | tr '[:upper:]' '[:lower:]') build SUCCESS!" - exit 0 -# run tests -else - TEST_PROGRAM="$SCRIPT_PATH/Testing/build/unit_testing" - - # check for test executable existance - if [[ ! -f $TEST_PROGRAM ]]; then - throw_error "Error: No test executable found. Build testing project first." - fi - - $TEST_PROGRAM --gtest_filter=$TEST_FILTER - exit $? -fi diff --git a/Tools/tools.ps1 b/Tools/tools.ps1 deleted file mode 100644 index 9493b59e..00000000 --- a/Tools/tools.ps1 +++ /dev/null @@ -1,126 +0,0 @@ -# ==================== -# --- var declare --- -# ==================== - -# read options from command line -param( - [Parameter(Mandatory = $true, Position = 0)] [string] $FUNCTION, - [string] $t, - [string] $p, - [switch] $c, - [string] $f, - [string] $m -) - -# read defaults from file, and set variable intial value -foreach($line in Get-Content "$PSScriptRoot/default_config.txt") { - # ignore comments and empty lines - if($line -match "(^\s*#.*$|^\s*$)") { - continue - } - - # split line into a key-value pair - $key, $value = $line -split "=" - - # remove leading and trailing spaces, then write variables - New-Variable -name $key.trim() -value $value.trim().replace('"', '') -} - -# override initial value if command line options are present -$COMPILE_TYPE = if ($t) {$t} else {$COMPILE_TYPE} -$PLATFORM = if ($p) {$p} else {$PLATFORM} -$TEST_FILTER = if ($f) {$f} else {$TEST_FILTER} -$MODEL_NAME = if ($m) {$m} else {$MODEL_NAME} - - -# ==================== -# --- compile/run --- -# ==================== - -if($FUNCTION -eq "compile") { - # validate build type - if(! ( $COMPILE_TYPE -eq "Firmware" -or $COMPILE_TYPE -eq "Testing" ) ) { - Write-Error "Error: Build type $COMPILE_TYPE is undefined." - exit 1 - } - - # select generator - if(Get-Command "ninja" -ErrorAction SilentlyContinue) { - $GENERATOR = "Ninja" - } - elseif(Get-Command "make" -ErrorAction SilentlyContinue) { - $GENERATOR = "Unix Makefiles" - } - elseif(Get-Command "mingw32-make" -ErrorAction SilentlyContinue) { - $GENERATOR = "MinGW Makefiles" - } - else { - Write-Error "Error: No cmake generator found." - exit 1 - } - - # compile setup - Write-Host "Building ZeroPilot for $($COMPILE_TYPE.ToLower())." - $COMPILE_DIR = "$PSScriptRoot/$COMPILE_TYPE/build" - if($COMPILE_TYPE -eq "Firmware") { - Write-Host "Building for platform $PLATFORM and model $MODEL_NAME." - } - if($c) { - Write-Host "Cleaning old $($COMPILE_TYPE.ToLower()) build environment." - cmake -E rm -rf $COMPILE_DIR - } - - # create build system - Write-Host "`nCreating $GENERATOR build system..." - cmake -E make_directory $COMPILE_DIR - if($COMPILE_TYPE -eq "Firmware") { - cmake -E chdir $COMPILE_DIR ` - cmake ` - -G "${GENERATOR}" ` - -DCMAKE_BUILD_TYPE="Debug" ` - -DCMAKE_TOOLCHAIN_FILE="../../../Boardfiles/$PLATFORM/$PLATFORM.cmake" ` - -DMODEL_NAME="$MODEL_NAME" ` - -Wdev ` - -Wdeprecated ` - .. - } - else { - cmake -E chdir $COMPILE_DIR ` - cmake ` - -G "${GENERATOR}" ` - .. - } - if(! $LASTEXITCODE -eq 0) { - Write-Error "Error: Failed to create $GENERATOR build system." - exit 1 - } - - # compile project - Write-Host "`nCompiling project..." - cmake --build $COMPILE_DIR - if(! $LASTEXITCODE -eq 0) { - Write-Error "Error: Failed to compile project." - exit 1 - } - - # compile done - Write-Host "`nZeroPilot $($COMPILE_TYPE.toLower()) build SUCCESS!" - exit 0 -} -elseif ($FUNCTION -eq "run") { - $TEST_PROGRAM = "$PSScriptRoot/Testing/build/unit_testing" - - # check for test executable existance - if($null -eq (Get-Command "$TEST_PROGRAM" -ErrorAction SilentlyContinue)) - { - Write-Error "Error: No test executable found. Build testing project first." - exit 1 - } - - & $TEST_PROGRAM --gtest_filter=$TEST_FILTER - exit $LASTEXITCODE -} -else { - Write-Error "Error: Function $FUNCTION is undefined." - exit 1 -} diff --git a/tools/Dockerfile b/tools/Dockerfile new file mode 100644 index 00000000..5d004261 --- /dev/null +++ b/tools/Dockerfile @@ -0,0 +1,59 @@ +FROM ubuntu:jammy-20240125 + +LABEL Description="EFS Linux Build Environment (Ubuntu 22.04)" + +ENV HOME /root + +SHELL ["/bin/bash", "-c"] + +RUN apt-get update && apt-get -y --no-install-recommends install \ + wget \ + xz-utils \ + tar \ + make \ + cmake \ + ca-certificates \ + g++ \ + git + +# ARM GNU Toolchain +ARG ARM_PKG_NAME=arm-gnu-toolchain-12.3.rel1-x86_64-arm-none-eabi +RUN wget https://developer.arm.com/-/media/Files/downloads/gnu/12.3.rel1/binrel/arm-gnu-toolchain-12.3.rel1-x86_64-arm-none-eabi.tar.xz -O /tmp/$ARM_PKG_NAME.tar.xz && \ + tar -xvf /tmp/$ARM_PKG_NAME.tar.xz -C /usr/share/ && \ + ln -s /usr/share/$ARM_PKG_NAME/bin/arm-none-eabi-gcc /usr/bin/arm-none-eabi-gcc && \ + ln -s /usr/share/$ARM_PKG_NAME/bin/arm-none-eabi-g++ /usr/bin/arm-none-eabi-g++ && \ + ln -s /usr/share/$ARM_PKG_NAME/bin/arm-none-eabi-gdb /usr/bin/arm-none-eabi-gdb && \ + ln -s /usr/share/$ARM_PKG_NAME/bin/arm-none-eabi-size /usr/bin/arm-none-eabi-size && \ + ln -s /usr/share/$ARM_PKG_NAME/bin/arm-none-eabi-objcopy /usr/bin/arm-none-eabi-objcopy + +# clang-tidy and clang-format +RUN wget https://apt.llvm.org/llvm-snapshot.gpg.key -O /etc/apt/keyrings/llvm-snapshot.gpg.key && \ + echo "deb [signed-by=/etc/apt/keyrings/llvm-snapshot.gpg.key] http://apt.llvm.org/jammy/ llvm-toolchain-jammy-18 main" >> /etc/apt/sources.list.d/llvm.list && \ + echo "deb-src [signed-by=/etc/apt/keyrings/llvm-snapshot.gpg.key] http://apt.llvm.org/jammy/ llvm-toolchain-jammy-18 main" >> /etc/apt/sources.list.d/llvm.list && \ + chmod 644 /etc/apt/keyrings/llvm-snapshot.gpg.key && \ + chmod 644 /etc/apt/sources.list.d/llvm.list && \ + apt-get update && \ + apt-get -y --no-install-recommends install clang-tidy-18 && \ + ln -s /usr/bin/clang-tidy-18 /usr/bin/clang-tidy && \ + apt-get -y --no-install-recommends install clang-format-18 && \ + ln -s /usr/bin/clang-format-18 /usr/bin/clang-format + +# cppcheck +ARG CPPCHECK_PKG_NAME=cppcheck-2.13.0 +RUN wget https://github.com/danmar/cppcheck/archive/2.13.0.tar.gz -O /tmp/$CPPCHECK_PKG_NAME.tar.gz && \ + tar -xvf /tmp/$CPPCHECK_PKG_NAME.tar.gz -C /tmp/ && \ + cd /tmp/$CPPCHECK_PKG_NAME && \ + make FILESDIR=/usr/share/cppcheck && \ + make install FILESDIR=/usr/share/cppcheck + +# GoogleTest +RUN git clone https://github.com/google/googletest.git -b v1.14.0 /tmp/googletest && \ + cd /tmp/googletest && \ + mkdir build && \ + cd build && \ + cmake .. && \ + make && \ + make install + +# Cleanup +RUN rm -rf /tmp/* \ No newline at end of file diff --git a/tools/configs/compile_config.txt b/tools/configs/compile_config.txt new file mode 100644 index 00000000..cf8ba539 --- /dev/null +++ b/tools/configs/compile_config.txt @@ -0,0 +1,7 @@ +# --- Compile settings begin --- + +COMPILE_TYPE="firmware" +PLATFORM="nucleol552zeq" +MODEL_NAME="example_model" + +# --- Compile settings end --- \ No newline at end of file diff --git a/tools/configs/lint_config.txt b/tools/configs/lint_config.txt new file mode 100644 index 00000000..945c2085 --- /dev/null +++ b/tools/configs/lint_config.txt @@ -0,0 +1,7 @@ +# --- Linting settings begin --- + +CLANG_FORMAT_FLAGS="" +CLANG_TIDY_FLAGS="" +CPPCHECK_FLAGS="" + +# --- Linting settings end --- \ No newline at end of file diff --git a/tools/configs/static_analysis_ignore.txt b/tools/configs/static_analysis_ignore.txt new file mode 100644 index 00000000..f0117be1 --- /dev/null +++ b/tools/configs/static_analysis_ignore.txt @@ -0,0 +1,7 @@ +# Add pathes to be ignored by static analysis (clang-tidy, clang-format, cppcheck) + +tools +Boardfiles +TelemetryManager/Inc/Official_Mavlink_2_Library + +# Do not remove this last line \ No newline at end of file diff --git a/tools/configs/test_config.txt b/tools/configs/test_config.txt new file mode 100644 index 00000000..4d051f0b --- /dev/null +++ b/tools/configs/test_config.txt @@ -0,0 +1,5 @@ +# --- Testing settings begin --- + +TEST_FILTER="*" + +# --- Testing settings end --- \ No newline at end of file diff --git a/Tools/Firmware/CMakeLists.txt b/tools/firmware/CMakeLists.txt similarity index 100% rename from Tools/Firmware/CMakeLists.txt rename to tools/firmware/CMakeLists.txt diff --git a/tools/run_docker.bash b/tools/run_docker.bash new file mode 100755 index 00000000..555305b6 --- /dev/null +++ b/tools/run_docker.bash @@ -0,0 +1,96 @@ +#!/usr/bin/env bash + +# define path to the tools dir +TOOLS_DIR=$(dirname -- "$0") +# define container paths +DOCKER_TOOLS_DIR=efs_container:/zeropilot-3.5/tools +SCRIPTS_DIR=/zeropilot-3.5/tools/scripts + +# Help message +if [[ $1 == "help" ]]; then + echo "run_docker.bash help | show this message" + echo "run_docker.bash init | setup docker only" + echo "run_docker.bash compile | compile/build ZeroPilot and return build files in firmware/build/" + echo "run_docker.bash test | compile tests, run tests, and return build files in testing/build/" + echo "run_docker.bash clang-tidy | lint code with clang-tidy and return linting log in lint_output/" + echo "run_docker.bash clang-format | reformat and return source files with clang-format" + echo " in lint_output/formatted_files" + echo "run_docker.bash cppcheck | lint code with cppcheck and return linting log in lint_output/" + echo "run_docker.bash shell | launch a bash shell in the Docker container" + exit +fi + +# Build image if it doesn't exist +IMAGES=$(docker image ls) +if [[ $IMAGES != *efs_image* ]]; then + if [[ "$OSTYPE" == "darwin"* ]]; then + docker build --platform linux/amd64 -t efs_image -f $TOOLS_DIR/Dockerfile . + else + docker build -t efs_image -f $TOOLS_DIR/Dockerfile . + fi +fi + +# Create container if it doesn't exist +CONTAINERS=$(docker ps -a) +if [[ $CONTAINERS != *efs_container* ]]; then + if [[ "$OSTYPE" == "darwin"* ]]; then + docker run --platform linux/amd64 -tid --name=efs_container efs_image bash + else + docker run -tid --name=efs_container efs_image bash + fi +else + # Start container + docker start efs_container +fi + +docker cp $TOOLS_DIR/../. efs_container:/zeropilot-3.5/ + +# Create directory for linting output if it doesn't exist +mkdir -p $TOOLS_DIR/lint_output + +case $1 in + "init") + IMAGES=$(docker image ls) + CONTAINERS=$(docker ps -a) + if [[ $IMAGES == *efs_image* ]] && [[ $CONTAINERS == *efs_container* ]]; then + echo "Docker is initialized." + else + echo "Docker failed to initialize." + fi + ;; + + "shell") + docker attach efs_container + ;; + + "compile") + docker exec efs_container /bin/bash -c "cd $SCRIPTS_DIR && ./build.bash -c" + docker cp $DOCKER_TOOLS_DIR/firmware $TOOLS_DIR/ + ;; + + "test") + docker exec efs_container /bin/bash -c "cd $SCRIPTS_DIR && ./build.bash -t testing -c && ./test.bash" + docker cp $DOCKER_TOOLS_DIR/testing $TOOLS_DIR/ + ;; + + "clang-format") + docker exec efs_container /bin/bash -c "cd $SCRIPTS_DIR && ./clang-format.bash" + docker cp $DOCKER_TOOLS_DIR/lint_output/formatted_files $TOOLS_DIR/lint_output/ + ;; + + "clang-tidy") + docker exec efs_container /bin/bash -c "cd $SCRIPTS_DIR && ./clang-tidy.bash" + docker cp $DOCKER_TOOLS_DIR/lint_output/clang-tidy.txt $TOOLS_DIR/lint_output/ + ;; + + "cppcheck") + docker exec efs_container /bin/bash -c "cd $SCRIPTS_DIR && ./cppcheck.bash" + docker cp $DOCKER_TOOLS_DIR/lint_output/cppcheck.txt $TOOLS_DIR/lint_output/ + ;; + + *) + echo "Invalid run_docker option!" + ;; +esac + +docker stop -t 3 efs_container diff --git a/tools/run_docker.ps1 b/tools/run_docker.ps1 new file mode 100644 index 00000000..2032a8d8 --- /dev/null +++ b/tools/run_docker.ps1 @@ -0,0 +1,87 @@ +# define container paths +$DOCKER_TOOLS_DIR = "efs_container:/zeropilot-3.5/tools" +$SCRIPTS_DIR = "/zeropilot-3.5/tools/scripts" + +# Help message +if ( $args[0] -eq "help" ) { + echo "run_docker.ps1 help | show this message" + echo "run_docker.ps1 init | setup docker only" + echo "run_docker.ps1 compile | compile/build ZeroPilot and return build files in firmware/build/" + echo "run_docker.ps1 test | compile tests, run tests, and return build files in testing/build/" + echo "run_docker.ps1 clang-tidy | lint code with clang-tidy and return linting log in lint_output/" + echo "run_docker.ps1 clang-format | reformat and return source files with clang-format" + echo " in lint_output/formatted_files" + echo "run_docker.ps1 cppcheck | lint code with cppcheck and return linting log in lint_output/" + echo "run_docker.ps1 shell | launch a bash shell in the Docker container" + exit +} + +# Build image if it doesn't exist +$images = docker image ls +if ( -not ( $images -like "*efs_image*" ) ) { + docker build -t efs_image -f $PSScriptRoot/Dockerfile . +} + +# Create container if it doesn't exist +$containers = docker ps -a +if ( -not ( $containers -like "*efs_container*" ) ) { + docker run -tid --name=efs_container efs_image bash +} else { + # Start container + docker start efs_container +} + +docker cp $PSScriptRoot/../. efs_container:/zeropilot-3.5/ + +# Create directory for linting output if it doesn't exist +if ( -not ( Test-Path $PSScriptRoot/lint_output ) ) { + New-Item -ItemType Directory -Force -Path $PSScriptRoot/lint_output +} + +switch ( $args[0] ) +{ + "init" { + $images = docker image ls + $containers = docker ps -a + if ( ( $images -like "*efs_image*" ) -and ( $containers -like "*efs_container*" ) ) { + echo "Docker is initialized." + } else { + echo "Docker failed to initialize." + } + } + + "shell" { + docker attach efs_container + } + + "compile" { + docker exec efs_container /bin/bash -c "cd $SCRIPTS_DIR && ./build.bash -c" + docker cp $DOCKER_TOOLS_DIR/firmware $PSScriptRoot/ + } + + "test" { + docker exec efs_container /bin/bash -c "cd $SCRIPTS_DIR && ./build.bash -t testing -c && ./test.bash" + docker cp $DOCKER_TOOLS_DIR/testing $PSScriptRoot/ + } + + "clang-format" { + docker exec efs_container /bin/bash -c "cd $SCRIPTS_DIR && ./clang-format.bash" + docker cp $DOCKER_TOOLS_DIR/lint_output/formatted_files $PSScriptRoot/lint_output/ + } + + "clang-tidy" { + docker exec efs_container /bin/bash -c "cd $SCRIPTS_DIR && ./clang-tidy.bash" + docker cp $DOCKER_TOOLS_DIR/lint_output/clang-tidy.txt $PSScriptRoot/lint_output/ + } + + "cppcheck" { + docker exec efs_container /bin/bash -c "cd $SCRIPTS_DIR && ./cppcheck.bash" + docker cp $DOCKER_TOOLS_DIR/lint_output/cppcheck.txt $PSScriptRoot/lint_output/ + } + + default { + echo "Invalid run_docker option!" + } +} + +docker stop -t 3 efs_container diff --git a/tools/scripts/build.bash b/tools/scripts/build.bash new file mode 100755 index 00000000..8b6dadcb --- /dev/null +++ b/tools/scripts/build.bash @@ -0,0 +1,119 @@ +#!/usr/bin/env bash + + +# ==================== +# --- script setup --- +# ==================== + +# exit on attempt to use undeclared variable +set -o nounset +# enable error tracing +set -o errtrace +# define path to the tools dir +TOOLS_DIR=$(dirname -- "$0")/.. + +# display error message +throw_error() { + echo "" + echo $1 + exit 1 +} + + +# ==================== +# --- var declare --- +# ==================== + +# read compile configurations +source $TOOLS_DIR/scripts/read_configs.bash "$TOOLS_DIR/configs/compile_config.txt" + +# read user inputs +CLEAN=false +while getopts :t:p:m:c opt +do + case ${opt} in + t) + COMPILE_TYPE=${OPTARG} + ;; + p) + PLATFORM=${OPTARG} + ;; + m) + MODEL_NAME=${OPTARG} + ;; + c) + CLEAN=true + ;; + \?) + throw_error "Error: Flag -$OPTARG is undefined for compile." + ;; + esac +done + +# ==================== +# ------compile------- +# ==================== + +# validate build type +if [[ $COMPILE_TYPE != "firmware" ]] && [[ $COMPILE_TYPE != "testing" ]]; then + throw_error "Error: Build type $COMPILE_TYPE is undefined." +fi + +# select generator +if command -v ninja >/dev/null 2>&1; then + GENERATOR="Ninja" +elif command -v make >/dev/null 2>&1; then + GENERATOR="Unix Makefiles" +elif command -v mingw32-make >/dev/null 2>&1; then + GENERATOR="MinGW Makefiles" +else + throw_error "Error: No cmake generator found." +fi + +# compile setup +echo "Building ZeroPilot for $(echo $COMPILE_TYPE | tr '[:upper:]' '[:lower:]')." +COMPILE_DIR="$TOOLS_DIR/$COMPILE_TYPE/build" +if [[ $COMPILE_TYPE == "firmware" ]]; then + echo "Building for platform $PLATFORM and model $MODEL_NAME." +fi +if [[ $CLEAN == true ]]; then + echo "Cleaning old $(echo $COMPILE_TYPE | tr '[:upper:]' '[:lower:]') build environment." + cmake -E rm -rf $COMPILE_DIR +fi + +# create build system +echo "" +echo "Creating $GENERATOR build system..." +cmake -E make_directory $COMPILE_DIR +if [[ $COMPILE_TYPE == "firmware" ]]; then + cmake -E chdir $COMPILE_DIR \ + cmake \ + -G "${GENERATOR}" \ + -DCMAKE_BUILD_TYPE="Debug" \ + -DCMAKE_TOOLCHAIN_FILE="$TOOLS_DIR/../Boardfiles/$PLATFORM/$PLATFORM.cmake" \ + -DMODEL_NAME="$MODEL_NAME" \ + -Wdev \ + -Wdeprecated \ + ../ +else + cmake -E chdir $COMPILE_DIR \ + cmake \ + -G "${GENERATOR}" \ + ../ +fi +if [[ ! $? -eq 0 ]]; then + throw_error "Error: Failed to create $GENERATOR build system." +fi + +# compile project +echo "" +echo "Compiling project..." +cmake --build $COMPILE_DIR +if [[ ! $? -eq 0 ]]; then + throw_error "Error: Failed to compile project." +fi + +# compile done +echo "" +echo "ZeroPilot $(echo $COMPILE_TYPE | tr '[:upper:]' '[:lower:]') build SUCCESS!" +exit 0 diff --git a/tools/scripts/clang-format.bash b/tools/scripts/clang-format.bash new file mode 100755 index 00000000..6a2b471d --- /dev/null +++ b/tools/scripts/clang-format.bash @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +# define path to the tools dir +TOOLS_DIR=$(dirname -- "$0")/.. + +# read lint configurations +source $TOOLS_DIR/scripts/read_configs.bash "$TOOLS_DIR/configs/lint_config.txt" + +# get source files +SRC_FILES=$(bash $TOOLS_DIR/scripts/static_analysis_files.bash) +if [ -z "$SRC_FILES" ]; then + >&2 echo "No source files found for linting." + exit +fi + +mkdir -p $TOOLS_DIR/lint_output/formatted_files + +# Get differences between the original and formatted files using a for loop +for file in $SRC_FILES; do + clang-format $CLANG_FORMAT_FLAGS $file > $TOOLS_DIR/lint_output/formatted_files/$(basename $file) + + # if the file exists in the formatted_files + if [ -f $TOOLS_DIR/lint_output/formatted_files/$(basename $file) ]; then + diff -u $file $TOOLS_DIR/lint_output/formatted_files/$(basename $file) + fi +done diff --git a/tools/scripts/clang-tidy.bash b/tools/scripts/clang-tidy.bash new file mode 100755 index 00000000..2869726b --- /dev/null +++ b/tools/scripts/clang-tidy.bash @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +# define path to the tools dir +TOOLS_DIR=$(dirname -- "$0")/.. + +# read lint configurations +source $TOOLS_DIR/scripts/read_configs.bash "$TOOLS_DIR/configs/lint_config.txt" + +# get source files +SRC_FILES=$(bash $TOOLS_DIR/scripts/static_analysis_files.bash) +if [ -z "$SRC_FILES" ]; then + >&2 echo "No source files found for linting." + exit +fi + +COMPILER_ROOT=/usr/share/arm-gnu-toolchain-12.3.rel1-x86_64-arm-none-eabi +mkdir -p $TOOLS_DIR/lint_output +clang-tidy \ + -p $TOOLS_DIR/firmware/build \ + --extra-arg=--target=arm-none-eabi \ + --extra-arg=-I"${COMPILER_ROOT}/arm-none-eabi/include/c++/12.3.1" \ + --extra-arg=-I"${COMPILER_ROOT}/arm-none-eabi/include/c++/12.3.1/arm-none-eabi" \ + --extra-arg=-I"${COMPILER_ROOT}/arm-none-eabi/include/c++/12.3.1/backward" \ + --extra-arg=-I"${COMPILER_ROOT}/lib/gcc/arm-none-eabi/12.3.1/include" \ + --extra-arg=-I"${COMPILER_ROOT}/lib/gcc/arm-none-eabi/12.3.1/include-fixed" \ + --extra-arg=-I"${COMPILER_ROOT}/arm-none-eabi/include" \ + $CLANG_TIDY_FLAGS \ + $SRC_FILES \ + 2>&1 | tee $TOOLS_DIR/lint_output/clang-tidy.txt \ No newline at end of file diff --git a/tools/scripts/cppcheck.bash b/tools/scripts/cppcheck.bash new file mode 100755 index 00000000..8e9e192b --- /dev/null +++ b/tools/scripts/cppcheck.bash @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +# define path to the tools dir +TOOLS_DIR=$(dirname -- "$0")/.. + +# read lint configurations +source $TOOLS_DIR/scripts/read_configs.bash "$TOOLS_DIR/configs/lint_config.txt" + +# get source files +SRC_FILES=$(bash $TOOLS_DIR/scripts/static_analysis_files.bash) +if [ -z "$SRC_FILES" ]; then + >&2 echo "No source files found for linting." + exit +fi + +mkdir -p $TOOLS_DIR/lint_output +cppcheck $CPPCHECK_FLAGS $SRC_FILES 2>&1 | tee $TOOLS_DIR/lint_output/cppcheck.txt \ No newline at end of file diff --git a/tools/scripts/read_configs.bash b/tools/scripts/read_configs.bash new file mode 100644 index 00000000..63541ddb --- /dev/null +++ b/tools/scripts/read_configs.bash @@ -0,0 +1,17 @@ +while read -r line +do + # skip comment lines and blank lines + if [[ $line =~ ^\s*#.*$ ]] || [[ -z $(echo $line | tr -d '[:space:]') ]]; then + continue + fi + + # split line at "=" into a key-value pair + IFS="=" read -r key value <<< "$line" + + # strip extra spaces + key=$(echo $key) + value=$(echo $value) + + # declare variables + declare $key="${value//\"/}" +done < $1 \ No newline at end of file diff --git a/tools/scripts/static_analysis_files.bash b/tools/scripts/static_analysis_files.bash new file mode 100644 index 00000000..94fb5715 --- /dev/null +++ b/tools/scripts/static_analysis_files.bash @@ -0,0 +1,57 @@ +#!/usr/bin/env bash + +# define path to the tools dir +TOOLS_DIR=$(dirname -- "$0")/.. +JSON_PATH=$TOOLS_DIR/firmware/build/compile_commands.json + +# check json file exists +if ! test -f $JSON_PATH; then + >&2 echo "$JSON_PATH not found. Please build the project before linting." + exit +fi + +# exclude paths specified in static_analysis_ignore.txt +EXCLUDE='' +while IFS=$'\n' read -r line; do + if [[ $line != *#* && $line != "" ]]; then + EXCLUDE+="$line|" + fi +done < "$TOOLS_DIR/configs/static_analysis_ignore.txt" +EXCLUDE=${EXCLUDE:0:-1} + +ALL_INC_FILES=$(find /zeropilot-3.5 -name "*.h*" | grep -Ev "$EXCLUDE") +TRAVERSE_STACK=() +FILES=() + +# initialize traverse stack with source files +while read -r file; do + TRAVERSE_STACK+=( $file ) +done <<< $(grep -Po "\-c \/zeropilot-3.5\/.*\.cp*" $JSON_PATH | grep -Ev "$EXCLUDE" | sed "s/\-c //g" && \ + grep -Po "\-c \/zeropilot-3.5\/.*main\.cp*" $JSON_PATH | sed "s/\-c //g") + +# traverse +while [ ${#TRAVERSE_STACK[@]} != 0 ]; do + # pop from traverse stack + file=${TRAVERSE_STACK[-1]} + unset 'TRAVERSE_STACK[-1]' + + # skip if file is already in list + if [[ "${FILES[@]}" == *$file* ]]; then + continue + fi + + # add file to list + FILES+=( $file ) + + # find all included headers in file + while read -r header; do + if [[ $header != "" && $ALL_INC_FILES == *$header* ]]; then + # get full header path + header_path=$(echo $ALL_INC_FILES | grep -Po "\/zeropilot-3.5[A-Za-z0-9_/]*\/$header") + # add to traverse stack + TRAVERSE_STACK+=( $header_path ) + fi + done <<< $(cat $file | grep -Po "[A-Za-z0-9_]*\.hp*") +done + +echo ${FILES[@]} \ No newline at end of file diff --git a/tools/scripts/test.bash b/tools/scripts/test.bash new file mode 100755 index 00000000..d3dddaae --- /dev/null +++ b/tools/scripts/test.bash @@ -0,0 +1,55 @@ +#!/usr/bin/env bash + + +# ==================== +# --- script setup --- +# ==================== + +# exit on attempt to use undeclared variable +set -o nounset +# enable error tracing +set -o errtrace +# define path to the tools dir +TOOLS_DIR=$(dirname -- "$0")/.. + +# display error message +throw_error() { + echo "" + echo $1 + exit 1 +} + + +# ==================== +# --- var declare --- +# ==================== + +# read compile configurations +source $TOOLS_DIR/scripts/read_configs.bash "$TOOLS_DIR/configs/test_config.txt" + +# read user inputs +while getopts :f: opt +do + case "${opt}" in + f) + TEST_FILTER=${OPTARG} + ;; + \?) + throw_error "Error: Flag -$OPTARG is undefined for run." + ;; + esac +done + +# ==================== +# -----run tests------ +# ==================== + +TEST_PROGRAM="$TOOLS_DIR/testing/build/unit_testing" + +# check for test executable existance +if [[ ! -f $TEST_PROGRAM ]]; then + throw_error "Error: No test executable found. Build testing project first." +fi + +$TEST_PROGRAM --gtest_filter=$TEST_FILTER +exit $? diff --git a/Tools/Testing/CMakeLists.txt b/tools/testing/CMakeLists.txt similarity index 100% rename from Tools/Testing/CMakeLists.txt rename to tools/testing/CMakeLists.txt