discord-rpc/build.py

227 lines
6.8 KiB
Python
Raw Normal View History

2017-09-14 17:59:32 +02:00
#!/usr/bin/env python
import os
import subprocess
import sys
import shutil
import zipfile
from contextlib import contextmanager
2017-11-23 01:12:37 +01:00
import click
2017-11-28 19:27:40 +01:00
def get_platform():
2017-11-23 01:12:37 +01:00
""" a name for the platform """
if sys.platform.startswith('win'):
return 'win'
elif sys.platform == 'darwin':
return 'osx'
elif sys.platform.startswith('linux'):
return 'linux'
raise Exception('Unsupported platform ' + sys.platform)
2017-11-29 23:00:28 +01:00
SCRIPT_PATH = os.path.dirname(os.path.abspath(__file__))
# we use Buildkite which sets this env variable by default
IS_BUILD_MACHINE = os.environ.get('CI', '') == 'true'
PLATFORM = get_platform()
INSTALL_ROOT = os.path.join(SCRIPT_PATH, 'builds', 'install')
def get_signtool():
""" get path to code signing tool """
if PLATFORM == 'win':
sdk_dir = os.environ['WindowsSdkDir']
return os.path.join(sdk_dir, 'bin', 'x86', 'signtool.exe')
elif PLATFORM == 'osx':
return '/usr/bin/codesign'
@contextmanager
def cd(new_dir):
""" Temporarily change current directory """
if new_dir:
old_dir = os.getcwd()
os.chdir(new_dir)
yield
if new_dir:
os.chdir(old_dir)
def mkdir_p(path):
""" mkdir -p """
if not os.path.isdir(path):
2017-11-23 01:12:37 +01:00
click.secho('Making ' + path, fg='yellow')
os.makedirs(path)
2017-11-23 01:12:37 +01:00
@click.group(invoke_without_command=True)
@click.pass_context
@click.option('--clean', is_flag=True)
def cli(ctx, clean):
2017-11-28 19:27:40 +01:00
""" click wrapper for command line stuff """
2017-11-23 01:12:37 +01:00
if ctx.invoked_subcommand is None:
ctx.invoke(libs, clean=clean)
2017-11-29 23:00:28 +01:00
if IS_BUILD_MACHINE:
ctx.invoke(sign)
2017-11-23 01:12:37 +01:00
ctx.invoke(archive)
@cli.command()
def unity():
2017-11-28 19:27:40 +01:00
""" todo: build unity project """
2017-11-23 01:12:37 +01:00
pass
@cli.command()
@click.pass_context
def for_unity(ctx):
""" build just dynamic libs for use in unity project """
ctx.invoke(libs, clean=False, static=False, shared=True, skip_formatter=False)
2017-11-23 01:12:37 +01:00
@cli.command()
def unreal():
2017-11-28 19:27:40 +01:00
""" todo: build unreal project """
2017-11-23 01:12:37 +01:00
pass
def build_lib(build_name, generator, options):
2017-11-23 01:12:37 +01:00
""" Create a dir under builds, run build and install in it """
build_path = os.path.join(SCRIPT_PATH, 'builds', build_name)
2017-11-29 23:00:28 +01:00
install_path = os.path.join(INSTALL_ROOT, build_name)
mkdir_p(build_path)
mkdir_p(install_path)
with cd(build_path):
2017-11-23 01:12:37 +01:00
initial_cmake = [
'cmake',
SCRIPT_PATH,
'-DCMAKE_INSTALL_PREFIX=%s' % os.path.join('..', 'install', build_name)
]
if generator:
initial_cmake.extend(['-G', generator])
2017-11-29 18:50:22 +01:00
if IS_BUILD_MACHINE:
# disable formatting on CI builds
initial_cmake.append('-DCLANG_FORMAT_SUFFIX=none')
for key in options:
val = options[key]
if type(val) is bool:
val = 'ON' if val else 'OFF'
2017-11-23 01:12:37 +01:00
initial_cmake.append('-D%s=%s' % (key, val))
click.echo('--- Building ' + build_name)
subprocess.check_call(initial_cmake)
if not IS_BUILD_MACHINE:
subprocess.check_call(['cmake', '--build', '.', '--config', 'Debug'])
subprocess.check_call(['cmake', '--build', '.', '--config', 'Release', '--target', 'install'])
2017-11-23 01:12:37 +01:00
@cli.command()
def archive():
2017-11-28 19:27:40 +01:00
""" create zip of install dir """
click.echo('--- Archiving')
2017-11-28 19:27:40 +01:00
archive_file_path = os.path.join(SCRIPT_PATH, 'builds', 'discord-rpc-%s.zip' % get_platform())
archive_file = zipfile.ZipFile(archive_file_path, 'w', zipfile.ZIP_DEFLATED)
2017-11-29 23:00:28 +01:00
archive_src_base_path = INSTALL_ROOT
archive_dst_base_path = 'discord-rpc'
with cd(archive_src_base_path):
2017-11-28 19:27:40 +01:00
for path, _, filenames in os.walk('.'):
for fname in filenames:
fpath = os.path.join(path, fname)
dst_path = os.path.normpath(os.path.join(archive_dst_base_path, fpath))
click.echo('Adding ' + dst_path)
archive_file.write(fpath, dst_path)
2017-11-28 19:27:40 +01:00
@cli.command()
2017-11-29 23:00:28 +01:00
def sign():
""" Do code signing within install directory using our cert """
tool = get_signtool()
2017-11-28 19:27:40 +01:00
signable_extensions = set()
2017-11-29 23:00:28 +01:00
if PLATFORM == 'win':
2017-11-28 19:27:40 +01:00
signable_extensions.add('.dll')
sign_command_base = [
tool,
'sign',
'/n', 'Hammer & Chisel Inc.',
'/a',
'/tr', 'http://timestamp.digicert.com/rfc3161',
'/as',
'/td', 'sha256',
'/fd', 'sha256',
]
2017-11-29 23:00:28 +01:00
elif PLATFORM == 'osx':
2017-11-28 19:27:40 +01:00
signable_extensions.add('.dylib')
sign_command_base = [
tool,
'--keychain', os.path.expanduser('~/Library/Keychains/login.keychain'),
'-vvvv',
'--deep',
'--force',
'--sign', 'Developer ID Application: Hammer & Chisel Inc. (53Q6R32WPB)',
]
else:
click.secho('Not signing things on this platform yet', fg='red')
return
2017-11-29 23:00:28 +01:00
click.echo('--- Signing')
2017-11-29 23:00:28 +01:00
for path, _, filenames in os.walk(INSTALL_ROOT):
for fname in filenames:
2017-11-28 19:27:40 +01:00
ext = os.path.splitext(fname)[1]
if ext not in signable_extensions:
continue
2017-11-29 23:00:28 +01:00
fpath = os.path.join(path, fname)
click.echo('Sign ' + fpath)
2017-11-28 19:27:40 +01:00
sign_command = sign_command_base + [fpath]
subprocess.check_call(sign_command)
2017-11-23 01:12:37 +01:00
@cli.command()
@click.option('--clean', is_flag=True)
@click.option('--static', is_flag=True)
@click.option('--shared', is_flag=True)
@click.option('--skip_formatter', is_flag=True)
def libs(clean, static, shared, skip_formatter):
2017-11-28 19:27:40 +01:00
""" Do all the builds for this platform """
if clean:
shutil.rmtree('builds', ignore_errors=True)
2017-09-14 17:59:32 +02:00
mkdir_p('builds')
if not (static or shared):
static = True
shared = True
static_options = {}
dynamic_options = {
'BUILD_SHARED_LIBS': True,
'USE_STATIC_CRT': True,
}
if skip_formatter:
static_options['CLANG_FORMAT_SUFFIX'] = 'nope'
dynamic_options['CLANG_FORMAT_SUFFIX'] = 'nope'
2017-11-29 23:00:28 +01:00
if PLATFORM == 'win':
generator32 = 'Visual Studio 14 2015'
generator64 = 'Visual Studio 14 2015 Win64'
if static:
build_lib('win32-static', generator32, static_options)
build_lib('win64-static', generator64, static_options)
if shared:
build_lib('win32-dynamic', generator32, dynamic_options)
build_lib('win64-dynamic', generator64, dynamic_options)
2017-11-29 23:00:28 +01:00
elif PLATFORM == 'osx':
if static:
build_lib('osx-static', None, static_options)
if shared:
build_lib('osx-dynamic', None, dynamic_options)
2017-11-29 23:00:28 +01:00
elif PLATFORM == 'linux':
if static:
build_lib('linux-static', None, static_options)
if shared:
build_lib('linux-dynamic', None, dynamic_options)
if __name__ == '__main__':
2017-11-28 19:27:40 +01:00
os.chdir(SCRIPT_PATH)
2017-11-23 01:12:37 +01:00
sys.exit(cli())