These changes are the raw update to qemu-2.6.
[kvmfornfv.git] / qemu / roms / seabios / scripts / buildversion.py
1 #!/usr/bin/env python
2 # Generate version information for a program
3 #
4 # Copyright (C) 2015  Kevin O'Connor <kevin@koconnor.net>
5 #
6 # This file may be distributed under the terms of the GNU GPLv3 license.
7 import sys, os, subprocess, shlex, time, socket, optparse, logging, traceback
8
9 VERSION_FORMAT = """
10 /* DO NOT EDIT!  This is an autogenerated file.  See scripts/buildversion.py. */
11 #define BUILD_VERSION "%s"
12 #define BUILD_TOOLS "%s"
13 """
14
15 # Run program and return the specified output
16 def check_output(prog):
17     logging.debug("Running %s" % (repr(prog),))
18     try:
19         process = subprocess.Popen(shlex.split(prog), stdout=subprocess.PIPE)
20         output = process.communicate()[0]
21         retcode = process.poll()
22     except OSError:
23         logging.debug("Exception on run: %s" % (traceback.format_exc(),))
24         return ""
25     logging.debug("Got (code=%s): %s" % (retcode, repr(output)))
26     if retcode:
27         return ""
28     try:
29         return output.decode()
30     except UnicodeError:
31         logging.debug("Exception on decode: %s" % (traceback.format_exc(),))
32         return ""
33
34 # Obtain version info from "git" program
35 def git_version():
36     if not os.path.exists('.git'):
37         logging.debug("No '.git' file/directory found")
38         return ""
39     ver = check_output("git describe --tags --long --dirty").strip()
40     logging.debug("Got git version: %s" % (repr(ver),))
41     return ver
42
43 # Look for version in a ".version" file.  Official release tarballs
44 # have this file (see scripts/tarball.sh).
45 def file_version():
46     if not os.path.isfile('.version'):
47         logging.debug("No '.version' file found")
48         return ""
49     try:
50         f = open('.version', 'r')
51         ver = f.readline().strip()
52         f.close()
53     except OSError:
54         logging.debug("Exception on read: %s" % (traceback.format_exc(),))
55         return ""
56     logging.debug("Got .version: %s" % (repr(ver),))
57     return ver
58
59 # Generate an output file with the version information
60 def write_version(outfile, version, toolstr):
61     logging.debug("Write file %s and %s" % (repr(version), repr(toolstr)))
62     sys.stdout.write("Version: %s\n" % (version,))
63     f = open(outfile, 'w')
64     f.write(VERSION_FORMAT % (version, toolstr))
65     f.close()
66
67 # Run "tool --version" for each specified tool and extract versions
68 def tool_versions(tools):
69     tools = [t.strip() for t in tools.split(';')]
70     versions = ['', '']
71     success = 0
72     for tool in tools:
73         # Extract first line from "tool --version" output
74         verstr = check_output("%s --version" % (tool,)).split('\n')[0]
75         # Check if this tool looks like a binutils program
76         isbinutils = 0
77         if verstr.startswith('GNU '):
78             isbinutils = 1
79             verstr = verstr[4:]
80         # Extract version information and exclude program name
81         if ' ' not in verstr:
82             continue
83         prog, ver = verstr.split(' ', 1)
84         if not prog or not ver:
85             continue
86         # Check for any version conflicts
87         if versions[isbinutils] and versions[isbinutils] != ver:
88             logging.debug("Mixed version %s vs %s" % (
89                 repr(versions[isbinutils]), repr(ver)))
90             versions[isbinutils] = "mixed"
91             continue
92         versions[isbinutils] = ver
93         success += 1
94     cleanbuild = versions[0] and versions[1] and success == len(tools)
95     return cleanbuild, "gcc: %s binutils: %s" % (versions[0], versions[1])
96
97 def main():
98     usage = "%prog [options] <outputheader.h>"
99     opts = optparse.OptionParser(usage)
100     opts.add_option("-e", "--extra", dest="extra", default="",
101                     help="extra version string to append to version")
102     opts.add_option("-t", "--tools", dest="tools", default="",
103                     help="list of build programs to extract version from")
104     opts.add_option("-v", action="store_true", dest="verbose",
105                     help="enable debug messages")
106
107     options, args = opts.parse_args()
108     if len(args) != 1:
109         opts.error("Incorrect arguments")
110     outfile = args[0]
111     if options.verbose:
112         logging.basicConfig(level=logging.DEBUG)
113
114     cleanbuild, toolstr = tool_versions(options.tools)
115
116     ver = git_version()
117     cleanbuild = cleanbuild and 'dirty' not in ver
118     if not ver:
119         ver = file_version()
120         # We expect the "extra version" to contain information on the
121         # distributor and distribution package version (if
122         # applicable).  It is a "clean" build if this is a build from
123         # an official release tarball and the above info is present.
124         cleanbuild = cleanbuild and ver and options.extra != ""
125         if not ver:
126             ver = "?"
127     if not cleanbuild:
128         btime = time.strftime("%Y%m%d_%H%M%S")
129         hostname = socket.gethostname()
130         ver = "%s-%s-%s" % (ver, btime, hostname)
131     write_version(outfile, ver + options.extra, toolstr)
132
133 if __name__ == '__main__':
134     main()