Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: Add static code analyzer integration #51179

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions cmake/generic_toolchain.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,5 @@ set_ifndef(TOOLCHAIN_KCONFIG_DIR ${TOOLCHAIN_ROOT}/cmake/toolchain/${ZEPHYR_TOOL
include(${TOOLCHAIN_ROOT}/cmake/compiler/${COMPILER}/generic.cmake OPTIONAL)
include(${TOOLCHAIN_ROOT}/cmake/linker/${LINKER}/generic.cmake OPTIONAL)
include(${TOOLCHAIN_ROOT}/cmake/bintools/${BINTOOLS}/generic.cmake OPTIONAL)

include(${TOOLCHAIN_ROOT}/cmake/sca_integration.cmake OPTIONAL)
142 changes: 142 additions & 0 deletions cmake/sca_integration.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
# SPDX-License-Identifier: Apache-2.0

function(write_sca_export_jsons SCA_IN_TREE_INTEGRATION_DIR SCA_OUT_OF_TREE_INTEGRATION_DIR)
# Write current selected toolchain/compiler to export file
message(STATUS "Reading '${SCA_IN_TREE_INTEGRATION_DIR}/sca_export.json.in'")
# Read the json
file(READ ${SCA_IN_TREE_INTEGRATION_DIR}/sca_export.json.in SCA_EXPORT_JSON)
#message(STATUS "read result: ${SCA_EXPORT_JSON}")
# Modify the json
string(TIMESTAMP DATE_TIME "%Y-%m-%d %H:%M:%S")
string(JSON SCA_EXPORT_JSON ERROR_VARIABLE ERR_VAR SET ${SCA_EXPORT_JSON} "Build" "TIMESTAMP" \"${DATE_TIME}\")
string(JSON SCA_EXPORT_JSON ERROR_VARIABLE ERR_VAR SET ${SCA_EXPORT_JSON} "Build" "C_COMPILER" \"${CMAKE_C_COMPILER}\")
string(JSON SCA_EXPORT_JSON ERROR_VARIABLE ERR_VAR SET ${SCA_EXPORT_JSON} "Build" "CXX_COMPILER" \"${CMAKE_CXX_COMPILER}\")
string(JSON SCA_EXPORT_JSON ERROR_VARIABLE ERR_VAR SET ${SCA_EXPORT_JSON} "Build" "ASM_COMPILER" \"${CMAKE_ASM_COMPILER}\")
string(JSON SCA_EXPORT_JSON ERROR_VARIABLE ERR_VAR SET ${SCA_EXPORT_JSON} "Build" "LINKER" \"${CMAKE_LINKER}\")
#message(STATUS "err-var: ${ERR_VAR}")
#message(STATUS "json: ${SCA_EXPORT_JSON}")

# Write the in tree json
file(WRITE ${SCA_IN_TREE_INTEGRATION_DIR}/sca_export.json ${SCA_EXPORT_JSON})
message(STATUS "Writing '${SCA_IN_TREE_INTEGRATION_DIR}/sca_export.json'")

# Write the out of tree json
if(NOT ${SCA_OUT_OF_TREE_INTEGRATION_DIR} MATCHES ".*-NOTFOUND")
file(WRITE ${SCA_OUT_OF_TREE_INTEGRATION_DIR}/sca_export.json ${SCA_EXPORT_JSON})
message(STATUS "Writing '${SCA_OUT_OF_TREE_INTEGRATION_DIR}/sca_export.json'")
endif()
endfunction()

function(exec_sca_hook_scripts SCA_INTEGRATION_DIR)
if(${SCA_INTEGRATION_DIR} MATCHES ".*-NOTFOUND")
message(STATUS "SCA_INTEGRATION_DIR: ${SCA_INTEGRATION_DIR} - bailing out!")
return()
endif()
string(TOLOWER "${SCA_VARIANT}" LC_SCA_VARIANT)
set(SCA_VARIANT_HOOKS_DIR "${SCA_INTEGRATION_DIR}/hooks/${LC_SCA_VARIANT}")
# Update the SCA configuration if required, run any matching script!
set(SCA_UPDATE_SCRIPT_EXTS sh bat py rb pl js ps1)
foreach(SCA_UPDATE_SCRIPT_EXT ${SCA_UPDATE_SCRIPT_EXTS})
# unset SCA_UPDATE_SCRIPT everytime before find_program to force new search!
unset(SCA_UPDATE_SCRIPT CACHE)
string(TOLOWER "update.${SCA_UPDATE_SCRIPT_EXT}" SCA_UPDATE_SCRIPT_NAME)
find_program(SCA_UPDATE_SCRIPT ${SCA_UPDATE_SCRIPT_NAME} PATHS ${SCA_VARIANT_HOOKS_DIR} NO_CACHE)
if(NOT ${SCA_UPDATE_SCRIPT} MATCHES ".*-NOTFOUND")
execute_process(COMMAND ${SCA_UPDATE_SCRIPT} ${SCA_INTEGRATION_DIR}/sca_export.json
WORKING_DIRECTORY ${SCA_INTEGRATION_DIR}
RESULT_VARIABLE SCA_UPDATE_SCRIPT_RETVAL)
# In accordance with https://tldp.org/LDP/abs/html/exitcodes.html for the user-defined exit code range
if(${SCA_UPDATE_SCRIPT_RETVAL} EQUAL 0)
# The script was successful. No further scripts will be executed.
break()
elseif(${SCA_UPDATE_SCRIPT_RETVAL} EQUAL 111)
# The script wants more scripts to be executed.
else()
# The script was unsuccessful. The build will be terminated.
message(FATAL_ERROR "The script '${SCA_UPDATE_SCRIPT_NAME}' returned '${SCA_UPDATE_SCRIPT_RETVAL}'")
endif()
else()
message(STATUS "'${SCA_UPDATE_SCRIPT_NAME}' in '${SCA_VARIANT_HOOKS_DIR}' not found or not an executable!")
endif()
endforeach()
endfunction()

function(read_sca_import_json SCA_INTEGRATION_DIR)
if(${SCA_INTEGRATION_DIR} MATCHES ".*-NOTFOUND")
message(STATUS "SCA_INTEGRATION_DIR: ${SCA_INTEGRATION_DIR} - bailing out!")
return()
endif()
# read SCA integration import file
message(STATUS "Reading '${SCA_INTEGRATION_DIR}/sca_import.json'")
file(READ ${SCA_INTEGRATION_DIR}/sca_import.json SCA_IMPORT_JSON)
#message(STATUS ${SCA_IMPORT_JSON})

# read the variables from the json
string(JSON SCA_CONFIG ERROR_VARIABLE ERR_VAR GET ${SCA_IMPORT_JSON} "SCAs" ${SCA_VARIANT})
#message(STATUS "SCA_CONFIG: ${SCA_CONFIG}")

if(${SCA_CONFIG} MATCHES ".*-NOTFOUND")
message(STATUS "Config not found!")
else()
message(STATUS "Config found!")
set(SCA_CONFIG_FOUND TRUE PARENT_SCOPE)
string(JSON SCA_C_COMPILER ERROR_VARIABLE ERR_VAR GET ${SCA_IMPORT_JSON} "SCAs" ${SCA_VARIANT} "C_COMPILER")
message(STATUS "SCA_C_COMPILER: ${SCA_C_COMPILER}")

string(JSON SCA_CXX_COMPILER ERROR_VARIABLE ERR_VAR GET ${SCA_IMPORT_JSON} "SCAs" ${SCA_VARIANT} "CXX_COMPILER")
message(STATUS "SCA_CXX_COMPILER: ${SCA_CXX_COMPILER}")

string(JSON SCA_ASM_COMPILER ERROR_VARIABLE ERR_VAR GET ${SCA_IMPORT_JSON} "SCAs" ${SCA_VARIANT} "ASM_COMPILER")
message(STATUS "SCA_ASM_COMPILER: ${SCA_ASM_COMPILER}")

string(JSON SCA_LINKER ERROR_VARIABLE ERR_VAR GET ${SCA_IMPORT_JSON} "SCAs" ${SCA_VARIANT} "LINKER")
message(STATUS "SCA_LINKER: ${SCA_LINKER}")

# replace the current selected toolchain/compiler by SCA executables
if(${SCA_C_COMPILER})
#set(CMAKE_C_COMPILER ${SCA_C_COMPILER})
endif()
if(${SCA_CXX_COMPILER})
#set(CMAKE_CXX_COMPILER ${SCA_CXX_COMPILER})
endif()
if(${SCA_ASM_COMPILER})
#set(CMAKE_ASM_COMPILER ${SCA_ASM_COMPILER})
endif()
if(${SCA_LINKER})
#set(CMAKE_LINKER ${SCA_LINKER})
endif()
endif()
endfunction()

if(DEFINED SCA_VARIANT)
message(STATUS "*** Start SCA integration for '${SCA_VARIANT}' ***")
set(SCA_IN_TREE_INTEGRATION_DIR "${ZEPHYR_BASE}/scripts/sca_integration")
if(DEFINED ENV{SCA_INTEGRATION_DIR})
set(SCA_OUT_OF_TREE_INTEGRATION_DIR $ENV{SCA_INTEGRATION_DIR})
else()
set(SCA_OUT_OF_TREE_INTEGRATION_DIR "-NOTFOUND")
message(STATUS "No SCA integration folder defined!")
endif()

write_sca_export_jsons(${SCA_IN_TREE_INTEGRATION_DIR} ${SCA_OUT_OF_TREE_INTEGRATION_DIR})

message(STATUS "Calling 'read_sca_import_json' (out of tree): ${SCA_OUT_OF_TREE_INTEGRATION_DIR}")
read_sca_import_json(${SCA_OUT_OF_TREE_INTEGRATION_DIR})
if(${SCA_CONFIG_FOUND})
message(STATUS "Calling 'exec_sca_hook_scripts' ${SCA_OUT_OF_TREE_INTEGRATION_DIR}")
exec_sca_hook_scripts(${SCA_OUT_OF_TREE_INTEGRATION_DIR})
else()
message(STATUS "Calling 'read_sca_import_json' (in tree): ${SCA_IN_TREE_INTEGRATION_DIR}")
read_sca_import_json(${SCA_IN_TREE_INTEGRATION_DIR})
if(${SCA_CONFIG_FOUND})
message(STATUS "Calling 'exec_sca_hook_scripts' ${SCA_IN_TREE_INTEGRATION_DIR}")
exec_sca_hook_scripts(${SCA_IN_TREE_INTEGRATION_DIR})
endif()
endif()
message(STATUS "*** SCA integration for: '${SCA_VARIANT}' done! ***")
else()
message(STATUS "No SCA integration (SCA_VARIANT undefined)")
endif()



7 changes: 7 additions & 0 deletions scripts/sca_integration/hooks/cppcheck/update.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/bash

echo "Executing batch as bash: '$0 $@'" >&2

# 'Do some useful processing of sca_export.json as passed in $@ resp. $1

exit 111
11 changes: 11 additions & 0 deletions scripts/sca_integration/hooks/cppcheck/update.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/usr/bin/env python3

import os
import sys
import json

print( "Exectuing: '" + str(sys.argv[0:]) + "'", file=sys.stderr)

# Do some useful processing of sca_export.json as passed in argv[1]

sys.exit(0)
7 changes: 7 additions & 0 deletions scripts/sca_integration/hooks/cppcheck/update.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/bash

echo "Executing: '$0 $@'" >&2

# Do some useful processing of sca_export.json as passed in $@ resp. $1

exit 111
7 changes: 7 additions & 0 deletions scripts/sca_integration/hooks/cpptest/update.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/bash

echo "Executing batch as bash: '$0 $@'" >&2

# 'Do some useful processing of sca_export.json as passed in $@ resp. $1

exit 111
20 changes: 20 additions & 0 deletions scripts/sca_integration/hooks/cpptest/update.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/env python3

import subprocess
import sys
import json

print( "Exectuing: '" + str(sys.argv[0:]) + "'", file=sys.stderr)

# Do some useful processing of sca_export.json as passed in argv[1]

file = open(sys.argv[1])
data = json.load(file)

print("Write/update 'extern CPPTEST_CC=\"" + data['Build']['C_COMPILER'] + "\"' in your ~/.bashrc or similar", file=sys.stderr)

file.close()


sys.exit(0)

7 changes: 7 additions & 0 deletions scripts/sca_integration/hooks/cpptest/update.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/bash

echo "Executing: '$0 $@'" >&2

# Do some useful processing of sca_export.json as passed in $@ resp. $1

exit 111
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/bash

echo "Executing batch as bash: '$0 $@'" >&2

# 'Do some useful processing of sca_build_export.json as passed in $@ resp. $1

exit 111
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env python3

import sys

print( "Exectuing: '" + str(sys.argv[0:]) + "'", file=sys.stderr)

# Do some useful processing of sca_build_export.json as passed in argv[1]

sys.exit(0)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/bash

echo "Executing: '$0 $@'" >&2

# Do some useful processing of sca_build_export.json as passed in $@ resp. $1

exit 111
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/bash

echo "Executing batch as bash: '$0 $@'" >&2

# 'Do some useful processing of sca_build_export.json as passed in $@ resp. $1

exit 111
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env python3

import sys

print( "Exectuing: '" + str(sys.argv[0:]) + "'", file=sys.stderr)

# Do some useful processing of sca_build_export.json as passed in argv[1]

sys.exit(0)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/bash

echo "Executing: '$0 $@'" >&2

# Do some useful processing of sca_build_export.json as passed in $@ resp. $1

exit 111
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{ "SCAs": {
"Axivion" : {
"C_COMPILER" : "/opt/bauhaus-suite/bin/ircc",
"CXX_COMPILER" : "/opt/bauhaus-suite/bin/ircc",
"ASM_COMPILER" : "/opt/bauhaus-suite/bin/ircc",
"LINKER" : "/opt/bauhaus-suite/bin/ircc"
},
"cppcheck" : {
"C_COMPILER" : "/opt/cppcheck/bin/cppcheck",
"CXX_COMPILER" : "/opt/cppcheck/bin/cppcheck",
"ASM_COMPILER" : "/opt/cppcheck/bin/cppcheck",
"LINKER" : "/opt/cppcheck/bin/cppcheck"
}
}
}
10 changes: 10 additions & 0 deletions scripts/sca_integration/sca_export.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
Copy link
Contributor Author

@romkell romkell Oct 11, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The file is a generated file and will be removed from the commit sooner or later.
It is here to illustrate the output format.

Question:
Why are CMAKE_CXX_COMPILER and all the other variables empty except for the CMAKE_C_COMPILER?
Did I include the sca_integration.cmake too early?
Any hints for me?

"Build" :
{
"ASM_COMPILER" : "",
"CXX_COMPILER" : "",
"C_COMPILER" : "/usr/bin/gcc",
"LINKER" : "",
"TIMESTAMP" : "2022-10-12 07:30:50"
}
}
8 changes: 8 additions & 0 deletions scripts/sca_integration/sca_export.json.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{ "Build" : {
"TIMESTAMP" : "<unset>",
"C_COMPILER" : "<unset>",
"CXX_COMPILER" : "<unset>",
"ASM_COMPILER" : "<unset>",
"LINKER" : "<unset>"
}
}
15 changes: 15 additions & 0 deletions scripts/sca_integration/sca_import.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{ "SCAs": {
"cppcheck" : {
"C_COMPILER" : "/opt/cppcheck/bin/cppcheck",
"CXX_COMPILER" : "/opt/cppcheck/bin/cppcheck",
"ASM_COMPILER" : "/opt/cppcheck/bin/cppcheck",
"LINKER" : "/opt/cppcheck/bin/cppcheck"
},
"cpptest" : {
"C_COMPILER" : "/opt/cpptest/bin/cpptest",
"CXX_COMPILER" : "/opt/cpptest/bin/cpptest",
"ASM_COMPILER" : "/opt/cpptest/bin/cpptest",
"LINKER" : "/opt/cpptest/bin/cpptest"
}
}
}