mirror of
https://github.com/jemalloc/jemalloc.git
synced 2026-04-14 22:51:50 +03:00
686 lines
20 KiB
Python
Executable file
686 lines
20 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
|
|
from itertools import combinations, chain
|
|
from enum import Enum, auto
|
|
|
|
|
|
LINUX = 'ubuntu-24.04'
|
|
OSX = 'macos-latest'
|
|
WINDOWS = 'windows-latest'
|
|
FREEBSD = 'freebsd'
|
|
|
|
AMD64 = 'amd64'
|
|
ARM64 = 'arm64'
|
|
PPC64LE = 'ppc64le'
|
|
|
|
|
|
GITHUB_ACTIONS_TEMPLATE = """\
|
|
# This config file is generated by ./scripts/gen_gh_actions.py.
|
|
# Do not edit by hand.
|
|
|
|
name: {name}
|
|
|
|
on:
|
|
push:
|
|
branches: [ dev, ci_travis ]
|
|
pull_request:
|
|
branches: [ dev ]
|
|
|
|
jobs:
|
|
{jobs}
|
|
"""
|
|
|
|
|
|
class Option(object):
|
|
class Type:
|
|
COMPILER = auto()
|
|
COMPILER_FLAG = auto()
|
|
CONFIGURE_FLAG = auto()
|
|
MALLOC_CONF = auto()
|
|
FEATURE = auto()
|
|
|
|
def __init__(self, type, value):
|
|
self.type = type
|
|
self.value = value
|
|
|
|
@staticmethod
|
|
def as_compiler(value):
|
|
return Option(Option.Type.COMPILER, value)
|
|
|
|
@staticmethod
|
|
def as_compiler_flag(value):
|
|
return Option(Option.Type.COMPILER_FLAG, value)
|
|
|
|
@staticmethod
|
|
def as_configure_flag(value):
|
|
return Option(Option.Type.CONFIGURE_FLAG, value)
|
|
|
|
@staticmethod
|
|
def as_malloc_conf(value):
|
|
return Option(Option.Type.MALLOC_CONF, value)
|
|
|
|
@staticmethod
|
|
def as_feature(value):
|
|
return Option(Option.Type.FEATURE, value)
|
|
|
|
def __eq__(self, obj):
|
|
return (isinstance(obj, Option) and obj.type == self.type
|
|
and obj.value == self.value)
|
|
|
|
def __repr__(self):
|
|
type_names = {
|
|
Option.Type.COMPILER: 'COMPILER',
|
|
Option.Type.COMPILER_FLAG: 'COMPILER_FLAG',
|
|
Option.Type.CONFIGURE_FLAG: 'CONFIGURE_FLAG',
|
|
Option.Type.MALLOC_CONF: 'MALLOC_CONF',
|
|
Option.Type.FEATURE: 'FEATURE'
|
|
}
|
|
return f"Option({type_names[self.type]}, {repr(self.value)})"
|
|
|
|
|
|
# The 'default' configuration is gcc, on linux, with no compiler or configure
|
|
# flags. We also test with clang, -m32, --enable-debug, --enable-prof,
|
|
# --disable-stats, and --with-malloc-conf=tcache:false. To avoid abusing
|
|
# CI resources though, we don't test all 2**7 = 128 possible combinations of these;
|
|
# instead, we only test combinations of up to 2 'unusual' settings, under the
|
|
# hope that bugs involving interactions of such settings are rare.
|
|
MAX_UNUSUAL_OPTIONS = 2
|
|
|
|
|
|
GCC = Option.as_compiler('CC=gcc CXX=g++')
|
|
CLANG = Option.as_compiler('CC=clang CXX=clang++')
|
|
CL = Option.as_compiler('CC=cl.exe CXX=cl.exe')
|
|
|
|
|
|
compilers_unusual = [CLANG,]
|
|
|
|
|
|
CROSS_COMPILE_32BIT = Option.as_feature('CROSS_COMPILE_32BIT')
|
|
feature_unusuals = [CROSS_COMPILE_32BIT]
|
|
|
|
|
|
configure_flag_unusuals = [Option.as_configure_flag(opt) for opt in (
|
|
'--enable-debug',
|
|
'--enable-prof',
|
|
'--disable-stats',
|
|
'--disable-libdl',
|
|
'--enable-opt-safety-checks',
|
|
'--with-lg-page=16',
|
|
'--with-lg-page=16 --with-lg-hugepage=29',
|
|
)]
|
|
LARGE_HUGEPAGE = Option.as_configure_flag("--with-lg-page=16 --with-lg-hugepage=29")
|
|
|
|
|
|
malloc_conf_unusuals = [Option.as_malloc_conf(opt) for opt in (
|
|
'tcache:false',
|
|
'dss:primary',
|
|
'percpu_arena:percpu',
|
|
'background_thread:true',
|
|
)]
|
|
|
|
|
|
all_unusuals = (compilers_unusual + feature_unusuals
|
|
+ configure_flag_unusuals + malloc_conf_unusuals)
|
|
|
|
|
|
def get_extra_cflags(os, compiler):
|
|
if os == WINDOWS:
|
|
# For non-CL compilers under Windows (for now it's only MinGW-GCC),
|
|
# -fcommon needs to be specified to correctly handle multiple
|
|
# 'malloc_conf' symbols and such, which are declared weak under Linux.
|
|
# Weak symbols don't work with MinGW-GCC.
|
|
if compiler != CL.value:
|
|
return ['-fcommon']
|
|
else:
|
|
return []
|
|
|
|
# We get some spurious errors when -Warray-bounds is enabled.
|
|
extra_cflags = ['-Werror', '-Wno-array-bounds']
|
|
if compiler == CLANG.value or os == OSX:
|
|
extra_cflags += [
|
|
'-Wno-unknown-warning-option',
|
|
'-Wno-ignored-attributes'
|
|
]
|
|
if os == OSX:
|
|
extra_cflags += [
|
|
'-Wno-deprecated-declarations',
|
|
]
|
|
return extra_cflags
|
|
|
|
|
|
def format_env_dict(os, arch, combination):
|
|
"""Format environment variables as a dictionary for the matrix."""
|
|
compilers = [x.value for x in combination if x.type == Option.Type.COMPILER]
|
|
compiler_flags = [x.value for x in combination if x.type == Option.Type.COMPILER_FLAG]
|
|
configure_flags = [x.value for x in combination if x.type == Option.Type.CONFIGURE_FLAG]
|
|
malloc_conf = [x.value for x in combination if x.type == Option.Type.MALLOC_CONF]
|
|
features = [x.value for x in combination if x.type == Option.Type.FEATURE]
|
|
|
|
if len(malloc_conf) > 0:
|
|
configure_flags.append('--with-malloc-conf=' + ','.join(malloc_conf))
|
|
|
|
if not compilers:
|
|
compiler = GCC.value
|
|
else:
|
|
compiler = compilers[0]
|
|
|
|
cross_compile = CROSS_COMPILE_32BIT.value in features
|
|
if os == LINUX and cross_compile:
|
|
compiler_flags.append('-m32')
|
|
|
|
env_dict = {}
|
|
|
|
# Parse compiler
|
|
cc_parts = compiler.split()
|
|
for part in cc_parts:
|
|
if part.startswith('CC='):
|
|
env_dict['CC'] = part.split('=')[1]
|
|
elif part.startswith('CXX='):
|
|
env_dict['CXX'] = part.split('=')[1]
|
|
|
|
# Add features
|
|
for feature in features:
|
|
env_dict[feature] = 'yes'
|
|
|
|
# Add flags
|
|
if compiler_flags:
|
|
env_dict['COMPILER_FLAGS'] = ' '.join(compiler_flags)
|
|
if configure_flags:
|
|
env_dict['CONFIGURE_FLAGS'] = ' '.join(configure_flags)
|
|
|
|
extra_cflags = get_extra_cflags(os, compiler)
|
|
if extra_cflags:
|
|
env_dict['EXTRA_CFLAGS'] = ' '.join(extra_cflags)
|
|
|
|
return env_dict
|
|
|
|
|
|
def generate_job_matrix_entries(os, arch, exclude, max_unusual_opts, unusuals=all_unusuals):
|
|
"""Generate matrix entries for a job."""
|
|
entries = []
|
|
for combination in chain.from_iterable(
|
|
[combinations(unusuals, i) for i in range(max_unusual_opts + 1)]):
|
|
if not any(excluded in combination for excluded in exclude):
|
|
env_dict = format_env_dict(os, arch, combination)
|
|
entries.append(env_dict)
|
|
return entries
|
|
|
|
|
|
def generate_linux_job(arch):
|
|
"""Generate Linux job configuration."""
|
|
os = LINUX
|
|
|
|
# Only generate 2 unusual options for AMD64 to reduce matrix size
|
|
max_unusual_opts = MAX_UNUSUAL_OPTIONS if arch == AMD64 else 1
|
|
|
|
exclude = []
|
|
if arch == PPC64LE:
|
|
# Avoid 32 bit builds and clang on PowerPC
|
|
exclude = (CROSS_COMPILE_32BIT, CLANG,)
|
|
if arch == ARM64:
|
|
# Avoid 32 bit build on ARM64
|
|
exclude = (CROSS_COMPILE_32BIT,)
|
|
|
|
if arch != ARM64:
|
|
exclude += [LARGE_HUGEPAGE]
|
|
|
|
linux_configure_flags = list(configure_flag_unusuals)
|
|
linux_configure_flags.append(Option.as_configure_flag("--enable-prof --enable-prof-frameptr"))
|
|
|
|
linux_unusuals = (compilers_unusual + feature_unusuals
|
|
+ linux_configure_flags + malloc_conf_unusuals)
|
|
|
|
matrix_entries = generate_job_matrix_entries(os, arch, exclude, max_unusual_opts, linux_unusuals)
|
|
|
|
arch_suffix = f"-{arch}" if arch != AMD64 else ""
|
|
|
|
# Select appropriate runner based on architecture
|
|
if arch == ARM64:
|
|
runner = "ubuntu-24.04-arm" # Free ARM64 runner for public repos (Public Preview)
|
|
elif arch == PPC64LE:
|
|
# GitHub doesn't provide PPC runners, would need self-hosted
|
|
runner = "self-hosted-ppc64le"
|
|
else: # AMD64
|
|
runner = "ubuntu-24.04" # Ubuntu 24.04 LTS
|
|
|
|
job = f""" test-linux{arch_suffix}:
|
|
runs-on: {runner}
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
"""
|
|
|
|
for entry in matrix_entries:
|
|
job += " - env:\n"
|
|
for key, value in entry.items():
|
|
# Properly escape values with special characters
|
|
if ' ' in str(value) or any(c in str(value) for c in [':', ',', '#']):
|
|
job += f' {key}: "{value}"\n'
|
|
else:
|
|
job += f" {key}: {value}\n"
|
|
|
|
# Add manual job entries
|
|
manual_entries = [
|
|
{
|
|
'CC': 'gcc',
|
|
'CXX': 'g++',
|
|
'CONFIGURE_FLAGS': '--enable-debug --disable-cache-oblivious --enable-stats --enable-log --enable-prof',
|
|
'EXTRA_CFLAGS': '-Werror -Wno-array-bounds'
|
|
},
|
|
{
|
|
'CC': 'gcc',
|
|
'CXX': 'g++',
|
|
'CONFIGURE_FLAGS': '--enable-debug --enable-experimental-smallocx --enable-stats --enable-prof',
|
|
'EXTRA_CFLAGS': '-Werror -Wno-array-bounds'
|
|
}
|
|
]
|
|
|
|
if arch == AMD64:
|
|
for entry in manual_entries:
|
|
job += " - env:\n"
|
|
for key, value in entry.items():
|
|
if ' ' in str(value):
|
|
job += f' {key}: "{value}"\n'
|
|
else:
|
|
job += f" {key}: {value}\n"
|
|
|
|
job += f"""
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Show OS version
|
|
run: |
|
|
echo "=== System Information ==="
|
|
uname -a
|
|
echo ""
|
|
echo "=== Architecture ==="
|
|
uname -m
|
|
arch
|
|
echo ""
|
|
echo "=== OS Release ==="
|
|
cat /etc/os-release || true
|
|
echo ""
|
|
echo "=== CPU Info ==="
|
|
lscpu | grep -E "Architecture|CPU op-mode|Byte Order|CPU\(s\):" || true
|
|
|
|
- name: Install dependencies (32-bit)
|
|
if: matrix.env.CROSS_COMPILE_32BIT == 'yes'
|
|
run: |
|
|
sudo dpkg --add-architecture i386
|
|
sudo apt-get update
|
|
sudo apt-get install -y gcc-multilib g++-multilib libc6-dev-i386
|
|
|
|
- name: Build and test
|
|
env:
|
|
CC: ${{{{ matrix.env.CC }}}}
|
|
CXX: ${{{{ matrix.env.CXX }}}}
|
|
COMPILER_FLAGS: ${{{{ matrix.env.COMPILER_FLAGS }}}}
|
|
CONFIGURE_FLAGS: ${{{{ matrix.env.CONFIGURE_FLAGS }}}}
|
|
EXTRA_CFLAGS: ${{{{ matrix.env.EXTRA_CFLAGS }}}}
|
|
run: |
|
|
# Verify the script generates the same output
|
|
./scripts/gen_gh_actions.py > gh_actions_script.yml
|
|
|
|
# Run autoconf
|
|
autoconf
|
|
|
|
# Configure with flags
|
|
if [ -n "$COMPILER_FLAGS" ]; then
|
|
./configure CC="${{CC}} ${{COMPILER_FLAGS}}" CXX="${{CXX}} ${{COMPILER_FLAGS}}" $CONFIGURE_FLAGS
|
|
else
|
|
./configure $CONFIGURE_FLAGS
|
|
fi
|
|
|
|
# Build
|
|
make -j3
|
|
make -j3 tests
|
|
|
|
# Run tests
|
|
make check
|
|
|
|
"""
|
|
|
|
return job
|
|
|
|
|
|
def generate_macos_job(arch):
|
|
"""Generate macOS job configuration."""
|
|
os = OSX
|
|
max_unusual_opts = 1
|
|
|
|
exclude = ([Option.as_malloc_conf(opt) for opt in (
|
|
'dss:primary',
|
|
'background_thread:true')] +
|
|
[Option.as_configure_flag('--enable-prof')] +
|
|
[CLANG,])
|
|
|
|
if arch != ARM64:
|
|
exclude += [LARGE_HUGEPAGE]
|
|
|
|
matrix_entries = generate_job_matrix_entries(os, arch, exclude, max_unusual_opts)
|
|
|
|
arch_suffix = f"-{arch}" if arch != AMD64 else ""
|
|
|
|
# Select appropriate runner based on architecture
|
|
# Pin both for more control over OS upgrades
|
|
if arch == ARM64:
|
|
runner = "macos-15" # Pinned macOS 15 on Apple Silicon
|
|
else: # AMD64
|
|
runner = "macos-15-intel" # Pinned macOS 15 on Intel (last Intel runner, EOL Aug 2027)
|
|
|
|
job = f""" test-macos{arch_suffix}:
|
|
runs-on: {runner}
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
"""
|
|
|
|
for entry in matrix_entries:
|
|
job += " - env:\n"
|
|
for key, value in entry.items():
|
|
if ' ' in str(value) or any(c in str(value) for c in [':', ',', '#']):
|
|
job += f' {key}: "{value}"\n'
|
|
else:
|
|
job += f" {key}: {value}\n"
|
|
|
|
job += f"""
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Show OS version
|
|
run: |
|
|
echo "=== macOS Version ==="
|
|
sw_vers
|
|
echo ""
|
|
echo "=== Architecture ==="
|
|
uname -m
|
|
arch
|
|
echo ""
|
|
echo "=== CPU Info ==="
|
|
sysctl -n machdep.cpu.brand_string
|
|
sysctl -n hw.machine
|
|
|
|
- name: Install dependencies
|
|
run: |
|
|
brew install autoconf
|
|
|
|
- name: Build and test
|
|
env:
|
|
CC: ${{{{ matrix.env.CC || 'gcc' }}}}
|
|
CXX: ${{{{ matrix.env.CXX || 'g++' }}}}
|
|
COMPILER_FLAGS: ${{{{ matrix.env.COMPILER_FLAGS }}}}
|
|
CONFIGURE_FLAGS: ${{{{ matrix.env.CONFIGURE_FLAGS }}}}
|
|
EXTRA_CFLAGS: ${{{{ matrix.env.EXTRA_CFLAGS }}}}
|
|
run: |
|
|
# Run autoconf
|
|
autoconf
|
|
|
|
# Configure with flags
|
|
if [ -n "$COMPILER_FLAGS" ]; then
|
|
./configure CC="${{CC}} ${{COMPILER_FLAGS}}" CXX="${{CXX}} ${{COMPILER_FLAGS}}" $CONFIGURE_FLAGS
|
|
else
|
|
./configure $CONFIGURE_FLAGS
|
|
fi
|
|
|
|
# Build
|
|
make -j3
|
|
make -j3 tests
|
|
|
|
# Run tests
|
|
make check
|
|
|
|
"""
|
|
|
|
return job
|
|
|
|
|
|
def generate_windows_job(arch):
|
|
"""Generate Windows job configuration."""
|
|
os = WINDOWS
|
|
max_unusual_opts = 3
|
|
unusuals = (
|
|
Option.as_configure_flag('--enable-debug'),
|
|
CL,
|
|
CROSS_COMPILE_32BIT,
|
|
)
|
|
|
|
matrix_entries = generate_job_matrix_entries(os, arch, (), max_unusual_opts, unusuals)
|
|
|
|
arch_suffix = f"-{arch}" if arch != AMD64 else ""
|
|
|
|
# Use latest for Windows - tends to be backward compatible and stable
|
|
job = f""" test-windows{arch_suffix}:
|
|
runs-on: windows-latest
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
"""
|
|
|
|
for entry in matrix_entries:
|
|
job += " - env:\n"
|
|
for key, value in entry.items():
|
|
if ' ' in str(value) or any(c in str(value) for c in [':', ',', '#']):
|
|
job += f' {key}: "{value}"\n'
|
|
else:
|
|
job += f" {key}: {value}\n"
|
|
|
|
job += f"""
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Show OS version
|
|
shell: cmd
|
|
run: |
|
|
echo === Windows Version ===
|
|
systeminfo | findstr /B /C:"OS Name" /C:"OS Version"
|
|
ver
|
|
echo.
|
|
echo === Architecture ===
|
|
echo PROCESSOR_ARCHITECTURE=%PROCESSOR_ARCHITECTURE%
|
|
echo.
|
|
|
|
- name: Setup MSYS2
|
|
uses: msys2/setup-msys2@v2
|
|
with:
|
|
msystem: ${{{{ matrix.env.CROSS_COMPILE_32BIT == 'yes' && 'MINGW32' || 'MINGW64' }}}}
|
|
update: true
|
|
install: >-
|
|
autotools
|
|
git
|
|
pacboy: >-
|
|
make:p
|
|
gcc:p
|
|
binutils:p
|
|
|
|
- name: Build and test (MinGW-GCC)
|
|
if: matrix.env.CC != 'cl.exe'
|
|
shell: msys2 {{0}}
|
|
env:
|
|
CC: ${{{{ matrix.env.CC || 'gcc' }}}}
|
|
CXX: ${{{{ matrix.env.CXX || 'g++' }}}}
|
|
COMPILER_FLAGS: ${{{{ matrix.env.COMPILER_FLAGS }}}}
|
|
CONFIGURE_FLAGS: ${{{{ matrix.env.CONFIGURE_FLAGS }}}}
|
|
EXTRA_CFLAGS: ${{{{ matrix.env.EXTRA_CFLAGS }}}}
|
|
run: |
|
|
# Run autoconf
|
|
autoconf
|
|
|
|
# Configure with flags
|
|
if [ -n "$COMPILER_FLAGS" ]; then
|
|
./configure CC="${{CC}} ${{COMPILER_FLAGS}}" CXX="${{CXX}} ${{COMPILER_FLAGS}}" $CONFIGURE_FLAGS
|
|
else
|
|
./configure $CONFIGURE_FLAGS
|
|
fi
|
|
|
|
# Build (mingw32-make is the "make" command in MSYS2)
|
|
mingw32-make -j3
|
|
mingw32-make tests
|
|
|
|
# Run tests
|
|
mingw32-make -k check
|
|
|
|
- name: Setup MSVC environment
|
|
if: matrix.env.CC == 'cl.exe'
|
|
uses: ilammy/msvc-dev-cmd@v1
|
|
with:
|
|
arch: ${{{{ matrix.env.CROSS_COMPILE_32BIT == 'yes' && 'x86' || 'x64' }}}}
|
|
|
|
- name: Build and test (MSVC)
|
|
if: matrix.env.CC == 'cl.exe'
|
|
shell: msys2 {{0}}
|
|
env:
|
|
CONFIGURE_FLAGS: ${{{{ matrix.env.CONFIGURE_FLAGS }}}}
|
|
MSYS2_PATH_TYPE: inherit
|
|
run: |
|
|
# Export MSVC environment variables for configure
|
|
export CC=cl.exe
|
|
export CXX=cl.exe
|
|
export AR=lib.exe
|
|
export NM=dumpbin.exe
|
|
export RANLIB=:
|
|
|
|
# Verify cl.exe is accessible (should be in PATH via inherit)
|
|
if ! which cl.exe > /dev/null 2>&1; then
|
|
echo "cl.exe not found, trying to locate MSVC..."
|
|
# Find and add MSVC bin directory to PATH
|
|
MSVC_BIN=$(cmd.exe /c "echo %VCToolsInstallDir%" | tr -d '\\\\r' | sed 's/\\\\\\\\\\\\\\\\/\\//g' | sed 's/C:/\\\\/c/g')
|
|
if [ -n "$MSVC_BIN" ]; then
|
|
export PATH="$PATH:$MSVC_BIN/bin/Hostx64/x64:$MSVC_BIN/bin/Hostx86/x86"
|
|
fi
|
|
fi
|
|
|
|
# Run autoconf
|
|
autoconf
|
|
|
|
# Configure with MSVC
|
|
./configure CC=cl.exe CXX=cl.exe AR=lib.exe $CONFIGURE_FLAGS
|
|
|
|
# Build (mingw32-make is the "make" command in MSYS2)
|
|
mingw32-make -j3
|
|
# Build tests sequentially due to PDB file issues
|
|
mingw32-make tests
|
|
|
|
# Run tests
|
|
mingw32-make -k check
|
|
|
|
"""
|
|
|
|
return job
|
|
|
|
|
|
def generate_freebsd_job(arch):
|
|
"""Generate FreeBSD job configuration."""
|
|
# FreeBSD runs in a VM on ubuntu-latest, not native
|
|
|
|
job = f""" test-freebsd:
|
|
runs-on: ubuntu-latest
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
debug: ['--enable-debug', '--disable-debug']
|
|
prof: ['--enable-prof', '--disable-prof']
|
|
arch: ['64-bit', '32-bit']
|
|
uncommon:
|
|
- ''
|
|
- '--with-lg-page=16 --with-malloc-conf=tcache:false'
|
|
|
|
name: FreeBSD (${{{{ matrix.arch }}}}, debug=${{{{ matrix.debug }}}}, prof=${{{{ matrix.prof }}}}${{{{ matrix.uncommon && ', uncommon' || '' }}}})
|
|
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 1
|
|
|
|
- name: Test on FreeBSD
|
|
uses: vmactions/freebsd-vm@v1
|
|
with:
|
|
release: '15.0'
|
|
usesh: true
|
|
prepare: |
|
|
pkg install -y autoconf gmake
|
|
run: |
|
|
# Verify we're running in FreeBSD
|
|
echo "==== System Information ===="
|
|
uname -a
|
|
freebsd-version
|
|
echo "============================"
|
|
|
|
# Set compiler flags for 32-bit if needed
|
|
if [ "${{{{ matrix.arch }}}}" = "32-bit" ]; then
|
|
export CC="cc -m32"
|
|
export CXX="c++ -m32"
|
|
fi
|
|
|
|
# Generate configure script
|
|
autoconf
|
|
|
|
# Configure with matrix options
|
|
./configure --with-jemalloc-prefix=ci_ ${{{{ matrix.debug }}}} ${{{{ matrix.prof }}}} ${{{{ matrix.uncommon }}}}
|
|
|
|
# Get CPU count for parallel builds
|
|
export JFLAG=$(sysctl -n kern.smp.cpus)
|
|
|
|
gmake -j${{JFLAG}}
|
|
gmake -j${{JFLAG}} tests
|
|
gmake check
|
|
|
|
"""
|
|
|
|
return job
|
|
|
|
|
|
def main():
|
|
import sys
|
|
|
|
# Determine which workflow to generate based on command-line argument
|
|
workflow_type = sys.argv[1] if len(sys.argv) > 1 else 'linux'
|
|
|
|
if workflow_type == 'linux':
|
|
jobs = '\n'.join((
|
|
generate_linux_job(AMD64),
|
|
generate_linux_job(ARM64),
|
|
))
|
|
print(GITHUB_ACTIONS_TEMPLATE.format(name='Linux CI', jobs=jobs))
|
|
|
|
elif workflow_type == 'macos':
|
|
jobs = '\n'.join((
|
|
generate_macos_job(AMD64), # Intel x86_64
|
|
generate_macos_job(ARM64), # Apple Silicon
|
|
))
|
|
print(GITHUB_ACTIONS_TEMPLATE.format(name='macOS CI', jobs=jobs))
|
|
|
|
elif workflow_type == 'windows':
|
|
jobs = generate_windows_job(AMD64)
|
|
print(GITHUB_ACTIONS_TEMPLATE.format(name='Windows CI', jobs=jobs))
|
|
|
|
elif workflow_type == 'freebsd':
|
|
jobs = generate_freebsd_job(AMD64)
|
|
print(GITHUB_ACTIONS_TEMPLATE.format(name='FreeBSD CI', jobs=jobs))
|
|
|
|
elif workflow_type == 'all':
|
|
# Generate all workflow files
|
|
linux_jobs = '\n'.join((
|
|
generate_linux_job(AMD64),
|
|
generate_linux_job(ARM64),
|
|
))
|
|
macos_jobs = '\n'.join((
|
|
generate_macos_job(AMD64), # Intel
|
|
generate_macos_job(ARM64), # Apple Silicon
|
|
))
|
|
windows_jobs = generate_windows_job(AMD64)
|
|
freebsd_jobs = generate_freebsd_job(AMD64)
|
|
|
|
all_jobs = '\n'.join((linux_jobs, macos_jobs, windows_jobs, freebsd_jobs))
|
|
print(GITHUB_ACTIONS_TEMPLATE.format(name='CI', jobs=all_jobs))
|
|
|
|
else:
|
|
print(f"Unknown workflow type: {workflow_type}", file=sys.stderr)
|
|
print("Usage: gen_gh_actions.py [linux|macos|windows|freebsd|all]", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|