Bring build scripts to AMBuild 2.2

This commit is contained in:
Kenzzer
2023-02-18 23:39:16 +01:00
parent 0c6274058e
commit 2824a307e4
8 changed files with 789 additions and 640 deletions
+35 -37
View File
@@ -1,41 +1,39 @@
# vim: set ts=2 sw=2 tw=99 noet ft=python:
import os
import urllib.request
from ambuild.command import Command
from ambuild.command import ShellCommand
import os, sys
class IterateDebugInfoCommand(Command):
def run(self, master, job):
pdblog = open(os.path.join(AMBuild.outputFolder, 'pdblog.txt'), 'rt')
for debug_info in pdblog:
debug_info = os.path.join(AMBuild.outputFolder, debug_info.strip())
job.AddCommand(SymbolCommand(debug_info, symbolServer))
pdblog.close()
class SymbolCommand(ShellCommand):
def __init__(self, debugFile, symbolServer):
self.serverResponse = None
self.symbolServer = symbolServer
if AMBuild.target['platform'] == 'linux':
cmdstring = "dump_syms {0} {1}".format(debugFile, os.path.dirname(debugFile))
elif AMBuild.target['platform'] == 'darwin':
cmdstring = "dump_syms {0}".format(debugFile)
elif AMBuild.target['platform'] == 'windows':
cmdstring = "dump_syms.exe {0}".format(debugFile)
ShellCommand.__init__(self, cmdstring)
def run(self, master, job):
ShellCommand.run(self, master, job)
if self.stdout != None and len(self.stdout) > 0:
request = urllib.request.Request(symbolServer, self.stdout.encode('utf-8'))
request.add_header("Content-Type", "text/plain")
self.serverResponse = urllib.request.urlopen(request).read().decode('utf-8')
def spew(self, runner):
if self.stderr != None and len(self.stderr) > 0:
runner.PrintOut(self.stderr)
if self.serverResponse != None and len(self.serverResponse) > 0:
runner.PrintOut(self.serverResponse)
UPLOAD_SCRIPT = os.path.join(Extension.sm_root, 'tools', 'buildbot', 'upload_symbols.py')
if 'BREAKPAD_SYMBOL_SERVER' in os.environ:
symbolServer = os.environ['BREAKPAD_SYMBOL_SERVER']
job = AMBuild.AddJob('breakpad-symbols')
job.AddCommand(IterateDebugInfoCommand())
symbolServer = os.environ['BREAKPAD_SYMBOL_SERVER']
builder.SetBuildFolder('breakpad-symbols')
for cxx_task in Extension.extensions:
if cxx_task.target.platform in ['windows']:
debug_entry = cxx_task.debug
else:
debug_entry = cxx_task.binary
debug_file = os.path.join(builder.buildPath, debug_entry.path)
if cxx_task.target.platform == 'linux':
argv = ['dump_syms', debug_file, os.path.dirname(debug_file)]
elif cxx_task.target.platform == 'mac':
# Required once dump_syms is updated on the slaves.
#argv = ['dump_syms', '-g', debug_file + '.dSYM', debug_file]
argv = ['dump_syms', debug_file + '.dSYM']
elif cxx_task.target.platform == 'windows':
argv = ['dump_syms.exe', debug_file]
plat_dir = os.path.dirname(debug_file)
bin_dir = os.path.split(plat_dir)[0]
symbol_file = '{}-{}-{}.breakpad'.format(
os.path.split(bin_dir)[1],
cxx_task.target.platform,
cxx_task.target.arch)
argv = [sys.executable, UPLOAD_SCRIPT, symbol_file] + argv
builder.AddCommand(
inputs = [UPLOAD_SCRIPT, debug_entry],
argv = argv,
outputs = [symbol_file]
)
+34 -102
View File
@@ -4,112 +4,44 @@ import shutil
import ambuild.osutil as osutil
from ambuild.command import Command
job = AMBuild.AddJob('package')
builder.SetBuildFolder('package')
class DestroyPath(Command):
def __init__(self, folder):
Command.__init__(self)
self.folder = folder
def CreateFolders(folders):
dict = {}
for folder in folders:
path = os.path.normpath(folder)
dict[folder] = builder.AddFolder(path)
return dict
def destroy(self, path):
entries = os.listdir(path)
for entry in entries:
newpath = os.path.join(path, entry)
if os.path.isdir(newpath):
self.destroy(newpath)
os.rmdir(newpath)
elif os.path.isfile(newpath):
os.remove(newpath)
def run(self, runner, job):
runner.PrintOut('rm -rf {0}/*'.format(self.folder))
self.destroy(self.folder)
class CreateFolders(Command):
def __init__(self, folders):
Command.__init__(self)
self.folders = folders
def run(self, runner, job):
for folder in self.folders:
path = os.path.join(*folder)
runner.PrintOut('mkdir {0}'.format(path))
os.makedirs(path)
#Shallow folder copy
class CopyFolder(Command):
def __init__(self, fromList, toList, excludes = []):
Command.__init__(self)
self.fromPath = os.path.join(AMBuild.sourceFolder, *fromList)
self.toPath = os.path.join(*toList)
self.excludes = excludes
def run(self, runner, job):
entries = os.listdir(self.fromPath)
for entry in entries:
if entry in self.excludes:
continue
path = os.path.join(self.fromPath, entry)
if not os.path.isfile(path):
continue
runner.PrintOut('copy {0} to {1}'.format(path, self.toPath))
shutil.copy(path, self.toPath)
#Single file copy
class CopyFile(Command):
def __init__(self, fromFile, toPath):
Command.__init__(self)
self.fromFile = fromFile
self.toPath = toPath
def run(self, runner, job):
runner.PrintOut('copy {0} to {1}'.format(self.fromFile, self.toPath))
shutil.copy(self.fromFile, self.toPath)
def CopyFiles(src, dest, filter_ext=None):
source_path = os.path.join(builder.sourcePath, src)
if os.path.isfile(source_path):
builder.AddCopy(source_path, dest)
return
for entry in os.listdir(source_path):
entry_path = os.path.join(source_path, entry)
if not os.path.isfile(entry_path):
continue
if filter_ext:
_, ext = os.path.splitext(entry)
if filter_ext != ext:
continue
builder.AddCopy(entry_path, dest)
folders = [['addons', 'sourcemod', 'extensions'], ['addons', 'sourcemod', 'gamedata'], ['addons', 'sourcemod', 'scripting', 'include']]
folders = CreateFolders(['addons/sourcemod/extensions', 'addons/sourcemod/gamedata', 'addons/sourcemod/scripting', 'addons/sourcemod/scripting/include'])
#Setup
job.AddCommand(DestroyPath(os.path.join(AMBuild.outputFolder, 'package')))
job.AddCommand(CreateFolders(folders))
#Copy Files
job.AddCommand(CopyFile(os.path.join(AMBuild.sourceFolder, 'connect.games.txt'),
os.path.join('addons', 'sourcemod', 'gamedata')))
job.AddCommand(CopyFile(os.path.join(AMBuild.sourceFolder, 'connect.inc'),
os.path.join('addons', 'sourcemod', 'scripting', 'include')))
job.AddCommand(CopyFile(os.path.join(AMBuild.sourceFolder, 'connect.sp'),
os.path.join('addons', 'sourcemod', 'scripting')))
bincopies = []
def AddNormalLibrary(name, dest):
dest = os.path.join('addons', 'sourcemod', dest)
bincopies.append(CopyFile(os.path.join('..', name, name + osutil.SharedLibSuffix()), dest))
# Each platform's version of dump_syms needs the path in a different format.
if AMBuild.target['platform'] == 'linux':
debug_info.append(name + '/' + name + '.so')
elif AMBuild.target['platform'] == 'darwin':
debug_info.append(name + '/' + name + '.dylib.dSYM')
elif AMBuild.target['platform'] == 'windows':
debug_info.append(name + '\\' + name + '.pdb')
def AddHL2Library(name, dest):
for i in SM.sdkInfo:
sdk = SM.sdkInfo[i]
if AMBuild.target['platform'] not in sdk['platform']:
continue
AddNormalLibrary(name + '.ext.' + sdk['ext'], dest)
debug_info = []
AddHL2Library('connect', 'extensions')
job.AddCommandGroup(bincopies)
pdblog = open(os.path.join(AMBuild.outputFolder, 'pdblog.txt'), 'wt')
for pdb in debug_info:
pdblog.write(pdb + '\n')
pdblog = open(os.path.join(builder.buildPath, 'pdblog.txt'), 'wt')
for cxx_task in Extension.extensions:
if cxx_task.target.arch == 'x86_64':
builder.AddCopy(cxx_task.binary, folders['addons/sourcemod/extensions/x64'])
else:
builder.AddCopy(cxx_task.binary, folders['addons/sourcemod/extensions'])
pdblog.write(cxx_task.debug.path + '\n')
pdblog.close()
CopyFiles('connect.games.txt', folders['addons/sourcemod/gamedata'])
CopyFiles('connect.inc', folders['addons/sourcemod/scripting/include'])
CopyFiles('connect.sp', folders['addons/sourcemod/scripting'])
debug_info = []
+41 -46
View File
@@ -1,55 +1,50 @@
# vim: set ts=2 sw=2 tw=99 noet ft=python:
import os
# vim: set ts=8 sts=2 sw=2 tw=99 et ft=python:
import os, sys
import re
import subprocess
from ambuild.cache import Cache
import ambuild.command as command
#Quickly try to ascertain the current repository revision
def GetVersion():
args = ['hg', 'parent', '-R', AMBuild.sourceFolder]
p = command.RunDirectCommand(AMBuild, args)
m = re.match('changeset:\s+(\d+):(.+)', p.stdoutText)
if m == None:
raise Exception('Could not determine repository version')
return m.groups()
builder.SetBuildFolder('/')
includes = builder.AddFolder('includes')
def PerformReversioning():
rev, cset = GetVersion()
cacheFile = os.path.join(AMBuild.outputFolder, '.ambuild', 'hgcache')
cache = Cache(cacheFile)
if os.path.isfile(cacheFile):
cache.LoadCache()
if cache.HasVariable('cset') and cache['cset'] == cset:
return False
cache.CacheVariable('cset', cset)
argv = [
sys.executable,
os.path.join(builder.sourcePath, 'buildbot', 'generate_header.py'),
os.path.join(builder.sourcePath),
os.path.join(builder.buildPath, 'includes'),
]
productFile = open(os.path.join(AMBuild.sourceFolder, 'product.version'), 'r')
productContents = productFile.read()
productFile.close()
m = re.match('(\d+)\.(\d+)\.(\d+)(.*)', productContents)
if m == None:
raise Exception('Could not detremine product version')
major, minor, release, tag = m.groups()
outputs = [
os.path.join(builder.buildFolder, 'includes', 'version_auto.h')
]
incFolder = os.path.join(AMBuild.sourceFolder, 'extension')
incFile = open(os.path.join(incFolder, 'version_auto.h'), 'w')
incFile.write("""
#ifndef _AUTO_VERSION_INFORMATION_H_
#define _AUTO_VERSION_INFORMATION_H_
repo_head_path = os.path.join(builder.sourcePath, 'product.version')
if os.path.exists(os.path.join(builder.sourcePath, '.git')):
with open(os.path.join(builder.sourcePath, '.git', 'HEAD')) as fp:
head_contents = fp.read().strip()
if re.search('^[a-fA-F0-9]{40}$', head_contents):
repo_head_path = os.path.join(builder.sourcePath, '.git', 'HEAD')
else:
git_state = head_contents.split(':')[1].strip()
repo_head_path = os.path.join(builder.sourcePath, '.git', git_state)
if not os.path.exists(repo_head_path):
repo_head_path = os.path.join(builder.sourcePath, '.git', 'HEAD')
#define SM_BUILD_TAG \"{0}\"
#define SM_BUILD_UNIQUEID \"{1}:{2}\" SM_BUILD_TAG
#define SM_VERSION \"{3}.{4}.{5}\"
#define SM_FULL_VERSION SM_VERSION SM_BUILD_TAG
#define SM_FILE_VERSION {6},{7},{8},0
sources = [
os.path.join(builder.sourcePath, 'product.version'),
repo_head_path,
argv[1]
]
#endif /* _AUTO_VERSION_INFORMATION_H_ */
""".format(tag, rev, cset, major, minor, release, major, minor, release))
incFile.close()
cache.WriteCache()
PerformReversioning()
for source in sources:
if not os.path.exists(source):
print(source)
for source in sources:
if not os.path.exists(source):
print(source)
output_nodes = builder.AddCommand(
inputs=sources,
argv=argv,
outputs=outputs
)
rvalue = output_nodes
+69
View File
@@ -0,0 +1,69 @@
# vim: set ts=2 sw=2 tw=99 noet ft=python:
import os, sys
import re
import subprocess
argv = sys.argv[1:]
if len(argv) < 2:
sys.stderr.write('Usage: generate_header.py <source_path> <output_folder>\n')
sys.exit(1)
SourceFolder = os.path.abspath(os.path.normpath(argv[0]))
OutputFolder = os.path.normpath(argv[1])
def run_and_return(argv):
# Python 2.6 doesn't have check_output.
if hasattr(subprocess, 'check_output'):
text = subprocess.check_output(argv)
if str != bytes:
text = str(text, 'utf-8')
else:
p = subprocess.Popen(argv, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
output, ignored = p.communicate()
rval = p.poll()
if rval:
raise subprocess.CalledProcessError(rval, argv)
text = output.decode('utf8')
return text.strip()
def GetGHVersion():
p = run_and_return(['hg', 'parent', '-R', SourceFolder])
m = re.match('changeset:\s+(\d+):(.+)', p.stdoutText)
if m == None:
raise Exception('Could not determine repository version')
return m.groups()
def GetGitVersion():
revision_count = run_and_return(['git', 'rev-list', '--count', 'HEAD'])
revision_hash = run_and_return(['git', 'log', '--pretty=format:%h:%H', '-n', '1'])
shorthash, longhash = revision_hash.split(':')
return revision_count, shorthash
rev = None
cset = None
if os.path.exists(os.path.join(SourceFolder, '.hg')): # Mercurial repository
rev, cset = GetGHVersion()
else: # Assume its a git repository
rev, cset = GetGitVersion()
productFile = open(os.path.join(SourceFolder, 'product.version'), 'r')
productContents = productFile.read()
productFile.close()
m = re.match('(\d+)\.(\d+)\.(\d+)(.*)', productContents)
if m == None:
raise Exception('Could not detremine product version')
major, minor, release, tag = m.groups()
incFile = open(os.path.join(OutputFolder, 'version_auto.h'), 'w')
incFile.write("""
#ifndef _AUTO_VERSION_INFORMATION_H_
#define _AUTO_VERSION_INFORMATION_H_
#define SM_BUILD_TAG \"{0}\"
#define SM_BUILD_UNIQUEID \"{1}:{2}\" SM_BUILD_TAG
#define SM_VERSION \"{3}.{4}.{5}\"
#define SM_FULL_VERSION SM_VERSION SM_BUILD_TAG
#define SM_FILE_VERSION {6},{7},{8},0
#endif /* _AUTO_VERSION_INFORMATION_H_ */
""".format(tag, rev, cset, major, minor, release, major, minor, release))
incFile.close()