Esempio n. 1
0
def analyze_compiler_wrapper_impl(result, execution):
    """ Implements analyzer compiler wrapper functionality. """

    # don't run analyzer when compilation fails. or when it's not requested.
    if result or not os.getenv('ANALYZE_BUILD_CLANG'):
        return

    # check is it a compilation?
    compilation = split_command(execution.cmd)
    if compilation is None:
        return
    # collect the needed parameters from environment, crash when missing
    parameters = {
        'clang': os.getenv('ANALYZE_BUILD_CLANG'),
        'output_dir': os.getenv('ANALYZE_BUILD_REPORT_DIR'),
        'output_format': os.getenv('ANALYZE_BUILD_REPORT_FORMAT'),
        'output_failures': os.getenv('ANALYZE_BUILD_REPORT_FAILURES'),
        'direct_args': os.getenv('ANALYZE_BUILD_PARAMETERS',
                                 '').split(' '),
        'force_debug': os.getenv('ANALYZE_BUILD_FORCE_DEBUG'),
        'directory': execution.cwd,
        'command': [execution.cmd[0], '-c'] + compilation.flags,
        'ctu': get_ctu_config_from_json(os.getenv('ANALYZE_BUILD_CTU'))
    }
    # call static analyzer against the compilation
    for source in compilation.files:
        parameters.update({'file': source})
        logging.debug('analyzer parameters %s', parameters)
        current = run(parameters)
        # display error message from the static analyzer
        if current is not None:
            for line in current['error_output']:
                logging.info(line.rstrip())
Esempio n. 2
0
def analyze_build_wrapper(**kwargs):
    """ Entry point for `analyze-cc` and `analyze-c++` compiler wrappers. """

    # don't run analyzer when compilation fails.
    if kwargs['result'] or not os.getenv('ANALYZE_BUILD_CLANG'):
        return
    # don't run analyzer when the command is not a compilation
    # (can be preprocessing or a linking only execution of the compiler)
    compilation = split_command(kwargs['command'])
    if compilation is None:
        return
    # collect the needed parameters from environment, crash when missing
    env = os.environ.copy()
    parameters = {
        'clang': env['ANALYZE_BUILD_CLANG'],
        'output_dir': env['ANALYZE_BUILD_REPORT_DIR'],
        'output_format': env['ANALYZE_BUILD_REPORT_FORMAT'],
        'output_failures': env.get('ANALYZE_BUILD_REPORT_FAILURES', False),
        'direct_args': env.get('ANALYZE_BUILD_PARAMETERS', '').split(' '),
        'force_debug': env.get('ANALYZE_BUILD_FORCE_DEBUG', False),
        'directory': os.getcwd(),
        'command': [kwargs['compiler'], '-c'] + compilation.flags
    }
    # call static analyzer against the compilation
    for source in compilation.files:
        current = run(dict(parameters, file=source))
        # display error message from the static analyzer
        logging_analyzer_output(current)
Esempio n. 3
0
def analyze_compiler_wrapper_impl(result, execution):
    """ Implements analyzer compiler wrapper functionality. """

    # don't run analyzer when compilation fails. or when it's not requested.
    if result or not os.getenv('ANALYZE_BUILD_CLANG'):
        return

    # check is it a compilation?
    compilation = split_command(execution.cmd)
    if compilation is None:
        return
    # collect the needed parameters from environment, crash when missing
    parameters = {
        'clang': os.getenv('ANALYZE_BUILD_CLANG'),
        'output_dir': os.getenv('ANALYZE_BUILD_REPORT_DIR'),
        'output_format': os.getenv('ANALYZE_BUILD_REPORT_FORMAT'),
        'output_failures': os.getenv('ANALYZE_BUILD_REPORT_FAILURES'),
        'direct_args': os.getenv('ANALYZE_BUILD_PARAMETERS',
                                 '').split(' '),
        'force_debug': os.getenv('ANALYZE_BUILD_FORCE_DEBUG'),
        'directory': execution.cwd,
        'command': [execution.cmd[0], '-c'] + compilation.flags
    }
    # call static analyzer against the compilation
    for source in compilation.files:
        parameters.update({'file': source})
        logging.debug('analyzer parameters %s', parameters)
        current = run(parameters)
        # display error message from the static analyzer
        if current is not None:
            for line in current['error_output']:
                logging.info(line.rstrip())
Esempio n. 4
0
    def test_source_file(self):
        def test(expected, cmd):
            self.assertEqual(expected, sut.split_command(cmd).files)

        test(['src.c'], ['clang', 'src.c'])
        test(['src.c'], ['clang', '-c', 'src.c'])
        test(['src.C'], ['clang', '-x', 'c', 'src.C'])
        test(['src.cpp'], ['clang++', '-c', 'src.cpp'])
        test(['s1.c', 's2.c'], ['clang', '-c', 's1.c', 's2.c'])
        test(['s1.c', 's2.c'], ['cc', 's1.c', 's2.c', '-ldep', '-o', 'a.out'])
        test(['src.c'], ['clang', '-c', '-I', './include', 'src.c'])
        test(['src.c'], ['clang', '-c', '-I', '/opt/me/include', 'src.c'])
        test(['src.c'], ['clang', '-c', '-D', 'config=file.c', 'src.c'])

        self.assertIsNone(
            sut.split_command(['cc', 'this.o', 'that.o', '-o', 'a.out']))
        self.assertIsNone(
            sut.split_command(['cc', 'this.o', '-lthat', '-o', 'a.out']))
