blob: bceae63d203ee45c90b74b929208e2185177ef61 [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'Connor23421012015-10-21 20:35:50 -04007import sys, os, subprocess, time, socket, optparse
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 -040045# Run "tool --version" for each specified tool and extract versions
46def tool_versions(tools):
47 tools = [t.strip() for t in tools.split(';')]
Kevin O'Connor23421012015-10-21 20:35:50 -040048 versions = ['', '']
Kevin O'Connorefd70a52015-10-13 15:44:25 -040049 success = 0
50 for tool in tools:
Kevin O'Connor23421012015-10-21 20:35:50 -040051 # Extract first line from "tool --version" output
Kevin O'Connorefd70a52015-10-13 15:44:25 -040052 try:
53 ver = subprocess.check_output([tool, '--version']).decode()
54 except:
55 continue
Kevin O'Connor23421012015-10-21 20:35:50 -040056 verstr = ver.split('\n')[0]
57 # Check if this tool looks like a binutils program
58 isbinutils = 0
59 if verstr.startswith('GNU '):
60 isbinutils = 1
61 verstr = verstr[4:]
62 # Extract version information and exclude program name
63 if ' ' not in verstr:
Kevin O'Connorefd70a52015-10-13 15:44:25 -040064 continue
Kevin O'Connor23421012015-10-21 20:35:50 -040065 prog, ver = verstr.split(' ', 1)
66 if not prog or not ver:
67 continue
68 # Check for any version conflicts
69 if versions[isbinutils] and versions[isbinutils] != ver:
70 vers[isbinutils] = "mixed"
71 continue
72 versions[isbinutils] = ver
73 success += 1
74 cleanbuild = versions[0] and versions[1] and success == len(tools)
75 return cleanbuild, "gcc: %s binutils: %s" % (versions[0], versions[1])
Kevin O'Connorefd70a52015-10-13 15:44:25 -040076
Kevin O'Connora6c87742015-10-13 15:09:40 -040077def main():
78 usage = "%prog [options] <outputheader.h>"
79 opts = optparse.OptionParser(usage)
80 opts.add_option("-e", "--extra", dest="extra", default="",
81 help="extra version string to append to version")
Kevin O'Connorefd70a52015-10-13 15:44:25 -040082 opts.add_option("-t", "--tools", dest="tools", default="",
Kevin O'Connor23421012015-10-21 20:35:50 -040083 help="list of build programs to extract version from")
Kevin O'Connora6c87742015-10-13 15:09:40 -040084
85 options, args = opts.parse_args()
86 if len(args) != 1:
87 opts.error("Incorrect arguments")
88 outfile = args[0]
89
Kevin O'Connorefd70a52015-10-13 15:44:25 -040090 cleanbuild, toolstr = tool_versions(options.tools)
91
Kevin O'Connora6c87742015-10-13 15:09:40 -040092 ver = git_version()
Kevin O'Connora1b4dd02015-10-13 15:49:03 -040093 cleanbuild = cleanbuild and ver and 'dirty' not in ver
Kevin O'Connora6c87742015-10-13 15:09:40 -040094 if not ver:
95 ver = file_version()
96 if not ver:
97 ver = "?"
Kevin O'Connora1b4dd02015-10-13 15:49:03 -040098 if not cleanbuild:
99 btime = time.strftime("%Y%m%d_%H%M%S")
100 hostname = socket.gethostname()
101 ver = "%s-%s-%s" % (ver, btime, hostname)
102 write_version(outfile, ver + options.extra, toolstr)
Kevin O'Connora6c87742015-10-13 15:09:40 -0400103
104if __name__ == '__main__':
105 main()