forked from signalapp/libsignal
-
Notifications
You must be signed in to change notification settings - Fork 0
/
build_node_bridge.py
executable file
·130 lines (105 loc) · 4.78 KB
/
build_node_bridge.py
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
#!/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'
abs_build_dir = os.path.abspath(options.cargo_build_dir)
if 'GITHUB_WORKSPACE' in cargo_env:
# Avoid long build directory paths on GitHub Actions,
# breaking the old Win32 limit of 260 characters.
# (https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation)
# We don't do this everywhere because it breaks cleaning.
#
# In the long run, Visual Studio's CLI tools will become long-path aware and this should
# become unnecessary.
# It would be nice if using extended-length path syntax `\\?\` was sufficient,
# but that also isn't accepted by all of Visual Studio's CLI tools.
tmpdir = cargo_env['RUNNER_TEMP']
if len(tmpdir) < len(abs_build_dir):
cargo_env['CARGO_BUILD_TARGET_DIR'] = os.path.join(tmpdir, "libsignal")
cmd = subprocess.Popen(cmdline, env=cargo_env)
cmd.wait()
if cmd.returncode != 0:
print('ERROR: cargo failed')
return 1
libs_in = os.path.join(cargo_env['CARGO_BUILD_TARGET_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())