1import argparse
2import os
3import sys
4
5from subprocess import call, check_call, CalledProcessError
6from time import sleep
7from typing import List, Tuple
8
9
10def main():
11    settings, rest = parse_arguments()
12    cmake_opts = ['-D' + cmd for cmd in settings.D]
13    if settings.wait:
14        wait()
15    if settings.build_llvm or settings.build_llvm_only:
16        build_llvm(cmake_opts)
17    if settings.build_llvm_only:
18        return
19    sys.exit(test(rest))
20
21
22def wait():
23    # It is an easy on CPU way of keeping the docker container running
24    # while the user has a terminal session in that container.
25    while True:
26        sleep(3600)
27
28
29def parse_arguments() -> Tuple[argparse.Namespace, List[str]]:
30    parser = argparse.ArgumentParser()
31    parser.add_argument('--wait', action='store_true')
32    parser.add_argument('--build-llvm', action='store_true')
33    parser.add_argument('--build-llvm-only', action='store_true')
34    parser.add_argument('-D', action='append', default=[])
35    return parser.parse_known_args()
36
37
38def build_llvm(cmake_options):
39    os.chdir('/build')
40    try:
41        if is_cmake_needed():
42            cmake(cmake_options)
43        ninja()
44    except CalledProcessError:
45        print("Build failed!")
46        sys.exit(1)
47
48
49def is_cmake_needed():
50    return "build.ninja" not in os.listdir()
51
52
53CMAKE_COMMAND = "cmake -G Ninja -DCMAKE_BUILD_TYPE=Release " \
54    "-DCMAKE_INSTALL_PREFIX=/analyzer -DLLVM_TARGETS_TO_BUILD=X86 " \
55    "-DLLVM_ENABLE_PROJECTS=\"clang;openmp\" -DLLVM_BUILD_RUNTIME=OFF " \
56    "-DLLVM_ENABLE_TERMINFO=OFF -DCLANG_ENABLE_ARCMT=OFF " \
57    "-DCLANG_ENABLE_STATIC_ANALYZER=ON"
58
59
60def cmake(cmake_options):
61    check_call(CMAKE_COMMAND + ' '.join(cmake_options) + ' /llvm-project/llvm',
62            shell=True)
63
64
65def ninja():
66    check_call("ninja install", shell=True)
67
68
69def test(args: List[str]) -> int:
70    os.chdir("/projects")
71    return call("/scripts/SATest.py " + " ".join(args), shell=True)
72
73
74if __name__ == '__main__':
75    main()
76