Esempio n. 5
0
    def test_source_file(self):
        def test(expected, cmd):
            self.assertEqual(expected, sut.split_command(cmd).files)

        test(['src.c'], ['clang', 'src.c'])
        test(['src.c'], ['clang', '-c', 'src.c'])
        test(['src.C'], ['clang', '-x', 'c', 'src.C'])
        test(['src.cpp'], ['clang++', '-c', 'src.cpp'])
        test(['s1.c', 's2.c'], ['clang', '-c', 's1.c', 's2.c'])
        test(['s1.c', 's2.c'], ['cc', 's1.c', 's2.c', '-ldep', '-o', 'a.out'])
        test(['src.c'], ['clang', '-c', '-I', './include', 'src.c'])
        test(['src.c'], ['clang', '-c', '-I', '/opt/me/include', 'src.c'])
        test(['src.c'], ['clang', '-c', '-D', 'config=file.c', 'src.c'])

        self.assertIsNone(
            sut.split_command(['cc', 'this.o', 'that.o', '-o', 'a.out']))
        self.assertIsNone(
            sut.split_command(['cc', 'this.o', '-lthat', '-o', 'a.out']))
Esempio n. 6
0
    def test_action(self):
        self.assertIsNotNone(sut.split_command(['clang', 'source.c']))
        self.assertIsNotNone(sut.split_command(['clang', '-c', 'source.c']))
        self.assertIsNotNone(sut.split_command(['clang', '-c', 'source.c',
                                                '-MF', 'a.d']))

        self.assertIsNone(sut.split_command(['clang', '-E', 'source.c']))
        self.assertIsNone(sut.split_command(['clang', '-c', '-E', 'source.c']))
        self.assertIsNone(sut.split_command(['clang', '-c', '-M', 'source.c']))
        self.assertIsNone(
            sut.split_command(['clang', '-c', '-MM', 'source.c']))
Esempio n. 7
0
    def test_action(self):
        self.assertIsNotNone(sut.split_command(['clang', 'source.c']))
        self.assertIsNotNone(sut.split_command(['clang', '-c', 'source.c']))
        self.assertIsNotNone(
            sut.split_command(['clang', '-c', 'source.c', '-MF', 'a.d']))

        self.assertIsNone(sut.split_command(['clang', '-E', 'source.c']))
        self.assertIsNone(sut.split_command(['clang', '-c', '-E', 'source.c']))
        self.assertIsNone(sut.split_command(['clang', '-c', '-M', 'source.c']))
        self.assertIsNone(sut.split_command(['clang', '-c', '-MM',
                                             'source.c']))
Esempio n. 8
0
def analyze_build_wrapper(cplusplus):
    """ Entry point for `analyze-cc` and `analyze-c++` compiler wrappers. """

    # initialize wrapper logging
    logging.basicConfig(format='analyze: %(levelname)s: %(message)s',
                        level=os.getenv('ANALYZE_BUILD_VERBOSE', 'INFO'))
    # execute with real compiler
    compiler = os.getenv('ANALYZE_BUILD_CXX', 'c++') if cplusplus \
        else os.getenv('ANALYZE_BUILD_CC', 'cc')
    compilation = [compiler] + sys.argv[1:]
    logging.info('execute compiler: %s', compilation)
    result = subprocess.call(compilation)
    # exit when it fails, ...
    if result or not os.getenv('ANALYZE_BUILD_CLANG'):
        return result
    # ... and run the analyzer if all went well.
    try:
        # check is it a compilation
        compilation = split_command(sys.argv)
        if compilation is None:
            return result
        # collect the needed parameters from environment, crash when missing
        parameters = {
            'clang': os.getenv('ANALYZE_BUILD_CLANG'),
            'output_dir': os.getenv('ANALYZE_BUILD_REPORT_DIR'),
            'output_format': os.getenv('ANALYZE_BUILD_REPORT_FORMAT'),
            'output_failures': os.getenv('ANALYZE_BUILD_REPORT_FAILURES'),
            'direct_args': os.getenv('ANALYZE_BUILD_PARAMETERS',
                                     '').split(' '),
            'force_debug': os.getenv('ANALYZE_BUILD_FORCE_DEBUG'),
            'directory': os.getcwd(),
            'command': [sys.argv[0], '-c'] + compilation.flags
        }
        # call static analyzer against the compilation
        for source in compilation.files:
            parameters.update({'file': source})
            logging.debug('analyzer parameters %s', parameters)
            current = run(parameters)
            # display error message from the static analyzer
            if current is not None:
                for line in current['error_output']:
                    logging.info(line.rstrip())
    except Exception:
        logging.exception("run analyzer inside compiler wrapper failed.")
    return result
