From e00b17d5039e88fae48d2e39a985c07b15227c66 Mon Sep 17 00:00:00 2001 From: caxanga334 <10157643+caxanga334@users.noreply.github.com> Date: Sat, 27 Jan 2024 13:31:58 -0300 Subject: [PATCH 1/8] Modernize Build Scripts --- public/sample_ext/AMBuildScript | 478 +++++++++++++------------- public/sample_ext/AMBuilder | 23 +- public/sample_ext/PackageScript | 10 +- public/sample_ext/configure.py | 30 +- public/sample_ext_nosdk/AMBuildScript | 163 ++++++--- public/sample_ext_nosdk/AMBuilder | 6 +- public/sample_ext_nosdk/PackageScript | 11 +- public/sample_ext_nosdk/configure.py | 18 +- 8 files changed, 415 insertions(+), 324 deletions(-) diff --git a/public/sample_ext/AMBuildScript b/public/sample_ext/AMBuildScript index bf48ee5097..2b732ae304 100644 --- a/public/sample_ext/AMBuildScript +++ b/public/sample_ext/AMBuildScript @@ -1,47 +1,5 @@ # vim: set sts=2 ts=8 sw=2 tw=99 et ft=python: -import os, sys - -# Simple extensions do not need to modify this file. - -class SDK(object): - def __init__(self, sdk, ext, aDef, name, platform, dir): - self.folder = 'hl2sdk-' + dir - self.envvar = sdk - self.ext = ext - self.code = aDef - self.define = name - self.platform = platform - self.name = dir - self.path = None # Actual path - -WinOnly = ['windows'] -WinLinux = ['windows', 'linux'] -WinLinuxMac = ['windows', 'linux', 'mac'] - -PossibleSDKs = { - 'episode1': SDK('HL2SDK', '1.ep1', '1', 'EPISODEONE', WinLinux, 'episode1'), - 'ep2': SDK('HL2SDKOB', '2.ep2', '3', 'ORANGEBOX', WinLinux, 'orangebox'), - 'css': SDK('HL2SDKCSS', '2.css', '6', 'CSS', WinLinuxMac, 'css'), - 'hl2dm': SDK('HL2SDKHL2DM', '2.hl2dm', '7', 'HL2DM', WinLinuxMac, 'hl2dm'), - 'dods': SDK('HL2SDKDODS', '2.dods', '8', 'DODS', WinLinuxMac, 'dods'), - 'sdk2013': SDK('HL2SDK2013', '2.sdk2013', '9', 'SDK2013', WinLinuxMac, 'sdk2013'), - 'tf2': SDK('HL2SDKTF2', '2.tf2', '12', 'TF2', WinLinuxMac, 'tf2'), - 'l4d': SDK('HL2SDKL4D', '2.l4d', '13', 'LEFT4DEAD', WinLinuxMac, 'l4d'), - 'nucleardawn': SDK('HL2SDKND', '2.nd', '14', 'NUCLEARDAWN', WinLinuxMac, 'nucleardawn'), - 'l4d2': SDK('HL2SDKL4D2', '2.l4d2', '16', 'LEFT4DEAD2', WinLinuxMac, 'l4d2'), - 'darkm': SDK('HL2SDK-DARKM', '2.darkm', '2', 'DARKMESSIAH', WinOnly, 'darkm'), - 'swarm': SDK('HL2SDK-SWARM', '2.swarm', '17', 'ALIENSWARM', WinOnly, 'swarm'), - 'bgt': SDK('HL2SDK-BGT', '2.bgt', '4', 'BLOODYGOODTIME', WinOnly, 'bgt'), - 'eye': SDK('HL2SDK-EYE', '2.eye', '5', 'EYE', WinOnly, 'eye'), - 'csgo': SDK('HL2SDKCSGO', '2.csgo', '22', 'CSGO', WinLinuxMac, 'csgo'), - 'portal2': SDK('HL2SDKPORTAL2', '2.portal2', '18', 'PORTAL2', [], 'portal2'), - 'blade': SDK('HL2SDKBLADE', '2.blade', '19', 'BLADE', WinLinux, 'blade'), - 'insurgency': SDK('HL2SDKINSURGENCY', '2.insurgency', '20', 'INSURGENCY', WinLinuxMac, 'insurgency'), - 'contagion': SDK('HL2SDKCONTAGION', '2.contagion', '15', 'CONTAGION', WinOnly, 'contagion'), - 'bms': SDK('HL2SDKBMS', '2.bms', '11', 'BMS', WinLinux, 'bms'), - 'doi': SDK('HL2SDKDOI', '2.doi', '21', 'DOI', WinLinuxMac, 'doi'), - 'pvkii': SDK('HL2SDKPVKII', '2.pvkii', '10', 'PVKII', WinLinux, 'pvkii'), -} +import os, shutil def ResolveEnvPath(env, folder): if env in os.environ: @@ -63,15 +21,72 @@ def ResolveEnvPath(env, folder): def Normalize(path): return os.path.abspath(os.path.normpath(path)) + +def SetArchFlags(compiler): + if compiler.behavior == 'gcc': + if compiler.target.arch == 'x86_64': + compiler.cflags += ['-fPIC'] + elif compiler.like('msvc'): + if compiler.target.arch == 'x86_64': + compiler.defines += ['WIN64'] + +hl2sdk_manifests_root = None +hl2sdk_manifests_dest = Normalize(builder.sourcePath + '/hl2sdk-manifests/') + +if not builder.options.hl2sdk_manifest: + if not os.path.exists(hl2sdk_manifests_dest): # if no root was specified and an hl2sdk-manifests folder does not exists in the source folder + raise Exception('HL2SDK Manifests directory not found! Set --hl2sdk-manifest-path or manually copy the hl2sdk manifests folder to the current source folder.') +else: + # The HL2SDK Manifest looks for the manifest file based on the current sourcePath, so we need to copy it to our sourcePath first + hl2sdk_manifests_root = Normalize(builder.options.hl2sdk_manifest + '/') + + if not os.path.exists(hl2sdk_manifests_dest): + shutil.copytree(hl2sdk_manifests_root, hl2sdk_manifests_dest) + else: + print('HL2SDK Manifests folder already exists, not copying.') + +SdkHelpers = builder.Eval('hl2sdk-manifests/SdkHelpers.ambuild', { + 'Project': 'sm-extension' +}) class ExtensionConfig(object): def __init__(self): + self.sdk_manifests = [] self.sdks = {} - self.binaries = [] + self.sdk_targets = [] self.extensions = [] self.generated_headers = None self.mms_root = None self.sm_root = None + self.all_targets = [] + self.target_archs = set() + + if builder.options.targets: + target_archs = builder.options.targets.split(',') + else: + target_archs = ['x86'] + if builder.backend != 'amb2': + target_archs.append('x86_64') + + for arch in target_archs: + try: + cxx = builder.DetectCxx(target_arch = arch) + self.target_archs.add(cxx.target.arch) + except Exception as e: + # Error if archs were manually overridden. + if builder.options.targets: + raise + print('Skipping target {}: {}'.format(arch, e)) + continue + self.all_targets.append(cxx) + + if not self.all_targets: + raise Exception('No suitable C/C++ compiler was found.') + + def use_auto_versioning(self): + if builder.backend != 'amb2': + return False + return not getattr(builder.options, 'disable_auto_versioning', False) @property def tag(self): @@ -79,48 +94,33 @@ class ExtensionConfig(object): return 'Debug' return 'Release' - def detectSDKs(self): - sdk_list = builder.options.sdks.split(',') - use_all = sdk_list[0] == 'all' - use_present = sdk_list[0] == 'present' - - for sdk_name in PossibleSDKs: - sdk = PossibleSDKs[sdk_name] - if builder.target_platform in sdk.platform: - if builder.options.hl2sdk_root: - sdk_path = os.path.join(builder.options.hl2sdk_root, sdk.folder) - else: - sdk_path = ResolveEnvPath(sdk.envvar, sdk.folder) - if sdk_path is None or not os.path.isdir(sdk_path): - if use_all or sdk_name in sdk_list: - raise Exception('Could not find a valid path for {0}'.format(sdk.envvar)) - continue - if use_all or use_present or sdk_name in sdk_list: - sdk.path = Normalize(sdk_path) - self.sdks[sdk_name] = sdk - - if len(self.sdks) < 1: - raise Exception('At least one SDK must be available.') + def findSdkPath(self, sdk_name): + dir_name = 'hl2sdk-{}'.format(sdk_name) + if builder.options.hl2sdk_root: + sdk_path = os.path.join(builder.options.hl2sdk_root, dir_name) + if os.path.exists(sdk_path): + return sdk_path + return ResolveEnvPath('HL2SDK{}'.format(sdk_name.upper()), dir_name) - if builder.options.sm_path: - self.sm_root = builder.options.sm_path - else: - self.sm_root = ResolveEnvPath('SOURCEMOD18', 'sourcemod-1.8') - if not self.sm_root: - self.sm_root = ResolveEnvPath('SOURCEMOD', 'sourcemod') - if not self.sm_root: - self.sm_root = ResolveEnvPath('SOURCEMOD_DEV', 'sourcemod-central') + def shouldIncludeSdk(self, sdk): + return not sdk.get('source2', False) - if not self.sm_root or not os.path.isdir(self.sm_root): - raise Exception('Could not find a source copy of SourceMod') - self.sm_root = Normalize(self.sm_root) + def detectSDKs(self): + sdk_list = [s for s in builder.options.sdks.split(',') if s] + SdkHelpers.sdk_filter = self.shouldIncludeSdk + SdkHelpers.find_sdk_path = self.findSdkPath + SdkHelpers.findSdks(builder, self.all_targets, sdk_list) + + self.sdks = SdkHelpers.sdks + self.sdk_manifests = SdkHelpers.sdk_manifests + self.sdk_targets = SdkHelpers.sdk_targets if builder.options.mms_path: self.mms_root = builder.options.mms_path else: self.mms_root = ResolveEnvPath('MMSOURCE112', 'mmsource-1.12') if not self.mms_root: - self.mms_root = ResolveEnvPath('MMSOURCE', 'metamod-source') + self.mms_root = ResolveEnvPath('MMSOURCE_DEV', 'metamod-source') if not self.mms_root: self.mms_root = ResolveEnvPath('MMSOURCE_DEV', 'mmsource-central') @@ -128,15 +128,46 @@ class ExtensionConfig(object): raise Exception('Could not find a source copy of Metamod:Source') self.mms_root = Normalize(self.mms_root) + if builder.options.sm_path: + self.sm_root = builder.options.sm_path + else: + self.sm_root = ResolveEnvPath('SOURCEMOD112', 'sourcemod-1.12') + if not self.sm_root: + self.sm_root = ResolveEnvPath('SOURCEMOD_DEV', 'sourcemod') + if not self.sm_root: + self.sm_root = ResolveEnvPath('SOURCEMOD_DEV', 'sourcemod-central') + + if not self.sm_root or not os.path.isdir(self.sm_root): + raise Exception('Could not find a source copy of SourceMod') + self.sm_root = Normalize(self.sm_root) + def configure(self): - cxx = builder.DetectCompilers() + + allowed_archs = ['x86','x86_64'] + + if not set(self.target_archs).issubset(allowed_archs): + raise Exception('Unknown target architecture: {0}'.format(self.target_archs)) + + for cxx in self.all_targets: + self.configure_cxx(cxx) + + def configure_cxx(self, cxx): + if cxx.family == 'msvc': + if cxx.version < 1914 and builder.options.generator != 'vs': + raise Exception(f'Only MSVC 2017 15.7 and later are supported, full C++17 support is required. ({str(cxx.version)} < 1914)') + elif cxx.family == 'gcc': + if cxx.version < 'gcc-9': + raise Exception('Only GCC versions 9 or later are supported, full C++17 support is required.') + elif cxx.family == 'clang': + if cxx.version < 'clang-5': + raise Exception('Only clang versions 5 or later are supported, full C++17 support is required.') if cxx.like('gcc'): self.configure_gcc(cxx) - elif cxx.vendor == 'msvc': + elif cxx.family == 'msvc': self.configure_msvc(cxx) - # Optimization + # Optimizaiton if builder.options.opt == '1': cxx.defines += ['NDEBUG'] @@ -145,16 +176,15 @@ class ExtensionConfig(object): cxx.defines += ['DEBUG', '_DEBUG'] # Platform-specifics - if builder.target_platform == 'linux': + if cxx.target.platform == 'linux': self.configure_linux(cxx) - elif builder.target_platform == 'mac': + elif cxx.target.platform == 'mac': self.configure_mac(cxx) - elif builder.target_platform == 'windows': + elif cxx.target.platform == 'windows': self.configure_windows(cxx) - # Finish up. cxx.includes += [ - os.path.join(self.sm_root, 'public'), + os.path.join(builder.sourcePath, 'public'), ] def configure_gcc(self, cxx): @@ -174,31 +204,39 @@ class ExtensionConfig(object): '-Wno-unused', '-Wno-switch', '-Wno-array-bounds', - '-msse', - '-m32', '-fvisibility=hidden', ] + if cxx.target.arch in ['x86', 'x86_64']: + cxx.cflags += ['-msse'] + + cxx.cxxflags += ['-std=c++17'] + cxx.cxxflags += [ - '-std=c++14', - '-fno-exceptions', '-fno-threadsafe-statics', '-Wno-non-virtual-dtor', '-Wno-overloaded-virtual', + '-Wno-register', '-fvisibility-inlines-hidden', ] - cxx.linkflags += ['-m32'] - have_gcc = cxx.vendor == 'gcc' - have_clang = cxx.vendor == 'clang' - if cxx.version >= 'clang-3.6': + have_gcc = cxx.family == 'gcc' + have_clang = cxx.family == 'clang' + if cxx.version >= 'clang-3.9' or cxx.version == 'clang-3.4' or cxx.version > 'apple-clang-6.0': + cxx.cxxflags += ['-Wno-expansion-to-defined'] + if cxx.version == 'clang-3.9' or cxx.version == 'apple-clang-8.0': + cxx.cflags += ['-Wno-varargs'] + if cxx.version >= 'clang-3.4' or cxx.version >= 'apple-clang-7.0': cxx.cxxflags += ['-Wno-inconsistent-missing-override'] + if cxx.version >= 'clang-2.9' or cxx.version >= 'apple-clang-3.0': + cxx.cxxflags += ['-Wno-null-dereference'] if have_clang or (cxx.version >= 'gcc-4.6'): cxx.cflags += ['-Wno-narrowing'] if have_clang or (cxx.version >= 'gcc-4.7'): cxx.cxxflags += ['-Wno-delete-non-virtual-dtor'] if cxx.version >= 'gcc-4.8': cxx.cflags += ['-Wno-unused-result'] - + if cxx.version >= 'gcc-9.0': + cxx.cxxflags += ['-Wno-class-memaccess', '-Wno-packed-not-aligned'] if have_clang: cxx.cxxflags += ['-Wno-implicit-exception-spec-mismatch'] if cxx.version >= 'apple-clang-5.1' or cxx.version >= 'clang-3.4': @@ -207,13 +245,25 @@ class ExtensionConfig(object): cxx.cxxflags += ['-Wno-deprecated'] cxx.cflags += ['-Wno-sometimes-uninitialized'] + # Work around SDK warnings. + if cxx.version >= 'clang-10.0' or cxx.version >= 'apple-clang-12.0': + cxx.cflags += [ + '-Wno-implicit-int-float-conversion', + '-Wno-tautological-overlap-compare', + ] + if have_gcc: cxx.cflags += ['-mfpmath=sse'] + cxx.cflags += ['-Wno-maybe-uninitialized'] if builder.options.opt == '1': - cxx.cflags += ['-O3'] + cxx.cflags += ['-O3'] + + # Don't omit the frame pointer. + cxx.cflags += ['-fno-omit-frame-pointer'] def configure_msvc(self, cxx): + if builder.options.debug == '1': cxx.cflags += ['/MTd'] cxx.linkflags += ['/NODEFAULTLIB:libcmt'] @@ -232,9 +282,9 @@ class ExtensionConfig(object): '/EHsc', '/GR-', '/TP', + '/std:c++17', ] cxx.linkflags += [ - '/MACHINE:X86', 'kernel32.lib', 'user32.lib', 'gdi32.lib', @@ -261,27 +311,66 @@ class ExtensionConfig(object): cxx.cflags += ['/Oy-'] def configure_linux(self, cxx): - cxx.defines += ['_LINUX', 'POSIX'] - cxx.linkflags += ['-Wl,--exclude-libs,ALL', '-lm'] - if cxx.vendor == 'gcc': + cxx.defines += ['LINUX', '_LINUX', 'POSIX', '_FILE_OFFSET_BITS=64'] + cxx.linkflags += ['-lm'] + if cxx.family == 'gcc': cxx.linkflags += ['-static-libgcc'] - elif cxx.vendor == 'clang': + elif cxx.family == 'clang': cxx.linkflags += ['-lgcc_eh'] + cxx.linkflags += ['-static-libstdc++'] def configure_mac(self, cxx): - cxx.defines += ['OSX', '_OSX', 'POSIX'] - cxx.cflags += ['-mmacosx-version-min=10.5'] + cxx.defines += ['OSX', '_OSX', 'POSIX', 'KE_ABSOLUTELY_NO_STL'] + cxx.cflags += ['-mmacosx-version-min=10.15'] cxx.linkflags += [ - '-mmacosx-version-min=10.5', - '-arch', 'i386', - '-lstdc++', - '-stdlib=libstdc++', + '-mmacosx-version-min=10.15', + '-stdlib=libc++', + '-lc++', ] - cxx.cxxflags += ['-stdlib=libstdc++'] + cxx.cxxflags += ['-stdlib=libc++'] def configure_windows(self, cxx): cxx.defines += ['WIN32', '_WINDOWS'] - + + def LibraryBuilder(self, compiler, name): + binary = compiler.Library(name) + self.AddVersioning(binary) + if binary.compiler.like('msvc'): + binary.compiler.linkflags += ['/SUBSYSTEM:WINDOWS'] + self.AddCxxCompat(binary) + return binary + + def ProgramBuilder(self, compiler, name): + binary = compiler.Program(name) + self.AddVersioning(binary) + if '-static-libgcc' in binary.compiler.linkflags: + binary.compiler.linkflags.remove('-static-libgcc') + if '-lgcc_eh' in binary.compiler.linkflags: + binary.compiler.linkflags.remove('-lgcc_eh') + if binary.compiler.like('gcc'): + binary.compiler.linkflags += ['-lstdc++', '-lpthread'] + if binary.compiler.like('msvc'): + binary.compiler.linkflags += ['/SUBSYSTEM:CONSOLE'] + return binary + + def StaticLibraryBuilder(self, compiler, name): + return compiler.StaticLibrary(name) + + def Library(self, context, compiler, name): + compiler = compiler.clone() + SetArchFlags(compiler) + return self.LibraryBuilder(compiler, name) + + def Program(self, context, compiler, name): + compiler = compiler.clone() + SetArchFlags(compiler) + return self.ProgramBuilder(compiler, name) + + def StaticLibrary(self, context, compiler, name): + compiler = compiler.clone() + SetArchFlags(compiler) + return self.StaticLibraryBuilder(compiler, name) + def ConfigureForExtension(self, context, compiler): compiler.cxxincludes += [ os.path.join(context.currentSourcePath), @@ -294,149 +383,61 @@ class ExtensionConfig(object): ] return compiler - def ConfigureForHL2(self, binary, sdk): - compiler = binary.compiler + def ExtLibrary(self, context, compiler, name): + binary = self.Library(context, compiler, name) + SetArchFlags(compiler) + self.ConfigureForExtension(context, binary.compiler) + return binary - if sdk.name == 'episode1': - mms_path = os.path.join(self.mms_root, 'core-legacy') - else: - mms_path = os.path.join(self.mms_root, 'core') + def AddCxxCompat(self, binary): + if binary.compiler.target.platform == 'linux': + binary.sources += [ + os.path.join(self.sm_root, 'public', 'amtl', 'compat', 'stdcxx.cpp'), + ] - compiler.cxxincludes += [ - os.path.join(mms_path), - os.path.join(mms_path, 'sourcehook'), - ] - - defines = ['SE_' + PossibleSDKs[i].define + '=' + PossibleSDKs[i].code for i in PossibleSDKs] - compiler.defines += defines + def ConfigureForHL2(self, context, binary, sdk): + compiler = binary.compiler + SetArchFlags(compiler) - paths = [ - ['public'], - ['public', 'engine'], - ['public', 'mathlib'], - ['public', 'vstdlib'], - ['public', 'tier0'], - ['public', 'tier1'] + compiler.cxxincludes += [ + os.path.join(self.mms_root, 'core'), + os.path.join(self.mms_root, 'core', 'sourcehook'), ] - if sdk.name == 'episode1' or sdk.name == 'darkm': - paths.append(['public', 'dlls']) - paths.append(['game_shared']) - else: - paths.append(['public', 'game', 'server']) - paths.append(['public', 'toolframework']) - paths.append(['game', 'shared']) - paths.append(['common']) - - compiler.defines += ['SOURCE_ENGINE=' + sdk.code] - - if sdk.name in ['sdk2013', 'bms', 'pvkii'] and compiler.like('gcc'): - # The 2013 SDK already has these in public/tier0/basetypes.h - compiler.defines.remove('stricmp=strcasecmp') - compiler.defines.remove('_stricmp=strcasecmp') - compiler.defines.remove('_snprintf=snprintf') - compiler.defines.remove('_vsnprintf=vsnprintf') - - if compiler.like('msvc'): - compiler.defines += ['COMPILER_MSVC', 'COMPILER_MSVC32'] - else: - compiler.defines += ['COMPILER_GCC'] - - # For everything after Swarm, this needs to be defined for entity networking - # to work properly with sendprop value changes. - if sdk.name in ['blade', 'insurgency', 'doi', 'csgo']: - compiler.defines += ['NETWORK_VARS_ENABLED'] - - if sdk.name in ['css', 'hl2dm', 'dods', 'sdk2013', 'bms', 'tf2', 'l4d', 'nucleardawn', 'l4d2', 'pvkii']: - if builder.target_platform in ['linux', 'mac']: - compiler.defines += ['NO_HOOK_MALLOC', 'NO_MALLOC_OVERRIDE'] - if sdk.name == 'csgo' and builder.target_platform == 'linux': - compiler.linkflags += ['-lstdc++'] + for other_sdk in self.sdk_manifests: + compiler.defines += ['SE_{}={}'.format(other_sdk['define'], other_sdk['code'])] - for path in paths: - compiler.cxxincludes += [os.path.join(sdk.path, *path)] - - if builder.target_platform == 'linux': - if sdk.name == 'episode1': - lib_folder = os.path.join(sdk.path, 'linux_sdk') - elif sdk.name in ['sdk2013', 'bms', 'pvkii']: - lib_folder = os.path.join(sdk.path, 'lib', 'public', 'linux32') - else: - lib_folder = os.path.join(sdk.path, 'lib', 'linux') - elif builder.target_platform == 'mac': - if sdk.name in ['sdk2013', 'bms']: - lib_folder = os.path.join(sdk.path, 'lib', 'public', 'osx32') - else: - lib_folder = os.path.join(sdk.path, 'lib', 'mac') - - if builder.target_platform in ['linux', 'mac']: - if sdk.name in ['sdk2013', 'bms', 'pvkii']: - compiler.postlink += [ - compiler.Dep(os.path.join(lib_folder, 'tier1.a')), - compiler.Dep(os.path.join(lib_folder, 'mathlib.a')) - ] - else: - compiler.postlink += [ - compiler.Dep(os.path.join(lib_folder, 'tier1_i486.a')), - compiler.Dep(os.path.join(lib_folder, 'mathlib_i486.a')) - ] - - if sdk.name in ['blade', 'insurgency', 'doi', 'csgo']: - compiler.postlink += [compiler.Dep(os.path.join(lib_folder, 'interfaces_i486.a'))] - - dynamic_libs = [] - if builder.target_platform == 'linux': - if sdk.name in ['css', 'hl2dm', 'dods', 'tf2', 'sdk2013', 'bms', 'nucleardawn', 'l4d2', 'insurgency', 'doi']: - dynamic_libs = ['libtier0_srv.so', 'libvstdlib_srv.so'] - elif sdk.name in ['l4d', 'blade', 'insurgency', 'doi', 'csgo', 'pvkii']: - dynamic_libs = ['libtier0.so', 'libvstdlib.so'] - else: - dynamic_libs = ['tier0_i486.so', 'vstdlib_i486.so'] - elif builder.target_platform == 'mac': - compiler.linkflags.append('-liconv') - dynamic_libs = ['libtier0.dylib', 'libvstdlib.dylib'] - elif builder.target_platform == 'windows': - libs = ['tier0', 'tier1', 'vstdlib', 'mathlib'] - if sdk.name in ['swarm', 'blade', 'insurgency', 'doi', 'csgo']: - libs.append('interfaces') - for lib in libs: - lib_path = os.path.join(sdk.path, 'lib', 'public', lib) + '.lib' - compiler.linkflags.append(compiler.Dep(lib_path)) - - for library in dynamic_libs: - source_path = os.path.join(lib_folder, library) - output_path = os.path.join(binary.localFolder, library) - - def make_linker(source_path, output_path): - def link(context, binary): - cmd_node, (output,) = context.AddSymlink(source_path, output_path) - return output - return link - - linker = make_linker(source_path, output_path) - compiler.linkflags[0:0] = [compiler.Dep(library, linker)] + SdkHelpers.configureCxx(context, binary, sdk) return binary - def HL2Library(self, context, name, sdk): - binary = context.compiler.Library(name) + def HL2Library(self, context, compiler, name, sdk): + binary = self.Library(context, compiler, name) self.ConfigureForExtension(context, binary.compiler) - return self.ConfigureForHL2(binary, sdk) - - def HL2Project(self, context, name): - project = context.compiler.LibraryProject(name) - self.ConfigureForExtension(context, project.compiler) - return project - - def HL2Config(self, project, name, sdk): - binary = project.Configure(name, '{0} - {1}'.format(self.tag, sdk.name)) - return self.ConfigureForHL2(binary, sdk) + return self.ConfigureForHL2(context, binary, sdk) + + def HL2Config(self, project, context, compiler, name, sdk): + binary = project.Configure(compiler, name, + '{0} - {1} {2}'.format(self.tag, sdk['name'], compiler.target.arch)) + self.AddCxxCompat(binary) + return self.ConfigureForHL2(context, binary, sdk) + + def HL2ExtConfig(self, project, context, compiler, name, sdk): + binary = project.Configure(compiler, name, + '{0} - {1} {2}'.format(self.tag, sdk['name'], compiler.target.arch)) + self.AddCxxCompat(binary) + self.ConfigureForHL2(context, binary, sdk) + self.ConfigureForExtension(context, binary.compiler) + return binary Extension = ExtensionConfig() Extension.detectSDKs() Extension.configure() -# Add additional buildscripts here +# This will clone the list and each cxx object as we recurse, preventing child +# scripts from messing up global state. +builder.targets = builder.CloneableList(Extension.all_targets) + BuildScripts = [ 'AMBuilder', ] @@ -446,4 +447,5 @@ if builder.backend == 'amb2': 'PackageScript', ] -builder.RunBuildScripts(BuildScripts, { 'Extension': Extension}) +builder.Build(BuildScripts, { 'Extension': Extension }) + diff --git a/public/sample_ext/AMBuilder b/public/sample_ext/AMBuilder index a4c106f393..e4339d5407 100644 --- a/public/sample_ext/AMBuilder +++ b/public/sample_ext/AMBuilder @@ -1,18 +1,15 @@ # vim: set sts=2 ts=8 sw=2 tw=99 et ft=python: -import os, sys +import os projectName = 'sample' +extName = projectName + '.ext' # smsdk_ext.cpp will be automatically added later sourceFiles = [ 'extension.cpp', ] -############### -# Make sure to edit PackageScript, which copies your files to their appropriate locations -# Simple extensions do not need to modify past this point. - -project = Extension.HL2Project(builder, projectName + '.ext') +project = builder.LibraryProject(extName) if os.path.isfile(os.path.join(builder.currentSourcePath, 'sdk', 'smsdk_ext.cpp')): # Use the copy included in the project @@ -22,10 +19,16 @@ else: project.sources += [os.path.join(Extension.sm_root, 'public', 'smsdk_ext.cpp')] project.sources += sourceFiles - + for sdk_name in Extension.sdks: sdk = Extension.sdks[sdk_name] - - binary = Extension.HL2Config(project, projectName + '.ext.' + sdk.ext, sdk) + if sdk['name'] in ['mock']: + continue + + for cxx in builder.targets: + if not cxx.target.arch in sdk['platforms'][cxx.target.platform]: + continue + + binary = Extension.HL2ExtConfig(project, builder, cxx, extName + sdk['extension'], sdk) -Extension.extensions = builder.Add(project) +Extension.extensions += builder.Add(project) diff --git a/public/sample_ext/PackageScript b/public/sample_ext/PackageScript index 36ce6e48ec..d65b550986 100644 --- a/public/sample_ext/PackageScript +++ b/public/sample_ext/PackageScript @@ -13,6 +13,11 @@ folder_list = [ #'addons/sourcemod/configs', ] +if 'x86_64' in Extension.target_archs: + folder_list.extend([ + 'addons/sourcemod/extensions/x64', + ]) + # Create the distribution folder hierarchy. folder_map = {} for folder in folder_list: @@ -49,4 +54,7 @@ def CopyFiles(src, dest, files): # Copy binaries. for cxx_task in Extension.extensions: - builder.AddCopy(cxx_task.binary, folder_map['addons/sourcemod/extensions']) + if cxx_task.target.arch == 'x86_64': + builder.AddCopy(cxx_task.binary, folder_map['addons/sourcemod/extensions/x64']) + else: + builder.AddCopy(cxx_task.binary, folder_map['addons/sourcemod/extensions']) diff --git a/public/sample_ext/configure.py b/public/sample_ext/configure.py index 57910e8501..88f1cad423 100644 --- a/public/sample_ext/configure.py +++ b/public/sample_ext/configure.py @@ -4,20 +4,24 @@ # Simple extensions do not need to modify this file. -builder = run.PrepareBuild(sourcePath = sys.path[0]) - -builder.options.add_option('--hl2sdk-root', type=str, dest='hl2sdk_root', default=None, - help='Root search folder for HL2SDKs') -builder.options.add_option('--mms-path', type=str, dest='mms_path', default=None, - help='Path to Metamod:Source') -builder.options.add_option('--sm-path', type=str, dest='sm_path', default=None, +parser = run.BuildParser(sourcePath=sys.path[0], api='2.2') +parser.options.add_argument('--hl2sdk-root', type=str, dest='hl2sdk_root', default=None, + help='Root search folder for HL2SDKs') +parser.options.add_argument('--hl2sdk-manifest-path', type=str, dest='hl2sdk_manifest', default=None, + help='Path to HL2SDK Manifests') +parser.options.add_argument('--sm-path', type=str, dest='sm_path', default=None, help='Path to SourceMod') -builder.options.add_option('--enable-debug', action='store_const', const='1', dest='debug', +parser.options.add_argument('--mms-path', type=str, dest='mms_path', default=None, + help='Path to Metamod:Source') + +parser.options.add_argument('--enable-debug', action='store_const', const='1', dest='debug', help='Enable debugging symbols') -builder.options.add_option('--enable-optimize', action='store_const', const='1', dest='opt', +parser.options.add_argument('--enable-optimize', action='store_const', const='1', dest='opt', help='Enable optimization') -builder.options.add_option('-s', '--sdks', default='all', dest='sdks', - help='Build against specified SDKs; valid args are "all", "present", or ' - 'comma-delimited list of engine names (default: %default)') +parser.options.add_argument('-s', '--sdks', default='present', dest='sdks', + help='Build against specified SDKs; valid args are "none", "all", "present",' + ' or comma-delimited list of engine names') +parser.options.add_argument('--targets', type=str, dest='targets', default=None, + help="Override the target architecture (use commas to separate multiple targets).") +parser.Configure() -builder.Configure() diff --git a/public/sample_ext_nosdk/AMBuildScript b/public/sample_ext_nosdk/AMBuildScript index 54c9a1d0f3..318cfe51b7 100644 --- a/public/sample_ext_nosdk/AMBuildScript +++ b/public/sample_ext_nosdk/AMBuildScript @@ -24,6 +24,14 @@ def ResolveEnvPath(env, folder): def Normalize(path): return os.path.abspath(os.path.normpath(path)) +def SetArchFlags(compiler): + if compiler.behavior == 'gcc': + if compiler.target.arch == 'x86_64': + compiler.cflags += ['-fPIC'] + elif compiler.like('msvc'): + if compiler.target.arch == 'x86_64': + compiler.defines += ['WIN64'] + class ExtensionConfig(object): def __init__(self): self.binaries = [] @@ -31,6 +39,30 @@ class ExtensionConfig(object): self.generated_headers = None self.mms_root = None self.sm_root = None + self.all_targets = [] + self.target_archs = set() + + if builder.options.targets: + target_archs = builder.options.targets.split(',') + else: + target_archs = ['x86'] + if builder.backend != 'amb2': + target_archs.append('x86_64') + + for arch in target_archs: + try: + cxx = builder.DetectCxx(target_arch = arch) + self.target_archs.add(cxx.target.arch) + except Exception as e: + # Error if archs were manually overridden. + if builder.options.targets: + raise + print('Skipping target {}: {}'.format(arch, e)) + continue + self.all_targets.append(cxx) + + if not self.all_targets: + raise Exception('No suitable C/C++ compiler was found.') @property def tag(self): @@ -42,7 +74,7 @@ class ExtensionConfig(object): if builder.options.sm_path: self.sm_root = builder.options.sm_path else: - self.sm_root = ResolveEnvPath('SOURCEMOD18', 'sourcemod-1.8') + self.sm_root = ResolveEnvPath('SOURCEMOD112', 'sourcemod-1.12') if not self.sm_root: self.sm_root = ResolveEnvPath('SOURCEMOD', 'sourcemod') if not self.sm_root: @@ -66,14 +98,32 @@ class ExtensionConfig(object): self.mms_root = Normalize(self.mms_root) def configure(self): - cxx = builder.DetectCompilers() + + allowed_archs = ['x86','x86_64'] + + if not set(self.target_archs).issubset(allowed_archs): + raise Exception('Unknown target architecture: {0}'.format(self.target_archs)) + + for cxx in self.all_targets: + self.configure_cxx(cxx) + + def configure_cxx(self, cxx): + if cxx.family == 'msvc': + if cxx.version < 1914 and builder.options.generator != 'vs': + raise Exception(f'Only MSVC 2017 15.7 and later are supported, full C++17 support is required. ({str(cxx.version)} < 1914)') + elif cxx.family == 'gcc': + if cxx.version < 'gcc-9': + raise Exception('Only GCC versions 9 or later are supported, full C++17 support is required.') + elif cxx.family == 'clang': + if cxx.version < 'clang-5': + raise Exception('Only clang versions 5 or later are supported, full C++17 support is required.') if cxx.like('gcc'): self.configure_gcc(cxx) - elif cxx.vendor == 'msvc': + elif cxx.family == 'msvc': self.configure_msvc(cxx) - # Optimization + # Optimizaiton if builder.options.opt == '1': cxx.defines += ['NDEBUG'] @@ -82,16 +132,15 @@ class ExtensionConfig(object): cxx.defines += ['DEBUG', '_DEBUG'] # Platform-specifics - if builder.target_platform == 'linux': + if cxx.target.platform == 'linux': self.configure_linux(cxx) - elif builder.target_platform == 'mac': + elif cxx.target.platform == 'mac': self.configure_mac(cxx) - elif builder.target_platform == 'windows': + elif cxx.target.platform == 'windows': self.configure_windows(cxx) - # Finish up. cxx.includes += [ - os.path.join(self.sm_root, 'public'), + os.path.join(builder.sourcePath, 'public'), ] def configure_gcc(self, cxx): @@ -111,31 +160,39 @@ class ExtensionConfig(object): '-Wno-unused', '-Wno-switch', '-Wno-array-bounds', - '-msse', - '-m32', '-fvisibility=hidden', ] + if cxx.target.arch in ['x86', 'x86_64']: + cxx.cflags += ['-msse'] + + cxx.cxxflags += ['-std=c++17'] + cxx.cxxflags += [ - '-std=c++14', - '-fno-exceptions', '-fno-threadsafe-statics', '-Wno-non-virtual-dtor', '-Wno-overloaded-virtual', + '-Wno-register', '-fvisibility-inlines-hidden', ] - cxx.linkflags += ['-m32'] - have_gcc = cxx.vendor == 'gcc' - have_clang = cxx.vendor == 'clang' - if cxx.version >= 'clang-3.6': + have_gcc = cxx.family == 'gcc' + have_clang = cxx.family == 'clang' + if cxx.version >= 'clang-3.9' or cxx.version == 'clang-3.4' or cxx.version > 'apple-clang-6.0': + cxx.cxxflags += ['-Wno-expansion-to-defined'] + if cxx.version == 'clang-3.9' or cxx.version == 'apple-clang-8.0': + cxx.cflags += ['-Wno-varargs'] + if cxx.version >= 'clang-3.4' or cxx.version >= 'apple-clang-7.0': cxx.cxxflags += ['-Wno-inconsistent-missing-override'] + if cxx.version >= 'clang-2.9' or cxx.version >= 'apple-clang-3.0': + cxx.cxxflags += ['-Wno-null-dereference'] if have_clang or (cxx.version >= 'gcc-4.6'): cxx.cflags += ['-Wno-narrowing'] if have_clang or (cxx.version >= 'gcc-4.7'): cxx.cxxflags += ['-Wno-delete-non-virtual-dtor'] if cxx.version >= 'gcc-4.8': cxx.cflags += ['-Wno-unused-result'] - + if cxx.version >= 'gcc-9.0': + cxx.cxxflags += ['-Wno-class-memaccess', '-Wno-packed-not-aligned'] if have_clang: cxx.cxxflags += ['-Wno-implicit-exception-spec-mismatch'] if cxx.version >= 'apple-clang-5.1' or cxx.version >= 'clang-3.4': @@ -144,13 +201,25 @@ class ExtensionConfig(object): cxx.cxxflags += ['-Wno-deprecated'] cxx.cflags += ['-Wno-sometimes-uninitialized'] + # Work around SDK warnings. + if cxx.version >= 'clang-10.0' or cxx.version >= 'apple-clang-12.0': + cxx.cflags += [ + '-Wno-implicit-int-float-conversion', + '-Wno-tautological-overlap-compare', + ] + if have_gcc: cxx.cflags += ['-mfpmath=sse'] + cxx.cflags += ['-Wno-maybe-uninitialized'] if builder.options.opt == '1': - cxx.cflags += ['-O3'] + cxx.cflags += ['-O3'] + + # Don't omit the frame pointer. + cxx.cflags += ['-fno-omit-frame-pointer'] def configure_msvc(self, cxx): + if builder.options.debug == '1': cxx.cflags += ['/MTd'] cxx.linkflags += ['/NODEFAULTLIB:libcmt'] @@ -169,9 +238,9 @@ class ExtensionConfig(object): '/EHsc', '/GR-', '/TP', + '/std:c++17', ] cxx.linkflags += [ - '/MACHINE:X86', 'kernel32.lib', 'user32.lib', 'gdi32.lib', @@ -198,23 +267,23 @@ class ExtensionConfig(object): cxx.cflags += ['/Oy-'] def configure_linux(self, cxx): - cxx.defines += ['_LINUX', 'POSIX'] - cxx.linkflags += ['-Wl,--exclude-libs,ALL', '-lm'] - if cxx.vendor == 'gcc': + cxx.defines += ['LINUX', '_LINUX', 'POSIX', '_FILE_OFFSET_BITS=64'] + cxx.linkflags += ['-lm'] + if cxx.family == 'gcc': cxx.linkflags += ['-static-libgcc'] - elif cxx.vendor == 'clang': + elif cxx.family == 'clang': cxx.linkflags += ['-lgcc_eh'] + cxx.linkflags += ['-static-libstdc++'] def configure_mac(self, cxx): - cxx.defines += ['OSX', '_OSX', 'POSIX'] - cxx.cflags += ['-mmacosx-version-min=10.5'] + cxx.defines += ['OSX', '_OSX', 'POSIX', 'KE_ABSOLUTELY_NO_STL'] + cxx.cflags += ['-mmacosx-version-min=10.15'] cxx.linkflags += [ - '-mmacosx-version-min=10.5', - '-arch', 'i386', - '-lstdc++', - '-stdlib=libstdc++', + '-mmacosx-version-min=10.15', + '-stdlib=libc++', + '-lc++', ] - cxx.cxxflags += ['-stdlib=libstdc++'] + cxx.cxxflags += ['-stdlib=libc++'] def configure_windows(self, cxx): cxx.defines += ['WIN32', '_WINDOWS'] @@ -233,26 +302,14 @@ class ExtensionConfig(object): def ConfigureForHL2(self, binary): compiler = binary.compiler - - mms_path = os.path.join(self.mms_root, 'core') + SetArchFlags(compiler) compiler.cxxincludes += [ - os.path.join(mms_path), - os.path.join(mms_path, 'sourcehook'), + os.path.join(self.mms_root, 'core'), + os.path.join(self.mms_root, 'core', 'sourcehook'), ] compiler.defines += ['META_NO_HL2SDK'] - - if compiler.like('msvc'): - compiler.defines += ['COMPILER_MSVC', 'COMPILER_MSVC32'] - else: - compiler.defines += ['COMPILER_GCC'] - - if builder.target_platform == 'linux': - compiler.linkflags += ['-lstdc++'] - elif builder.target_platform == 'mac': - compiler.linkflags.append('-liconv') - return binary def HL2Library(self, context, name): @@ -261,18 +318,22 @@ class ExtensionConfig(object): return self.ConfigureForHL2(binary) def HL2Project(self, context, name): - project = context.compiler.LibraryProject(name) - self.ConfigureForExtension(context, project.compiler) + project = builder.LibraryProject(name) return project - def HL2Config(self, project, name): - binary = project.Configure(name, '{0}'.format(self.tag)) + def HL2Config(self, context, project, name, compiler): + binary = project.Configure(compiler, name, '{0} - {1}'.format(self.tag, compiler.target.arch)) + self.ConfigureForExtension(context, binary.compiler) return self.ConfigureForHL2(binary) Extension = ExtensionConfig() Extension.detectSDKs() Extension.configure() +# This will clone the list and each cxx object as we recurse, preventing child +# scripts from messing up global state. +builder.targets = builder.CloneableList(Extension.all_targets) + # Add additional buildscripts here BuildScripts = [ 'AMBuilder', @@ -283,4 +344,4 @@ if builder.backend == 'amb2': 'PackageScript', ] -builder.RunBuildScripts(BuildScripts, { 'Extension': Extension}) +builder.Build(BuildScripts, { 'Extension': Extension }) diff --git a/public/sample_ext_nosdk/AMBuilder b/public/sample_ext_nosdk/AMBuilder index e7112a01c0..dbfd0fa2ba 100644 --- a/public/sample_ext_nosdk/AMBuilder +++ b/public/sample_ext_nosdk/AMBuilder @@ -2,6 +2,7 @@ import os, sys projectName = 'sample' +extName = projectName + '.ext' # smsdk_ext.cpp will be automatically added later sourceFiles = [ @@ -23,6 +24,9 @@ else: project.sources += sourceFiles -binary = Extension.HL2Config(project, projectName + '.ext') +for cxx in builder.targets: + binary = Extension.HL2Config(builder, project, projectName + '.ext', cxx) + + Extension.extensions = builder.Add(project) diff --git a/public/sample_ext_nosdk/PackageScript b/public/sample_ext_nosdk/PackageScript index 36ce6e48ec..29127ac6c3 100644 --- a/public/sample_ext_nosdk/PackageScript +++ b/public/sample_ext_nosdk/PackageScript @@ -13,6 +13,11 @@ folder_list = [ #'addons/sourcemod/configs', ] +if 'x86_64' in Extension.target_archs: + folder_list.extend([ + 'addons/sourcemod/extensions/x64', + ]) + # Create the distribution folder hierarchy. folder_map = {} for folder in folder_list: @@ -49,4 +54,8 @@ def CopyFiles(src, dest, files): # Copy binaries. for cxx_task in Extension.extensions: - builder.AddCopy(cxx_task.binary, folder_map['addons/sourcemod/extensions']) + if cxx_task.target.arch == 'x86_64': + builder.AddCopy(cxx_task.binary, folder_map['addons/sourcemod/extensions/x64']) + else: + builder.AddCopy(cxx_task.binary, folder_map['addons/sourcemod/extensions']) + diff --git a/public/sample_ext_nosdk/configure.py b/public/sample_ext_nosdk/configure.py index 3616aba2e5..10b7ac6ea0 100644 --- a/public/sample_ext_nosdk/configure.py +++ b/public/sample_ext_nosdk/configure.py @@ -4,15 +4,15 @@ # Simple extensions do not need to modify this file. -builder = run.PrepareBuild(sourcePath = sys.path[0]) - -builder.options.add_option('--mms-path', type=str, dest='mms_path', default=None, - help='Path to Metamod:Source') -builder.options.add_option('--sm-path', type=str, dest='sm_path', default=None, +parser = run.BuildParser(sourcePath=sys.path[0], api='2.2') +parser.options.add_argument('--sm-path', type=str, dest='sm_path', default=None, help='Path to SourceMod') -builder.options.add_option('--enable-debug', action='store_const', const='1', dest='debug', +parser.options.add_argument('--mms-path', type=str, dest='mms_path', default=None, + help='Path to Metamod:Source') +parser.options.add_argument('--enable-debug', action='store_const', const='1', dest='debug', help='Enable debugging symbols') -builder.options.add_option('--enable-optimize', action='store_const', const='1', dest='opt', +parser.options.add_argument('--enable-optimize', action='store_const', const='1', dest='opt', help='Enable optimization') - -builder.Configure() +parser.options.add_argument('--targets', type=str, dest='targets', default=None, + help="Override the target architecture (use commas to separate multiple targets).") +parser.Configure() \ No newline at end of file From 102b6618792f17c957a3e11548fc129a9d0d0bbe Mon Sep 17 00:00:00 2001 From: caxanga334 <10157643+caxanga334@users.noreply.github.com> Date: Fri, 12 Apr 2024 14:19:00 -0300 Subject: [PATCH 2/8] Fix: Missing dot at extension file name. Reported by @FortyTwoFortyTwo --- public/sample_ext/AMBuilder | 2 +- public/sample_ext_nosdk/AMBuilder | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/public/sample_ext/AMBuilder b/public/sample_ext/AMBuilder index e4339d5407..43a6d961fc 100644 --- a/public/sample_ext/AMBuilder +++ b/public/sample_ext/AMBuilder @@ -2,7 +2,7 @@ import os projectName = 'sample' -extName = projectName + '.ext' +extName = projectName + '.ext.' # smsdk_ext.cpp will be automatically added later sourceFiles = [ diff --git a/public/sample_ext_nosdk/AMBuilder b/public/sample_ext_nosdk/AMBuilder index dbfd0fa2ba..5cfee7e30c 100644 --- a/public/sample_ext_nosdk/AMBuilder +++ b/public/sample_ext_nosdk/AMBuilder @@ -2,7 +2,7 @@ import os, sys projectName = 'sample' -extName = projectName + '.ext' +extName = projectName + '.ext.' # smsdk_ext.cpp will be automatically added later sourceFiles = [ From 399a90bcdcecd672d0780106098ffc66845296b8 Mon Sep 17 00:00:00 2001 From: caxanga334 <10157643+caxanga334@users.noreply.github.com> Date: Fri, 12 Apr 2024 14:28:01 -0300 Subject: [PATCH 3/8] Clean Up: Removed unused variable --- public/sample_ext_nosdk/AMBuilder | 1 - 1 file changed, 1 deletion(-) diff --git a/public/sample_ext_nosdk/AMBuilder b/public/sample_ext_nosdk/AMBuilder index 5cfee7e30c..4c797424fe 100644 --- a/public/sample_ext_nosdk/AMBuilder +++ b/public/sample_ext_nosdk/AMBuilder @@ -2,7 +2,6 @@ import os, sys projectName = 'sample' -extName = projectName + '.ext.' # smsdk_ext.cpp will be automatically added later sourceFiles = [ From 0b8b9ed72f109a2f4dd46ddc47527c61646bdad8 Mon Sep 17 00:00:00 2001 From: caxanga334 <10157643+caxanga334@users.noreply.github.com> Date: Wed, 31 Jul 2024 15:00:29 -0300 Subject: [PATCH 4/8] Copying No Longer Needed Copying the HL2SDK manifest is no longer needed. Requires latest AMBuild. --- public/sample_ext/AMBuildScript | 19 +++++++------------ public/sample_ext/AMBuilder | 6 +++--- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/public/sample_ext/AMBuildScript b/public/sample_ext/AMBuildScript index 2b732ae304..ca2fd4dac3 100644 --- a/public/sample_ext/AMBuildScript +++ b/public/sample_ext/AMBuildScript @@ -1,5 +1,5 @@ # vim: set sts=2 ts=8 sw=2 tw=99 et ft=python: -import os, shutil +import os def ResolveEnvPath(env, folder): if env in os.environ: @@ -30,22 +30,17 @@ def SetArchFlags(compiler): if compiler.target.arch == 'x86_64': compiler.defines += ['WIN64'] -hl2sdk_manifests_root = None -hl2sdk_manifests_dest = Normalize(builder.sourcePath + '/hl2sdk-manifests/') +hl2sdk_manifests_path = None if not builder.options.hl2sdk_manifest: - if not os.path.exists(hl2sdk_manifests_dest): # if no root was specified and an hl2sdk-manifests folder does not exists in the source folder - raise Exception('HL2SDK Manifests directory not found! Set --hl2sdk-manifest-path or manually copy the hl2sdk manifests folder to the current source folder.') + raise Exception('HL2SDK Manifest root path not set! (--hl2sdk-manifest-path)') else: - # The HL2SDK Manifest looks for the manifest file based on the current sourcePath, so we need to copy it to our sourcePath first - hl2sdk_manifests_root = Normalize(builder.options.hl2sdk_manifest + '/') + hl2sdk_manifests_path = os.path.join(builder.options.hl2sdk_manifest, 'SdkHelpers.ambuild') - if not os.path.exists(hl2sdk_manifests_dest): - shutil.copytree(hl2sdk_manifests_root, hl2sdk_manifests_dest) - else: - print('HL2SDK Manifests folder already exists, not copying.') + if not os.path.exists(hl2sdk_manifests_path): + raise Exception('Could not find SdkHelpers.ambuild in the given HL2SDK Manifest path!') -SdkHelpers = builder.Eval('hl2sdk-manifests/SdkHelpers.ambuild', { +SdkHelpers = builder.Eval(hl2sdk_manifests_path, { 'Project': 'sm-extension' }) diff --git a/public/sample_ext/AMBuilder b/public/sample_ext/AMBuilder index 43a6d961fc..ca2b1bb936 100644 --- a/public/sample_ext/AMBuilder +++ b/public/sample_ext/AMBuilder @@ -1,15 +1,15 @@ # vim: set sts=2 ts=8 sw=2 tw=99 et ft=python: import os +# Name of your extesion, this will also be it's file name. projectName = 'sample' -extName = projectName + '.ext.' # smsdk_ext.cpp will be automatically added later sourceFiles = [ 'extension.cpp', ] -project = builder.LibraryProject(extName) +project = builder.LibraryProject(projectName) if os.path.isfile(os.path.join(builder.currentSourcePath, 'sdk', 'smsdk_ext.cpp')): # Use the copy included in the project @@ -29,6 +29,6 @@ for sdk_name in Extension.sdks: if not cxx.target.arch in sdk['platforms'][cxx.target.platform]: continue - binary = Extension.HL2ExtConfig(project, builder, cxx, extName + sdk['extension'], sdk) + binary = Extension.HL2ExtConfig(project, builder, cxx, projectName + '.ext.' + sdk['extension'], sdk) Extension.extensions += builder.Add(project) From 3248a92bce04c2d203a7ac21343c7c790554a6db Mon Sep 17 00:00:00 2001 From: caxanga334 <10157643+caxanga334@users.noreply.github.com> Date: Wed, 31 Jul 2024 15:09:13 -0300 Subject: [PATCH 5/8] Allow Using Manifests From Project Folder Check if the manifest already exists in the project folder. If not, then search in the path specified by --hl2sdk-manifest-path. --- public/sample_ext/AMBuildScript | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/public/sample_ext/AMBuildScript b/public/sample_ext/AMBuildScript index ca2fd4dac3..8538671220 100644 --- a/public/sample_ext/AMBuildScript +++ b/public/sample_ext/AMBuildScript @@ -32,13 +32,19 @@ def SetArchFlags(compiler): hl2sdk_manifests_path = None -if not builder.options.hl2sdk_manifest: - raise Exception('HL2SDK Manifest root path not set! (--hl2sdk-manifest-path)') -else: - hl2sdk_manifests_path = os.path.join(builder.options.hl2sdk_manifest, 'SdkHelpers.ambuild') +# First we check if the manifest exists in the current path +hl2sdk_manifests_path = os.path.join(builder.sourcePath, 'hl2sdk-manifests/SdkHelpers.ambuild') + +if not os.path.exists(hl2sdk_manifests_path): + # manifests does not exists in the project file, use the path from --hl2sdk-manifest-path + if not builder.options.hl2sdk_manifest: + raise Exception('HL2SDK Manifest root path not set! (--hl2sdk-manifest-path)') + else: + hl2sdk_manifests_path = os.path.join(builder.options.hl2sdk_manifest, 'SdkHelpers.ambuild') + + if not os.path.exists(hl2sdk_manifests_path): + raise Exception('Could not find SdkHelpers.ambuild in the given HL2SDK Manifest path!') - if not os.path.exists(hl2sdk_manifests_path): - raise Exception('Could not find SdkHelpers.ambuild in the given HL2SDK Manifest path!') SdkHelpers = builder.Eval(hl2sdk_manifests_path, { 'Project': 'sm-extension' From 9da7e650e63c629eb20af4dd50e6bcdc071be1a1 Mon Sep 17 00:00:00 2001 From: caxanga334 <10157643+caxanga334@users.noreply.github.com> Date: Mon, 21 Oct 2024 20:10:41 -0300 Subject: [PATCH 6/8] Requested Changes by Kenzzer --- public/sample_ext/AMBuildScript | 74 ++++----------------------- public/sample_ext_nosdk/AMBuildScript | 47 ++++------------- 2 files changed, 19 insertions(+), 102 deletions(-) diff --git a/public/sample_ext/AMBuildScript b/public/sample_ext/AMBuildScript index 8538671220..e6122cffbd 100644 --- a/public/sample_ext/AMBuildScript +++ b/public/sample_ext/AMBuildScript @@ -65,9 +65,7 @@ class ExtensionConfig(object): if builder.options.targets: target_archs = builder.options.targets.split(',') else: - target_archs = ['x86'] - if builder.backend != 'amb2': - target_archs.append('x86_64') + target_archs = ['x86', 'x86_64'] for arch in target_archs: try: @@ -157,8 +155,8 @@ class ExtensionConfig(object): if cxx.version < 1914 and builder.options.generator != 'vs': raise Exception(f'Only MSVC 2017 15.7 and later are supported, full C++17 support is required. ({str(cxx.version)} < 1914)') elif cxx.family == 'gcc': - if cxx.version < 'gcc-9': - raise Exception('Only GCC versions 9 or later are supported, full C++17 support is required.') + if cxx.version < 'gcc-8': + raise Exception('Only GCC versions 8 or later are supported, full C++17 support is required.') elif cxx.family == 'clang': if cxx.version < 'clang-5': raise Exception('Only clang versions 5 or later are supported, full C++17 support is required.') @@ -168,7 +166,7 @@ class ExtensionConfig(object): elif cxx.family == 'msvc': self.configure_msvc(cxx) - # Optimizaiton + # Optimization if builder.options.opt == '1': cxx.defines += ['NDEBUG'] @@ -184,10 +182,6 @@ class ExtensionConfig(object): elif cxx.target.platform == 'windows': self.configure_windows(cxx) - cxx.includes += [ - os.path.join(builder.sourcePath, 'public'), - ] - def configure_gcc(self, cxx): cxx.defines += [ 'stricmp=strcasecmp', @@ -207,44 +201,26 @@ class ExtensionConfig(object): '-Wno-array-bounds', '-fvisibility=hidden', ] + if cxx.target.arch in ['x86', 'x86_64']: cxx.cflags += ['-msse'] - cxx.cxxflags += ['-std=c++17'] - cxx.cxxflags += [ '-fno-threadsafe-statics', '-Wno-non-virtual-dtor', '-Wno-overloaded-virtual', '-Wno-register', '-fvisibility-inlines-hidden', + '-std=c++17', ] + have_gcc = cxx.family == 'gcc' have_clang = cxx.family == 'clang' - if cxx.version >= 'clang-3.9' or cxx.version == 'clang-3.4' or cxx.version > 'apple-clang-6.0': - cxx.cxxflags += ['-Wno-expansion-to-defined'] - if cxx.version == 'clang-3.9' or cxx.version == 'apple-clang-8.0': - cxx.cflags += ['-Wno-varargs'] - if cxx.version >= 'clang-3.4' or cxx.version >= 'apple-clang-7.0': - cxx.cxxflags += ['-Wno-inconsistent-missing-override'] - if cxx.version >= 'clang-2.9' or cxx.version >= 'apple-clang-3.0': - cxx.cxxflags += ['-Wno-null-dereference'] - if have_clang or (cxx.version >= 'gcc-4.6'): - cxx.cflags += ['-Wno-narrowing'] - if have_clang or (cxx.version >= 'gcc-4.7'): - cxx.cxxflags += ['-Wno-delete-non-virtual-dtor'] - if cxx.version >= 'gcc-4.8': - cxx.cflags += ['-Wno-unused-result'] - if cxx.version >= 'gcc-9.0': - cxx.cxxflags += ['-Wno-class-memaccess', '-Wno-packed-not-aligned'] + + # Work around errors from smsdk_ext.cpp if have_clang: cxx.cxxflags += ['-Wno-implicit-exception-spec-mismatch'] - if cxx.version >= 'apple-clang-5.1' or cxx.version >= 'clang-3.4': - cxx.cxxflags += ['-Wno-deprecated-register'] - else: - cxx.cxxflags += ['-Wno-deprecated'] - cxx.cflags += ['-Wno-sometimes-uninitialized'] # Work around SDK warnings. if cxx.version >= 'clang-10.0' or cxx.version >= 'apple-clang-12.0': @@ -341,37 +317,11 @@ class ExtensionConfig(object): self.AddCxxCompat(binary) return binary - def ProgramBuilder(self, compiler, name): - binary = compiler.Program(name) - self.AddVersioning(binary) - if '-static-libgcc' in binary.compiler.linkflags: - binary.compiler.linkflags.remove('-static-libgcc') - if '-lgcc_eh' in binary.compiler.linkflags: - binary.compiler.linkflags.remove('-lgcc_eh') - if binary.compiler.like('gcc'): - binary.compiler.linkflags += ['-lstdc++', '-lpthread'] - if binary.compiler.like('msvc'): - binary.compiler.linkflags += ['/SUBSYSTEM:CONSOLE'] - return binary - - def StaticLibraryBuilder(self, compiler, name): - return compiler.StaticLibrary(name) - def Library(self, context, compiler, name): compiler = compiler.clone() SetArchFlags(compiler) return self.LibraryBuilder(compiler, name) - def Program(self, context, compiler, name): - compiler = compiler.clone() - SetArchFlags(compiler) - return self.ProgramBuilder(compiler, name) - - def StaticLibrary(self, context, compiler, name): - compiler = compiler.clone() - SetArchFlags(compiler) - return self.StaticLibraryBuilder(compiler, name) - def ConfigureForExtension(self, context, compiler): compiler.cxxincludes += [ os.path.join(context.currentSourcePath), @@ -441,12 +391,8 @@ builder.targets = builder.CloneableList(Extension.all_targets) BuildScripts = [ 'AMBuilder', + 'PackageScript', ] -if builder.backend == 'amb2': - BuildScripts += [ - 'PackageScript', - ] - builder.Build(BuildScripts, { 'Extension': Extension }) diff --git a/public/sample_ext_nosdk/AMBuildScript b/public/sample_ext_nosdk/AMBuildScript index 318cfe51b7..33f166aee7 100644 --- a/public/sample_ext_nosdk/AMBuildScript +++ b/public/sample_ext_nosdk/AMBuildScript @@ -45,9 +45,7 @@ class ExtensionConfig(object): if builder.options.targets: target_archs = builder.options.targets.split(',') else: - target_archs = ['x86'] - if builder.backend != 'amb2': - target_archs.append('x86_64') + target_archs = ['x86', 'x86_64'] for arch in target_archs: try: @@ -112,8 +110,8 @@ class ExtensionConfig(object): if cxx.version < 1914 and builder.options.generator != 'vs': raise Exception(f'Only MSVC 2017 15.7 and later are supported, full C++17 support is required. ({str(cxx.version)} < 1914)') elif cxx.family == 'gcc': - if cxx.version < 'gcc-9': - raise Exception('Only GCC versions 9 or later are supported, full C++17 support is required.') + if cxx.version < 'gcc-8': + raise Exception('Only GCC versions 8 or later are supported, full C++17 support is required.') elif cxx.family == 'clang': if cxx.version < 'clang-5': raise Exception('Only clang versions 5 or later are supported, full C++17 support is required.') @@ -123,7 +121,7 @@ class ExtensionConfig(object): elif cxx.family == 'msvc': self.configure_msvc(cxx) - # Optimizaiton + # Optimization if builder.options.opt == '1': cxx.defines += ['NDEBUG'] @@ -139,10 +137,6 @@ class ExtensionConfig(object): elif cxx.target.platform == 'windows': self.configure_windows(cxx) - cxx.includes += [ - os.path.join(builder.sourcePath, 'public'), - ] - def configure_gcc(self, cxx): cxx.defines += [ 'stricmp=strcasecmp', @@ -162,44 +156,25 @@ class ExtensionConfig(object): '-Wno-array-bounds', '-fvisibility=hidden', ] + if cxx.target.arch in ['x86', 'x86_64']: cxx.cflags += ['-msse'] - cxx.cxxflags += ['-std=c++17'] - cxx.cxxflags += [ '-fno-threadsafe-statics', '-Wno-non-virtual-dtor', '-Wno-overloaded-virtual', '-Wno-register', '-fvisibility-inlines-hidden', + '-std=c++17', ] have_gcc = cxx.family == 'gcc' have_clang = cxx.family == 'clang' - if cxx.version >= 'clang-3.9' or cxx.version == 'clang-3.4' or cxx.version > 'apple-clang-6.0': - cxx.cxxflags += ['-Wno-expansion-to-defined'] - if cxx.version == 'clang-3.9' or cxx.version == 'apple-clang-8.0': - cxx.cflags += ['-Wno-varargs'] - if cxx.version >= 'clang-3.4' or cxx.version >= 'apple-clang-7.0': - cxx.cxxflags += ['-Wno-inconsistent-missing-override'] - if cxx.version >= 'clang-2.9' or cxx.version >= 'apple-clang-3.0': - cxx.cxxflags += ['-Wno-null-dereference'] - if have_clang or (cxx.version >= 'gcc-4.6'): - cxx.cflags += ['-Wno-narrowing'] - if have_clang or (cxx.version >= 'gcc-4.7'): - cxx.cxxflags += ['-Wno-delete-non-virtual-dtor'] - if cxx.version >= 'gcc-4.8': - cxx.cflags += ['-Wno-unused-result'] - if cxx.version >= 'gcc-9.0': - cxx.cxxflags += ['-Wno-class-memaccess', '-Wno-packed-not-aligned'] + + # Work around errors from smsdk_ext.cpp if have_clang: cxx.cxxflags += ['-Wno-implicit-exception-spec-mismatch'] - if cxx.version >= 'apple-clang-5.1' or cxx.version >= 'clang-3.4': - cxx.cxxflags += ['-Wno-deprecated-register'] - else: - cxx.cxxflags += ['-Wno-deprecated'] - cxx.cflags += ['-Wno-sometimes-uninitialized'] # Work around SDK warnings. if cxx.version >= 'clang-10.0' or cxx.version >= 'apple-clang-12.0': @@ -337,11 +312,7 @@ builder.targets = builder.CloneableList(Extension.all_targets) # Add additional buildscripts here BuildScripts = [ 'AMBuilder', + 'PackageScript', ] -if builder.backend == 'amb2': - BuildScripts += [ - 'PackageScript', - ] - builder.Build(BuildScripts, { 'Extension': Extension }) From 9ecf6c2752cc8067ca5a7d62c0b9791e8723ce6d Mon Sep 17 00:00:00 2001 From: caxanga334 <10157643+caxanga334@users.noreply.github.com> Date: Tue, 22 Oct 2024 09:08:53 -0300 Subject: [PATCH 7/8] Fix Differences Between SDK/No SDK --- public/sample_ext_nosdk/AMBuildScript | 28 +++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/public/sample_ext_nosdk/AMBuildScript b/public/sample_ext_nosdk/AMBuildScript index 33f166aee7..e794984715 100644 --- a/public/sample_ext_nosdk/AMBuildScript +++ b/public/sample_ext_nosdk/AMBuildScript @@ -69,25 +69,12 @@ class ExtensionConfig(object): return 'Release' def detectSDKs(self): - if builder.options.sm_path: - self.sm_root = builder.options.sm_path - else: - self.sm_root = ResolveEnvPath('SOURCEMOD112', 'sourcemod-1.12') - if not self.sm_root: - self.sm_root = ResolveEnvPath('SOURCEMOD', 'sourcemod') - if not self.sm_root: - self.sm_root = ResolveEnvPath('SOURCEMOD_DEV', 'sourcemod-central') - - if not self.sm_root or not os.path.isdir(self.sm_root): - raise Exception('Could not find a source copy of SourceMod') - self.sm_root = Normalize(self.sm_root) - if builder.options.mms_path: self.mms_root = builder.options.mms_path else: self.mms_root = ResolveEnvPath('MMSOURCE112', 'mmsource-1.12') if not self.mms_root: - self.mms_root = ResolveEnvPath('MMSOURCE', 'metamod-source') + self.mms_root = ResolveEnvPath('MMSOURCE_DEV', 'metamod-source') if not self.mms_root: self.mms_root = ResolveEnvPath('MMSOURCE_DEV', 'mmsource-central') @@ -95,6 +82,19 @@ class ExtensionConfig(object): raise Exception('Could not find a source copy of Metamod:Source') self.mms_root = Normalize(self.mms_root) + if builder.options.sm_path: + self.sm_root = builder.options.sm_path + else: + self.sm_root = ResolveEnvPath('SOURCEMOD112', 'sourcemod-1.12') + if not self.sm_root: + self.sm_root = ResolveEnvPath('SOURCEMOD_DEV', 'sourcemod') + if not self.sm_root: + self.sm_root = ResolveEnvPath('SOURCEMOD_DEV', 'sourcemod-central') + + if not self.sm_root or not os.path.isdir(self.sm_root): + raise Exception('Could not find a source copy of SourceMod') + self.sm_root = Normalize(self.sm_root) + def configure(self): allowed_archs = ['x86','x86_64'] From 6872d6485f108572c829569c963f3e4cc4210b12 Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Fri, 25 Oct 2024 18:48:45 +0200 Subject: [PATCH 8/8] add extra env checks --- AMBuildScript | 2 ++ public/sample_ext/AMBuildScript | 4 ++++ public/sample_ext_nosdk/AMBuildScript | 4 ++++ 3 files changed, 10 insertions(+) diff --git a/AMBuildScript b/AMBuildScript index 50af518b5a..6a5a00ea73 100644 --- a/AMBuildScript +++ b/AMBuildScript @@ -128,6 +128,8 @@ class SMConfig(object): self.mms_root = builder.options.mms_path else: self.mms_root = ResolveEnvPath('MMSOURCE112', 'mmsource-1.12') + if not self.mms_root: + self.mms_root = ResolveEnvPath('MMSOURCE', 'metamod-source') if not self.mms_root: self.mms_root = ResolveEnvPath('MMSOURCE_DEV', 'metamod-source') if not self.mms_root: diff --git a/public/sample_ext/AMBuildScript b/public/sample_ext/AMBuildScript index e6122cffbd..271d109a02 100644 --- a/public/sample_ext/AMBuildScript +++ b/public/sample_ext/AMBuildScript @@ -118,6 +118,8 @@ class ExtensionConfig(object): self.mms_root = builder.options.mms_path else: self.mms_root = ResolveEnvPath('MMSOURCE112', 'mmsource-1.12') + if not self.mms_root: + self.mms_root = ResolveEnvPath('MMSOURCE', 'metamod-source') if not self.mms_root: self.mms_root = ResolveEnvPath('MMSOURCE_DEV', 'metamod-source') if not self.mms_root: @@ -131,6 +133,8 @@ class ExtensionConfig(object): self.sm_root = builder.options.sm_path else: self.sm_root = ResolveEnvPath('SOURCEMOD112', 'sourcemod-1.12') + if not self.sm_root: + self.sm_root = ResolveEnvPath('SOURCEMOD', 'sourcemod') if not self.sm_root: self.sm_root = ResolveEnvPath('SOURCEMOD_DEV', 'sourcemod') if not self.sm_root: diff --git a/public/sample_ext_nosdk/AMBuildScript b/public/sample_ext_nosdk/AMBuildScript index e794984715..29440b1097 100644 --- a/public/sample_ext_nosdk/AMBuildScript +++ b/public/sample_ext_nosdk/AMBuildScript @@ -73,6 +73,8 @@ class ExtensionConfig(object): self.mms_root = builder.options.mms_path else: self.mms_root = ResolveEnvPath('MMSOURCE112', 'mmsource-1.12') + if not self.mms_root: + self.mms_root = ResolveEnvPath('MMSOURCE', 'metamod-source') if not self.mms_root: self.mms_root = ResolveEnvPath('MMSOURCE_DEV', 'metamod-source') if not self.mms_root: @@ -86,6 +88,8 @@ class ExtensionConfig(object): self.sm_root = builder.options.sm_path else: self.sm_root = ResolveEnvPath('SOURCEMOD112', 'sourcemod-1.12') + if not self.sm_root: + self.sm_root = ResolveEnvPath('SOURCEMOD', 'sourcemod') if not self.sm_root: self.sm_root = ResolveEnvPath('SOURCEMOD_DEV', 'sourcemod') if not self.sm_root: