Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-24.04]
sourcemod-version: [1.11-dev]
sourcemod-version: [master]
libboost-version: [boost-1.82.0]
python-version: ['3.10']
include:
Expand Down
128 changes: 85 additions & 43 deletions AMBuildScript
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ 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':
Expand All @@ -77,7 +77,7 @@ class ExtensionConfig(object):
self.all_targets = []
self.target_archs = set()
self.libboost_root = None

self.libsafetyhook = {}

if builder.options.targets:
target_archs = builder.options.targets.split(',')
Expand Down Expand Up @@ -125,13 +125,11 @@ class ExtensionConfig(object):
if builder.options.sm_path:
self.sm_root = builder.options.sm_path
else:
self.sm_root = ResolveEnvPath('SOURCEMOD18', 'sourcemod-1.10')
self.sm_root = ResolveEnvPath('SOURCEMOD113', 'sourcemod-1.13')
if not self.sm_root:
self.sm_root = ResolveEnvPath('SOURCEMOD', 'sourcemod-source')
self.sm_root = ResolveEnvPath('SOURCEMOD', 'sourcemod')
if not self.sm_root:
self.sm_root = ResolveEnvPath('SOURCEMOD_DEV', 'sourcemod-central')
if not self.sm_root:
self.sm_root = ResolveEnvPath('SOURCEMOD', 'sourcemod')

if not self.sm_root or not os.path.isdir(self.sm_root):
raise Exception('Could not find a source copy of Sourcemod')
Expand All @@ -140,13 +138,11 @@ class ExtensionConfig(object):
if builder.options.mms_path:
self.mms_root = builder.options.mms_path
else:
self.mms_root = ResolveEnvPath('MMSOURCE110', 'mmsource-1.10')
if not self.mms_root:
self.mms_root = ResolveEnvPath('MMSOURCE_DEV', 'metamod-source')
self.mms_root = ResolveEnvPath('MMSOURCE112', 'mmsource-1.12')
if not self.mms_root:
self.mms_root = ResolveEnvPath('MMSOURCE_DEV', 'mmsource-central')
self.mms_root = ResolveEnvPath('MMSOURCE', 'metamod-source')
if not self.mms_root:
self.mms_root = ResolveEnvPath('MMSOURCE_DEV', 'metamod')
self.mms_root = ResolveEnvPath('MMSOURCE_DEV', 'metamod-source')

if not self.mms_root or not os.path.isdir(self.mms_root):
raise Exception('Could not find a source copy of Metamod:Source')
Expand Down Expand Up @@ -176,21 +172,21 @@ class ExtensionConfig(object):

def configure_cxx(self, cxx):
if cxx.family == 'msvc':
if cxx.version < 1900:
raise Exception('Only MSVC 2015 and later are supported, c++14 support is required.')
if cxx.family == 'gcc':
if cxx.version < 'gcc-4.9':
raise Exception('Only GCC versions 4.9 or greater are supported, c++14 support is required.')
if cxx.family == 'clang':
if cxx.version < 'clang-3.4':
raise Exception('Only clang versions 3.4 or greater are supported, c++14 support is required.')
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.family == 'msvc':
self.configure_msvc(cxx)

# Optimizaiton
# Optimization
if builder.options.opt == '1':
cxx.defines += ['NDEBUG']

Expand Down Expand Up @@ -228,20 +224,21 @@ class ExtensionConfig(object):
'-Wno-unused',
'-Wno-switch',
'-Wno-array-bounds',
'-msse',
'-Wno-unknown-pragmas',
'-Wno-dangling-else',
'-fvisibility=hidden',
]

if cxx.version == 'apple-clang-6.0' or cxx.version == 'clang-3.4':
cxx.cxxflags += ['-std=c++1y']
else:
cxx.cxxflags += ['-std=c++14']
if cxx.target.arch in ['x86', 'x86_64']:
cxx.cflags += ['-msse']

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'
Expand Down Expand Up @@ -271,29 +268,21 @@ class ExtensionConfig(object):
cxx.cflags += ['-Wno-sometimes-uninitialized']

# Work around SDK warnings.
if cxx.version >= 'clang-10.0':
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 cxx.version >= 'clang-21.0':
cxx.cflags += ['-Wno-uninitialized-const-pointer']

if have_gcc:
cxx.cflags += ['-mfpmath=sse']
cxx.cflags += ['-Wno-maybe-uninitialized']

if builder.options.opt == '1':
cxx.cflags += [
'-O3',
'-ftree-vectorize',
]
if have_clang:
cxx.cflags += [
'-fexperimental-new-pass-manager',
'-mllvm',
'-inline-threshold=1000',
'-mllvm',
'-vectorize-loops',
]
cxx.cflags += ['-O3']

