1<<<<<<< HEAD 2#!/usr/bin/env python3 3 4from itertools import combinations, chain 5from enum import Enum, auto 6 7 8LINUX = 'linux' 9OSX = 'osx' 10WINDOWS = 'windows' 11FREEBSD = 'freebsd' 12 13 14AMD64 = 'amd64' 15ARM64 = 'arm64' 16PPC64LE = 'ppc64le' 17 18 19TRAVIS_TEMPLATE = """\ 20# This config file is generated by ./scripts/gen_travis.py. 21# Do not edit by hand. 22 23# We use 'minimal', because 'generic' makes Windows VMs hang at startup. Also 24# the software provided by 'generic' is simply not needed for our tests. 25# Differences are explained here: 26# https://docs.travis-ci.com/user/languages/minimal-and-generic/ 27language: minimal 28dist: focal 29 30jobs: 31 include: 32{jobs} 33 34before_install: 35 - |- 36 if test -f "./scripts/$TRAVIS_OS_NAME/before_install.sh"; then 37 source ./scripts/$TRAVIS_OS_NAME/before_install.sh 38 fi 39 40before_script: 41 - |- 42 if test -f "./scripts/$TRAVIS_OS_NAME/before_script.sh"; then 43 source ./scripts/$TRAVIS_OS_NAME/before_script.sh 44 else 45 scripts/gen_travis.py > travis_script && diff .travis.yml travis_script 46 autoconf 47 # If COMPILER_FLAGS are not empty, add them to CC and CXX 48 ./configure ${{COMPILER_FLAGS:+ CC="$CC $COMPILER_FLAGS" \ 49CXX="$CXX $COMPILER_FLAGS"}} $CONFIGURE_FLAGS 50 make -j3 51 make -j3 tests 52 fi 53 54script: 55 - |- 56 if test -f "./scripts/$TRAVIS_OS_NAME/script.sh"; then 57 source ./scripts/$TRAVIS_OS_NAME/script.sh 58 else 59 make check 60 fi 61""" 62 63 64class Option(object): 65 class Type: 66 COMPILER = auto() 67 COMPILER_FLAG = auto() 68 CONFIGURE_FLAG = auto() 69 MALLOC_CONF = auto() 70 FEATURE = auto() 71 72 def __init__(self, type, value): 73 self.type = type 74 self.value = value 75 76 @staticmethod 77 def as_compiler(value): 78 return Option(Option.Type.COMPILER, value) 79 80 @staticmethod 81 def as_compiler_flag(value): 82 return Option(Option.Type.COMPILER_FLAG, value) 83 84 @staticmethod 85 def as_configure_flag(value): 86 return Option(Option.Type.CONFIGURE_FLAG, value) 87 88 @staticmethod 89 def as_malloc_conf(value): 90 return Option(Option.Type.MALLOC_CONF, value) 91 92 @staticmethod 93 def as_feature(value): 94 return Option(Option.Type.FEATURE, value) 95 96 def __eq__(self, obj): 97 return (isinstance(obj, Option) and obj.type == self.type 98 and obj.value == self.value) 99 100 101# The 'default' configuration is gcc, on linux, with no compiler or configure 102# flags. We also test with clang, -m32, --enable-debug, --enable-prof, 103# --disable-stats, and --with-malloc-conf=tcache:false. To avoid abusing 104# travis though, we don't test all 2**7 = 128 possible combinations of these; 105# instead, we only test combinations of up to 2 'unusual' settings, under the 106# hope that bugs involving interactions of such settings are rare. 107MAX_UNUSUAL_OPTIONS = 2 108 109 110GCC = Option.as_compiler('CC=gcc CXX=g++') 111CLANG = Option.as_compiler('CC=clang CXX=clang++') 112CL = Option.as_compiler('CC=cl.exe CXX=cl.exe') 113 114 115compilers_unusual = [CLANG,] 116 117 118CROSS_COMPILE_32BIT = Option.as_feature('CROSS_COMPILE_32BIT') 119feature_unusuals = [CROSS_COMPILE_32BIT] 120 121 122configure_flag_unusuals = [Option.as_configure_flag(opt) for opt in ( 123 '--enable-debug', 124 '--enable-prof', 125 '--disable-stats', 126 '--disable-libdl', 127 '--enable-opt-safety-checks', 128 '--with-lg-page=16', 129)] 130 131 132malloc_conf_unusuals = [Option.as_malloc_conf(opt) for opt in ( 133 'tcache:false', 134 'dss:primary', 135 'percpu_arena:percpu', 136 'background_thread:true', 137)] 138 139 140all_unusuals = (compilers_unusual + feature_unusuals 141 + configure_flag_unusuals + malloc_conf_unusuals) 142 143 144def get_extra_cflags(os, compiler): 145 if os == FREEBSD: 146 return [] 147 148 if os == WINDOWS: 149 # For non-CL compilers under Windows (for now it's only MinGW-GCC), 150 # -fcommon needs to be specified to correctly handle multiple 151 # 'malloc_conf' symbols and such, which are declared weak under Linux. 152 # Weak symbols don't work with MinGW-GCC. 153 if compiler != CL.value: 154 return ['-fcommon'] 155 else: 156 return [] 157 158 # We get some spurious errors when -Warray-bounds is enabled. 159 extra_cflags = ['-Werror', '-Wno-array-bounds'] 160 if compiler == CLANG.value or os == OSX: 161 extra_cflags += [ 162 '-Wno-unknown-warning-option', 163 '-Wno-ignored-attributes' 164 ] 165 if os == OSX: 166 extra_cflags += [ 167 '-Wno-deprecated-declarations', 168 ] 169 return extra_cflags 170 171 172# Formats a job from a combination of flags 173def format_job(os, arch, combination): 174 compilers = [x.value for x in combination if x.type == Option.Type.COMPILER] 175 assert(len(compilers) <= 1) 176 compiler_flags = [x.value for x in combination if x.type == Option.Type.COMPILER_FLAG] 177 configure_flags = [x.value for x in combination if x.type == Option.Type.CONFIGURE_FLAG] 178 malloc_conf = [x.value for x in combination if x.type == Option.Type.MALLOC_CONF] 179 features = [x.value for x in combination if x.type == Option.Type.FEATURE] 180 181 if len(malloc_conf) > 0: 182 configure_flags.append('--with-malloc-conf=' + ','.join(malloc_conf)) 183 184 if not compilers: 185 compiler = GCC.value 186 else: 187 compiler = compilers[0] 188 189 extra_environment_vars = '' 190 cross_compile = CROSS_COMPILE_32BIT.value in features 191 if os == LINUX and cross_compile: 192 compiler_flags.append('-m32') 193 194 features_str = ' '.join([' {}=yes'.format(feature) for feature in features]) 195 196 stringify = lambda arr, name: ' {}="{}"'.format(name, ' '.join(arr)) if arr else '' 197 env_string = '{}{}{}{}{}{}'.format( 198 compiler, 199 features_str, 200 stringify(compiler_flags, 'COMPILER_FLAGS'), 201 stringify(configure_flags, 'CONFIGURE_FLAGS'), 202 stringify(get_extra_cflags(os, compiler), 'EXTRA_CFLAGS'), 203 extra_environment_vars) 204 205 job = ' - os: {}\n'.format(os) 206 job += ' arch: {}\n'.format(arch) 207 job += ' env: {}'.format(env_string) 208 return job 209 210 211def generate_unusual_combinations(unusuals, max_unusual_opts): 212 """ 213 Generates different combinations of non-standard compilers, compiler flags, 214 configure flags and malloc_conf settings. 215 216 @param max_unusual_opts: Limit of unusual options per combination. 217 """ 218 return chain.from_iterable( 219 [combinations(unusuals, i) for i in range(max_unusual_opts + 1)]) 220 221 222def included(combination, exclude): 223 """ 224 Checks if the combination of options should be included in the Travis 225 testing matrix. 226 227 @param exclude: A list of options to be avoided. 228 """ 229 return not any(excluded in combination for excluded in exclude) 230 231 232def generate_jobs(os, arch, exclude, max_unusual_opts, unusuals=all_unusuals): 233 jobs = [] 234 for combination in generate_unusual_combinations(unusuals, max_unusual_opts): 235 if included(combination, exclude): 236 jobs.append(format_job(os, arch, combination)) 237 return '\n'.join(jobs) 238 239 240def generate_linux(arch): 241 os = LINUX 242 243 # Only generate 2 unusual options for AMD64 to reduce matrix size 244 max_unusual_opts = MAX_UNUSUAL_OPTIONS if arch == AMD64 else 1 245 246 exclude = [] 247 if arch == PPC64LE: 248 # Avoid 32 bit builds and clang on PowerPC 249 exclude = (CROSS_COMPILE_32BIT, CLANG,) 250 251 return generate_jobs(os, arch, exclude, max_unusual_opts) 252 253 254def generate_macos(arch): 255 os = OSX 256 257 max_unusual_opts = 1 258 259 exclude = ([Option.as_malloc_conf(opt) for opt in ( 260 'dss:primary', 261 'percpu_arena:percpu', 262 'background_thread:true')] + 263 [Option.as_configure_flag('--enable-prof')] + 264 [CLANG,]) 265 266 return generate_jobs(os, arch, exclude, max_unusual_opts) 267 268 269def generate_windows(arch): 270 os = WINDOWS 271 272 max_unusual_opts = 3 273 unusuals = ( 274 Option.as_configure_flag('--enable-debug'), 275 CL, 276 CROSS_COMPILE_32BIT, 277 ) 278 return generate_jobs(os, arch, (), max_unusual_opts, unusuals) 279 280 281def generate_freebsd(arch): 282 os = FREEBSD 283 284 max_unusual_opts = 4 285 unusuals = ( 286 Option.as_configure_flag('--enable-debug'), 287 Option.as_configure_flag('--enable-prof --enable-prof-libunwind'), 288 Option.as_configure_flag('--with-lg-page=16 --with-malloc-conf=tcache:false'), 289 CROSS_COMPILE_32BIT, 290 ) 291 return generate_jobs(os, arch, (), max_unusual_opts, unusuals) 292 293 294 295def get_manual_jobs(): 296 return """\ 297 # Development build 298 - os: linux 299 env: CC=gcc CXX=g++ CONFIGURE_FLAGS="--enable-debug \ 300--disable-cache-oblivious --enable-stats --enable-log --enable-prof" \ 301EXTRA_CFLAGS="-Werror -Wno-array-bounds" 302 # --enable-expermental-smallocx: 303 - os: linux 304 env: CC=gcc CXX=g++ CONFIGURE_FLAGS="--enable-debug \ 305--enable-experimental-smallocx --enable-stats --enable-prof" \ 306EXTRA_CFLAGS="-Werror -Wno-array-bounds" 307""" 308 309 310def main(): 311 jobs = '\n'.join(( 312 generate_windows(AMD64), 313 314 generate_freebsd(AMD64), 315 316 generate_linux(AMD64), 317 generate_linux(PPC64LE), 318 319 generate_macos(AMD64), 320 321 get_manual_jobs(), 322 )) 323 324 print(TRAVIS_TEMPLATE.format(jobs=jobs)) 325 326 327if __name__ == '__main__': 328 main() 329||||||| dec341af7695 330======= 331#!/usr/bin/env python 332 333from itertools import combinations 334 335travis_template = """\ 336language: generic 337dist: precise 338 339matrix: 340 include: 341%s 342 343before_script: 344 - autoconf 345 - scripts/gen_travis.py > travis_script && diff .travis.yml travis_script 346 - ./configure ${COMPILER_FLAGS:+ \ 347 CC="$CC $COMPILER_FLAGS" \ 348 CXX="$CXX $COMPILER_FLAGS" } \ 349 $CONFIGURE_FLAGS 350 - make -j3 351 - make -j3 tests 352 353script: 354 - make check 355""" 356 357# The 'default' configuration is gcc, on linux, with no compiler or configure 358# flags. We also test with clang, -m32, --enable-debug, --enable-prof, 359# --disable-stats, and --with-malloc-conf=tcache:false. To avoid abusing 360# travis though, we don't test all 2**7 = 128 possible combinations of these; 361# instead, we only test combinations of up to 2 'unusual' settings, under the 362# hope that bugs involving interactions of such settings are rare. 363# Things at once, for C(7, 0) + C(7, 1) + C(7, 2) = 29 364MAX_UNUSUAL_OPTIONS = 2 365 366os_default = 'linux' 367os_unusual = 'osx' 368 369compilers_default = 'CC=gcc CXX=g++' 370compilers_unusual = 'CC=clang CXX=clang++' 371 372compiler_flag_unusuals = ['-m32'] 373 374configure_flag_unusuals = [ 375 '--enable-debug', 376 '--enable-prof', 377 '--disable-stats', 378 '--disable-libdl', 379 '--enable-opt-safety-checks', 380] 381 382malloc_conf_unusuals = [ 383 'tcache:false', 384 'dss:primary', 385 'percpu_arena:percpu', 386 'background_thread:true', 387] 388 389all_unusuals = ( 390 [os_unusual] + [compilers_unusual] + compiler_flag_unusuals 391 + configure_flag_unusuals + malloc_conf_unusuals 392) 393 394unusual_combinations_to_test = [] 395for i in xrange(MAX_UNUSUAL_OPTIONS + 1): 396 unusual_combinations_to_test += combinations(all_unusuals, i) 397 398gcc_multilib_set = False 399# Formats a job from a combination of flags 400def format_job(combination): 401 global gcc_multilib_set 402 403 os = os_unusual if os_unusual in combination else os_default 404 compilers = compilers_unusual if compilers_unusual in combination else compilers_default 405 406 compiler_flags = [x for x in combination if x in compiler_flag_unusuals] 407 configure_flags = [x for x in combination if x in configure_flag_unusuals] 408 malloc_conf = [x for x in combination if x in malloc_conf_unusuals] 409 410 # Filter out unsupported configurations on OS X. 411 if os == 'osx' and ('dss:primary' in malloc_conf or \ 412 'percpu_arena:percpu' in malloc_conf or 'background_thread:true' \ 413 in malloc_conf): 414 return "" 415 if len(malloc_conf) > 0: 416 configure_flags.append('--with-malloc-conf=' + ",".join(malloc_conf)) 417 418 # Filter out an unsupported configuration - heap profiling on OS X. 419 if os == 'osx' and '--enable-prof' in configure_flags: 420 return "" 421 422 # We get some spurious errors when -Warray-bounds is enabled. 423 env_string = ('{} COMPILER_FLAGS="{}" CONFIGURE_FLAGS="{}" ' 424 'EXTRA_CFLAGS="-Werror -Wno-array-bounds"').format( 425 compilers, " ".join(compiler_flags), " ".join(configure_flags)) 426 427 job = "" 428 job += ' - os: %s\n' % os 429 job += ' env: %s\n' % env_string 430 if '-m32' in combination and os == 'linux': 431 job += ' addons:' 432 if gcc_multilib_set: 433 job += ' *gcc_multilib\n' 434 else: 435 job += ' &gcc_multilib\n' 436 job += ' apt:\n' 437 job += ' packages:\n' 438 job += ' - gcc-multilib\n' 439 gcc_multilib_set = True 440 return job 441 442include_rows = "" 443for combination in unusual_combinations_to_test: 444 include_rows += format_job(combination) 445 446# Development build 447include_rows += '''\ 448 # Development build 449 - os: linux 450 env: CC=gcc CXX=g++ COMPILER_FLAGS="" CONFIGURE_FLAGS="--enable-debug --disable-cache-oblivious --enable-stats --enable-log --enable-prof" EXTRA_CFLAGS="-Werror -Wno-array-bounds" 451''' 452 453# Enable-expermental-smallocx 454include_rows += '''\ 455 # --enable-expermental-smallocx: 456 - os: linux 457 env: CC=gcc CXX=g++ COMPILER_FLAGS="" CONFIGURE_FLAGS="--enable-debug --enable-experimental-smallocx --enable-stats --enable-prof" EXTRA_CFLAGS="-Werror -Wno-array-bounds" 458''' 459 460# Valgrind build bots 461include_rows += ''' 462 # Valgrind 463 - os: linux 464 env: CC=gcc CXX=g++ COMPILER_FLAGS="" CONFIGURE_FLAGS="" EXTRA_CFLAGS="-Werror -Wno-array-bounds" JEMALLOC_TEST_PREFIX="valgrind" 465 addons: 466 apt: 467 packages: 468 - valgrind 469''' 470 471# To enable valgrind on macosx add: 472# 473# - os: osx 474# env: CC=gcc CXX=g++ COMPILER_FLAGS="" CONFIGURE_FLAGS="" EXTRA_CFLAGS="-Werror -Wno-array-bounds" JEMALLOC_TEST_PREFIX="valgrind" 475# install: brew install valgrind 476# 477# It currently fails due to: https://github.com/jemalloc/jemalloc/issues/1274 478 479print travis_template % include_rows 480>>>>>>> main 481