def scan_build(): """ Entry point for scan-build command. """ args = parse_args_for_scan_build() # will re-assign the report directory as new output with report_directory( args.output, args.keep_empty, args.output_format) as args.output: # Run against a build command. there are cases, when analyzer run # is not required. But we need to set up everything for the # wrappers, because 'configure' needs to capture the CC/CXX values # for the Makefile. if args.intercept_first: # Run build command with intercept module. exit_code = capture(args) # Run the analyzer against the captured commands. if need_analyzer(args.build): govern_analyzer_runs(args) else: # Run build command and analyzer with compiler wrappers. environment = setup_environment(args) exit_code = run_build(args.build, env=environment) # Cover report generation and bug counting. number_of_bugs = document(args) # Set exit status as it was requested. return number_of_bugs if args.status_bugs else exit_code
def scan_build(): # type: () -> int """ Entry point for scan-build command. """ args = parse_args_for_scan_build() # will re-assign the report directory as new output with report_directory(args.output, args.keep_empty) as args.output: # run against a build command. there are cases, when analyzer run # is not required. but we need to set up everything for the # wrappers, because 'configure' needs to capture the CC/CXX values # for the Makefile. if args.intercept_first: # run build command with intercept module exit_code, compilations = capture(args) if need_analyzer(args.build): # run the analyzer against the captured commands run_analyzer_parallel(compilations, args) else: # run build command and analyzer with compiler wrappers environment = setup_environment(args) exit_code = run_build(args.build, env=environment) # cover report generation and bug counting number_of_bugs = document(args) # set exit status as it was requested return number_of_bugs if args.status_bugs else exit_code
def analyze_build_main(bin_dir, from_build_command): """ Entry point for 'analyze-build' and 'scan-build'. """ parser = create_parser(from_build_command) args = parser.parse_args() validate(parser, args, from_build_command) # setup logging initialize_logging(args.verbose) logging.debug('Parsed arguments: %s', args) with report_directory(args.output, args.keep_empty) as target_dir: if not from_build_command: # run analyzer only and generate cover report run_analyzer(args, target_dir) number_of_bugs = document(args, target_dir, True) return number_of_bugs if args.status_bugs else 0 elif args.intercept_first: # run build command and capture compiler executions exit_code = capture(args, bin_dir) # next step to run the analyzer against the captured commands if need_analyzer(args.build): run_analyzer(args, target_dir) # cover report generation and bug counting number_of_bugs = document(args, target_dir, True) # remove the compilation database when it was not requested if os.path.exists(args.cdb): os.unlink(args.cdb) # set exit status as it was requested return number_of_bugs if args.status_bugs else exit_code else: return exit_code else: # run the build command with compiler wrappers which # execute the analyzer too. (interposition) environment = setup_environment(args, target_dir, bin_dir) logging.debug('run build in environment: %s', environment) exit_code = subprocess.call(args.build, env=environment) logging.debug('build finished with exit code: %d', exit_code) # cover report generation and bug counting number_of_bugs = document(args, target_dir, False) # set exit status as it was requested return number_of_bugs if args.status_bugs else exit_code
def scan_build(): """ Entry point for scan-build command. """ args = parse_args_for_scan_build() with report_directory(args.output, args.keep_empty) as target_dir: # Run against a build command. there are cases, when analyzer run # is not required. But we need to set up everything for the # wrappers, because 'configure' needs to capture the CC/CXX values # for the Makefile. if args.intercept_first: # Run build command with intercept module. exit_code = capture(args) # Run the analyzer against the captured commands. if need_analyzer(args.build): run_analyzer(args, target_dir) else: # Run build command and analyzer with compiler wrappers. environment = setup_environment(args, target_dir) exit_code = run_build(args.build, env=environment) # Cover report generation and bug counting. number_of_bugs = document(args, target_dir, False) # Set exit status as it was requested. return number_of_bugs if args.status_bugs else exit_code
def intercept_build(args): # type: () -> int """ Entry point for 'intercept-build' command. """ parser = arguments.create_intercept_parser() parser.add_argument('--project-path', metavar="<path>", dest='cwd', type=str, default=getcwd(), help="""used path where the build tools are invoked""") parser.add_argument('--sanitize-build', action='store_true', help="""Rebuild command with sanitizers enabled""") parser.add_argument('--fuzzing-targets', action='store_true', help="""Build fuzzing targets""") args = parser.parse_args(args) chdir(args.cwd) if args.sanitize_build: if not args.build: LOGGER.error("Please provide a build command") sys.exit(2) compiler = "{} -g {} {}" LOGGER.debug( "Compiler command %s", compiler.format(CLANG, CLANG_SANITIZE_CMD, CLANG_COVERAGE_CMD)) proc = subprocess.run( args.build, shell=True, env={ **env, **{ 'CC': compiler.format(CLANG, CLANG_SANITIZE_CMD, CLANG_COVERAGE_CMD), 'CXX': compiler.format(CLANGPP, CLANG_SANITIZE_CMD, CLANG_COVERAGE_CMD) } }) parser.exit(status=proc.returncode) if args.fuzzing_targets: LOGGER.info("Building fuzzing targets") ret = build_fuzzing_targets() parser.exit(status=ret) args.append = True libscanbuild.reconfigure_logging(args.verbose) logging.debug('Raw arguments %s', sys.argv) # short validation logic if not args.build: parser.error(message='missing build command') logging.debug('Parsed arguments: %s', args) exit_code, current = intercept.capture(args) # To support incremental builds, it is desired to read elements from # an existing compilation database from a previous run. if args.append and path.isfile(args.cdb): previous = compilation.CompilationDatabase.load(args.cdb) entries = iter(set(itertools.chain(previous, current))) compilation.CompilationDatabase.save(args.cdb, entries) else: compilation.CompilationDatabase.save(args.cdb, current) return exit_code