blob: 56bfcfa4bc6dd4fa83d064543a5b407e77d67bd8 [file] [log] [blame]
Kevin O'Connora6c87742015-10-13 15:09:40 -04001#!/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.
Kevin O'Connorefd70a52015-10-13 15:44:25 -04007import sys, os, subprocess, time, socket, optparse, re
Kevin O'Connora6c87742015-10-13 15:09:40 -04008
9VERSION_FORMAT = """
10/* DO NOT EDIT! This is an autogenerated file. See scripts/buildversion.py. */
11#define BUILD_VERSION "%s"
Kevin O'Connorefd70a52015-10-13 15:44:25 -040012#define BUILD_TOOLS "%s"
Kevin O'Connora6c87742015-10-13 15:09:40 -040013"""
14
15# Obtain version info from "git" program
16def git_version():
17 if not os.path.exists('.git'):
18 return ""
19 params = "git describe --tags --long --dirty".split()
20 try:
21 ver = subprocess.check_output(params).decode().strip()
22 except:
23 return ""
24 return ver
25
26# Look for version in a ".version" file
27def file_version():
28 if not os.path.isfile('.version'):
29 return ""
30 try:
31 f = open('.version', 'r')
32 ver = f.readline().strip()
33 f.close()
34 except:
35 return ""
36 return ver
37
38# Generate an output file with the version information
Kevin O'Connorefd70a52015-10-13 15:44:25 -040039def write_version(outfile, version, toolstr):
Kevin O'Connora6c87742015-10-13 15:09:40 -040040 sys.stdout.write("Version: %s\n" % (version,))
41 f = open(outfile, 'w')
Kevin O'Connorefd70a52015-10-13 15:44:25 -040042 f.write(VERSION_FORMAT % (version, toolstr))
Kevin O'Connora6c87742015-10-13 15:09:40 -040043 f.close()
44
Kevin O'Connorefd70a52015-10-13 15:44:25 -040045re_gcc = re.compile(r'^(?P<prog>.*) \(GCC\) (?P<version>.*)$')
46re_binutils = re.compile(r'^GNU (?P<prog>.*) version (?P<version>.*)$')
47
48# Run "tool --version" for each specified tool and extract versions
49def tool_versions(tools):
50 tools = [t.strip() for t in tools.split(';')]
51 gcc = binutils = ""
52 success = 0
53 for tool in tools:
54 try:
55 ver = subprocess.check_output([tool, '--version']).decode()
56 except:
57 continue
58 ver = ver.split('\n')[0]
59 m = re_gcc.match(ver)
60 if m:
61 ver = m.group('version')
62 if gcc and gcc != ver:
63 gcc = "mixed"
64 continue
65 gcc = ver
66 success += 1
67 continue
68 m = re_binutils.match(ver)
69 if m:
70 ver = m.group('version')
71 if binutils and binutils != ver:
72 binutils = "mixed"
73 continue
74 binutils = ver
75 success += 1
76 cleanbuild = binutils and gcc and success == len(tools)
77 return cleanbuild, "gcc: %s binutils: %s" % (gcc, binutils)
78
Kevin O'Connora6c87742015-10-13 15:09:40 -040079def main():
80 usage = "%prog [options] <outputheader.h>"
81 opts = optparse.OptionParser(usage)
82 opts.add_option("-e", "--extra", dest="extra", default="",
83 help="extra version string to append to version")
Kevin O'Connorefd70a52015-10-13 15:44:25 -040084 opts.add_option("-t", "--tools", dest="tools", default="",
85 help="list of build programs to extra version from")
Kevin O'Connora6c87742015-10-13 15:09:40 -040086
87 options, args = opts.parse_args()
88 if len(args) != 1:
89 opts.error("Incorrect arguments")
90 outfile = args[0]
91
Kevin O'Connorefd70a52015-10-13 15:44:25 -040092 cleanbuild, toolstr = tool_versions(options.tools)
93
Kevin O'Connora6c87742015-10-13 15:09:40 -040094 ver = git_version()
95 if not ver:
96 ver = file_version()
97 if not ver:
98 ver = "?"
99 btime = time.strftime("%Y%m%d_%H%M%S")
100 hostname = socket.gethostname()
101 ver = "%s-%s-%s%s" % (ver, btime, hostname, options.extra)
Kevin O'Connorefd70a52015-10-13 15:44:25 -0400102 write_version(outfile, ver, toolstr)
Kevin O'Connora6c87742015-10-13 15:09:40 -0400103
104if __name__ == '__main__':
105 main()