diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 000000000..481519ad7 --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,69 @@ +--- +Checks: '*, + -altera-id-dependent-backward-branch, + -altera-struct-pack-align, + -altera-unroll-loops, + -android-cloexec-*, + -bugprone-branch-clone, + -bugprone-easily-swappable-parameters, + -bugprone-macro-parentheses, + -bugprone-reserved-identifier, + -bugprone-sizeof-expression, + -cert-dcl37-c, + -cert-dcl51-cpp, + -cert-err33-c, + -cert-err34-c, + -clang-analyzer-optin.performance.Padding, + -clang-analyzer-security.insecureAPI.bcmp, + -clang-analyzer-security.insecureAPI.bcopy, + -clang-analyzer-security.insecureAPI.bzero, + -clang-diagnostic-error, + -clang-diagnostic-typedef-redefinition, + -clang-diagnostic-unknown-warning-option, + -concurrency-mt-unsafe, + -cppcoreguidelines-avoid-magic-numbers, + -cppcoreguidelines-avoid-non-const-global-variables, + -cppcoreguidelines-init-variables, + -google-readability-braces-around-statements, + -google-readability-casting, + -google-readability-function-size, + -google-readability-todo, + -hicpp-braces-around-statements, + -hicpp-function-size, + -hicpp-multiway-paths-covered, + -llvm-else-after-return, + -llvm-header-guard, + -llvm-include-order, + -llvmlibc-restrict-system-libc-headers, + -misc-no-recursion, + -misc-unused-parameters, + -performance-no-int-to-ptr, + -readability-avoid-const-params-in-decls, + -readability-braces-around-statements, + -readability-duplicate-include, + -readability-else-after-return, + -readability-function-cognitive-complexity, + -readability-function-size, + -readability-identifier-length, + -readability-isolate-declaration, + -readability-magic-numbers, + -readability-non-const-parameter, + -readability-redundant-control-flow, + -readability-redundant-declaration, + -readability-suspicious-call-argument, + + + -bugprone-implicit-widening-of-multiplication-result, + -bugprone-narrowing-conversions, + -cert-exp42-c, + -cert-flp37-c, + -clang-analyzer-core.NullDereference, + -clang-analyzer-deadcode.DeadStores, + -clang-analyzer-security.insecureAPI.strcpy, + -cppcoreguidelines-interfaces-global-init, + -cppcoreguidelines-narrowing-conversions, + -hicpp-signed-bitwise, + ' + +WarningsAsErrors: false +HeaderFilterRegex: '(.*\.h)' diff --git a/meson.build b/meson.build index 03009673d..b9cedfd2d 100644 --- a/meson.build +++ b/meson.build @@ -42,6 +42,12 @@ python3 = find_program('python3', 'python') python3_exe = join_paths(python3.path()) mkdir_p = 'import os; os.makedirs("@0@", exist_ok=True) if not os.environ.get("DESTDIR") else False;' install_conf = 'import os; import shutil; shutil.copy("@0@", "@1@") if not os.environ.get("DESTDIR") and not os.path.isfile(os.path.join("@1@", os.path.split("@0@")[1])) else False;' +cppcheck = find_program('cppcheck', required: false) +clangtidy = find_program('run-clang-tidy', required: false) # requires clang-tools package +if clangtidy.found() != true + clangtidy = find_program('clang-tidy', required: false) +endif + meson.add_install_script(python3_exe, '-c', mkdir_p.format(join_paths(localstatedir, 'log', 'open5gs'))) @@ -131,3 +137,24 @@ message('\n'.join([ ' debugging support: ' + get_option('buildtype'), '', ])) + + +if cppcheck.found() + run_target('analyze-cppcheck', + command : [ 'misc/static_code_analyze.sh', + cppcheck.path(), + meson.build_root(), + meson.source_root() + ] + ) +endif + +if clangtidy.found() + run_target('analyze-clang-tidy', + command : [ 'misc/static_code_analyze.sh', + clangtidy.path(), + meson.build_root(), + meson.source_root() + ] + ) +endif diff --git a/misc/static_code_analyze.sh b/misc/static_code_analyze.sh new file mode 100755 index 000000000..7fb82ca7a --- /dev/null +++ b/misc/static_code_analyze.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash + +ANALYZE_TOOL="${1}" && shift +BUILD_DIR="${1}" && shift +SOURCES_DIR="${1}" && shift + +SOURCES=$(find ${SOURCES_DIR}/src ${SOURCES_DIR}/lib -not -path *asn1c* -not -path *ipfw* -name *.c) +#SOURCES=$(find ${SOURCES_DIR}/src ${SOURCES_DIR}/lib ${SOURCES_DIR}/subprojects -name *.c) + +if [[ ${ANALYZE_TOOL} == *"clang-tidy"* ]]; +then + if [[ ${ANALYZE_TOOL} == *"run-clang-tidy"* ]]; then + OPTS="${OPTS} -j $(nproc)" + fi + + OPTS="${OPTS} -quiet" + OPTS="${OPTS} -p=${BUILD_DIR}" + + ${ANALYZE_TOOL} ${OPTS} ${SOURCES} 2>/dev/null + +elif [[ ${ANALYZE_TOOL} == *"cppcheck"* ]]; +then + OPTS="${OPTS} -j $(nproc)" +# OPTS="${OPTS} --quiet" + OPTS="${OPTS} --verbose" + OPTS="${OPTS} --enable=all" + OPTS="${OPTS} --verbose" + OPTS="${OPTS} --suppress=variableScope" + OPTS="${OPTS} --suppress=preprocessorErrorDirective" + OPTS="${OPTS} --suppress=unusedVariable" + OPTS="${OPTS} --output-file=cppchecklog.log" + OPTS="${OPTS} --cppcheck-build-dir=${BUILD_DIR}/cppcheck" + OPTS="${OPTS} --project=${BUILD_DIR}/compile_commands.json" + + ${ANALYZE_TOOL} ${OPTS} ${SOURCES} + +else + echo "Unknown static code analysis tool: ${ANALYZE_TOOL}" + exit 1 +fi