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