forked from lmbelo/python3-embeddable
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbuild_deps.py
More file actions
182 lines (142 loc) · 5.88 KB
/
Copy pathbuild_deps.py
File metadata and controls
182 lines (142 loc) · 5.88 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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
#!/usr/bin/env python3
import shlex
import logging
import os
import re
import subprocess
from typing import List
from util import ARCHITECTURES, BASE, SYSROOT, env_vars, ndk_unified_toolchain, parse_args
logger = logging.getLogger(__name__)
class Package:
def __init__(self, target_arch_name: str, android_api_level: int):
self.target_arch_name = target_arch_name
self.target_arch = ARCHITECTURES[target_arch_name]
self.android_api_level = android_api_level
def run(self, cmd: List[str]):
cwd = BASE / 'deps' / re.sub(r'\.tar\..*', '', os.path.basename(self.source))
logger.debug(f'Running in {cwd}: ' + ' '.join([shlex.quote(str(arg)) for arg in cmd]))
subprocess.check_call(cmd, cwd=cwd)
def build(self):
self.configure()
self.make()
self.make_install()
def configure(self):
self.run([
'./configure',
'--prefix=/usr',
'--libdir=/usr/lib',
'--host=' + self.target_arch.ANDROID_TARGET,
'--disable-shared',
] + getattr(self, 'configure_args', []))
def make(self):
self.run(['make'])
def make_install(self):
self.run(['make', 'install', f'DESTDIR={SYSROOT}'])
class BZip2(Package):
source = 'https://sourceware.org/pub/bzip2/bzip2-1.0.8.tar.gz'
def configure(self):
pass
def make(self):
self.run([
'make', 'libbz2.a',
f'CC={os.environ["CC"]}',
f'CFLAGS={os.environ["CFLAGS"]} {os.environ["CPPFLAGS"]}',
f'AR={os.environ["AR"]}',
f'RANLIB={os.environ["RANLIB"]}',
])
def make_install(self):
# The install target in bzip2's Makefile needs too many fixes -
# Installing files manually is simpler.
self.run(['install', '-Dm644', 'libbz2.a', '-t', str(SYSROOT / 'usr' / 'lib')])
self.run(['install', '-Dm644', 'bzlib.h', '-t', str(SYSROOT / 'usr' / 'include')])
class GDBM(Package):
source = 'https://ftp.gnu.org/gnu/gdbm/gdbm-1.18.1.tar.gz'
configure_args = ['--enable-libgdbm-compat']
class LibFFI(Package):
source = 'https://github.com/libffi/libffi/releases/download/v3.3/libffi-3.3.tar.gz'
# libffi may fail to configure with Docker on WSL2 (#33)
configure_args = ['--disable-builddir']
class LibUUID(Package):
source = 'https://mirrors.edge.kernel.org/pub/linux/utils/util-linux/v2.36/util-linux-2.36.tar.xz'
configure_args = ['--disable-all-programs', '--enable-libuuid']
class NCurses(Package):
#source = 'https://invisible-mirror.net/archives/ncurses/ncurses-6.2.tar.gz'
source = 'https://ftp.gnu.org/pub/gnu/ncurses/ncurses-6.2.tar.gz'
# Not stripping the binaries as there is no easy way to specify the strip program for Android
configure_args = ['--without-ada', '--enable-widec', '--without-debug', '--without-cxx-binding', '--disable-stripping']
class OpenSSL(Package):
source = 'https://www.openssl.org/source/openssl-1.1.1h.tar.gz'
def configure(self):
# OpenSSL handles NDK internal paths by itself
path = os.pathsep.join((
# OpenSSL requires NDK's clang in $PATH to enable usage of clang
str(ndk_unified_toolchain()),
# and it requires unprefixed binutils, too
str(ndk_unified_toolchain().parent / self.target_arch.ANDROID_TARGET / 'bin'),
os.environ['PATH'],
))
logger.debug(f'$PATH for OpenSSL: {path}')
os.environ['PATH'] = path
openssl_target = 'android-' + self.target_arch_name
self.run(['./Configure', '--prefix=/usr', '--openssldir=/etc/ssl', openssl_target,
'no-shared', 'no-tests', f'-D__ANDROID_API__={self.android_api_level}'])
def make_install(self):
self.run(['make', 'install_sw', 'install_ssldirs', f'DESTDIR={SYSROOT}'])
class Readline(Package):
source = 'https://ftp.gnu.org/gnu/readline/readline-8.0.tar.gz'
# See the wcwidth() test in aclocal.m4. Tested on Android 6.0 and it's broken
# XXX: wcwidth() is implemented in [1], which may be in Android P
# Need a conditional configuration then?
# [1] https://android.googlesource.com/platform/bionic/+/c41b560f5f624cbf40febd0a3ec0b2a3f74b8e42
configure_args = ['bash_cv_wcwidth_broken=yes']
class SQLite(Package):
source = 'https://sqlite.org/2020/sqlite-autoconf-3330000.tar.gz'
class XZ(Package):
source = 'https://tukaani.org/xz/xz-5.2.5.tar.xz'
class ZLib(Package):
source = 'https://zlib.net/fossils/zlib-1.2.12.tar.gz'
def configure(self):
os.environ.update({
'CHOST': self.target_arch.ANDROID_TARGET + '-',
'CFLAGS': ' '.join([os.environ['CPPFLAGS'], os.environ['CFLAGS']]),
})
self.run([
'./configure',
'--prefix=/usr',
'--static',
])
def make(self):
self.run(['make', 'libz.a'])
def build_package(pkg: Package):
subprocess.check_call(['curl', '-fLO', pkg.source], cwd=BASE / 'deps')
subprocess.check_call(['ls', '-a'], cwd=BASE / 'deps')
subprocess.check_call(['tar', '--no-same-owner', '-xf', os.path.basename(pkg.source)], cwd=BASE / 'deps')
try:
saved_env = os.environ.copy()
pkg.build()
finally:
os.environ.clear()
os.environ.update(saved_env)
def main():
logging.basicConfig(level=logging.DEBUG)
args, _ = parse_args()
os.environ.update(env_vars(args.target_arch_name, args.android_api_level))
(BASE / 'deps').mkdir(exist_ok=True)
SYSROOT.mkdir(exist_ok=True)
package_classes = (
# ncurses is a dependency of readline
#NCurses,
BZip2,
#GDBM,
LibFFI,
#LibUUID,
OpenSSL,
#Readline,
SQLite,
XZ,
ZLib,
)
for pkg_cls in package_classes:
build_package(pkg_cls(args.target_arch_name, args.android_api_level))
if __name__ == '__main__':
main()