1# 2# Copyright (C) 2023 The Android Open Source Project 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16""" 17This script helps to generate source based code coverage report. 18 19Usage: 20 python genReport.py --objects [OBJECTS] --format [FORMAT] 21 22""" 23 24import argparse 25import os 26import subprocess 27import sys 28import pathlib 29 30def genProfdata(files, llvmDir): 31 llvmProfdataBin = str(str(os.path.join(llvmDir, "./llvm-profdata"))) 32 subprocess_cmd = [llvmProfdataBin, 'merge'] 33 34 subprocess_cmd.extend(files) 35 subprocess_cmd.extend(['-o=out.profdata']) 36 37 subprocess.call(subprocess_cmd) 38 39def genHtml(llvmDir, objects, out): 40 llvmCovBin = str(str(os.path.join(llvmDir, "./llvm-cov"))) 41 subprocess_cmd = [llvmCovBin, 'show', '-instr-profile=out.profdata', '-object'] 42 43 subprocess_cmd.extend(objects) 44 subprocess_cmd.extend(['-use-color', '--format=html']) 45 with(open(out+".html", "w")) as f: 46 output = subprocess.call(subprocess_cmd, stdout=f) 47 48def genJson(llvmDir, objects, out): 49 llvmCovBin = str(str(os.path.join(llvmDir, "./llvm-cov"))) 50 subprocess_cmd = [llvmCovBin, 'export', '-summary-only', 51 '-instr-profile=out.profdata', '-object'] 52 53 subprocess_cmd.extend(objects) 54 with(open(out+".json", "w")) as f: 55 output = subprocess.call(subprocess_cmd, stdout=f) 56 57 58def main(): 59 arg_parser = argparse.ArgumentParser() 60 61 arg_parser.add_argument( 62 '--objects', 63 type=str, 64 required=True, 65 nargs='+', 66 help='List the elf files which are included in the test') 67 68 arg_parser.add_argument( 69 '--format', 70 type=str, 71 default='html', 72 help='Output format of the "llvm-cov show/export" command. The ' 73 'supported formats are "text", "html" and "lcov".') 74 75 arg_parser.add_argument( 76 '--llvm-dir', 77 type=str, 78 default="prebuilts/clang/host/linux-x86/llvm-binutils-stable/", 79 help='Provide path to LLVM binary directory to override the default one') 80 81 arg_parser.add_argument( 82 '--profraw-dir', 83 type=str, 84 default="tmp/", 85 help='Provide path to directory containing .profraw files') 86 87 arg_parser.add_argument( 88 '--output', 89 type=str, 90 default="out", 91 help='provide output filename(without extension)') 92 93 94 args = arg_parser.parse_args() 95 96 if (not os.path.isdir(args.llvm_dir)): 97 print("Provide path to LLVM binary directory") 98 return 99 100 if (not os.path.isdir(args.profraw_dir)): 101 print("Provide path to directory containing .profraw files") 102 return 103 104 profrawFiles = [str(os.path.join(args.profraw_dir, f)) 105 for f in os.listdir(args.profraw_dir) if f.endswith('.profraw')] 106 if (len(profrawFiles) == 0): 107 print("No profraw files found in directory " + args.profraw_dir) 108 109 genProfdata(profrawFiles, args.llvm_dir) 110 111 if (args.format == "html"): 112 genHtml(args.llvm_dir, args.objects, args.output) 113 114 elif (args.format == "json"): 115 genJson(args.llvm_dir, args.objects, args.output) 116 117 else: 118 print("Only json and html supported") 119 return 120 121if __name__ == '__main__': 122 sys.exit(main())