Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

64-bit support for CSGO on Linux and macOS #705

Merged
merged 27 commits into from
Dec 20, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
0107ccc
First pass at adding 64-bit build support to AMBuild files.
TheDS Sep 18, 2017
fe0f0f0
Add 64-bit support to loader.
TheDS Sep 18, 2017
f642344
64-bit build fixes for core.
TheDS Sep 20, 2017
3e31cf0
64-bit build fixes for logic.
TheDS Sep 20, 2017
909b21b
64-bit build fixes for regex extension.
TheDS Sep 20, 2017
a6645e3
64-bit build fixes for MySQL extension.
TheDS Sep 20, 2017
6906a83
64-bit support for CDetour.
TheDS Sep 21, 2017
eae4796
64-bit support for bintools extension and removal of IBinTools2.
TheDS Oct 3, 2017
9e617ef
Add game data for 64-bit Linux/macOS and fix code for some associated…
TheDS Oct 5, 2017
24c5304
Fill in field information in SDKTools when passing Vector or QAngle b…
TheDS Oct 5, 2017
efa19b7
Update package script for 64-bit binaries.
TheDS Oct 7, 2017
0dd20b7
Throw exception if attempting to configure for multiple archs with MSVC.
TheDS Oct 8, 2017
65957e0
Update bootstrap.pl to build 64-bit binaries on Linux and macOS.
TheDS Oct 8, 2017
c55654f
Throw error when using PrepSDKCall_SetAddress on 64-bit, for now.
TheDS Oct 8, 2017
0efd3b7
Fix -Wformat-truncate warnings on GCC 7 by checking snprintf return v…
TheDS Oct 9, 2017
231769e
Update checkout-deps script for 64-bit MySQL.
TheDS Oct 10, 2017
9dbb892
Use pseudo addresses on 64-bit platforms in places where natives use …
TheDS Oct 11, 2017
93a99ea
Fix build of TF2 extension.
TheDS Oct 14, 2017
bc462fe
Work around VS 2013's lack of constexpr support by not including Pseu…
TheDS Oct 14, 2017
4ec873b
Fix 32-bit Linux build.
TheDS Oct 14, 2017
58d7649
Fix Windows build.
TheDS Oct 14, 2017
0ef4bc3
Fix typo in CBaseTempEntity signature.
TheDS Oct 19, 2017
cf1c63d
Update CreateFakeClient signature for 64-bit macOS.
TheDS Oct 19, 2017
12448e5
Merge with updates from master.
TheDS Nov 4, 2017
4cb6bc1
Fix getting CS:GO item schema on macOS.
TheDS Nov 4, 2017
63386bd
Fix miscellaneous whitepsace issues in CDetour/detours.cpp.
TheDS Nov 13, 2017
0add56e
Merge with changes from master.
TheDS Dec 20, 2017
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
170 changes: 128 additions & 42 deletions AMBuildScript
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,29 @@ class SDK(object):
self.platform = platform
self.name = dir
self.path = None # Actual path
self.platformSpec = platform

# By default, nothing supports x64.
if type(platform) is list:
self.platformSpec = {p: ['x86'] for p in platform}
else:
self.platformSpec = platform

def shouldBuild(self, target, archs):
if target.platform not in self.platformSpec:
return False
if not len([i for i in self.platformSpec[target.platform] if i in archs]):
return False
return True

WinOnly = ['windows']
WinLinux = ['windows', 'linux']
WinLinuxMac = ['windows', 'linux', 'mac']
CSGO = {
'windows': ['x86'],
'linux': ['x86', 'x64'],
'mac': ['x64']
}