Esempio n. 9
0
def analyze_build_wrapper(cplusplus):
    """ Entry point for `analyze-cc` and `analyze-c++` compiler wrappers. """

    # initialize wrapper logging
    logging.basicConfig(format='analyze: %(levelname)s: %(message)s',
                        level=os.getenv('ANALYZE_BUILD_VERBOSE', 'INFO'))
    # execute with real compiler
    compiler = os.getenv('ANALYZE_BUILD_CXX', 'c++') if cplusplus \
        else os.getenv('ANALYZE_BUILD_CC', 'cc')
    compilation = [compiler] + sys.argv[1:]
    logging.info('execute compiler: %s', compilation)
    result = subprocess.call(compilation)
    # exit when it fails, ...
    if result or not os.getenv('ANALYZE_BUILD_CLANG'):
        return result
    # ... and run the analyzer if all went well.
    try:
        # check is it a compilation
        compilation = split_command(sys.argv)
        if compilation is None:
            return result
        # collect the needed parameters from environment, crash when missing
        parameters = {
            'clang': os.getenv('ANALYZE_BUILD_CLANG'),
            'output_dir': os.getenv('ANALYZE_BUILD_REPORT_DIR'),
            'output_format': os.getenv('ANALYZE_BUILD_REPORT_FORMAT'),
            'output_failures': os.getenv('ANALYZE_BUILD_REPORT_FAILURES'),
            'direct_args': os.getenv('ANALYZE_BUILD_PARAMETERS',
                                     '').split(' '),
            'force_debug': os.getenv('ANALYZE_BUILD_FORCE_DEBUG'),
            'directory': os.getcwd(),
            'command': [sys.argv[0], '-c'] + compilation.flags
        }
        # call static analyzer against the compilation
        for source in compilation.files:
            parameters.update({'file': source})
            logging.debug('analyzer parameters %s', parameters)
            current = run(parameters)
            # display error message from the static analyzer
            if current is not None:
                for line in current['error_output']:
                    logging.info(line.rstrip())
    except Exception:
        logging.exception("run analyzer inside compiler wrapper failed.")
    return result
Esempio n. 10
0
def format_entry(exec_trace):
    """ Generate the desired fields for compilation database entries. """
    def abspath(cwd, name):
        """ Create normalized absolute path from input filename. """
        fullname = name if os.path.isabs(name) else os.path.join(cwd, name)
        return os.path.normpath(fullname)

    logging.debug('format this command: %s', exec_trace['command'])
    compilation = split_command(exec_trace['command'])
    if compilation:
        for source in compilation.files:
            compiler = 'c++' if compilation.compiler == 'c++' else 'cc'
            command = [compiler, '-c'] + compilation.flags + [source]
            logging.debug('formated as: %s', command)
            yield {
                'directory': exec_trace['directory'],
                'command': encode(command),
                'file': abspath(exec_trace['directory'], source)
            }
Esempio n. 11
0
def format_entry(exec_trace):
    """ Generate the desired fields for compilation database entries. """

    def abspath(cwd, name):
        """ Create normalized absolute path from input filename. """
        fullname = name if os.path.isabs(name) else os.path.join(cwd, name)
        return os.path.normpath(fullname)

    logging.debug('format this command: %s', exec_trace['command'])
    compilation = split_command(exec_trace['command'])
    if compilation:
        for source in compilation.files:
            compiler = 'c++' if compilation.compiler == 'c++' else 'cc'
            command = [compiler, '-c'] + compilation.flags + [source]
            logging.debug('formated as: %s', command)
            yield {
                'directory': exec_trace['directory'],
                'command': encode(command),
                'file': abspath(exec_trace['directory'], source)
            }
Esempio n. 12
0
 def test(expected, flags):
     command = ['clang', '-c', 'src.c'] + flags
     self.assertEqual(expected, sut.split_command(command).flags)
Esempio n. 13
0
 def test(expected, cmd):
     self.assertEqual(expected, sut.split_command(cmd).files)
Esempio n. 14
0
 def test(cmd):
     result = sut.split_command([cmd, '-c', 'src.c'])
     self.assertIsNotNone(result, "wrong input for test")
     return result.compiler == 'c++'
Esempio n. 15
0
 def test(expected, flags):
     command = ['clang', '-c', 'src.c'] + flags
     self.assertEqual(expected, sut.split_command(command).flags)
Esempio n. 16
0
 def test(expected, cmd):
     self.assertEqual(expected, sut.split_command(cmd).files)
Esempio n. 17
0
 def test(cmd):
     result = sut.split_command([cmd, '-c', 'src.c'])
     self.assertIsNotNone(result, "wrong input for test")
     return result.compiler == 'c++'