Port versioning to AMBuild 2 (bug 5997 part 8, r=ds).
1.1 --- a/AMBuildScript Mon Dec 30 17:50:59 2013 -0500
1.2 +++ b/AMBuildScript Mon Dec 30 17:50:59 2013 -0500
1.3 @@ -63,11 +63,26 @@
1.4 self.sdks = {}
1.5 self.binaries = []
1.6 self.extensions = []
1.7 + self.generated_headers = None
1.8 self.mms_root = None
1.9 self.mysql_root = None
1.10 self.spcomp = None
1.11 self.smx_files = {}
1.12
1.13 + def detectProductVersion(self):
1.14 + builder.AddConfigureFile('product.version')
1.15 +
1.16 + # For OS X dylib versioning
1.17 + import re
1.18 + with open(os.path.join(builder.sourcePath, 'product.version'), 'r') as fp:
1.19 + productContents = fp.read()
1.20 + m = re.match('(\d+)\.(\d+)\.(\d+).*', productContents)
1.21 + if m == None:
1.22 + self.productVersion = '1.0.0'
1.23 + else:
1.24 + major, minor, release = m.groups()
1.25 + self.productVersion = '{0}.{1}.{2}'.format(major, minor, release)
1.26 +
1.27 def detectSDKs(self):
1.28 sdk_list = builder.options.sdks.split(',')
1.29 use_all = sdk_list[0] == 'all'
1.30 @@ -229,15 +244,35 @@
1.31 # Finish up.
1.32 cfg.defines += [
1.33 'SOURCEMOD_BUILD',
1.34 + 'SM_GENERATED_BUILD',
1.35 ]
1.36 cfg.includes += [os.path.join(builder.buildPath, 'includes')]
1.37
1.38 def LibraryBuilder(self, compiler, name):
1.39 binary = compiler.Library(name)
1.40 + if builder.target_platform == 'windows':
1.41 + binary.sources += ['version.rc']
1.42 + binary.compiler.rcdefines += [
1.43 + 'BINARY_NAME="{0}"'.format(binary.outputFile),
1.44 + 'SM_GENERATED_BUILD'
1.45 + ]
1.46 + elif builder.target_platform == 'mac':
1.47 + binary.compiler.postlink += [
1.48 + '-compatibility_version', '1.0.0',
1.49 + '-current_version', self.productVersion
1.50 + ]
1.51 + binary.compiler.sourcedeps += SM.generated_headers
1.52 return binary
1.53
1.54 def ProgramBuilder(self, compiler, name):
1.55 binary = compiler.Program(name)
1.56 + if builder.target_platform == 'windows':
1.57 + binary.sources += ['version.rc']
1.58 + binary.compiler.rcdefines += [
1.59 + 'BINARY_NAME="{0}"'.format(binary.outputFile),
1.60 + 'SM_GENERATED_BUILD'
1.61 + ]
1.62 + binary.compiler.sourcedeps += SM.generated_headers
1.63 return binary
1.64
1.65 def Library(self, context, name):
1.66 @@ -389,9 +424,15 @@
1.67 return binary
1.68
1.69 SM = SMConfig()
1.70 +SM.detectProductVersion()
1.71 SM.detectSDKs()
1.72 SM.configure()
1.73
1.74 +SM.generated_headers = builder.RunScript(
1.75 + 'tools/buildbot/Versioning',
1.76 + { 'SM': SM }
1.77 +)
1.78 +
1.79 builder.RunBuildScripts(
1.80 [
1.81 'loader/AMBuilder',
2.1 --- a/plugins/AMBuilder Mon Dec 30 17:50:59 2013 -0500
2.2 +++ b/plugins/AMBuilder Mon Dec 30 17:50:59 2013 -0500
2.3 @@ -30,6 +30,8 @@
2.4 spcomp_argv = [
2.5 os.path.join(builder.buildPath, SM.spcomp.binary.path),
2.6 'SM_GENERATED_BUILD=',
2.7 + '-i' + os.path.relpath(os.path.join(builder.buildPath, 'includes'),
2.8 + os.path.join(builder.buildPath, builder.buildFolder)),
2.9 '-i' + os.path.relpath(os.path.join(builder.sourcePath, 'plugins', 'include'),
2.10 os.path.join(builder.buildPath, builder.buildFolder)),
2.11 '-h',
2.12 @@ -48,7 +50,8 @@
2.13 inputs = inputs,
2.14 argv = argv,
2.15 outputs = outputs,
2.16 - dep_type = 'msvc'
2.17 + dep_type = 'msvc',
2.18 + weak_inputs = SM.generated_headers
2.19 )
2.20 SM.smx_files[smx_file] = smx_entry
2.21
3.1 --- a/tools/buildbot/Versioning Mon Dec 30 17:50:59 2013 -0500
3.2 +++ b/tools/buildbot/Versioning Mon Dec 30 17:50:59 2013 -0500
3.3 @@ -1,89 +1,34 @@
3.4 -# vim: set ts=2 sw=2 tw=99 noet ft=python:
3.5 -import os
3.6 -import re
3.7 -import subprocess
3.8 -from ambuild.cache import Cache
3.9 -import ambuild.command as command
3.10 +# vim: set ts=8 sts=2 sw=2 tw=99 et ft=python:
3.11 +import os, sys
3.12
3.13 -#Quickly try to ascertain the current repository revision
3.14 -def GetVersion():
3.15 - args = ['hg', 'parent', '-R', AMBuild.sourceFolder]
3.16 - p = command.RunDirectCommand(AMBuild, args)
3.17 - m = re.match('changeset:\s+(\d+):(.+)', p.stdoutText)
3.18 - if m == None:
3.19 - raise Exception('Could not determine repository version')
3.20 - return m.groups()
3.21 +builder.SetBuildFolder('/')
3.22
3.23 -def PerformReversioning():
3.24 - rev, cset = GetVersion()
3.25 - cacheFile = os.path.join(AMBuild.outputFolder, '.ambuild', 'hgcache')
3.26 - cache = Cache(cacheFile)
3.27 - if os.path.isfile(cacheFile):
3.28 - cache.LoadCache()
3.29 - if cache.HasVariable('cset') and cache['cset'] == cset:
3.30 - return False
3.31 - cache.CacheVariable('cset', cset)
3.32 +includes = builder.AddFolder('includes')
3.33
3.34 - productFile = open(os.path.join(AMBuild.sourceFolder, 'product.version'), 'r')
3.35 - productContents = productFile.read()
3.36 - productFile.close()
3.37 - m = re.match('(\d+)\.(\d+)\.(\d+)-?(.*)', productContents)
3.38 - if m == None:
3.39 - raise Exception('Could not detremine product version')
3.40 - major, minor, release, tag = m.groups()
3.41 -
3.42 - fullstring = "{0}.{1}.{2}".format(major, minor, release)
3.43 - if tag != "":
3.44 - fullstring += "-{0}".format(tag)
3.45 - if tag == "dev":
3.46 - fullstring += "+{0}".format(rev)
3.47 -
3.48 - incFolder = os.path.join(AMBuild.outputFolder, 'includes')
3.49 - if not os.path.isdir(incFolder):
3.50 - os.makedirs(incFolder)
3.51 - incFile = open(os.path.join(incFolder, 'sourcemod_version_auto.h'), 'w')
3.52 - incFile.write("""
3.53 -#ifndef _SOURCEMOD_AUTO_VERSION_INFORMATION_H_
3.54 -#define _SOURCEMOD_AUTO_VERSION_INFORMATION_H_
3.55 +argv = [
3.56 + sys.executable,
3.57 + os.path.join(builder.sourcePath, 'tools', 'buildbot', 'generate_headers.py'),
3.58 + os.path.join(builder.sourcePath),
3.59 + os.path.join(builder.buildPath, 'includes'),
3.60 +]
3.61 +outputs = [
3.62 + os.path.join(builder.buildFolder, 'includes', 'sourcemod_version_auto.h'),
3.63 + os.path.join(builder.buildFolder, 'includes', 'version_auto.inc'),
3.64 +]
3.65
3.66 -#define SM_BUILD_TAG \"{0}\"
3.67 -#define SM_BUILD_REV \"{1}\"
3.68 -#define SM_BUILD_CSET \"{2}\"
3.69 -#define SM_BUILD_MAJOR \"{3}\"
3.70 -#define SM_BUILD_MINOR \"{4}\"
3.71 -#define SM_BUILD_RELEASE \"{5}\"
3.72 -
3.73 -#define SM_BUILD_UNIQUEID SM_BUILD_REV \":\" SM_BUILD_CSET
3.74 +sources = [
3.75 + os.path.join(builder.sourcePath, 'product.version'),
3.76
3.77 -#define SM_VERSION_STRING \"{6}\"
3.78 -#define SM_VERSION_FILE {7},{8},{9},0
3.79 -
3.80 -#endif /* _SOURCEMOD_AUTO_VERSION_INFORMATION_H_ */
3.81 -
3.82 -""".format(tag, rev, cset, major, minor, release, fullstring, major, minor, release))
3.83 - incFile.close()
3.84 -
3.85 - incFile = open(os.path.join(incFolder, 'version_auto.inc'), 'w')
3.86 - incFile.write("""
3.87 -#if defined _auto_version_included
3.88 - #endinput
3.89 -#endif
3.90 -#define _auto_version_included
3.91 + # This is a hack, but we need some way to only run this script when HG changes.
3.92 + os.path.join(builder.sourcePath, '.hg', 'dirstate'),
3.93
3.94 -#define SOURCEMOD_V_TAG \"{0}\"
3.95 -#define SOURCEMOD_V_REV {1}
3.96 -#define SOURCEMOD_V_CSET \"{2}\"
3.97 -#define SOURCEMOD_V_MAJOR {3}
3.98 -#define SOURCEMOD_V_MINOR {4}
3.99 -#define SOURCEMOD_V_RELEASE {5}
3.100 -
3.101 -#define SOURCEMOD_VERSION \"{6}\"
3.102 + # The script source is a dependency, of course...
3.103 + argv[1]
3.104 +]
3.105 +cmd_node, output_nodes = builder.AddCommand(
3.106 + inputs=sources,
3.107 + argv=argv,
3.108 + outputs=outputs
3.109 +)
3.110
3.111 -""".format(tag, rev, cset, major, minor, release, fullstring))
3.112 - incFile.close()
3.113 -
3.114 - cache.WriteCache()
3.115 -
3.116 -PerformReversioning()
3.117 -
3.118 -
3.119 +rvalue = output_nodes
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/tools/buildbot/generate_headers.py Mon Dec 30 17:50:59 2013 -0500
4.3 @@ -0,0 +1,87 @@
4.4 +# vim: set ts=8 sts=2 sw=2 tw=99 et:
4.5 +import re
4.6 +import os, sys
4.7 +import subprocess
4.8 +
4.9 +argv = sys.argv[1:]
4.10 +if len(argv) < 2:
4.11 + sys.stderr.write('Usage: generate_headers.py <source_path> <output_folder>\n')
4.12 + sys.exit(1)
4.13 +
4.14 +SourceFolder = os.path.abspath(os.path.normpath(argv[0]))
4.15 +OutputFolder = os.path.normpath(argv[1])
4.16 +
4.17 +def get_hg_version():
4.18 + argv = ['hg', 'parent', '-R', SourceFolder]
4.19 +
4.20 + # Python 2.6 doesn't have check_output.
4.21 + if hasattr(subprocess, 'check_output'):
4.22 + text = subprocess.check_output(argv)
4.23 + if str != bytes:
4.24 + text = str(text, 'utf-8')
4.25 + else:
4.26 + p = subprocess.Popen(argv, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
4.27 + output, ignored = p.communicate()
4.28 + rval = p.poll()
4.29 + if rval:
4.30 + raise subprocess.CalledProcessError(rval, argv)
4.31 + text = output.decode('utf8')
4.32 +
4.33 + m = re.match('changeset:\s+(\d+):(.+)', text)
4.34 + if m == None:
4.35 + raise Exception('Could not determine repository version')
4.36 + return m.groups()
4.37 +
4.38 +def output_version_headers():
4.39 + cset, rev = get_hg_version()
4.40 +
4.41 + with open(os.path.join(SourceFolder, 'product.version')) as fp:
4.42 + contents = fp.read()
4.43 + m = re.match('(\d+)\.(\d+)\.(\d+)-?(.*)', contents)
4.44 + if m == None:
4.45 + raise Exception('Could not detremine product version')
4.46 + major, minor, release, tag = m.groups()
4.47 + fullstring = "{0}.{1}.{2}".format(major, minor, release)
4.48 + if tag != "":
4.49 + fullstring += "-{0}".format(tag)
4.50 + if tag == "dev":
4.51 + fullstring += "+{0}".format(rev)
4.52 +
4.53 + with open(os.path.join(OutputFolder, 'sourcemod_version_auto.h'), 'w') as fp:
4.54 + fp.write("""
4.55 +#ifndef _SOURCEMOD_AUTO_VERSION_INFORMATION_H_
4.56 +#define _SOURCEMOD_AUTO_VERSION_INFORMATION_H_
4.57 +
4.58 +#define SM_BUILD_TAG \"{0}\"
4.59 +#define SM_BUILD_REV \"{1}\"
4.60 +#define SM_BUILD_CSET \"{2}\"
4.61 +#define SM_BUILD_MAJOR \"{3}\"
4.62 +#define SM_BUILD_MINOR \"{4}\"
4.63 +#define SM_BUILD_RELEASE \"{5}\"
4.64 +
4.65 +#define SM_BUILD_UNIQUEID SM_BUILD_REV \":\" SM_BUILD_CSET
4.66 +
4.67 +#define SM_VERSION_STRING \"{6}\"
4.68 +#define SM_VERSION_FILE {7},{8},{9},0
4.69 +
4.70 +#endif /* _SOURCEMOD_AUTO_VERSION_INFORMATION_H_ */
4.71 + """.format(tag, rev, cset, major, minor, release, fullstring, major, minor, release))
4.72 +
4.73 + with open(os.path.join(OutputFolder, 'version_auto.inc'), 'w') as fp:
4.74 + fp.write("""
4.75 +#if defined _auto_version_included
4.76 + #endinput
4.77 +#endif
4.78 +#define _auto_version_included
4.79 +
4.80 +#define SOURCEMOD_V_TAG \"{0}\"
4.81 +#define SOURCEMOD_V_REV {1}
4.82 +#define SOURCEMOD_V_CSET \"{2}\"
4.83 +#define SOURCEMOD_V_MAJOR {3}
4.84 +#define SOURCEMOD_V_MINOR {4}
4.85 +#define SOURCEMOD_V_RELEASE {5}
4.86 +
4.87 +#define SOURCEMOD_VERSION \"{6}\"
4.88 + """.format(tag, rev, cset, major, minor, release, fullstring))
4.89 +
4.90 +output_version_headers()