Repository navigation
Expand file tree
/
Copy pathAMBuildScript
More file actions
162 lines (147 loc) · 7.59 KB
/
Copy pathAMBuildScript
File metadata and controls
162 lines (147 loc) · 7.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# vim: set sts=2 ts=8 sw=2 tw=99 et ft=python:
import os
def ResolveEnvPath(env, folder):
if env in os.environ and os.path.isdir(os.environ[env]):
return os.environ[env]
head = os.getcwd()
while head:
path = os.path.join(head, folder)
if os.path.isdir(path):
return path
parent = os.path.dirname(head)
if parent == head:
break
head = parent
return None
def Normalize(path):
return os.path.abspath(os.path.normpath(path))
manifest_helper = os.path.join(builder.sourcePath, 'hl2sdk-manifests', 'SdkHelpers.ambuild')
if not os.path.exists(manifest_helper):
if not builder.options.hl2sdk_manifest:
raise Exception('hl2sdk-manifests is missing; initialize submodules or pass --hl2sdk-manifest-path')
manifest_helper = os.path.join(builder.options.hl2sdk_manifest, 'SdkHelpers.ambuild')
if not os.path.exists(manifest_helper):
raise Exception('Could not find SdkHelpers.ambuild')
SdkHelpers = builder.Eval(manifest_helper, {'Project': 'sm-extension'})
class ExtensionConfig(object):
def __init__(self):
self.sdk_manifests = []
self.sdks = {}
self.sdk_targets = []
self.extensions = []
self.mms_root = None
self.sm_root = None
self.all_targets = []
self.target_archs = set()
self.libsafetyhook = []
target_archs = builder.options.targets.split(',') if builder.options.targets else ['x86', 'x86_64']
for arch in target_archs:
try:
cxx = builder.DetectCxx(target_arch=arch)
self.target_archs.add(cxx.target.arch)
self.all_targets.append(cxx)
except Exception as ex:
if builder.options.targets:
raise
print('Skipping target {}: {}'.format(arch, ex))
if not self.all_targets:
raise Exception('No suitable C/C++ compiler was found.')
@property
def tag(self):
return 'Debug' if builder.options.debug == '1' else 'Release'
def findSdkPath(self, sdk_name):
folder = 'hl2sdk-{}'.format(sdk_name)
if builder.options.hl2sdk_root:
path = os.path.join(builder.options.hl2sdk_root, folder)
if os.path.isdir(path):
return Normalize(path)
return ResolveEnvPath('HL2SDK{}'.format(sdk_name.upper()), folder)
def detectSDKs(self):
SdkHelpers.sdk_filter = lambda sdk: not sdk.get('source2', False)
SdkHelpers.find_sdk_path = self.findSdkPath
SdkHelpers.findSdks(builder, self.all_targets, [sdk for sdk in builder.options.sdks.split(',') if sdk])
self.sdks = SdkHelpers.sdks
self.sdk_manifests = SdkHelpers.sdk_manifests
self.sdk_targets = SdkHelpers.sdk_targets
self.sm_root = Normalize(builder.options.sm_path) if builder.options.sm_path else ResolveEnvPath('SOURCEMOD', 'sourcemod')
self.mms_root = Normalize(builder.options.mms_path) if builder.options.mms_path else ResolveEnvPath('MMSOURCE', 'metamod-source')
if not self.sm_root or not os.path.isdir(self.sm_root):
raise Exception('Could not find a source copy of SourceMod')
if not self.mms_root or not os.path.isdir(self.mms_root):
raise Exception('Could not find a source copy of Metamod:Source')
def configure(self):
for cxx in self.all_targets:
if cxx.target.arch not in ['x86', 'x86_64']:
raise Exception('Unknown target architecture: {}'.format(cxx.target.arch))
if cxx.like('gcc'):
cxx.defines += ['stricmp=strcasecmp', '_stricmp=strcasecmp', '_snprintf=snprintf', '_vsnprintf=vsnprintf', 'HAVE_STDINT_H', 'GNUC']
cxx.cflags += ['-pipe', '-fno-strict-aliasing', '-Wall', '-Werror', '-Wno-unused', '-Wno-switch', '-Wno-array-bounds', '-Wno-implicit-const-int-float-conversion', '-Wno-expansion-to-defined', '-fvisibility=hidden', '-fno-omit-frame-pointer']
cxx.cxxflags += ['-std=c++17', '-fno-exceptions', '-fno-threadsafe-statics', '-Wno-non-virtual-dtor', '-Wno-overloaded-virtual', '-Wno-register', '-fvisibility-inlines-hidden']
if cxx.target.arch == 'x86':
cxx.cflags += ['-m32', '-msse']
cxx.linkflags += ['-m32']
else:
cxx.cflags += ['-m64', '-fPIC']
cxx.linkflags += ['-m64']
if cxx.family == 'gcc':
cxx.cflags += ['-mfpmath=sse']
if builder.options.opt == '1':
cxx.cflags += ['-O3']
if cxx.target.platform == 'linux':
cxx.defines += ['LINUX', '_LINUX', 'POSIX', '_FILE_OFFSET_BITS=64']
cxx.linkflags += ['-lm', '-static-libgcc', '-static-libstdc++']
elif cxx.like('msvc'):
cxx.defines += ['_CRT_SECURE_NO_DEPRECATE', '_CRT_SECURE_NO_WARNINGS', '_CRT_NONSTDC_NO_DEPRECATE', '_ITERATOR_DEBUG_LEVEL=0']
cxx.cflags += ['/MTd' if builder.options.debug == '1' else '/MT', '/W3', '/Oy-']
cxx.cxxflags += ['/EHsc', '/GR-', '/TP', '/std:c++17']
cxx.linkflags += ['/MACHINE:X64' if cxx.target.arch == 'x86_64' else '/MACHINE:X86', '/SUBSYSTEM:WINDOWS', 'kernel32.lib', 'user32.lib', 'advapi32.lib', 'shell32.lib', 'ole32.lib', 'oleaut32.lib', 'uuid.lib', 'legacy_stdio_definitions.lib']
if builder.options.opt == '1':
cxx.cflags += ['/Ox', '/Zo']
cxx.linkflags += ['/OPT:ICF', '/OPT:REF']
if builder.options.opt == '1':
cxx.defines += ['NDEBUG']
if builder.options.debug == '1':
cxx.defines += ['DEBUG', '_DEBUG']
if cxx.target.platform == 'windows':
cxx.defines += ['WIN32', '_WINDOWS']
def ConfigureForExtension(self, context, compiler):
compiler.cxxincludes += [context.currentSourcePath, os.path.join(self.sm_root, 'public'), os.path.join(self.sm_root, 'public', 'extensions'), os.path.join(self.sm_root, 'sourcepawn', 'include'), os.path.join(self.sm_root, 'public', 'amtl'), os.path.join(self.sm_root, 'public', 'amtl', 'amtl')]
def ConfigureForHL2(self, context, binary, sdk):
cxx = binary.compiler
cxx.cxxincludes += [os.path.join(self.mms_root, 'core'), os.path.join(self.mms_root, 'core', 'sourcehook')]
for other_sdk in self.sdk_manifests:
cxx.defines += ['SE_{}={}'.format(other_sdk['define'], other_sdk['code'])]
SdkHelpers.configureCxx(context, binary, sdk)
return binary
def HL2Project(self, context, name):
return context.LibraryProject(name)
def HL2Config(self, project, context, compiler, name, sdk):
binary = project.Configure(compiler, name, '{} - {} {}'.format(self.tag, sdk['name'], compiler.target.arch))
self.ConfigureForExtension(context, binary.compiler)
return self.ConfigureForHL2(context, binary, sdk)
def AddCDetour(self, binary):
binary.sources += [os.path.join(self.sm_root, 'public', 'CDetour', 'detours.cpp')]
binary.compiler.cxxincludes += [os.path.join(self.sm_root, 'public', '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 SafetyHook build was found.')
Extension = ExtensionConfig()
Extension.detectSDKs()
Extension.configure()
builder.targets = builder.CloneableList(Extension.all_targets)
class SafetyHookShim(object):
def __init__(self):
self.all_targets = Extension.all_targets
self.libsafetyhook = []
SafetyHook = SafetyHookShim()
safetyhook_ambuilder = os.path.join(Extension.sm_root, 'public', 'safetyhook', 'AMBuilder')
if not os.path.isfile(safetyhook_ambuilder):
raise Exception('SourceMod checkout does not contain public/safetyhook; SM 1.12+ is required.')
old_source_path = builder.cm.sourcePath
builder.cm.sourcePath = os.path.dirname(safetyhook_ambuilder)
builder.Build('AMBuilder', {'SafetyHook': SafetyHook})
builder.cm.sourcePath = old_source_path
Extension.libsafetyhook = SafetyHook.libsafetyhook
builder.Build(['AMBuilder', 'PackageScript'], {'Extension': Extension})