Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/jemalloc/scripts/gen_travis.py
39507 views
1
#!/usr/bin/env python3
2
3
from itertools import combinations, chain
4
from enum import Enum, auto
5
6
7
LINUX = 'linux'
8
OSX = 'osx'
9
WINDOWS = 'windows'
10
FREEBSD = 'freebsd'
11
12
13
AMD64 = 'amd64'
14
ARM64 = 'arm64'
15
PPC64LE = 'ppc64le'
16
17
18
TRAVIS_TEMPLATE = """\
19
# This config file is generated by ./scripts/gen_travis.py.
20
# Do not edit by hand.
21
22
# We use 'minimal', because 'generic' makes Windows VMs hang at startup. Also
23
# the software provided by 'generic' is simply not needed for our tests.
24
# Differences are explained here:
25
# https://docs.travis-ci.com/user/languages/minimal-and-generic/
26
language: minimal
27
dist: focal
28
29
jobs:
30
include:
31
{jobs}
32
33
before_install:
34
- |-
35
if test -f "./scripts/$TRAVIS_OS_NAME/before_install.sh"; then
36
source ./scripts/$TRAVIS_OS_NAME/before_install.sh
37
fi
38
39
before_script:
40
- |-
41
if test -f "./scripts/$TRAVIS_OS_NAME/before_script.sh"; then
42
source ./scripts/$TRAVIS_OS_NAME/before_script.sh
43
else
44
scripts/gen_travis.py > travis_script && diff .travis.yml travis_script
45
autoconf
46
# If COMPILER_FLAGS are not empty, add them to CC and CXX
47
./configure ${{COMPILER_FLAGS:+ CC="$CC $COMPILER_FLAGS" \
48
CXX="$CXX $COMPILER_FLAGS"}} $CONFIGURE_FLAGS
49
make -j3
50
make -j3 tests
51
fi
52
53
script:
54
- |-
55
if test -f "./scripts/$TRAVIS_OS_NAME/script.sh"; then
56
source ./scripts/$TRAVIS_OS_NAME/script.sh
57
else
58
make check
59
fi
60
"""
61
62
63
class Option(object):
64
class Type:
65
COMPILER = auto()
66
COMPILER_FLAG = auto()
67
CONFIGURE_FLAG = auto()
68
MALLOC_CONF = auto()
69
FEATURE = auto()
70
71
def __init__(self, type, value):
72
self.type = type
73
self.value = value
74
75
@staticmethod
76
def as_compiler(value):
77
return Option(Option.Type.COMPILER, value)
78
79
@staticmethod
80
def as_compiler_flag(value):
81
return Option(Option.Type.COMPILER_FLAG, value)
82
83
@staticmethod
84
def as_configure_flag(value):
85
return Option(Option.Type.CONFIGURE_FLAG, value)
86
87
@staticmethod
88
def as_malloc_conf(value):
89
return Option(Option.Type.MALLOC_CONF, value)
90
91
@staticmethod
92
def as_feature(value):
93
return Option(Option.Type.FEATURE, value)
94
95
def __eq__(self, obj):
96
return (isinstance(obj, Option) and obj.type == self.type
97
and obj.value == self.value)
98
99
100
# The 'default' configuration is gcc, on linux, with no compiler or configure
101
# flags. We also test with clang, -m32, --enable-debug, --enable-prof,
102
# --disable-stats, and --with-malloc-conf=tcache:false. To avoid abusing
103
# travis though, we don't test all 2**7 = 128 possible combinations of these;
104
# instead, we only test combinations of up to 2 'unusual' settings, under the
105
# hope that bugs involving interactions of such settings are rare.
106
MAX_UNUSUAL_OPTIONS = 2
107
108
109
GCC = Option.as_compiler('CC=gcc CXX=g++')
110
CLANG = Option.as_compiler('CC=clang CXX=clang++')
111
CL = Option.as_compiler('CC=cl.exe CXX=cl.exe')
112
113
114
compilers_unusual = [CLANG,]
115
116
117
CROSS_COMPILE_32BIT = Option.as_feature('CROSS_COMPILE_32BIT')
118
feature_unusuals = [CROSS_COMPILE_32BIT]
119
120
121
configure_flag_unusuals = [Option.as_configure_flag(opt) for opt in (
122
'--enable-debug',
123
'--enable-prof',
124
'--disable-stats',
125
'--disable-libdl',
126
'--enable-opt-safety-checks',
127
'--with-lg-page=16',
128
)]
129
130
131
malloc_conf_unusuals = [Option.as_malloc_conf(opt) for opt in (
132
'tcache:false',
133
'dss:primary',
134
'percpu_arena:percpu',
135
'background_thread:true',
136
)]
137
138
139
all_unusuals = (compilers_unusual + feature_unusuals
140
+ configure_flag_unusuals + malloc_conf_unusuals)
141
142
143
def get_extra_cflags(os, compiler):
144
if os == FREEBSD:
145
return []
146
147
if os == WINDOWS:
148
# For non-CL compilers under Windows (for now it's only MinGW-GCC),
149
# -fcommon needs to be specified to correctly handle multiple
150
# 'malloc_conf' symbols and such, which are declared weak under Linux.
151
# Weak symbols don't work with MinGW-GCC.
152
if compiler != CL.value:
153
return ['-fcommon']
154
else:
155
return []
156
157
# We get some spurious errors when -Warray-bounds is enabled.
158
extra_cflags = ['-Werror', '-Wno-array-bounds']
159
if compiler == CLANG.value or os == OSX:
160
extra_cflags += [
161
'-Wno-unknown-warning-option',
162
'-Wno-ignored-attributes'
163
]
164
if os == OSX:
165
extra_cflags += [
166
'-Wno-deprecated-declarations',
167
]
168
return extra_cflags
169
170
171
# Formats a job from a combination of flags
172
def format_job(os, arch, combination):
173
compilers = [x.value for x in combination if x.type == Option.Type.COMPILER]
174
assert(len(compilers) <= 1)
175
compiler_flags = [x.value for x in combination if x.type == Option.Type.COMPILER_FLAG]
176
configure_flags = [x.value for x in combination if x.type == Option.Type.CONFIGURE_FLAG]
177
malloc_conf = [x.value for x in combination if x.type == Option.Type.MALLOC_CONF]
178
features = [x.value for x in combination if x.type == Option.Type.FEATURE]
179
180
if len(malloc_conf) > 0:
181
configure_flags.append('--with-malloc-conf=' + ','.join(malloc_conf))
182
183
if not compilers:
184
compiler = GCC.value
185
else:
186
compiler = compilers[0]
187
188
extra_environment_vars = ''
189
cross_compile = CROSS_COMPILE_32BIT.value in features
190
if os == LINUX and cross_compile:
191
compiler_flags.append('-m32')
192
193
features_str = ' '.join([' {}=yes'.format(feature) for feature in features])
194
195
stringify = lambda arr, name: ' {}="{}"'.format(name, ' '.join(arr)) if arr else ''
196
env_string = '{}{}{}{}{}{}'.format(
197
compiler,
198
features_str,
199
stringify(compiler_flags, 'COMPILER_FLAGS'),
200
stringify(configure_flags, 'CONFIGURE_FLAGS'),
201
stringify(get_extra_cflags(os, compiler), 'EXTRA_CFLAGS'),
202
extra_environment_vars)
203
204
job = ' - os: {}\n'.format(os)
205
job += ' arch: {}\n'.format(arch)
206
job += ' env: {}'.format(env_string)
207
return job
208
209
210
def generate_unusual_combinations(unusuals, max_unusual_opts):
211
"""
212
Generates different combinations of non-standard compilers, compiler flags,
213
configure flags and malloc_conf settings.
214
215
@param max_unusual_opts: Limit of unusual options per combination.
216
"""
217
return chain.from_iterable(
218
[combinations(unusuals, i) for i in range(max_unusual_opts + 1)])
219
220
221
def included(combination, exclude):
222
"""
223
Checks if the combination of options should be included in the Travis
224
testing matrix.
225
226
@param exclude: A list of options to be avoided.
227
"""
228
return not any(excluded in combination for excluded in exclude)
229
230
231
def generate_jobs(os, arch, exclude, max_unusual_opts, unusuals=all_unusuals):
232
jobs = []
233
for combination in generate_unusual_combinations(unusuals, max_unusual_opts):
234
if included(combination, exclude):
235
jobs.append(format_job(os, arch, combination))
236
return '\n'.join(jobs)
237
238
239
def generate_linux(arch):
240
os = LINUX
241
242
# Only generate 2 unusual options for AMD64 to reduce matrix size
243
max_unusual_opts = MAX_UNUSUAL_OPTIONS if arch == AMD64 else 1
244
245
exclude = []
246
if arch == PPC64LE:
247
# Avoid 32 bit builds and clang on PowerPC
248
exclude = (CROSS_COMPILE_32BIT, CLANG,)
249
250
return generate_jobs(os, arch, exclude, max_unusual_opts)
251
252
253
def generate_macos(arch):
254
os = OSX
255
256
max_unusual_opts = 1
257
258
exclude = ([Option.as_malloc_conf(opt) for opt in (
259
'dss:primary',
260
'percpu_arena:percpu',
261
'background_thread:true')] +
262
[Option.as_configure_flag('--enable-prof')] +
263
[CLANG,])
264
265
return generate_jobs(os, arch, exclude, max_unusual_opts)
266
267
268
def generate_windows(arch):
269
os = WINDOWS
270
271
max_unusual_opts = 3
272
unusuals = (
273
Option.as_configure_flag('--enable-debug'),
274
CL,
275
CROSS_COMPILE_32BIT,
276
)
277
return generate_jobs(os, arch, (), max_unusual_opts, unusuals)
278
279
280
def generate_freebsd(arch):
281
os = FREEBSD
282
283
max_unusual_opts = 4
284
unusuals = (
285
Option.as_configure_flag('--enable-debug'),
286
Option.as_configure_flag('--enable-prof --enable-prof-libunwind'),
287
Option.as_configure_flag('--with-lg-page=16 --with-malloc-conf=tcache:false'),
288
CROSS_COMPILE_32BIT,
289
)
290
return generate_jobs(os, arch, (), max_unusual_opts, unusuals)
291
292
293
294
def get_manual_jobs():
295
return """\
296
# Development build
297
- os: linux
298
env: CC=gcc CXX=g++ CONFIGURE_FLAGS="--enable-debug \
299
--disable-cache-oblivious --enable-stats --enable-log --enable-prof" \
300
EXTRA_CFLAGS="-Werror -Wno-array-bounds"
301
# --enable-expermental-smallocx:
302
- os: linux
303
env: CC=gcc CXX=g++ CONFIGURE_FLAGS="--enable-debug \
304
--enable-experimental-smallocx --enable-stats --enable-prof" \
305
EXTRA_CFLAGS="-Werror -Wno-array-bounds"
306
"""
307
308
309
def main():
310
jobs = '\n'.join((
311
generate_windows(AMD64),
312
313
generate_freebsd(AMD64),
314
315
generate_linux(AMD64),
316
generate_linux(PPC64LE),
317
318
generate_macos(AMD64),
319
320
get_manual_jobs(),
321
))
322
323
print(TRAVIS_TEMPLATE.format(jobs=jobs))
324
325
326
if __name__ == '__main__':
327
main()
328
329