mirror of
https://github.com/signalapp/libsignal.git
synced 2024-09-20 12:02:18 +02:00
ddce4ee3a4
On Windows, node-gyp tries to be helpful by changing forward slashes to backslashes and making paths relative to the source root rather than the build directory, and indeed we rely on that. However, it has to guess what's a path and what isn't. Previously, we worked around that by manually stripping the prepended "..\", but the node-gyp maintainers suggested a better workaround of using joined arguments instead (`--foo=bar` instead of `--foo bar`).
116 lines
3.9 KiB
Python
Executable File
116 lines
3.9 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
#
|
|
# Copyright (C) 2021 Signal Messenger, LLC.
|
|
# SPDX-License-Identifier: AGPL-3.0-only
|
|
#
|
|
|
|
import optparse
|
|
import sys
|
|
import subprocess
|
|
import os
|
|
import shutil
|
|
import shlex
|
|
|
|
|
|
def main(args=None):
|
|
if args is None:
|
|
args = sys.argv
|
|
|
|
if sys.platform == 'win32':
|
|
args = shlex.split(' '.join(args), posix=0)
|
|
|
|
print("Invoked with '%s'" % (' '.join(args)))
|
|
|
|
parser = optparse.OptionParser()
|
|
parser.add_option('--out-dir', '-o', default=None, metavar='DIR',
|
|
help='specify destination dir (default build/$CONFIGURATION_NAME)')
|
|
parser.add_option('--configuration', default='Release', metavar='C',
|
|
help='specify build configuration (Release or Debug)')
|
|
parser.add_option('--os-name', default=None, metavar='OS',
|
|
help='specify Node OS name')
|
|
parser.add_option('--cargo-build-dir', default='target', metavar='PATH',
|
|
help='specify cargo build dir (default %default)')
|
|
parser.add_option('--cargo-target', default=None,
|
|
help='specify cargo target')
|
|
parser.add_option('--node-arch', default=None,
|
|
help='specify node arch (x64, ia32, arm64)')
|
|
|
|
(options, args) = parser.parse_args(args)
|
|
|
|
configuration_name = options.configuration.strip('"')
|
|
if configuration_name is None:
|
|
print('ERROR: --configuration is required')
|
|
return 1
|
|
elif configuration_name not in ['Release', 'Debug']:
|
|
print("ERROR: Unknown value for --configuration '%s'" % (configuration_name))
|
|
return 1
|
|
|
|
node_os_name = options.os_name
|
|
if node_os_name is None:
|
|
print('ERROR: --os-name is required')
|
|
return 1
|
|
|
|
cargo_target = options.cargo_target
|
|
if cargo_target is None:
|
|
print('ERROR: --cargo-target is required')
|
|
return 1
|
|
|
|
node_arch = options.node_arch
|
|
if node_arch is None:
|
|
print('ERROR: --node_arch is required')
|
|
return 1
|
|
|
|
out_dir = options.out_dir.strip('"') or os.path.join('build', configuration_name)
|
|
|
|
cmdline = ['cargo', 'build', '--target', cargo_target, '-p', 'libsignal-node']
|
|
if configuration_name == 'Release':
|
|
cmdline.append('--release')
|
|
print("Running '%s'" % (' '.join(cmdline)))
|
|
|
|
cargo_env = os.environ.copy()
|
|
cargo_env['CARGO_BUILD_TARGET_DIR'] = options.cargo_build_dir
|
|
# On Linux, cdylibs don't include public symbols from their dependencies,
|
|
# even if those symbols have been re-exported in the Rust source.
|
|
# Using LTO works around this at the cost of a slightly slower build.
|
|
# https://github.com/rust-lang/rfcs/issues/2771
|
|
cargo_env['CARGO_PROFILE_RELEASE_LTO'] = 'thin'
|
|
|
|
if node_os_name == 'win32':
|
|
# By default, Rust on Windows depends on an MSVC component for the C runtime.
|
|
# Link it statically to avoid propagating that dependency.
|
|
cargo_env['RUSTFLAGS'] = '-C target-feature=+crt-static'
|
|
|
|
cmd = subprocess.Popen(cmdline, env=cargo_env)
|
|
cmd.wait()
|
|
|
|
if cmd.returncode != 0:
|
|
print('ERROR: cargo failed')
|
|
return 1
|
|
|
|
libs_in = os.path.join(options.cargo_build_dir,
|
|
cargo_target,
|
|
configuration_name.lower())
|
|
|
|
found_a_lib = False
|
|
for lib_format in ['%s.dll', 'lib%s.so', 'lib%s.dylib']:
|
|
src_path = os.path.join(libs_in, lib_format % 'signal_node')
|
|
if os.access(src_path, os.R_OK):
|
|
dst_path = os.path.join(out_dir, 'libsignal_client_%s_%s.node' % (node_os_name, node_arch))
|
|
print("Copying %s to %s" % (src_path, dst_path))
|
|
if not os.path.exists(out_dir):
|
|
os.makedirs(out_dir)
|
|
shutil.copyfile(src_path, dst_path)
|
|
found_a_lib = True
|
|
break
|
|
|
|
if not found_a_lib:
|
|
print("ERROR did not find generated library")
|
|
return 1
|
|
|
|
return 0
|
|
|
|
|
|
if __name__ == '__main__':
|
|
sys.exit(main())
|