diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /build/clang-plugin/import_mozilla_checks.py | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'build/clang-plugin/import_mozilla_checks.py')
-rwxr-xr-x | build/clang-plugin/import_mozilla_checks.py | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/build/clang-plugin/import_mozilla_checks.py b/build/clang-plugin/import_mozilla_checks.py new file mode 100755 index 0000000000..d573dafcf1 --- /dev/null +++ b/build/clang-plugin/import_mozilla_checks.py @@ -0,0 +1,177 @@ +#!/usr/bin/python3 +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +import errno +import glob +import os +import shutil + +import ThirdPartyPaths +import ThreadAllows + + +def copy_dir_contents(src, dest): + for f in glob.glob("%s/*" % src): + try: + destname = "%s/%s" % (dest, os.path.basename(f)) + if os.path.isdir(f): + shutil.copytree(f, destname) + else: + shutil.copy2(f, destname) + except OSError as e: + if e.errno == errno.ENOTDIR: + shutil.copy2(f, destname) + elif e.errno == errno.EEXIST: + if os.path.isdir(f): + copy_dir_contents(f, destname) + else: + os.remove(destname) + shutil.copy2(f, destname) + else: + raise Exception("Directory not copied. Error: %s" % e) + + +def write_cmake(module_path, import_options): + names = [" " + os.path.basename(f) for f in glob.glob("%s/*.cpp" % module_path)] + + if import_options["external"]: + names += [ + " " + os.path.join("external", os.path.basename(f)) + for f in glob.glob("%s/external/*.cpp" % (module_path)) + ] + + if import_options["alpha"]: + names += [ + " " + os.path.join("alpha", os.path.basename(f)) + for f in glob.glob("%s/alpha/*.cpp" % (module_path)) + ] + + with open(os.path.join(module_path, "CMakeLists.txt"), "w") as f: + f.write( + """set(LLVM_LINK_COMPONENTS support) + +add_definitions( -DCLANG_TIDY ) + +add_clang_library(clangTidyMozillaModule + ThirdPartyPaths.cpp +%(names)s + + LINK_LIBS + clangTidy + clangTidyReadabilityModule + clangTidyUtils + clangTidyMPIModule + ) + +clang_target_link_libraries(clangTidyMozillaModule + PRIVATE + clangAST + clangASTMatchers + clangBasic + clangLex + )""" + % {"names": "\n".join(names)} + ) + + +def add_moz_module(cmake_path): + with open(cmake_path, "r") as f: + lines = f.readlines() + f.close() + + try: + idx = lines.index("set(ALL_CLANG_TIDY_CHECKS\n") + lines.insert(idx + 1, " clangTidyMozillaModule\n") + + with open(cmake_path, "w") as f: + for line in lines: + f.write(line) + except ValueError: + raise Exception("Unable to find ALL_CLANG_TIDY_CHECKS in {}".format(cmake_path)) + + +def write_third_party_paths(mozilla_path, module_path): + tpp_txt = os.path.join(mozilla_path, "../../tools/rewriting/ThirdPartyPaths.txt") + generated_txt = os.path.join(mozilla_path, "../../tools/rewriting/Generated.txt") + with open(os.path.join(module_path, "ThirdPartyPaths.cpp"), "w") as f: + ThirdPartyPaths.generate(f, tpp_txt, generated_txt) + + +def generate_thread_allows(mozilla_path, module_path): + names = os.path.join(mozilla_path, "../../build/clang-plugin/ThreadAllows.txt") + files = os.path.join(mozilla_path, "../../build/clang-plugin/ThreadFileAllows.txt") + with open(os.path.join(module_path, "ThreadAllows.h"), "w") as f: + f.write( + ThreadAllows.generate_allows(allowed_names=[names], allowed_files=[files]) + ) + + +def do_import(mozilla_path, clang_tidy_path, import_options): + module = "mozilla" + module_path = os.path.join(clang_tidy_path, module) + try: + os.makedirs(module_path) + except OSError as e: + if e.errno != errno.EEXIST: + raise + + copy_dir_contents(mozilla_path, module_path) + write_third_party_paths(mozilla_path, module_path) + generate_thread_allows(mozilla_path, module_path) + write_cmake(module_path, import_options) + add_moz_module(os.path.join(module_path, "..", "CMakeLists.txt")) + with open(os.path.join(module_path, "..", "CMakeLists.txt"), "a") as f: + f.write("add_subdirectory(%s)\n" % module) + # A better place for this would be in `ClangTidyForceLinker.h` but `ClangTidyMain.cpp` + # is also OK. + with open(os.path.join(module_path, "..", "tool", "ClangTidyMain.cpp"), "a") as f: + f.write( + """ +// This anchor is used to force the linker to link the MozillaModule. +extern volatile int MozillaModuleAnchorSource; +static int LLVM_ATTRIBUTE_UNUSED MozillaModuleAnchorDestination = + MozillaModuleAnchorSource; +""" + ) + + +def main(): + import argparse + + parser = argparse.ArgumentParser( + usage="import_mozilla_checks.py <mozilla-clang-plugin-path> <clang-tidy-path> [option]", + description="Imports the Mozilla static analysis checks into a clang-tidy source tree.", + ) + parser.add_argument( + "mozilla_path", help="Full path to mozilla-central/build/clang-plugin" + ) + parser.add_argument( + "clang_tidy_path", help="Full path to llvm-project/clang-tools-extra/clang-tidy" + ) + parser.add_argument( + "--import-alpha", + help="Enable import of in-tree alpha checks", + action="store_true", + ) + parser.add_argument( + "--import-external", + help="Enable import of in-tree external checks", + action="store_true", + ) + args = parser.parse_args() + + if not os.path.isdir(args.mozilla_path): + print("Invalid path to mozilla clang plugin") + + if not os.path.isdir(args.clang_tidy_path): + print("Invalid path to clang-tidy source directory") + + import_options = {"alpha": args.import_alpha, "external": args.import_external} + + do_import(args.mozilla_path, args.clang_tidy_path, import_options) + + +if __name__ == "__main__": + main() |