mirror of https://github.com/ARMmbed/mbed-os.git
Added CPPCHECK static analysis for MBED and CMSIS libraries from command line. Use switch --cppcheck
parent
51b18186be
commit
9aaf2c1220
|
|
@ -31,7 +31,8 @@ from workspace_tools.targets import TARGET_NAMES, TARGET_MAP
|
|||
from workspace_tools.options import get_default_options_parser
|
||||
from workspace_tools.build_api import build_mbed_libs, build_lib
|
||||
from workspace_tools.build_api import mcu_toolchain_matrix
|
||||
|
||||
from workspace_tools.build_api import static_analysis_scan
|
||||
from workspace_tools.settings import CPPCHECK_CMD, CPPCHECK_MSG_FORMAT
|
||||
|
||||
if __name__ == '__main__':
|
||||
start = time()
|
||||
|
|
@ -50,14 +51,16 @@ if __name__ == '__main__':
|
|||
default=False, help="Compile the USB Device library")
|
||||
parser.add_option("-d", "--dsp", action="store_true", dest="dsp",
|
||||
default=False, help="Compile the DSP library")
|
||||
parser.add_option("-v", "--verbose", action="store_true", dest="verbose",
|
||||
default=False, help="Verbose diagnostic output")
|
||||
parser.add_option("-b", "--ublox", action="store_true", dest="ublox",
|
||||
default=False, help="Compile the u-blox library")
|
||||
parser.add_option("-D", "", action="append", dest="macros",
|
||||
help="Add a macro definition")
|
||||
parser.add_option("-S", "--supported-toolchains", action="store_true", dest="supported_toolchains",
|
||||
default=False, help="Displays supported matrix of MCUs and toolchains")
|
||||
parser.add_option("", "--cppcheck", action="store_true", dest="cppcheck_validation",
|
||||
default=False, help="Forces 'cppcheck' static code analysis")
|
||||
parser.add_option("-v", "--verbose", action="store_true", dest="verbose",
|
||||
default=False, help="Verbose diagnostic output")
|
||||
parser.add_option("-x", "--extra-verbose-notifications", action="store_true", dest="extra_verbose_notify",
|
||||
default=False, help="Makes compiler more verbose, CI friendly.")
|
||||
(options, args) = parser.parse_args()
|
||||
|
|
@ -106,41 +109,64 @@ if __name__ == '__main__':
|
|||
if options.ublox:
|
||||
libraries.extend(["rtx", "rtos", "usb_host", "ublox"])
|
||||
|
||||
# Build
|
||||
# Build results
|
||||
failures = []
|
||||
successes = []
|
||||
for toolchain in toolchains:
|
||||
for target in targets:
|
||||
id = "%s::%s" % (toolchain, target)
|
||||
try:
|
||||
mcu = TARGET_MAP[target]
|
||||
notify = print_notify_verbose if options.extra_verbose_notify else None # Special notify for CI (more verbose)
|
||||
build_mbed_libs(mcu, toolchain, options=options.options,
|
||||
notify=notify, verbose=options.verbose, clean=options.clean,
|
||||
macros=options.macros)
|
||||
for lib_id in libraries:
|
||||
notify = print_notify_verbose if options.extra_verbose_notify else None # Special notify for CI (more verbose)
|
||||
build_lib(lib_id, mcu, toolchain, options=options.options,
|
||||
notify=notify, verbose=options.verbose, clean=options.clean,
|
||||
macros=options.macros)
|
||||
successes.append(id)
|
||||
except Exception, e:
|
||||
if options.verbose:
|
||||
import sys, traceback
|
||||
traceback.print_exc(file=sys.stdout)
|
||||
sys.exit(1)
|
||||
|
||||
failures.append(id)
|
||||
print e
|
||||
# CPPCHECK code validation
|
||||
if options.cppcheck_validation:
|
||||
for toolchain in toolchains:
|
||||
for target in targets:
|
||||
try:
|
||||
mcu = TARGET_MAP[target]
|
||||
# CMSIS and MBED libs analysis
|
||||
static_analysis_scan(mcu, toolchain, CPPCHECK_CMD, CPPCHECK_MSG_FORMAT, verbose=options.verbose)
|
||||
for lib_id in libraries:
|
||||
# Static check for library
|
||||
pass
|
||||
except Exception, e:
|
||||
if options.verbose:
|
||||
import traceback
|
||||
traceback.print_exc(file=sys.stdout)
|
||||
sys.exit(1)
|
||||
print e
|
||||
else:
|
||||
# Build
|
||||
for toolchain in toolchains:
|
||||
for target in targets:
|
||||
tt_id = "%s::%s" % (toolchain, target)
|
||||
try:
|
||||
mcu = TARGET_MAP[target]
|
||||
notify = print_notify_verbose if options.extra_verbose_notify else None # Special notify for CI (more verbose)
|
||||
build_mbed_libs(mcu, toolchain, options=options.options,
|
||||
notify=notify, verbose=options.verbose, clean=options.clean,
|
||||
macros=options.macros)
|
||||
|
||||
for lib_id in libraries:
|
||||
notify = print_notify_verbose if options.extra_verbose_notify else None # Special notify for CI (more verbose)
|
||||
build_lib(lib_id, mcu, toolchain, options=options.options,
|
||||
notify=notify, verbose=options.verbose, clean=options.clean,
|
||||
macros=options.macros)
|
||||
successes.append(tt_id)
|
||||
except Exception, e:
|
||||
if options.verbose:
|
||||
import traceback
|
||||
traceback.print_exc(file=sys.stdout)
|
||||
sys.exit(1)
|
||||
failures.append(tt_id)
|
||||
print e
|
||||
|
||||
# Write summary of the builds
|
||||
print "\n\nCompleted in: (%.2f)s" % (time() - start)
|
||||
print "Completed in: (%.2f)s" % (time() - start)
|
||||
print
|
||||
|
||||
if successes:
|
||||
print "\n\nBuild successes:"
|
||||
print "Build successes:"
|
||||
print
|
||||
print "\n".join([" * %s" % s for s in successes])
|
||||
|
||||
if failures:
|
||||
print "\n\nBuild failures:"
|
||||
print "Build failures:"
|
||||
print
|
||||
print "\n".join([" * %s" % f for f in failures])
|
||||
sys.exit(1)
|
||||
|
|
|
|||
|
|
@ -239,7 +239,7 @@ def mcu_toolchain_matrix():
|
|||
print "Total permutations: %d"% (perm_counter)
|
||||
|
||||
|
||||
def static_analysis_scan(target, toolchain_name, options=None, verbose=False, clean=False, macros=None, notify=None):
|
||||
def static_analysis_scan(target, toolchain_name, CPPCHECK_CMD, CPPCHECK_MSG_FORMAT, options=None, verbose=False, clean=False, macros=None, notify=None):
|
||||
# Toolchain
|
||||
toolchain = TOOLCHAIN_CLASSES[toolchain_name](target, options, macros=macros, notify=notify)
|
||||
toolchain.VERBOSE = verbose
|
||||
|
|
@ -254,22 +254,22 @@ def static_analysis_scan(target, toolchain_name, options=None, verbose=False, cl
|
|||
mkdir(TMP_PATH)
|
||||
|
||||
# CMSIS
|
||||
toolchain.info("\n>>>> SCANNING %s (%s, %s)" % ('CMSIS', target.name, toolchain_name))
|
||||
toolchain.info(">>>> STATIC ANALYSIS FOR %s (%s, %s)" % ('CMSIS', target.name, toolchain_name))
|
||||
cmsis_src = join(MBED_TARGETS_PATH, "cmsis")
|
||||
resources = toolchain.scan_resources(cmsis_src)
|
||||
|
||||
# Copy files before analysis
|
||||
toolchain.copy_files(resources.headers, BUILD_TARGET)
|
||||
toolchain.copy_files(resources.linker_script, BUILD_TOOLCHAIN)
|
||||
|
||||
# Gather include paths, c, cpp sources and macros to transfer to cppcheck command line
|
||||
includes = ["-I%s " % i for i in resources.inc_dirs]
|
||||
includes.append(" -I%s "% str(BUILD_TARGET))
|
||||
c_sources = " ".join(resources.c_sources)
|
||||
cpp_sources = " ".join(resources.cpp_sources)
|
||||
macros = ['-D%s ' % s for s in toolchain.get_symbols() + toolchain.macros]
|
||||
|
||||
CPPCHECK_MSG_FORMAT = ["--template=\"[{severity}] {file}@{line}: {id}:{message}\"", "--xml"]
|
||||
|
||||
check_cmd = 'cppcheck --enable=style '
|
||||
check_cmd = " ".join(CPPCHECK_CMD) + " "
|
||||
check_cmd += " ".join(CPPCHECK_MSG_FORMAT) + " "
|
||||
check_cmd += " ".join(includes)
|
||||
check_cmd += " ".join(macros)
|
||||
|
|
@ -280,11 +280,12 @@ def static_analysis_scan(target, toolchain_name, options=None, verbose=False, cl
|
|||
#['cppcheck', includes, c_sources, cpp_sources]
|
||||
stdout, stderr, rc = run_cmd(check_cmd)
|
||||
|
||||
print stdout
|
||||
if verbose:
|
||||
print stdout
|
||||
print stderr
|
||||
|
||||
# MBED
|
||||
toolchain.info("\n>>> BUILD LIBRARY %s (%s, %s)" % ('MBED', target.name, toolchain_name))
|
||||
toolchain.info(">>> STATIC ANALYSIS FOR %s (%s, %s)" % ('MBED', target.name, toolchain_name))
|
||||
|
||||
# Common Headers
|
||||
toolchain.copy_files(toolchain.scan_resources(MBED_API).headers, MBED_LIBRARIES)
|
||||
|
|
@ -293,6 +294,8 @@ def static_analysis_scan(target, toolchain_name, options=None, verbose=False, cl
|
|||
# Target specific sources
|
||||
HAL_SRC = join(MBED_TARGETS_PATH, "hal")
|
||||
hal_implementation = toolchain.scan_resources(HAL_SRC)
|
||||
|
||||
# Copy files before analysis
|
||||
toolchain.copy_files(hal_implementation.headers + hal_implementation.hex_files, BUILD_TARGET, HAL_SRC)
|
||||
incdirs = toolchain.scan_resources(BUILD_TARGET)
|
||||
|
||||
|
|
@ -303,10 +306,10 @@ def static_analysis_scan(target, toolchain_name, options=None, verbose=False, cl
|
|||
target_cpp_sources = " ".join(incdirs.cpp_sources)
|
||||
target_macros = ['-D%s ' % s for s in toolchain.get_symbols() + toolchain.macros]
|
||||
|
||||
|
||||
# Common Sources
|
||||
mbed_resources = toolchain.scan_resources(MBED_COMMON)
|
||||
|
||||
# Gather include paths, c, cpp sources and macros to transfer to cppcheck command line
|
||||
mbed_includes = ["-I%s " % i for i in mbed_resources.inc_dirs]
|
||||
mbed_includes.append(" -I%s "% str(BUILD_TARGET))
|
||||
mbed_includes.append(" -I%s "% str(MBED_COMMON))
|
||||
|
|
@ -315,7 +318,8 @@ def static_analysis_scan(target, toolchain_name, options=None, verbose=False, cl
|
|||
mbed_c_sources = " ".join(mbed_resources.c_sources)
|
||||
mbed_cpp_sources = " ".join(mbed_resources.cpp_sources)
|
||||
|
||||
check_cmd = 'cppcheck --enable=all ' + " ".join(CPPCHECK_MSG_FORMAT) + " "
|
||||
check_cmd = " ".join(CPPCHECK_CMD) + " "
|
||||
check_cmd += " ".join(CPPCHECK_MSG_FORMAT) + " "
|
||||
check_cmd += " ".join(target_includes)
|
||||
check_cmd += " ".join(mbed_includes)
|
||||
check_cmd += " ".join(target_macros)
|
||||
|
|
@ -328,5 +332,6 @@ def static_analysis_scan(target, toolchain_name, options=None, verbose=False, cl
|
|||
#['cppcheck', includes, c_sources, cpp_sources]
|
||||
stdout, stderr, rc = run_cmd(check_cmd)
|
||||
|
||||
print stdout
|
||||
if verbose:
|
||||
print stdout
|
||||
print stderr
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
"""
|
||||
from optparse import OptionParser
|
||||
|
||||
from workspace_tools.toolchains import TOOLCHAINS
|
||||
from workspace_tools.targets import TARGET_NAMES
|
||||
|
||||
|
|
@ -35,6 +34,6 @@ def get_default_options_parser():
|
|||
help="clean the build directory")
|
||||
|
||||
parser.add_option("-o", "--options", action="append",
|
||||
help='Add a build option ("save-asm": save the asm generated by the compiler, "debug-info": generate debugging information, "analyze": run static code analyzer")')
|
||||
help='Add a build option ("save-asm": save the asm generated by the compiler, "debug-info": generate debugging information, "analyze": run Goanna static code analyzer")')
|
||||
|
||||
return parser
|
||||
|
|
|
|||
|
|
@ -71,6 +71,10 @@ CW_EWL_PATH = "C:/Freescale/CW MCU v10.3/MCU/ARM_GCC_Support/ewl/lib"
|
|||
# Goanna static analyzer
|
||||
GOANNA_PATH = "c:/Program Files (x86)/RedLizards/Goanna Central 3.1.4/bin"
|
||||
|
||||
# cppcheck path (command) and output message format
|
||||
CPPCHECK_CMD = ["cppcheck", "--enable=all"]
|
||||
CPPCHECK_MSG_FORMAT = ["--template=\"[{severity}] {file}@{line}: {id}:{message}\""]
|
||||
|
||||
BUILD_OPTIONS = []
|
||||
|
||||
# mbed.org username
|
||||
|
|
|
|||
Loading…
Reference in New Issue