PossibleSDKs = {
'episode1': SDK('HL2SDK', '2.ep1', '1', 'EPISODEONE', WinLinux, 'episode1'),
Expand All @@ -31,7 +50,7 @@ PossibleSDKs = {
'swarm': SDK('HL2SDK-SWARM', '2.swarm', '16', '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', '21', 'CSGO', WinLinux, 'csgo'),
'csgo': SDK('HL2SDKCSGO', '2.csgo', '21', 'CSGO', CSGO, 'csgo'),
'portal2': SDK('HL2SDKPORTAL2', '2.portal2', '17', 'PORTAL2', [], 'portal2'),
'blade': SDK('HL2SDKBLADE', '2.blade', '18', 'BLADE', WinLinux, 'blade'),
'insurgency': SDK('HL2SDKINSURGENCY', '2.insurgency', '19', 'INSURGENCY', WinLinuxMac, 'insurgency'),
Expand Down Expand Up @@ -60,6 +79,28 @@ def ResolveEnvPath(env, folder):

def Normalize(path):
return os.path.abspath(os.path.normpath(path))

def SetArchFlags(compiler, arch, platform):
if compiler.behavior == 'gcc':
if arch == 'x86':
compiler.cflags += ['-m32']
compiler.linkflags += ['-m32']
if platform == 'mac':
compiler.linkflags += ['-arch', 'i386']
elif arch == 'x64':
compiler.cflags += ['-m64', '-fPIC']
compiler.linkflags += ['-m64']
if platform == 'mac':
compiler.linkflags += ['-arch', 'x86_64']
elif compiler.like('msvc'):
if builder.target.arch == 'x86':
compiler.linkflags += ['/MACHINE:X86']
elif builder.target.arch == 'x64':
compiler.linkflags += ['/MACHINE:X64']

def AppendArchSuffix(binary, name, arch):
if arch == 'x64':
binary.localFolder = name + '.x64'

class SMConfig(object):
def __init__(self):
Expand All @@ -68,10 +109,12 @@ class SMConfig(object):
self.extensions = []
self.generated_headers = None
self.mms_root = None
self.mysql_root = None
self.mysql_root = {}
self.spcomp = None
self.spcomp_bins = None
self.smx_files = {}
self.versionlib = None
self.archs = builder.target.arch.replace('x86_64', 'x64').split(',')

def use_auto_versioning(self):
if builder.backend != 'amb2':
Expand Down Expand Up @@ -105,7 +148,7 @@ class SMConfig(object):

for sdk_name in PossibleSDKs:
sdk = PossibleSDKs[sdk_name]
if builder.target.platform in sdk.platform:
if sdk.shouldBuild(builder.target, self.archs):
if builder.options.hl2sdk_root:
sdk_path = os.path.join(builder.options.hl2sdk_root, sdk.folder)
else:
Expand All @@ -118,8 +161,9 @@ class SMConfig(object):
sdk.path = Normalize(sdk_path)
self.sdks[sdk_name] = sdk

if len(self.sdks) < 1:
raise Exception('At least one SDK must be available.')
if len(self.sdks) < 1 and len(sdk_list):
raise Exception('No SDKs were found that build on {0}-{1}, nothing to do.'.format(
builder.target.platform, builder.target.arch))

if builder.options.mms_path:
self.mms_root = builder.options.mms_path
Expand All @@ -136,20 +180,39 @@ class SMConfig(object):

if builder.options.hasMySql:
if builder.options.mysql_path:
self.mysql_root = builder.options.mysql_path
self.mysql_root['x86'] = builder.options.mysql_path
else:
for i in range(7):
self.mysql_root = ResolveEnvPath('MYSQL5', 'mysql-5.' + str(i))
if self.mysql_root:
self.mysql_root['x86'] = ResolveEnvPath('MYSQL5', 'mysql-5.' + str(i))
if self.mysql_root['x86']:
break
if not self.mysql_root or not os.path.isdir(self.mysql_root):
if not self.mysql_root['x86'] or not os.path.isdir(self.mysql_root['x86']):
raise Exception('Could not find a path to MySQL!')
self.mysql_root = Normalize(self.mysql_root)
self.mysql_root['x86'] = Normalize(self.mysql_root['x86'])

# For now, ignore 64-bit MySQL on Windows
if 'x64' in self.archs and builder.target.platform != 'windows':
if builder.options.mysql_path:
self.mysql_root['x64'] = builder.options.mysql64_path
else:
for i in range(7):
self.mysql_root['x64'] = ResolveEnvPath('MYSQL5_64', 'mysql-5.' + str(i) + '-x86_64')
if self.mysql_root['x64']:
break
if not self.mysql_root['x64'] or not os.path.isdir(self.mysql_root['x64']):
raise Exception('Could not find a path to 64-bit MySQL!')
self.mysql_root['x64'] = Normalize(self.mysql_root['x64'])

def configure(self):
builder.AddConfigureFile('pushbuild.txt')

if not set(self.archs).issubset(['x86', 'x64']):
raise Exception('Unknown target architecture: {0}'.format(builder.target.arch))

cxx = builder.DetectCxx()

if cxx.like('msvc') and len(self.archs) > 1:
raise Exception('Building multiple archs with MSVC is not currently supported')

if cxx.like('gcc'):
self.configure_gcc(cxx)
Expand Down Expand Up @@ -205,7 +268,6 @@ class SMConfig(object):
'-Wno-switch',
'-Wno-array-bounds',
'-msse',
'-m32',
'-fvisibility=hidden',
]
cxx.cxxflags += [
Expand All @@ -216,7 +278,6 @@ class SMConfig(object):
'-Wno-overloaded-virtual',
'-fvisibility-inlines-hidden',
]
cxx.linkflags += ['-m32']

have_gcc = cxx.family == 'gcc'
have_clang = cxx.family == 'clang'
Expand Down Expand Up @@ -271,7 +332,6 @@ class SMConfig(object):
'/TP',
]
cxx.linkflags += [
'/MACHINE:X86',
'kernel32.lib',
'user32.lib',
'gdi32.lib',
Expand Down Expand Up @@ -310,7 +370,6 @@ class SMConfig(object):
cxx.cflags += ['-mmacosx-version-min=10.5']
cxx.linkflags += [
'-mmacosx-version-min=10.5',
'-arch', 'i386',
'-lstdc++',
'-stdlib=libstdc++',
]
Expand All @@ -319,7 +378,7 @@ class SMConfig(object):
def configure_windows(self, cxx):
cxx.defines += ['WIN32', '_WINDOWS']

def AddVersioning(self, binary):
def AddVersioning(self, binary, arch):
if builder.target.platform == 'windows':
binary.sources += ['version.rc']
binary.compiler.rcdefines += [
Expand All @@ -335,20 +394,22 @@ class SMConfig(object):
'-current_version', self.productVersion
]
if self.use_auto_versioning():
binary.compiler.linkflags += [self.versionlib]
binary.compiler.linkflags += [self.versionlib[arch]]
binary.compiler.sourcedeps += SM.generated_headers
return binary

def LibraryBuilder(self, compiler, name):
def LibraryBuilder(self, compiler, name, arch):
binary = compiler.Library(name)
self.AddVersioning(binary)
AppendArchSuffix(binary, name, arch)
self.AddVersioning(binary, arch)
if binary.compiler.like('msvc'):
binary.compiler.linkflags += ['/SUBSYSTEM:WINDOWS']
return binary

def ProgramBuilder(self, compiler, name):
def ProgramBuilder(self, compiler, name, arch):
binary = compiler.Program(name)
self.AddVersioning(binary)
AppendArchSuffix(binary, name, arch)
self.AddVersioning(binary, arch)
if '-static-libgcc' in binary.compiler.linkflags:
binary.compiler.linkflags.remove('-static-libgcc')
if '-lgcc_eh' in binary.compiler.linkflags:
Expand All @@ -359,21 +420,25 @@ class SMConfig(object):
binary.compiler.linkflags += ['/SUBSYSTEM:CONSOLE']
return binary

def StaticLibraryBuilder(self, compiler, name):
def StaticLibraryBuilder(self, compiler, name, arch):
binary = compiler.StaticLibrary(name)
AppendArchSuffix(binary, name, arch)
return binary;

def Library(self, context, name):
def Library(self, context, name, arch):
compiler = context.cxx.clone()
return self.LibraryBuilder(compiler, name)
SetArchFlags(compiler, arch, builder.target.platform)
return self.LibraryBuilder(compiler, name, arch)

def Program(self, context, name):
def Program(self, context, name, arch):
compiler = context.cxx.clone()
return self.ProgramBuilder(compiler, name)
SetArchFlags(compiler, arch, builder.target.platform)
return self.ProgramBuilder(compiler, name, arch)

def StaticLibrary(self, context, name):
def StaticLibrary(self, context, name, arch):
compiler = context.cxx.clone()
return self.StaticLibraryBuilder(compiler, name)
SetArchFlags(compiler, arch, builder.target.platform)
return self.StaticLibraryBuilder(compiler, name, arch)

def ConfigureForExtension(self, context, compiler):
compiler.cxxincludes += [
Expand All @@ -386,13 +451,15 @@ class SMConfig(object):
]
return compiler

def ExtLibrary(self, context, name):
binary = self.Library(context, name)
def ExtLibrary(self, context, name, arch):
binary = self.Library(context, name, arch)
self.ConfigureForExtension(context, binary.compiler)
return binary

def ConfigureForHL2(self, binary, sdk):
def ConfigureForHL2(self, binary, sdk, arch):
compiler = binary.compiler

SetArchFlags(compiler, arch, builder.target.platform)

compiler.cxxincludes += [
os.path.join(self.mms_root, 'core'),
Expand Down Expand Up @@ -435,6 +502,9 @@ class SMConfig(object):
else:
compiler.defines += ['COMPILER_GCC']

if arch == 'x64':
compiler.defines += ['X64BITS', 'PLATFORM_64BITS']

# 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']:
Expand All @@ -446,6 +516,7 @@ class SMConfig(object):

if sdk.name == 'csgo' and builder.target.platform == 'linux':
compiler.linkflags += ['-lstdc++']
compiler.defines += ['_GLIBCXX_USE_CXX11_ABI=0']

for path in paths:
compiler.cxxincludes += [os.path.join(sdk.path, *path)]
Expand All @@ -455,16 +526,20 @@ class SMConfig(object):
lib_folder = os.path.join(sdk.path, 'linux_sdk')
elif sdk.name in ['sdk2013', 'bms']:
lib_folder = os.path.join(sdk.path, 'lib', 'public', 'linux32')
elif arch == 'x64':
lib_folder = os.path.join(sdk.path, 'lib', 'linux64')
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')
elif arch == 'x64':
lib_folder = os.path.join(sdk.path, 'lib', 'osx64')
else:
lib_folder = os.path.join(sdk.path, 'lib', 'mac')

if builder.target.platform in ['linux', 'mac']:
if sdk.name in ['sdk2013', 'bms']:
if sdk.name in ['sdk2013', 'bms'] or arch == 'x64':
compiler.postlink += [
compiler.Dep(os.path.join(lib_folder, 'tier1.a')),
compiler.Dep(os.path.join(lib_folder, 'mathlib.a'))
Expand All @@ -476,12 +551,17 @@ class SMConfig(object):
]

if sdk.name in ['blade', 'insurgency', 'doi', 'csgo']:
compiler.postlink += [compiler.Dep(os.path.join(lib_folder, 'interfaces_i486.a'))]
if arch == 'x64':
compiler.postlink += [compiler.Dep(os.path.join(lib_folder, 'interfaces.a'))]
else:
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 arch == 'x64' and sdk.name == 'csgo':
dynamic_libs = ['libtier0_client.so', 'libvstdlib_client.so']
elif sdk.name in ['l4d', 'blade', 'insurgency', 'doi', 'csgo']:
dynamic_libs = ['libtier0.so', 'libvstdlib.so']
else:
Expand Down Expand Up @@ -512,20 +592,21 @@ class SMConfig(object):

return binary

def HL2Library(self, context, name, sdk):
binary = self.Library(context, name)
def HL2Library(self, context, name, sdk, arch):
binary = self.Library(context, name, arch)
self.ConfigureForExtension(context, binary.compiler)
return self.ConfigureForHL2(binary, sdk)
return self.ConfigureForHL2(binary, sdk, arch)

def HL2Project(self, context, name):
project = context.cxx.LibraryProject(name)
self.ConfigureForExtension(context, project.compiler)
return project

def HL2Config(self, project, name, sdk):
def HL2Config(self, project, name, sdk, arch):
binary = project.Configure(name, '{0} - {1}'.format(self.tag, sdk.name))
self.AddVersioning(binary)
return self.ConfigureForHL2(binary, sdk)
AppendArchSuffix(binary, name, arch)
self.AddVersioning(binary, arch)
return self.ConfigureForHL2(binary, sdk, arch)

SM = SMConfig()
SM.detectProductVersion()
Expand All @@ -548,10 +629,15 @@ SP = builder.Build('sourcepawn/AMBuildScript', {
'external_amtl': os.path.join(builder.sourcePath, 'public', 'amtl'),
'external_build': ['core'],
})
SM.spcomp = SP.spcomp
SM.binaries += [
SP.libsourcepawn
]
if len(SP.spcomp) > 1:
SM.spcomp = SP.spcomp['x86']
else:
SM.spcomp = SP.spcomp[list(SP.spcomp.keys())[0]]
SM.spcomp_bins = list(SP.spcomp.values())
for arch in SM.archs:
SM.binaries += [
SP.libsourcepawn[arch]
]

BuildScripts = [
'loader/AMBuilder',
Expand Down
2 changes: 1 addition & 1 deletion bridge/include/BridgeAPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ namespace SourceMod {

// Add 1 to the RHS of this expression to bump the intercom file
// This is to prevent mismatching core/logic binaries
static const uint32_t SM_LOGIC_MAGIC = 0x0F47C0DE - 55;
static const uint32_t SM_LOGIC_MAGIC = 0x0F47C0DE - 56;

} // namespace SourceMod

Expand Down
2 changes: 2 additions & 0 deletions bridge/include/LogicProvider.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ struct sm_logic_t
void (*FreeDataPack)(IDataPack *pack);
ICellArray * (*CreateCellArray)(size_t blocksize);
void (*FreeCellArray)(ICellArray *arr);
void * (*FromPseudoAddress)(uint32_t pseudoAddr);
uint32_t (*ToPseudoAddress)(void *addr);
IScriptManager *scripts;
IShareSys *sharesys;
IExtensionSys *extsys;
Expand Down
Loading