# Don't omit the frame pointer.
cxx.cflags += ['-fno-omit-frame-pointer']
Expand All @@ -317,6 +306,7 @@ class ExtensionConfig(object):
'/EHsc',
'/GR-',
'/TP',
'/std:c++17',
]
cxx.linkflags += [
'kernel32.lib',
Expand Down Expand Up @@ -345,7 +335,7 @@ class ExtensionConfig(object):
cxx.cflags += ['/Oy-']

def configure_linux(self, cxx):
cxx.defines += ['_LINUX', 'POSIX', '_FILE_OFFSET_BITS=64']
cxx.defines += ['LINUX', '_LINUX', 'POSIX', '_FILE_OFFSET_BITS=64']
cxx.linkflags += ['-lm']
if cxx.family == 'gcc':
cxx.linkflags += ['-static-libgcc']
Expand All @@ -358,9 +348,9 @@ class ExtensionConfig(object):

def configure_mac(self, cxx):
cxx.defines += ['OSX', '_OSX', 'POSIX', 'KE_ABSOLUTELY_NO_STL']
cxx.cflags += ['-mmacosx-version-min=10.7']
cxx.cflags += ['-mmacosx-version-min=10.15']
cxx.linkflags += [
'-mmacosx-version-min=10.7',
'-mmacosx-version-min=10.15',
'-stdlib=libc++',
'-lc++',
]
Expand Down Expand Up @@ -393,7 +383,7 @@ class ExtensionConfig(object):
'-current_version', self.productVersion
]
return binary

def LibraryBuilder(self, compiler, name):
binary = compiler.Library(name)
self.AddVersioning(binary)
Expand Down Expand Up @@ -426,7 +416,7 @@ class ExtensionConfig(object):
compiler = compiler.clone()
SetArchFlags(compiler)
return self.ProgramBuilder(compiler, name)

def StaticLibrary(self, context, compiler, name):
compiler = compiler.clone()
SetArchFlags(compiler)
Expand All @@ -451,6 +441,47 @@ class ExtensionConfig(object):
self.ConfigureForExtension(context, binary.compiler)
return binary

def AddCDetour(self, binary):
sm_public_path = os.path.join(self.sm_root, 'public')
gameconfigs_header = os.path.join(sm_public_path, 'IGameConfigs.h')

if binary.compiler.like('msvc'):
binary.compiler.cflags += ['/FI' + gameconfigs_header]
else:
binary.compiler.cflags += ['-include', gameconfigs_header]

if os.path.exists(os.path.join(sm_public_path, 'safetyhook')):
binary.sources += [ os.path.join(sm_public_path, 'CDetour', 'detours.cpp') ]
binary.compiler.cxxincludes += [ os.path.join(builder.sourcePath, 'safetyhook', 'include') ]

for task in self.libsafetyhook:
if task.target.arch == binary.compiler.target.arch:
binary.compiler.linkflags += [task.binary]
return
raise Exception('No suitable build of safetyhook was found.')
else:
binary.sources += [
os.path.join(sm_public_path, 'CDetour', 'detours.cpp'),
os.path.join(sm_public_path, 'asm', 'asm.c'),
]
# sm1.10+
libudis_folder = os.path.join(sm_public_path, 'libudis86')
if os.path.isdir(libudis_folder):
binary.compiler.defines += ['HAVE_STRING_H']
binary.sources += [
os.path.join(libudis_folder, 'decode.c'),
os.path.join(libudis_folder, 'itab.c'),
os.path.join(libudis_folder, 'syn-att.c'),
os.path.join(libudis_folder, 'syn-intel.c'),
os.path.join(libudis_folder, 'syn.c'),
os.path.join(libudis_folder, 'udis86.c'),
]

class SafetyHookShim(object):
def __init__(self):
self.all_targets = {}
self.libsafetyhook = {}

if getattr(builder, 'target', None) is not None:
sys.stderr.write("Your output folder was configured for AMBuild 2.1, and SourceMod is now\n")
sys.stderr.write("configured to use AMBuild 2.2. Please remove your output folder and\n")
Expand All @@ -461,6 +492,17 @@ SM = ExtensionConfig()
SM.detectSDKs()
SM.configure()

if os.path.exists(os.path.join(SM.sm_root, 'public', 'safetyhook')):
# we need to pull safetyhook in locally because ambuild does not take kindly to outside relpaths
import shutil
safetyhook_dest = Normalize(builder.sourcePath + '/safetyhook/')
shutil.copytree(os.path.join(SM.sm_root, 'public', 'safetyhook'), safetyhook_dest, dirs_exist_ok=True)

SafetyHook = SafetyHookShim()
SafetyHook.all_targets = SM.all_targets
builder.Build('safetyhook/AMBuilder', {'SafetyHook': SafetyHook })
SM.libsafetyhook = SafetyHook.libsafetyhook

# This will clone the list and each cxx object as we recurse, preventing child
# scripts from messing up global state.
builder.targets = builder.CloneableList(SM.all_targets)
Expand Down
8 changes: 1 addition & 7 deletions AMBuilder
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,7 @@ for cxx in builder.targets:
'Callback.cpp',
'CallbackHandler.cpp',
os.path.join(SM.sm_root, 'public', 'smsdk_ext.cpp'),
os.path.join(SM.sm_root, 'public', 'asm', 'asm.c'),
os.path.join(SM.sm_root, 'public', 'libudis86', 'decode.c'),
os.path.join(SM.sm_root, 'public', 'libudis86', 'itab.c'),
os.path.join(SM.sm_root, 'public', 'libudis86', 'syn-att.c'),
os.path.join(SM.sm_root, 'public', 'libudis86', 'syn-intel.c'),
os.path.join(SM.sm_root, 'public', 'libudis86', 'syn.c'),
os.path.join(SM.sm_root, 'public', 'libudis86', 'udis86.c'),
]

SM.AddCDetour(binary)
SM.extensions += [builder.Add(binary)]
Loading