historical_build.py 3.61 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/usr/bin/env python2

import os
import sys
import logging
import time

tmp_path = "%s/git/versuchung/src"% os.environ["HOME"]
if os.path.exists(tmp_path):
    sys.path.append(tmp_path)

from versuchung.experiment import Experiment
from versuchung.types import String, Bool,Integer
from versuchung.files import File, Directory
from versuchung.archives import GitArchive
from versuchung.execute import shell
from versuchung.tex import DatarefDict
from lib import ClangHashHelper

class HistoricalCompilation(Experiment, ClangHashHelper):
    inputs = {
        "clang_hash": GitArchive("/home/stettberger/w/clang-hash/"),
        "project": GitArchive("/home/stettberger/w/clang-hash/hash-projects/lua"),
        "mode": String("normal"),
25
        "commits": Integer(500),
26
27
28
29
30
31
32
33
        "jobs": Integer(4),
    }
    outputs = {
        "stats": File("summary.dict"),
    }

    def run(self):
        # Determine the mode
34
        modes = ('normal', 'ccache', 'clang-hash', 'ccache-clang-hash')
35
36
37
38
39
        if not self.mode.value in modes:
            raise RuntimeError("Mode can only be one of: %s"%modes)

        logging.info("Build the Clang-Hash Plugin")
        with self.clang_hash as cl_path:
40
            shell("cd %s; mkdir build; cd build; cmake .. -DCMAKE_BUILD_TYPE=Release; make -j 4", cl_path)
41
            shell("strip %s/build/src/*.so", cl_path)
42
43
44
45
46
47
48
49

        # Project name
        logging.info("Cloning project... %s", self.project_name())
        self.build_info = {"project-name": self.project_name(),
                           "commit-hash": self.metadata["project-hash"],
                           'builds': []}

        with self.project as src_path:
50
            (commits, _) = shell("cd %s; git log --oneline --topo-order", src_path)
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
            commits = [x.split(" ", 1) for x in reversed(commits)]
            commits = commits[-self.commits.value:]

            # First, we redirect all calls to the compiler to our
            # clang hash wrapper
            self.setup_compiler_paths(cl_path)

            while True:
                commit = commits.pop(0)
                logging.info("Build: %s", commit)
                shell("cd %s; git clean -dfx; git reset --hard %s", src_path, commit[0])
                info = {"commit": "FRESH_BUILD"}
                            # Initial build of the given project
                self.call_configure(src_path)
                self.rebuild(src_path, info, True)
                # Did initial commit fail? Try again
                if "failed" in info:
                    continue
                self.build_info["builds"].append(info)
                break

            time = 0
            for commit in commits:
                shell("cd %s; git reset --hard %s", src_path, commit[0])
                info = {"commit": commit[0], "summary": commit[1]}
                if self.project_name() == "lua":
                    self.call_configure(src_path)
                self.rebuild(src_path, info, fail_ok=True)
                self.build_info["builds"].append(info)
                if not info.get("failed"):
                    time += info['build-time'] / 1e9
            logging.info("Rebuild for %d commits takes %f minutes",
                         self.commits.value, time/60.)

        # Output the summary of this build into the statistics file.
        with open(self.stats.path, "w+") as fd:
            fd.write(repr(self.build_info))

    def variant_name(self):
        return "%s-%s"%(self.project_name(), self.metadata['mode'])

    def symlink_name(self):
        return "%s-%s"%(self.title, self.variant_name())


if __name__ == "__main__":
    experiment = HistoricalCompilation()
    dirname = experiment(sys.argv)