2 # SPDX-License-Identifier: BSD-3-Clause
3 # Copyright(c) 2021 Intel Corporation
9 from os.path import abspath, relpath, join
10 from pathlib import Path
11 from mesonbuild import mesonmain
15 "parse arguments and return the argument object back to main"
16 parser = argparse.ArgumentParser(description="This script can be used to remove includes which are not in use\n")
17 parser.add_argument('-b', '--build_dir', type=str, default='build',
18 help="The path to the build directory in which the IWYU tool was used in.")
19 parser.add_argument('-d', '--sub_dir', type=str, default='',
20 help="The sub-directory to remove headers from.")
21 parser.add_argument('file', type=Path,
22 help="The path to the IWYU log file or output from stdin.")
24 return parser.parse_args()
28 "Runs a meson command logging output to process-iwyu.log"
29 with open('process-iwyu.log', 'a') as sys.stdout:
30 ret = mesonmain.run(args, abspath('meson'))
31 sys.stdout = sys.__stdout__
35 def remove_includes(filepath, include, build_dir):
36 "Attempts to remove include, if it fails then revert to original state"
37 with open(filepath) as f:
38 lines = f.readlines() # Read lines when file is opened
40 with open(filepath, 'w') as f:
41 for ln in lines: # Removes the include passed in
42 if not ln.startswith(include):
45 # run test build -> call meson on the build folder, meson compile -C build
46 ret = run_meson(['compile', '-C', build_dir])
47 if (ret == 0): # Include is not needed -> build is successful
50 # failed, catch the error
51 # return file to original state
52 with open(filepath, 'w') as f:
57 def get_build_config(builddir, condition):
58 "returns contents of rte_build_config.h"
59 with open(join(builddir, 'rte_build_config.h')) as f:
60 return [ln for ln in f.readlines() if condition(ln)]
63 def uses_libbsd(builddir):
64 "return whether the build uses libbsd or not"
65 return bool(get_build_config(builddir, lambda ln: 'RTE_USE_LIBBSD' in ln))
69 "process the iwyu output on a set of files"
71 build_dir = abspath(args.build_dir)
72 directory = args.sub_dir
74 print("Warning: The results of this script may include false positives which are required for different systems",
77 keep_str_fns = uses_libbsd(build_dir) # check for libbsd
79 print("Warning: libbsd is present, build will fail to detect incorrect removal of rte_string_fns.h",
82 run_meson(['configure', build_dir, '-Dwerror=true'])
83 # Use stdin if no iwyu_tool out file given
84 for line in fileinput.input(args.file):
85 if 'should remove' in line:
86 # If the file path in the iwyu_tool output is an absolute path it
87 # means the file is outside of the dpdk directory, therefore ignore it.
88 # Also check to see if the file is within the specified sub directory.
89 filename = line.split()[0]
90 if (filename != abspath(filename) and
91 directory in filename):
92 filepath = relpath(join(build_dir, filename))
93 elif line.startswith('-') and filepath:
94 include = '#include ' + line.split()[2]
95 print(f"Remove {include} from {filepath} ... ", end='', flush=True)
96 if keep_str_fns and '<rte_string_fns.h>' in include:
99 remove_includes(filepath, include, build_dir)
105 process(args_parse())
108 if __name__ == '__main__':