floooh / fips

High-level build system for distributed, multi-platform C/C++ projects.
MIT License
468 stars 82 forks source link

Clang static analyzer #59

Open HaronK opened 9 years ago

HaronK commented 9 years ago

I suggest to add Clang static analyzer to the list of fips targets. It will help to keep project in a good shape. I just run it right now with Oryol project and it shows 0 issues. Cool!!!

Diff:

diff --git a/cmake/fips_private.cmake b/cmake/fips_private.cmake
index 752ca87..5dd9f7f 100644
--- a/cmake/fips_private.cmake
+++ b/cmake/fips_private.cmake
@@ -177,6 +177,8 @@ macro(fips_choose_config)
             set (FIPS_CONFIG "linux-make-release")
         elseif (${CMAKE_BUILD_TYPE} AND ${CMAKE_BUILD_TYPE} STREQUAL "Profiling")
             set (FIPS_CONFIG "linux-make-profiling")
+        elseif (${CMAKE_BUILD_TYPE} AND ${CMAKE_BUILD_TYPE} STREQUAL "ScanBuild")
+            set (FIPS_CONFIG "linux-make-scan")
         else()
             set (FIPS_CONFIG "linux-make-debug")
         endif()
diff --git a/mod/config.py b/mod/config.py
index 80503cb..1db545e 100644
--- a/mod/config.py
+++ b/mod/config.py
@@ -5,7 +5,7 @@ import glob
 import yaml
 from collections import OrderedDict
 from mod import log, util
-from mod.tools import cmake, make, ninja, xcodebuild
+from mod.tools import cmake, make, ninja, xcodebuild, scan
 from mod import emscripten, nacl, android

 platforms = [
@@ -67,13 +67,15 @@ build_tools = [
     'make',
     'ninja',
     'xcodebuild',
+    'scan-build',
     'cmake'
 ]

 build_types = [
     'Release',
     'Debug',
-    'Profiling'
+    'Profiling',
+    'ScanBuild'
 ]

 default_config = {
@@ -226,6 +228,8 @@ def check_build_tool(fips_dir, tool_name) :
         return ninja.check_exists(fips_dir)
     elif tool_name == 'xcodebuild' :
         return xcodebuild.check_exists(fips_dir)
+    elif tool_name == 'scan-build' :
+        return scan.check_exists(fips_dir)
     else :
         return False;

diff --git a/mod/project.py b/mod/project.py
index 8359ae5..cae9162 100644
--- a/mod/project.py
+++ b/mod/project.py
@@ -6,7 +6,7 @@ import subprocess
 import yaml

 from mod import log, util, config, dep, template, settings
-from mod.tools import git, cmake, make, ninja, xcodebuild, ccmake, cmake_gui
+from mod.tools import git, cmake, make, ninja, xcodebuild, scan, ccmake, cmake_gui

 #-------------------------------------------------------------------------------
 def init(fips_dir, proj_name) :
@@ -181,6 +181,8 @@ def make_clean(fips_dir, proj_dir, cfg_name) :
                     result = ninja.run_clean(fips_dir, build_dir)
                 elif cfg['build_tool'] == xcodebuild.name :
                     result = xcodebuild.run_clean(fips_dir, build_dir)
+                elif cfg['build_tool'] == scan.name :
+                    result = scan.run_clean(fips_dir, build_dir)
                 else :
                     result = cmake.run_clean(fips_dir, build_dir)

@@ -240,6 +242,8 @@ def build(fips_dir, proj_dir, cfg_name, target=None) :
                     result = ninja.run_build(fips_dir, target, build_dir, num_jobs)
                 elif cfg['build_tool'] == xcodebuild.name :
                     result = xcodebuild.run_build(fips_dir, target, cfg['build_type'], build_dir, num_jobs)
+                elif cfg['build_tool'] == scan.name :
+                    result = scan.run_build(fips_dir, target, build_dir, num_jobs)
                 else :
                     result = cmake.run_build(fips_dir, target, cfg['build_type'], build_dir)

configs/linux-make-scan.yml:


---
platform: linux 
generator: Unix Makefiles
build_tool: scan-build
build_type: ScanBuild

mod/tools/scan.py:

"""
wrapper for scan-build tool 
"""
import subprocess

name = 'scan-build'
platforms = ['linux'] #, 'osx', 'win']
optional = True
not_found = "required for generating Clang static analyze report"

#-------------------------------------------------------------------------------
def check_exists(fips_dir) :
    """test if make tool is in the path

    :returns: True if make tool is in path
    """
    try:
        out = subprocess.check_output('scan-build -h', shell=True)
        return True
    except (OSError, subprocess.CalledProcessError):
        return False;

#-------------------------------------------------------------------------------
def run_build(fips_dir, target, build_dir, num_jobs=1) :
    """make a build target

    :param target:      name of build target, or None
    :param build_dir:   directory where Makefile is located
    :param num_jobs:    number of jobs, default is 1
    :returns:           True if build was successful
    """
    cmdLine = 'scan-build --use-analyzer /usr/local/bin/clang -o {}/oryol-scan make -j{}'.format(build_dir, num_jobs)
    if target is not None :
        cmdLine += ' ' + target;
    print(cmdLine)
    res = subprocess.call(cmdLine, cwd=build_dir, shell=True)
    return res == 0

#-------------------------------------------------------------------------------
def run_clean(fips_dir, build_dir) :
    """run the special 'clean' target

    :param build_dir:   directory where Makefile is located
    :returns:           True if make returned with success
    """
    return True
floooh commented 9 years ago

That's a really great idea! I'll try to integrate this soon-ish. Right now I've started to work on Oryol again but will try to squeeze this in. Thanks!

floooh commented 9 years ago

Hmm, the scan-build tool doesn't seem to be installed as part of the Xcode commane line tools on OSX (clang is though), instead xcodebuild is called with an 'analyze' option. There should be an alternate 'fips analyze' which is like 'fips build', but instead runs a code analyzer 'build'.

mgerhardy commented 9 years ago

Maybe thinking about a more generic solution would be cool. To e.g. also add cppcheck. But indeed, a cool patch. Will add it locally already ;)

floooh commented 9 years ago

doh, I totally forgot about his, Martin, if you're integrating and testing this in your fork anyway I'd be happy to accept a pull-request ;) (even if it doesn't work out-of-the-box on OSX)

fungos commented 8 years ago

:+1: Just to bump ;)

floooh commented 8 years ago

I wish github would implement a proper voting system, so that often requested thing would rise to the top...

fungos commented 8 years ago

Yes.. they say they are doing this, lets see...