From f331c3dfafad5eb5488fb313a4b5bc124491f921 Mon Sep 17 00:00:00 2001 From: Dr!fter Date: Sun, 1 Sep 2013 11:11:38 -0400 Subject: [PATCH] Add AMBuild --- AMBuildScript | 407 +++++++++++++++++++++++++++++++++++++++ AMBuilder | 37 ++++ buildbot/PackageScript | 116 +++++++++++ buildbot/bootstrap.pl | 78 ++++++++ buildbot/build_type | 1 + buildbot/helpers.pm | 94 +++++++++ buildbot/package.pl | 99 ++++++++++ buildbot/product.version | 1 + buildbot/startbuild.pl | 27 +++ buildbot/symstore.pl | 64 ++++++ msvc10/sdk.vcxproj | 12 +- vfunc_call.h | 94 +++++++-- 12 files changed, 1012 insertions(+), 18 deletions(-) create mode 100644 AMBuildScript create mode 100644 AMBuilder create mode 100644 buildbot/PackageScript create mode 100644 buildbot/bootstrap.pl create mode 100644 buildbot/build_type create mode 100644 buildbot/helpers.pm create mode 100644 buildbot/package.pl create mode 100644 buildbot/product.version create mode 100644 buildbot/startbuild.pl create mode 100644 buildbot/symstore.pl diff --git a/AMBuildScript b/AMBuildScript new file mode 100644 index 0000000..947c12d --- /dev/null +++ b/AMBuildScript @@ -0,0 +1,407 @@ +# vim: set ts=2 sw=2 tw=99 noet ft=python: +import os +import sys +import ambuild.command as command +from ambuild.command import SymlinkCommand + +vboxhack = 0 + +class SM: + def __init__(self): + self.compiler = Cpp.Compiler() + + #Build SDK info + self.sdkInfo = { } + self.sdkInfo['ep1'] = {'sdk': 'HL2SDK', 'ext': '1.ep1', 'def': '1', + 'name': 'EPISODEONE', 'platform': ['windows', 'linux']} + + self.sdkInfo['ep2'] = {'sdk': 'HL2SDKOB', 'ext': '2.ep2', 'def': '3', + 'name': 'ORANGEBOX', 'platform': ['windows', 'linux']} + + self.sdkInfo['css'] = {'sdk': 'HL2SDKCSS', 'ext': '2.css', 'def': '6', + 'name': 'CSS', 'platform': ['windows', 'linux', 'darwin']} + + self.sdkInfo['hl2dm'] = {'sdk': 'HL2SDKHL2DM', 'ext': '2.hl2dm', 'def': '7', + 'name': 'HL2DM', 'platform': ['windows', 'linux', 'darwin']} + + self.sdkInfo['dods'] = {'sdk': 'HL2SDKDODS', 'ext': '2.dods', 'def': '8', + 'name': 'DODS', 'platform': ['windows', 'linux', 'darwin']} + + self.sdkInfo['tf2'] = {'sdk': 'HL2SDKTF2', 'ext': '2.tf2', 'def': '9', + 'name': 'TF2', 'platform': ['windows', 'linux', 'darwin']} + + self.sdkInfo['l4d'] = {'sdk': 'HL2SDKL4D', 'ext': '2.l4d', 'def': '10', + 'name': 'LEFT4DEAD', 'platform': ['windows', 'linux', 'darwin']} + + self.sdkInfo['nd'] = {'sdk': 'HL2SDKND', 'ext': '2.nd', 'def': '11', + 'name': 'NUCLEARDAWN', 'platform': ['windows', 'linux', 'darwin']} + + self.sdkInfo['l4d2'] = {'sdk': 'HL2SDKL4D2', 'ext': '2.l4d2', 'def': '12', + 'name': 'LEFT4DEAD2', 'platform': ['windows', 'linux', 'darwin']} + + self.sdkInfo['swarm'] = {'sdk': 'HL2SDK-SWARM', 'ext': '2.swarm', 'def': '13', + 'name': 'ALIENSWARM', 'platform': ['windows']} + + self.sdkInfo['csgo'] = {'sdk': 'HL2SDKCSGO', 'ext': '2.csgo', 'def': '15', + 'name': 'CSGO', 'platform': ['windows', 'linux', 'darwin']} + + if AMBuild.mode == 'config': + #Detect compilers + self.compiler.DetectAll(AMBuild) + + #Detect variables + envvars = { 'MMSOURCE19': 'mmsource-1.9', + 'HL2SDKOBVALVE': 'hl2sdk-ob-valve', + 'HL2SDKCSS': 'hl2sdk-css', + 'SOURCEMOD14': 'sourcemod-central' + } + + if AMBuild.target['platform'] != 'darwin': + envvars['HL2SDK'] = 'hl2sdk' + envvars['HL2SDKOB'] = 'hl2sdk-ob' + + #Dark Messiah is Windows-only + if AMBuild.target['platform'] == 'windows': + envvars['HL2SDK-SWARM'] = 'hl2sdk-swarm' + + #Must have a path for each envvar (file a bug if you don't like this) + for i in envvars: + if i in os.environ: + path = os.environ[i] + if not os.path.isdir(path): + raise Exception('Path for {0} was not found: {1}'.format(i, path)) + else: + head = os.getcwd() + oldhead = None + while head != None and head != oldhead: + path = os.path.join(head, envvars[i]) + if os.path.isdir(path): + break + oldhead = head + head, tail = os.path.split(head) + if head == None or head == oldhead: + raise Exception('Could not find a valid path for {0}'.format(i)) + AMBuild.cache.CacheVariable(i, path) + + #Set up defines + cxx = self.compiler.cxx + if isinstance(cxx, Cpp.CompatGCC): + if isinstance(cxx, Cpp.GCC): + self.vendor = 'gcc' + elif isinstance(cxx, Cpp.Clang): + self.vendor = 'clang' + self.compiler.AddToListVar('CDEFINES', 'COMPILER_GCC') + self.compiler.AddToListVar('CDEFINES', 'POSIX') + self.compiler.AddToListVar('CDEFINES', 'stricmp=strcasecmp') + self.compiler.AddToListVar('CDEFINES', '_stricmp=strcasecmp') + self.compiler.AddToListVar('CDEFINES', '_snprintf=snprintf') + self.compiler.AddToListVar('CDEFINES', '_vsnprintf=vsnprintf') + self.compiler.AddToListVar('CFLAGS', '-pipe') + self.compiler.AddToListVar('CFLAGS', '-fno-strict-aliasing') + if (self.vendor == 'gcc' and cxx.majorVersion >= 4) or self.vendor == 'clang': + self.compiler.AddToListVar('CFLAGS', '-fvisibility=hidden') + self.compiler.AddToListVar('CXXFLAGS', '-fvisibility-inlines-hidden') + self.compiler.AddToListVar('CFLAGS', '-Wall') + #self.compiler.AddToListVar('CFLAGS', '-Werror') + self.compiler.AddToListVar('CFLAGS', '-Wno-uninitialized') + self.compiler.AddToListVar('CFLAGS', '-Wno-unused') + self.compiler.AddToListVar('CFLAGS', '-Wno-switch') + self.compiler.AddToListVar('CFLAGS', '-Wno-invalid-offsetof') + self.compiler.AddToListVar('CFLAGS', '-mfpmath=sse') + self.compiler.AddToListVar('CFLAGS', '-msse') + self.compiler.AddToListVar('CFLAGS', '-m32') + self.compiler.AddToListVar('POSTLINKFLAGS', '-m32') + self.compiler.AddToListVar('CFLAGS', '-static-libgcc') + self.compiler.AddToListVar('CXXFLAGS', '-fno-exceptions') + self.compiler.AddToListVar('CXXFLAGS', '-fno-rtti') + self.compiler.AddToListVar('CXXFLAGS', '-fno-threadsafe-statics') + self.compiler.AddToListVar('CXXFLAGS', '-Wno-non-virtual-dtor') + self.compiler.AddToListVar('CXXFLAGS', '-Wno-overloaded-virtual') + self.compiler.AddToListVar('CXXFLAGS', '-Wno-conversion') + if (self.vendor == 'gcc' and cxx.majorVersion >= 4 and cxx.minorVersion >= 7) or \ + (self.vendor == 'clang' and cxx.majorVersion >= 3): + self.compiler.AddToListVar('CXXFLAGS', '-Wno-delete-non-virtual-dtor') + self.compiler.AddToListVar('CDEFINES', 'HAVE_STDINT_H') + self.compiler.AddToListVar('CDEFINES', 'GNUC') + if self.vendor == 'gcc': + self.compiler.AddToListVar('CFLAGS', '-mfpmath=sse') + elif isinstance(cxx, Cpp.MSVC): + self.vendor = 'msvc' + if AMBuild.options.debug == '1': + self.compiler.AddToListVar('CFLAGS', '/MTd') + self.compiler.AddToListVar('POSTLINKFLAGS', '/NODEFAULTLIB:libcmt') + else: + self.compiler.AddToListVar('CFLAGS', '/MT') + self.compiler.AddToListVar('CDEFINES', 'COMPILER_MSVC') + self.compiler.AddToListVar('CDEFINES', 'COMPILER_MSVC32') + self.compiler.AddToListVar('CDEFINES', '_CRT_SECURE_NO_DEPRECATE') + self.compiler.AddToListVar('CDEFINES', '_CRT_SECURE_NO_WARNINGS') + self.compiler.AddToListVar('CDEFINES', '_CRT_NONSTDC_NO_DEPRECATE') + self.compiler.AddToListVar('CXXFLAGS', '/EHsc') + self.compiler.AddToListVar('CXXFLAGS', '/GR-') + self.compiler.AddToListVar('CFLAGS', '/W3') + self.compiler.AddToListVar('CFLAGS', '/nologo') + self.compiler.AddToListVar('CFLAGS', '/Zi') + self.compiler.AddToListVar('CXXFLAGS', '/TP') + self.compiler.AddToListVar('POSTLINKFLAGS', '/DEBUG') + self.compiler.AddToListVar('POSTLINKFLAGS', '/MACHINE:X86') + self.compiler.AddToListVar('POSTLINKFLAGS', '/SUBSYSTEM:WINDOWS') + self.compiler.AddToListVar('POSTLINKFLAGS', 'kernel32.lib') + self.compiler.AddToListVar('POSTLINKFLAGS', 'user32.lib') + self.compiler.AddToListVar('POSTLINKFLAGS', 'gdi32.lib') + self.compiler.AddToListVar('POSTLINKFLAGS', 'winspool.lib') + self.compiler.AddToListVar('POSTLINKFLAGS', 'comdlg32.lib') + self.compiler.AddToListVar('POSTLINKFLAGS', 'advapi32.lib') + self.compiler.AddToListVar('POSTLINKFLAGS', 'shell32.lib') + self.compiler.AddToListVar('POSTLINKFLAGS', 'ole32.lib') + self.compiler.AddToListVar('POSTLINKFLAGS', 'oleaut32.lib') + self.compiler.AddToListVar('POSTLINKFLAGS', 'uuid.lib') + self.compiler.AddToListVar('POSTLINKFLAGS', 'odbc32.lib') + self.compiler.AddToListVar('POSTLINKFLAGS', 'odbccp32.lib') + + #Optimization + if AMBuild.options.opt == '1': + self.compiler.AddToListVar('CDEFINES', 'NDEBUG') + if self.vendor == 'gcc' or self.vendor == 'clang': + self.compiler.AddToListVar('CFLAGS', '-O3') + elif self.vendor == 'msvc': + self.compiler.AddToListVar('CFLAGS', '/Ox') + self.compiler.AddToListVar('POSTLINKFLAGS', '/OPT:ICF') + self.compiler.AddToListVar('POSTLINKFLAGS', '/OPT:REF') + + #Debugging + if AMBuild.options.debug == '1': + self.compiler.AddToListVar('CDEFINES', 'DEBUG') + self.compiler.AddToListVar('CDEFINES', '_DEBUG') + if self.vendor == 'gcc' or self.vendor == 'clang': + self.compiler.AddToListVar('CFLAGS', '-g3') + elif self.vendor == 'msvc': + self.compiler.AddToListVar('CFLAGS', '/Od') + self.compiler.AddToListVar('CFLAGS', '/RTC1') + + #Platform-specifics + if AMBuild.target['platform'] == 'linux': + self.compiler.AddToListVar('CDEFINES', '_LINUX') + if self.vendor == 'gcc': + self.compiler.AddToListVar('POSTLINKFLAGS', '-static-libgcc') + if self.vendor == 'clang': + self.compiler.AddToListVar('POSTLINKFLAGS', '-lgcc_eh') + elif AMBuild.target['platform'] == 'darwin': + self.compiler.AddToListVar('POSTLINKFLAGS', '-mmacosx-version-min=10.5') + self.compiler.AddToListVar('POSTLINKFLAGS', ['-arch', 'i386']) + self.compiler.AddToListVar('POSTLINKFLAGS', '-lstdc++') + + # For OS X dylib versioning + import re + productFile = open(os.path.join(AMBuild.sourceFolder, 'buildbot', 'product.version'), 'r') + productContents = productFile.read() + productFile.close() + m = re.match('(\d+)\.(\d+)\.(\d+).*', productContents) + if m == None: + self.version = '1.0.0' + else: + major, minor, release = m.groups() + self.version = '{0}.{1}.{2}'.format(major, minor, release) + AMBuild.cache.CacheVariable('version', self.version) + elif AMBuild.target['platform'] == 'windows': + self.compiler.AddToListVar('CDEFINES', 'WIN32') + self.compiler.AddToListVar('CDEFINES', '_WINDOWS') + + #Finish up + self.compiler.AddToListVar('CDEFINES', 'SOURCEMOD_BUILD') + self.compiler.AddToListVar('CDEFINES', 'SM_GENERATED_BUILD') + self.compiler.AddToListVar('CINCLUDES', + os.path.join(AMBuild.outputFolder, 'includes')) + self.compiler.ToConfig(AMBuild, 'compiler') + AMBuild.cache.CacheVariable('vendor', self.vendor) + self.targetMap = { } + AMBuild.cache.CacheVariable('targetMap', self.targetMap) + else: + self.compiler.FromConfig(AMBuild, 'compiler') + self.targetMap = AMBuild.cache['targetMap'] + + if AMBuild.target['platform'] == 'windows': + self.compiler.AddToListVar('RCINCLUDES', os.path.join(AMBuild.sourceFolder, 'extension')) + + self.mmsPath = AMBuild.cache['MMSOURCE19'] + + def DefaultCompiler(self): + return self.compiler.Clone() + + def JobMatters(self, jobname): + file = sys._getframe().f_code.co_filename + if AMBuild.mode == 'config': + self.targetMap[jobname] = file + return True + if len(AMBuild.args) == 0: + return True + if not jobname in AMBuild.args: + return False + + def DefaultExtCompiler(self, path): + compiler = self.DefaultCompiler() + compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, path)) + compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, path, 'sdk')) + compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public')) + compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public', 'extensions')) + compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public', 'sourcepawn')) + return compiler + + def AutoVersion(self, folder, binary): + if AMBuild.target['platform'] == 'windows': + env = {'RCDEFINES': ['BINARY_NAME="' + binary.binaryFile + '"', 'SM_GENERATED_BUILD']} + binary.AddResourceFile(os.path.join(folder, 'version.rc' ), env) + elif AMBuild.target['platform'] == 'darwin' and isinstance(binary, Cpp.LibraryBuilder): + binary.compiler['POSTLINKFLAGS'].extend(['-compatibility_version', '1.0.0']) + binary.compiler['POSTLINKFLAGS'].extend(['-current_version', AMBuild.cache['version']]) + else: + return + + def PreSetupHL2Job(self, job, builder, sdk): + info = self.sdkInfo[sdk] + sdkPath = AMBuild.cache[info['sdk']] + if AMBuild.target['platform'] == 'linux': + if sdk == 'ep1': + staticLibs = os.path.join(sdkPath, 'linux_sdk') + else: + staticLibs = os.path.join(sdkPath, 'lib', 'linux') + workFolder = os.path.join(AMBuild.outputFolder, job.workFolder) + if sdk in ['ep2v', 'css']: + libs = ['tier1_i486.a', 'mathlib_i486.a', 'libvstdlib_srv.so', 'libtier0_srv.so'] + for i in libs: + link = os.path.join(workFolder, i) + target = os.path.join(staticLibs, i) + try: + os.lstat(link) + except: + if vboxhack == 1: + job.AddCommand(command.DirectCommand(['cp', '-f', target, link])) + else: + job.AddCommand(SymlinkCommand(link, target)) + elif sdk in ['l4d', 'l4d2', 'csgo']: + libs = ['tier1_i486.a', 'mathlib_i486.a', 'libvstdlib.so', 'libtier0.so'] + if sdk == 'csgo': + libs.append('interfaces_i486.a') + for i in libs: + link = os.path.join(workFolder, i) + target = os.path.join(staticLibs, i) + try: + os.lstat(link) + except: + if vboxhack == 1: + job.AddCommand(command.DirectCommand(['cp', '-f', target, link])) + else: + job.AddCommand(SymlinkCommand(link, target)) + else: + for i in ['tier1_i486.a', 'mathlib_i486.a', 'vstdlib_i486.so', 'tier0_i486.so']: + link = os.path.join(workFolder, i) + target = os.path.join(staticLibs, i) + try: + os.lstat(link) + except: + if vboxhack == 1: + job.AddCommand(command.DirectCommand(['cp', '-f', target, link])) + else: + job.AddCommand(SymlinkCommand(link, target)) + elif AMBuild.target['platform'] == 'darwin': + staticLibs = os.path.join(sdkPath, 'lib', 'mac') + workFolder = os.path.join(AMBuild.outputFolder, job.workFolder) + for i in ['tier1_i486.a', 'mathlib_i486.a', 'libvstdlib.dylib', 'libtier0.dylib']: + link = os.path.join(workFolder, i) + target = os.path.join(staticLibs, i) + try: + os.lstat(link) + except: + if vboxhack == 1: + job.AddCommand(command.DirectCommand(['cp', '-f', target, link])) + else: + job.AddCommand(SymlinkCommand(link, target)) + elif AMBuild.target['platform'] == 'windows': + libs = ['tier0', 'tier1', 'vstdlib', 'mathlib'] + if sdk in ['swarm', 'csgo']: + libs.append('interfaces') + for lib in libs: + libPath = os.path.join(sdkPath, 'lib', 'public', lib) + '.lib' + builder.RebuildIfNewer(libPath) + builder['POSTLINKFLAGS'].append(libPath) + + def PostSetupHL2Job(self, job, builder, sdk): + if AMBuild.target['platform'] in ['linux', 'darwin']: + builder.AddObjectFiles(['tier1_i486.a', 'mathlib_i486.a']) + if sdk == 'csgo': + builder.AddObjectFiles(['interfaces_i486.a']) + + def DefaultHL2Compiler(self, path, sdk, noLink = False, oldMms = '-legacy'): + compiler = self.DefaultExtCompiler(path) + + mms = 'core' + if sdk == 'ep1': + mms += oldMms + + compiler['CXXINCLUDES'].append(os.path.join(self.mmsPath, mms)) + compiler['CXXINCLUDES'].append(os.path.join(self.mmsPath, mms, 'sourcehook')) + + info = self.sdkInfo + compiler['CDEFINES'].extend(['SE_' + info[i]['name'] + '=' + info[i]['def'] for i in info]) + compiler['CDEFINES'].append("SE_PORTAL2=10") + + paths = [['public'], ['public', 'engine'], ['public', 'mathlib'], ['public', 'vstdlib'], + ['public', 'tier0'], ['public', 'tier1']] + if sdk == 'ep1' or sdk == 'darkm': + paths.append(['public', 'dlls']) + paths.append(['game_shared']) + else: + paths.append(['public', 'game', 'server']) + paths.append(['game', 'shared']) + paths.append(['common']) + + info = self.sdkInfo[sdk] + sdkPath = AMBuild.cache[info['sdk']] + + compiler['CDEFINES'].append('SOURCE_ENGINE=' + info['def']) + + if sdk == 'ep1': + if AMBuild.target['platform'] == 'linux': + staticLibs = os.path.join(sdkPath, 'linux_sdk') + else: + if AMBuild.target['platform'] == 'linux': + staticLibs = os.path.join(sdkPath, 'lib', 'linux') + elif AMBuild.target['platform'] == 'darwin': + staticLibs = os.path.join(sdkPath, 'lib', 'mac') + + for i in paths: + compiler['CXXINCLUDES'].append(os.path.join(sdkPath, *i)) + + if not noLink: + if AMBuild.target['platform'] == 'linux': + compiler['POSTLINKFLAGS'][0:0] = ['-lm'] + if sdk in ['tf2', 'css', 'l4d2', 'hl2dm', 'dods']: + compiler['POSTLINKFLAGS'][0:0] = ['libtier0_srv.so'] + compiler['POSTLINKFLAGS'][0:0] = ['libvstdlib_srv.so'] + elif sdk in ['l4d', 'csgo', 'nd']: + compiler['POSTLINKFLAGS'][0:0] = ['libtier0.so'] + compiler['POSTLINKFLAGS'][0:0] = ['libvstdlib.so'] + else: + compiler['POSTLINKFLAGS'][0:0] = ['tier0_i486.so'] + compiler['POSTLINKFLAGS'][0:0] = ['vstdlib_i486.so'] + elif AMBuild.target['platform'] == 'darwin': + compiler['POSTLINKFLAGS'][0:0] = ['libtier0.dylib'] + compiler['POSTLINKFLAGS'][0:0] = ['libvstdlib.dylib'] + + return compiler + +sm = SM() +globals = { + 'SM': sm +} + +AMBuild.Include(os.path.join('buildbot', 'Versioning'), globals) + +FileList = [ + ['AMBuilder'], + ['buildbot', 'PackageScript'] + ] + +for parts in FileList: + AMBuild.Include(os.path.join(*parts), globals) + diff --git a/AMBuilder b/AMBuilder new file mode 100644 index 0000000..596db61 --- /dev/null +++ b/AMBuilder @@ -0,0 +1,37 @@ +# vim: set ts=2 sw=2 tw=99 noet ft=python: +import os + +for i in SM.sdkInfo: + sdk = SM.sdkInfo[i] + if AMBuild.target['platform'] not in sdk['platform']: + continue + + compiler = SM.DefaultHL2Compiler('.', i) + compiler['CXXINCLUDES'].append(os.path.join(AMBuild.cache['SOURCEMOD14'], 'public')) + compiler['CXXINCLUDES'].append(os.path.join(AMBuild.cache['SOURCEMOD14'], 'public', 'sourcepawn')) + compiler['CXXINCLUDES'].append(os.path.join(AMBuild.cache['SOURCEMOD14'], 'public', 'extensions')) + #compiler['CXXINCLUDES'].append(os.path.join(AMBuild.cache['SOURCEMOD14'], 'public', 'jit')) + #compiler['CXXINCLUDES'].append(os.path.join(AMBuild.cache['SOURCEMOD14'], 'public', 'jit', 'x86')) + + if compiler.cc.name == 'gcc': + compiler['CFLAGS'].append('-Wno-parentheses') + + #if i != 'ep1': + # compiler['CDEFINES'].append('HOOKING_ENABLED') + + name = 'dhooks.ext.' + sdk['ext'] + extension = AMBuild.AddJob(name) + binary = Cpp.LibraryBuilder(name, AMBuild, extension, compiler) + SM.PreSetupHL2Job(extension, binary, i) + binary.AddSourceFiles('.', [ + 'extension.cpp', + 'listeners.cpp', + 'vhook.cpp', + 'natives.cpp', + 'sdk/smsdk_ext.cpp' + 'assembler-x86.cpp' + ]) + SM.PostSetupHL2Job(extension, binary, i) + #SM.AutoVersion('.', binary) + binary.SendToJob() + diff --git a/buildbot/PackageScript b/buildbot/PackageScript new file mode 100644 index 0000000..bfa1fb0 --- /dev/null +++ b/buildbot/PackageScript @@ -0,0 +1,116 @@ +# vim: set ts=2 sw=2 tw=99 noet ft=python: +import os +import shutil +import ambuild.osutil as osutil +from ambuild.command import Command + +job = AMBuild.AddJob('package') + +class DestroyPath(Command): + def __init__(self, folder): + Command.__init__(self) + self.folder = folder + + 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) + + +folders = [ + ['addons', 'sourcemod', 'extensions'], + ['addons', 'sourcemod', 'scripting', 'include'], + ['addons', 'sourcemod', 'gamedata'], + ['addons', 'sourcemod', 'gamedata', 'dhooks.games'] + ] + +#Setup +job.AddCommand(DestroyPath(os.path.join(AMBuild.outputFolder, 'package'))) +job.AddCommand(CreateFolders(folders)) + +#Copy Files +job.AddCommand(CopyFile(os.path.join(AMBuild.sourceFolder, 'sourcemod', 'scripting', 'include', 'dhooks.inc'), + os.path.join('addons', 'sourcemod', 'scripting', 'include'))) + +job.AddCommand(CopyFile(os.path.join(AMBuild.sourceFolder, 'sourcemod', 'scripting', 'dhooks-test.sp'), + os.path.join('addons', 'sourcemod', 'scripting'))) + +job.AddCommand(CopyFolder([AMBuild.sourceFolder, 'sourcemod', 'gamedata', 'dhooks-test.games'], + ['addons', 'sourcemod', 'gamedata', 'dhooks-test.games'])) + +bincopies = [] + +def AddNormalLibrary(name, dest): + dest = os.path.join('addons', 'sourcemod', dest) + bincopies.append(CopyFile(os.path.join('..', name, name + osutil.SharedLibSuffix()), dest)) + #pdb_list.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) + +#pdb_list = [] + +AddHL2Library('dhooks', 'extensions') + +job.AddCommandGroup(bincopies) + +#if AMBuild.target['platform'] == 'windows': +# pdblog = open(os.path.join(AMBuild.outputFolder, 'pdblog.txt'), 'wt') +# for pdb in pdb_list: +# pdblog.write(pdb + '\n') +# pdblog.close() + diff --git a/buildbot/bootstrap.pl b/buildbot/bootstrap.pl new file mode 100644 index 0000000..676f3b0 --- /dev/null +++ b/buildbot/bootstrap.pl @@ -0,0 +1,78 @@ +#!/usr/bin/perl +# vim: set ts=2 sw=2 tw=99 noet: + +use strict; +use Cwd; +use File::Basename; +use File::Path; + +my ($myself, $path) = fileparse($0); +chdir($path); + +require 'helpers.pm'; + +#Go back above build dir +chdir(Build::PathFormat('../..')); + +#Get the source path. +our ($root) = getcwd(); + +rmtree('OUTPUT'); +mkdir('OUTPUT') or die("Failed to create output folder: $!\n"); +chdir('OUTPUT'); +my ($result); +print "Attempting to reconfigure...\n"; + +#update and configure shiz +if ($^O eq "linux") { + #my @sdks = ('sourcemod-1.3', 'mmsource-1.8', 'hl2sdk', 'hl2sdk-ob', 'hl2sdk-ob-valve', 'hl2sdk-l4d', 'hl2sdk-l4d2'); + #my ($sdk); + #foreach $sdk (@sdks) { + # print "Updating checkout of ", $sdk, " on ", $^O, "\n"; + # $result = `hg pull -u /home/builds/common/$sdk`; + # print $result; + #} + + $ENV{'SOURCEMOD14'} = '/home/builds/common/sourcemod-1.4'; + $ENV{'MMSOURCE19'} = '/home/builds/common/mmsource-1.9'; + + $ENV{'HL2SDK'} = '/home/builds/common/hl2sdk'; + $ENV{'HL2SDKOB'} = '/home/builds/common/hl2sdk-ob'; + $ENV{'HL2SDKOBVALVE'} = '/home/builds/common/hl2sdk-ob-valve'; + $ENV{'HL2SDKL4D'} = '/home/builds/common/hl2sdk-l4d'; + $ENV{'HL2SDKL4D2'} = '/home/builds/common/hl2sdk-l4d2'; + $ENV{'HL2SDKCSGO'} = '/home/builds/common/hl2sdk-csgo'; +} elsif ($^O eq "darwin") { + #my @sdks = ('sourcemod-1.3', 'mmsource-1.8', 'hl2sdk-ob-valve'); + #my ($sdk); + #foreach $sdk (@sdks) { + # print "Updating checkout of ", $sdk, " on ", $^O, "\n"; + # $result = `hg pull -u /Users/builds/slaves/common/$sdk`; + # print $result; + #} + + $ENV{'SOURCEMOD14'} = '/Users/builds/slaves/common/sourcemod-1.4'; + $ENV{'MMSOURCE18'} = '/Users/builds/slaves/common/mmsource-1.8'; + $ENV{'MMSOURCE19'} = '/Users/builds/slaves/common/mmsource-central'; + + $ENV{'HL2SDKOBVALVE'} = '/Users/builds/slaves/common/hl2sdk-ob-valve'; + $ENV{'HL2SDKCSS'} = '/Users/builds/slaves/common/hl2sdk-css'; +} else { + #JUST IN CASE + #$ENV{'MMSOURCE19'} = "C:\\Scripts\\common\\mmsource-1.9"; + #$ENV{'HL2SDKCSGO'} = "C:\\Scripts\\common\\hl2sdk-csgo"; +} +# Windows vars should already be set. + +#configure AMBuild +if ($^O eq "linux") { + $result = `CC=gcc CXX=gcc python3 ../build/configure.py --enable-optimize`; +} elsif ($^O eq "darwin") { + $result = `CC=clang CXX=clang python3 ../build/configure.py --enable-optimize`; +} else { + $result = `C:\\Python31\\Python.exe ..\\build\\configure.py --enable-optimize`; +} +print "$result\n"; +if ($? != 0) { + die('Could not configure!'); +} diff --git a/buildbot/build_type b/buildbot/build_type new file mode 100644 index 0000000..38f8e88 --- /dev/null +++ b/buildbot/build_type @@ -0,0 +1 @@ +dev diff --git a/buildbot/helpers.pm b/buildbot/helpers.pm new file mode 100644 index 0000000..7dcb24d --- /dev/null +++ b/buildbot/helpers.pm @@ -0,0 +1,94 @@ +#!/usr/bin/perl + +use strict; +use Cwd; + +package Build; + +sub HgRevNum +{ + my ($path) = (@_); + my ($cd, $text, $rev); + + $cd = Cwd::cwd(); + chdir($path); + $text = `hg identify -n`; + chdir($cd); + + chomp $text; + if ($text =~ /^(\d+)/) + { + return $1; + } + + return 0; +} + +sub ProductVersion +{ + my ($file) = (@_); + my ($version); + open(FILE, $file) or die "Could not open $file: $!\n"; + $version = ; + close(FILE); + chomp $version; + return $version; +} + +sub Delete +{ + my ($str)=(@_); + if ($^O =~ /MSWin/) + { + Command("del /S /F /Q \"$str\""); + Command("rmdir /S /Q \"$str\""); + } else { + Command("rm -rf $str"); + } + return !(-e $str); +} + +sub Copy +{ + my ($src,$dest)=(@_); + if ($^O =~ /MSWin/) + { + Command("copy \"$src\" \"$dest\" /y"); + } else { + Command("cp \"$src\" \"$dest\""); + } + return (-e $dest); +} + +sub Move +{ + my ($src,$dest)=(@_); + if ($^O =~ /MSWin/) + { + Command("move \"$src\" \"$dest\""); + } else { + Command("mv \"$src\" \"$dest\""); + } + return (-e $dest); +} + +sub Command +{ + my($cmd)=(@_); + print "$cmd\n"; + return `$cmd`; +} + +sub PathFormat +{ + my ($str)=(@_); + if ($^O =~ /MSWin/) + { + $str =~ s#/#\\#g; + } else { + $str =~ s#\\#/#g; + } + return $str; +} + +return 1; diff --git a/buildbot/package.pl b/buildbot/package.pl new file mode 100644 index 0000000..d210a16 --- /dev/null +++ b/buildbot/package.pl @@ -0,0 +1,99 @@ +#!/usr/bin/perl + +use strict; +use Cwd; +use File::Basename; +use Net::FTP; + +my ($ftp_file, $ftp_host, $ftp_user, $ftp_pass, $ftp_path, $tag); + +$ftp_file = shift; +$tag = shift; + +open(FTP, $ftp_file) or die "Unable to read FTP config file $ftp_file: $!\n"; +$ftp_host = ; +$ftp_user = ; +$ftp_pass = ; +$ftp_path = ; +close(FTP); + +chomp $ftp_host; +chomp $ftp_user; +chomp $ftp_pass; +chomp $ftp_path; + +my ($myself, $path) = fileparse($0); +chdir($path); + +require 'helpers.pm'; + +my ($version); +$version = Build::ProductVersion(Build::PathFormat('product.version')); +$version .= '-hg' . Build::HgRevNum('.'); + +# Append OS to package version +if ($^O eq "darwin") +{ + $version .= '-mac'; +} +elsif ($^O =~ /MSWin/) +{ + $version .= '-windows'; +} +else +{ + $version .= '-' . $^O; +} + +#Switch to the output folder. +chdir(Build::PathFormat('../../OUTPUT/package')); + +my ($dirlist, $filename, $cmd); +$dirlist = "addons"; +$filename = 'sdkhooks-' . $version; +if ($^O eq "linux") +{ + $filename .= '.tar.gz'; + $cmd = "tar zcvf $filename $dirlist"; +} +else +{ + $filename .= '.zip'; + $cmd = "zip -r $filename $dirlist"; +} + +print "$cmd\n"; +system($cmd); + +$ftp_path .= "/sdkhooks"; + +my ($major,$minor) = ($version =~ /^(\d+)\.(\d+)/); +$ftp_path .= "/$major.$minor"; + +my ($ftp); + +$ftp = Net::FTP->new($ftp_host, Debug => 0, Passive => 0) + or die "Cannot connect to host $ftp_host: $@"; + +$ftp->login($ftp_user, $ftp_pass) + or die "Cannot connect to host $ftp_host as $ftp_user: " . $ftp->message . "\n"; + +if ($ftp_path ne '') +{ + # YOU LEAVE ME NO CHOICE + $ftp->mkdir($ftp_path, 1); + + $ftp->cwd($ftp_path) + or die "Cannot change to folder $ftp_path: " . $ftp->message . "\n"; +} + +$ftp->binary(); +$ftp->put($filename) + or die "Cannot drop file $filename ($ftp_path): " . $ftp->message . "\n"; + +$ftp->close(); + +print "File sent to drop site as $filename -- build succeeded.\n"; + +exit(0); + diff --git a/buildbot/product.version b/buildbot/product.version new file mode 100644 index 0000000..359a5b9 --- /dev/null +++ b/buildbot/product.version @@ -0,0 +1 @@ +2.0.0 \ No newline at end of file diff --git a/buildbot/startbuild.pl b/buildbot/startbuild.pl new file mode 100644 index 0000000..abe0dd3 --- /dev/null +++ b/buildbot/startbuild.pl @@ -0,0 +1,27 @@ +#!/usr/bin/perl +# vim: set ts=2 sw=2 tw=99 noet: + +use File::Basename; + +my ($myself, $path) = fileparse($0); +chdir($path); + +require 'helpers.pm'; + +chdir('../../OUTPUT'); + +if ($^O eq "linux" || $^O eq "darwin") { + system("python3 build.py 2>&1"); +} else { + system("C:\\Python31\\python.exe build.py 2>&1"); +} + +if ($? != 0) +{ + die "Build failed: $!\n"; +} +else +{ + exit(0); +} + diff --git a/buildbot/symstore.pl b/buildbot/symstore.pl new file mode 100644 index 0000000..7332903 --- /dev/null +++ b/buildbot/symstore.pl @@ -0,0 +1,64 @@ +#!/usr/bin/perl + +use File::Basename; + +my ($myself, $path) = fileparse($0); +chdir($path); + +require 'helpers.pm'; + +chdir('..'); + +open(PDBLOG, '../OUTPUT/pdblog.txt') or die "Could not open pdblog.txt: $!\n"; + +#Get version info +my ($version); +$version = Build::ProductVersion(Build::PathFormat('product.version')); +$version =~ s/-dev//g; +$version .= '-hg' . Build::HgRevNum('.'); + +my ($build_type); +$build_type = Build::GetBuildType(Build::PathFormat('buildbot/build_type')); + +if ($build_type eq "dev") +{ + $build_type = "buildbot"; +} +elsif ($build_type eq "rel") +{ + $build_type = "release"; +} + +my ($line); +while () +{ + $line = $_; + $line =~ s/\.pdb/\*/; + chomp $line; + Build::Command("symstore add /r /f \"..\\OUTPUT\\$line\" /s \"S:\\cssdm\" /t \"Stripper\" /v \"$version\" /c \"$build_type\""); +} + +close(PDBLOG); + +#Lowercase DLLs. Sigh. +my (@files); +opendir(DIR, "S:\\cssdm"); +@files = readdir(DIR); +closedir(DIR); + +my ($i, $j, $file, @subdirs); +for ($i = 0; $i <= $#files; $i++) +{ + $file = $files[$i]; + next unless ($file =~ /\.dll$/); + next unless (-d "S:\\cssdm\\$file"); + opendir(DIR, "S:\\cssdm\\$file"); + @subdirs = readdir(DIR); + closedir(DIR); + for ($j = 0; $j <= $#subdirs; $j++) + { + next unless ($subdirs[$j] =~ /[A-Z]/); + Build::Command("rename S:\\cssdm\\$file\\" . $subdirs[$j] . " " . lc($subdirs[$j])); + } +} + diff --git a/msvc10/sdk.vcxproj b/msvc10/sdk.vcxproj index 63c52c2..c1275cf 100644 --- a/msvc10/sdk.vcxproj +++ b/msvc10/sdk.vcxproj @@ -101,7 +101,7 @@ DynamicLibrary - v110 + v100 MultiByte true @@ -145,7 +145,7 @@ DynamicLibrary - v110 + v100 MultiByte true @@ -599,7 +599,7 @@ /MP /D SE_EPISODEONE=1 /D SE_DARKMESSIAH=2 /D SE_ORANGEBOX=3 /D SE_BLOODYGOODTIME=4 /D SE_EYE=5 /D SE_ORANGEBOXVALVE=6 /D SE_LEFT4DEAD=7 /D SE_LEFT4DEAD2=8 /D SE_ALIENSWARM=9 /D SE_PORTAL2=10 /D SE_CSGO=11 %(AdditionalOptions) Speed - ..;..\sdk;$(HL2SDKOBVALVE)\public;$(HL2SDKOBVALVE)\public\engine;$(HL2SDKOBVALVE)\public\game\server;$(HL2SDKOBVALVE)\public\tier0;$(HL2SDKOBVALVE)\public\tier1;$(MMSOURCE19)\core;$(MMSOURCE19)\core\sourcehook;$(SMCENTRAL)\public;$(SMCENTRAL)\public\sourcepawn;$(SMCENTRAL)\public\extensions;$(HL2SDKOBVALVE)\game\server;$(HL2SDKOBVALVE)\game\shared;$(SMCENTRAL)\public\jit;$(SMCENTRAL)\public\jit\x86;%(AdditionalIncludeDirectories) + ..;..\sdk;$(HL2SDKOBVALVE)\public;$(HL2SDKOBVALVE)\public\engine;$(HL2SDKOBVALVE)\public\game\server;$(HL2SDKOBVALVE)\public\tier0;$(HL2SDKOBVALVE)\public\tier1;$(MMSOURCE19)\core;$(MMSOURCE19)\core\sourcehook;$(SMCENTRAL)\public;$(SMCENTRAL)\public\sourcepawn;$(SMCENTRAL)\public\extensions;$(HL2SDKOBVALVE)\game\server;$(HL2SDKOBVALVE)\game\shared;$(SMCENTRAL)\public\jit;$(SMCENTRAL)\public\jit\x86;$(SMCENTRAL)\public\amtl;%(AdditionalIncludeDirectories) WIN32;NDEBUG;_WINDOWS;_USRDLL;SDK_EXPORTS;_CRT_SECURE_NO_DEPRECATE;SOURCEMOD_BUILD;SOURCE_ENGINE=6;%(PreprocessorDefinitions) MultiThreaded NotSet @@ -807,7 +807,7 @@ /MP /D SE_EPISODEONE=1 /D SE_DARKMESSIAH=2 /D SE_ORANGEBOX=3 /D SE_BLOODYGOODTIME=4 /D SE_EYE=5 /D SE_ORANGEBOXVALVE=6 /D SE_LEFT4DEAD=7 /D SE_LEFT4DEAD2=8 /D SE_ALIENSWARM=9 /D SE_PORTAL2=10 /D SE_CSGO=11 %(AdditionalOptions) Speed - ..;..\sdk;..\..;..\..\sourcepawn;$(HL2SDKCSGO)\public;$(HL2SDKCSGO)\public\engine;$(HL2SDKCSGO)\public\game\server;$(HL2SDKCSGO)\public\tier0;$(HL2SDKCSGO)\public\tier1;$(MMSOURCE19)\core;$(MMSOURCE19)\core\sourcehook;%(AdditionalIncludeDirectories) + ..;..\sdk;$(HL2SDKCSGO)\public;$(HL2SDKCSGO)\public\engine;$(HL2SDKCSGO)\public\game\server;$(HL2SDKCSGO)\public\tier0;$(HL2SDKCSGO)\public\tier1;$(MMSOURCE19)\core;$(MMSOURCE19)\core\sourcehook;$(SMCENTRAL)\public;$(SMCENTRAL)\public\sourcepawn;$(SMCENTRAL)\public\extensions;$(HL2SDKCSGO)\game\server;$(HL2SDKCSGO)\game\shared;$(SMCENTRAL)\public\jit;$(SMCENTRAL)\public\jit\x86;$(SMCENTRAL)\public\amtl WIN32;NDEBUG;_WINDOWS;_USRDLL;SDK_EXPORTS;_CRT_SECURE_NO_DEPRECATE;SOURCEMOD_BUILD;COMPILER_MSVC;COMPILER_MSVC32;SOURCE_ENGINE=11;%(PreprocessorDefinitions) MultiThreaded NotSet @@ -817,8 +817,8 @@ ProgramDatabase - $(HL2SDKCSGO)\lib\public\interfaces.lib;$(HL2SDKCSGO)\lib\public\tier0.lib;$(HL2SDKCSGO)\lib\public\tier1.lib;$(HL2SDKCSGO)\lib\public\vstdlib.lib;%(AdditionalDependencies) - $(OutDir)sample.ext.2.csgo.dll + $(HL2SDKCSGO)\lib\public\interfaces.lib;$(HL2SDKCSGO)\lib\public\tier1.lib;$(HL2SDKCSGO)\lib\public\vstdlib.lib;$(HL2SDKCSGO)\lib\public\tier0.lib + $(OutDir)dhooks.ext.2.csgo.dll LIBC;LIBCD;LIBCMTD;%(IgnoreSpecificDefaultLibraries) true Windows diff --git a/vfunc_call.h b/vfunc_call.h index 4f2fefc..4162cee 100644 --- a/vfunc_call.h +++ b/vfunc_call.h @@ -132,7 +132,85 @@ T CallVFunction(DHooksCallback *dg, HookParamsStruct *paramStruct, void *iface) return ret; } +template <> +Vector CallVFunction(DHooksCallback *dg, HookParamsStruct *paramStruct, void *iface) +{ + SourceMod::PassInfo *paramInfo = NULL; + SourceMod::PassInfo returnInfo; + if(dg->returnType != ReturnType_Void) + { + returnInfo.flags = dg->returnFlag; + returnInfo.size = sizeof(Vector); + returnInfo.type = PassType_Object; + } + + ICallWrapper *pCall; + + size_t size = GetStackArgsSize(dg); + + unsigned char *vstk = (unsigned char *)malloc(sizeof(void *) + size); + unsigned char *vptr = vstk; + + *(void **)vptr = iface; + + if(paramStruct) + { + vptr += sizeof(void *); + paramInfo = (SourceMod::PassInfo *)malloc(sizeof(SourceMod::PassInfo) * dg->params.Count()); + for(int i = 0; i < dg->params.Count(); i++) + { + switch(dg->params.Element(i).type) + { + case HookParamType_Int: + PARAMINFO_SWITCH(PassType_Basic); + VSTK_PARAM_SWITCH(int); + case HookParamType_Bool: + PARAMINFO_SWITCH(PassType_Basic); + VSTK_PARAM_SWITCH(cell_t); + case HookParamType_Float: + PARAMINFO_SWITCH(PassType_Float); + VSTK_PARAM_SWITCH_FLOAT(); + case HookParamType_String: + PARAMINFO_SWITCH(PassType_Object); + VSTK_PARAM_SWITCH(int); + case HookParamType_StringPtr: + PARAMINFO_SWITCH(PassType_Basic); + VSTK_PARAM_SWITCH(string_t *); + case HookParamType_CharPtr: + PARAMINFO_SWITCH(PassType_Basic); + VSTK_PARAM_SWITCH(char *); + case HookParamType_VectorPtr: + PARAMINFO_SWITCH(PassType_Basic); + VSTK_PARAM_SWITCH(Vector *); + case HookParamType_CBaseEntity: + PARAMINFO_SWITCH(PassType_Basic); + VSTK_PARAM_SWITCH(CBaseEntity *); + case HookParamType_Edict: + PARAMINFO_SWITCH(PassType_Basic); + VSTK_PARAM_SWITCH(edict_t *); + default: + PARAMINFO_SWITCH(PassType_Basic); + VSTK_PARAM_SWITCH(void *); + } + } + } + + Vector ret; + + pCall = g_pBinTools->CreateVCall(dg->offset, 0, 0, &returnInfo, paramInfo, dg->params.Count()); + pCall->Execute(vstk, &ret); + + pCall->Destroy(); + free(vstk); + + if(paramInfo != NULL) + { + free(paramInfo); + } + + return ret; +} #ifdef __linux__ template <> string_t CallVFunction(DHooksCallback *dg, HookParamsStruct *paramStruct, void *iface) @@ -198,18 +276,10 @@ string_t CallVFunction(DHooksCallback *dg, HookParamsStruct *paramStru } } - string_t ret = NULL_STRING; - - if(dg->returnType == ReturnType_Void) - { - pCall = g_pBinTools->CreateVCall(dg->offset, 0, 0, NULL, paramInfo, dg->params.Count()); - pCall->Execute(vstk, NULL); - } - else - { - pCall = g_pBinTools->CreateVCall(dg->offset, 0, 0, &returnInfo, paramInfo, dg->params.Count()); - pCall->Execute(vstk, &ret); - } + string_t ret; + + pCall = g_pBinTools->CreateVCall(dg->offset, 0, 0, &returnInfo, paramInfo, dg->params.Count()); + pCall->Execute(vstk, &ret); pCall->Destroy(); free(vstk);