CI improvements (#10)

The key change here is to use a python script to test all
configurations, rather than a github actions matrix which spawns
hundreds of 2 second builds, which is horribly inefficient. Builds were
taking 6 to 16 minutes, now they take 2.5 to 5.5.
This commit is contained in:
Jeremy Rifkin 2023-07-19 22:30:37 -04:00 committed by GitHub
parent 04f8b88efd
commit b2df292d80
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 596 additions and 387 deletions

View File

@ -7,214 +7,35 @@ on:
jobs:
build-linux:
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
compiler: [g++-10, clang++-14]
target: [Debug]
std: [11, 20]
unwind: [
CPPTRACE_UNWIND_WITH_EXECINFO,
CPPTRACE_UNWIND_WITH_NOTHING,
]
symbols: [
CPPTRACE_GET_SYMBOLS_WITH_LIBBACKTRACE,
CPPTRACE_GET_SYMBOLS_WITH_LIBDL,
CPPTRACE_GET_SYMBOLS_WITH_ADDR2LINE,
CPPTRACE_GET_SYMBOLS_WITH_NOTHING,
]
demangle: [
CPPTRACE_DEMANGLE_WITH_CXXABI,
CPPTRACE_DEMANGLE_WITH_NOTHING,
]
steps:
- uses: actions/checkout@v2
- name: dependencies
run: sudo apt install gcc-10 g++-10 libgcc-10-dev
- name: build
run: |
mkdir -p build
cd build
cmake .. \
-DCMAKE_BUILD_TYPE=${{matrix.target}} \
-DCMAKE_CXX_COMPILER=${{matrix.compiler}} \
-DCMAKE_CXX_STANDARD=${{matrix.std}} \
-D${{matrix.unwind}}=On \
-D${{matrix.symbols}}=On \
-D${{matrix.demangle}}=On \
-DCPPTRACE_BACKTRACE_PATH=/usr/lib/gcc/x86_64-linux-gnu/10/include/backtrace.h
make -j
python3 ci/build-in-all-configs.py
build-macos:
runs-on: macos-13
strategy:
fail-fast: false
matrix:
compiler: [g++-13, clang++]
target: [Debug]
std: [11, 20]
unwind: [
CPPTRACE_UNWIND_WITH_EXECINFO,
CPPTRACE_UNWIND_WITH_NOTHING,
]
symbols: [
#CPPTRACE_GET_SYMBOLS_WITH_LIBBACKTRACE,
CPPTRACE_GET_SYMBOLS_WITH_LIBDL,
CPPTRACE_GET_SYMBOLS_WITH_ADDR2LINE,
CPPTRACE_GET_SYMBOLS_WITH_NOTHING,
]
demangle: [
CPPTRACE_DEMANGLE_WITH_CXXABI,
CPPTRACE_DEMANGLE_WITH_NOTHING,
]
steps:
- uses: actions/checkout@v2
- name: build
run: |
mkdir -p build
cd build
cmake .. \
-DCMAKE_BUILD_TYPE=${{matrix.target}} \
-DCMAKE_CXX_COMPILER=${{matrix.compiler}} \
-DCMAKE_CXX_STANDARD=${{matrix.std}} \
-D${{matrix.unwind}}=On \
-D${{matrix.symbols}}=On \
-D${{matrix.demangle}}=On
make -j
build-windows:
python3 ci/build-in-all-configs.py
build-windows-msvc:
runs-on: windows-2019
strategy:
fail-fast: false
matrix:
compiler: [cl, clang++]
target: [Debug]
std: [11, 20]
unwind: [
CPPTRACE_UNWIND_WITH_WINAPI,
CPPTRACE_UNWIND_WITH_NOTHING,
]
symbols: [
CPPTRACE_GET_SYMBOLS_WITH_DBGHELP,
CPPTRACE_GET_SYMBOLS_WITH_NOTHING,
]
demangle: [
# CPPTRACE_DEMANGLE_WITH_CXXABI,
CPPTRACE_DEMANGLE_WITH_NOTHING,
]
exclude:
- demangle: CPPTRACE_DEMANGLE_WITH_CXXABI
compiler: cl
steps:
- uses: actions/checkout@v2
- name: Enable Developer Command Prompt
uses: ilammy/msvc-dev-cmd@v1.10.0
- name: build
run: |
mkdir -p build
cd build
cmake .. `
-DCMAKE_BUILD_TYPE=Debug `
-DCMAKE_CXX_COMPILER=${{matrix.compiler}} `
-DCMAKE_CXX_STANDARD=${{matrix.std}} `
-D${{matrix.unwind}}=On `
-D${{matrix.symbols}}=On `
-D${{matrix.demangle}}=On
msbuild .\cpptrace.sln
build-linux-full-or-auto:
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
compiler: [g++-10, clang++-14]
target: [Debug]
std: [11, 20]
config: ["-DCPPTRACE_FULL_TRACE_WITH_LIBBACKTRACE=On", ""]
steps:
- uses: actions/checkout@v2
- name: dependencies
run: sudo apt install gcc-10 g++-10 libgcc-10-dev
- name: build
run: |
mkdir -p build
cd build
cmake .. \
-DCMAKE_BUILD_TYPE=${{matrix.target}} \
-DCMAKE_CXX_COMPILER=${{matrix.compiler}} \
-DCMAKE_CXX_STANDARD=${{matrix.std}} \
-DCPPTRACE_BACKTRACE_PATH=/usr/lib/gcc/x86_64-linux-gnu/10/include/backtrace.h \
${{matrix.config}}
make -j
build-macos-full-or-auto:
runs-on: macos-13
strategy:
fail-fast: false
matrix:
compiler: [g++-13, clang++]
target: [Debug]
std: [11, 20]
config: [""]
steps:
- uses: actions/checkout@v2
- name: build
run: |
mkdir -p build
cd build
cmake .. \
-DCMAKE_BUILD_TYPE=${{matrix.target}} \
-DCMAKE_CXX_COMPILER=${{matrix.compiler}} \
-DCMAKE_CXX_STANDARD=${{matrix.std}} \
${{matrix.config}}
make -j
# TODO: -DCMAKE_CXX_STANDARD isn't being honored?
# build-linux-full-or-auto-23:
# runs-on: ubuntu-22.04
# strategy:
# fail-fast: false
# matrix:
# compiler: [g++-12, clang++-14]
# target: [Debug]
# std: [23]
# config: ["-DCPPTRACE_FULL_TRACE_WITH_STACKTRACE=On", ""]
# exclude:
# - config: "-DCPPTRACE_FULL_TRACE_WITH_STACKTRACE=On"
# compiler: clang++-14
# steps:
# - uses: actions/checkout@v2
# - name: dependencies
# run: sudo apt install gcc-12 g++-12 libgcc-12-dev
# - name: build
# run: |
# mkdir -p build
# cd build
# cmake .. \
# -DCMAKE_BUILD_TYPE=${{matrix.target}} \
# -DCMAKE_CXX_COMPILER=${{matrix.compiler}} \
# -DCMAKE_CXX_STANDARD=${{matrix.std}} \
# -DCPPTRACE_BACKTRACE_PATH=/usr/lib/gcc/x86_64-linux-gnu/12/include/backtrace.h \
# ${{matrix.config}}
# make
build-windows-full-or-auto:
python3 ci/build-in-all-configs.py --msvc-only
build-windows-clang:
runs-on: windows-2019
strategy:
fail-fast: false
matrix:
compiler: [cl, clang++]
target: [Debug]
std: [11, 20]
config: [""]
exclude:
- config: -DCPPTRACE_FULL_TRACE_WITH_LIBBACKTRACE=On # TODO
steps:
- uses: actions/checkout@v2
- name: Enable Developer Command Prompt
uses: ilammy/msvc-dev-cmd@v1.10.0
- name: build
run: |
mkdir -p build
cd build
cmake .. `
-DCMAKE_BUILD_TYPE=Debug `
-DCMAKE_CXX_COMPILER=${{matrix.compiler}} `
-DCMAKE_CXX_STANDARD=${{matrix.std}} `
${{matrix.config}}
msbuild .\cpptrace.sln
python3 ci/build-in-all-configs.py --clang-only

View File

@ -7,227 +7,37 @@ on:
# TODO: Test statically linked
jobs:
test-linux:
build-linux:
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
compiler: [g++-10, clang++-14]
target: [Debug]
std: [11, 20]
unwind: [
CPPTRACE_UNWIND_WITH_EXECINFO,
#CPPTRACE_UNWIND_WITH_NOTHING,
]
symbols: [
CPPTRACE_GET_SYMBOLS_WITH_LIBBACKTRACE,
CPPTRACE_GET_SYMBOLS_WITH_LIBDL,
CPPTRACE_GET_SYMBOLS_WITH_ADDR2LINE,
#CPPTRACE_GET_SYMBOLS_WITH_NOTHING,
]
demangle: [
CPPTRACE_DEMANGLE_WITH_CXXABI,
#CPPTRACE_DEMANGLE_WITH_NOTHING,
]
steps:
- uses: actions/checkout@v2
- name: dependencies
run: sudo apt install gcc-10 g++-10 libgcc-10-dev
- name: build
run: |
mkdir -p build
cd build
cmake .. \
-DCMAKE_BUILD_TYPE=${{matrix.target}} \
-DCMAKE_CXX_COMPILER=${{matrix.compiler}} \
-DCMAKE_CXX_STANDARD=${{matrix.std}} \
-D${{matrix.unwind}}=On \
-D${{matrix.symbols}}=On \
-D${{matrix.demangle}}=On \
-DCPPTRACE_BACKTRACE_PATH=/usr/lib/gcc/x86_64-linux-gnu/10/include/backtrace.h \
-DCPPTRACE_BUILD_TEST=On \
$(if [ "${{matrix.symbols}}" = "CPPTRACE_GET_SYMBOLS_WITH_LIBDL" ]; then echo "-DCPPTRACE_BUILD_TEST_RDYNAMIC=On"; else echo ""; fi) \
-DBUILD_SHARED_LIBS=On
make -j
- name: test
working-directory: build
run: |
./test | python3 ../test/test.py "${{matrix.compiler}}" "${{matrix.unwind}}" "${{matrix.symbols}}" "${{matrix.demangle}}"
test-macos:
python3 ci/test-all-configs.py
build-macos:
runs-on: macos-13
strategy:
fail-fast: false
matrix:
compiler: [g++-13, clang++]
target: [Debug]
std: [11, 20]
unwind: [
CPPTRACE_UNWIND_WITH_EXECINFO,
#CPPTRACE_UNWIND_WITH_NOTHING,
]
symbols: [
#CPPTRACE_GET_SYMBOLS_WITH_LIBBACKTRACE,
CPPTRACE_GET_SYMBOLS_WITH_LIBDL,
#CPPTRACE_GET_SYMBOLS_WITH_ADDR2LINE,
#CPPTRACE_GET_SYMBOLS_WITH_NOTHING,
]
demangle: [
CPPTRACE_DEMANGLE_WITH_CXXABI,
#CPPTRACE_DEMANGLE_WITH_NOTHING,
]
steps:
- uses: actions/checkout@v2
- name: build
run: |
mkdir -p build
cd build
cmake .. \
-DCMAKE_BUILD_TYPE=${{matrix.target}} \
-DCMAKE_CXX_COMPILER=${{matrix.compiler}} \
-DCMAKE_CXX_STANDARD=${{matrix.std}} \
-D${{matrix.unwind}}=On \
-D${{matrix.symbols}}=On \
-D${{matrix.demangle}}=On \
-DCPPTRACE_BUILD_TEST=On \
$(if [ "${{matrix.symbols}}" = "CPPTRACE_GET_SYMBOLS_WITH_LIBDL" ]; then echo "-DCPPTRACE_BUILD_TEST_RDYNAMIC=On"; else echo ""; fi) \
-DBUILD_SHARED_LIBS=On
make -j
- name: test
working-directory: build
run: |
./test | python3 ../test/test.py "${{matrix.compiler}}" "${{matrix.unwind}}" "${{matrix.symbols}}" "${{matrix.demangle}}"
test-windows:
python3 ci/test-all-configs.py
build-windows-msvc:
runs-on: windows-2019
strategy:
fail-fast: false
matrix:
compiler: [cl, clang++]
target: [Debug]
std: [11, 20]
unwind: [
CPPTRACE_UNWIND_WITH_WINAPI,
# CPPTRACE_UNWIND_WITH_NOTHING,
]
symbols: [
CPPTRACE_GET_SYMBOLS_WITH_DBGHELP,
# CPPTRACE_GET_SYMBOLS_WITH_ADDR2LINE, # TODO
# CPPTRACE_GET_SYMBOLS_WITH_NOTHING,
]
demangle: [
# CPPTRACE_DEMANGLE_WITH_CXXABI,
CPPTRACE_DEMANGLE_WITH_NOTHING,
]
exclude:
- demangle: CPPTRACE_DEMANGLE_WITH_CXXABI
compiler: cl
steps:
- uses: actions/checkout@v2
- name: Enable Developer Command Prompt
uses: ilammy/msvc-dev-cmd@v1.10.0
- name: build
run: |
mkdir -p build
cd build
cmake .. `
-DCMAKE_BUILD_TYPE=Debug `
-DCMAKE_CXX_COMPILER=${{matrix.compiler}} `
-DCMAKE_CXX_STANDARD=${{matrix.std}} `
-D${{matrix.unwind}}=On `
-D${{matrix.symbols}}=On `
-D${{matrix.demangle}}=On `
-DCPPTRACE_BUILD_TEST=On `
-DBUILD_SHARED_LIBS=On
msbuild .\cpptrace.sln
- name: test
working-directory: build
run: |
.\${{matrix.target}}\test.exe | python3 ..\test\test.py "${{matrix.compiler}}" "${{matrix.unwind}}" "${{matrix.symbols}}" "${{matrix.demangle}}"
test-linux-full-or-auto:
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
compiler: [g++-10, clang++-14]
target: [Debug]
std: [11, 20]
config: ["-DCPPTRACE_FULL_TRACE_WITH_LIBBACKTRACE=On", ""]
steps:
- uses: actions/checkout@v2
- name: dependencies
run: sudo apt install gcc-10 g++-10 libgcc-10-dev
- name: build
run: |
mkdir -p build
cd build
cmake .. \
-DCMAKE_BUILD_TYPE=${{matrix.target}} \
-DCMAKE_CXX_COMPILER=${{matrix.compiler}} \
-DCMAKE_CXX_STANDARD=${{matrix.std}} \
-DCPPTRACE_BACKTRACE_PATH=/usr/lib/gcc/x86_64-linux-gnu/10/include/backtrace.h \
${{matrix.config}} \
-DCPPTRACE_BUILD_TEST=On \
-DBUILD_SHARED_LIBS=On
make -j
- name: test
working-directory: build
run: |
./test | python3 ../test/test.py "${{matrix.compiler}}"
test-macos-full-or-auto:
runs-on: macos-13
strategy:
fail-fast: false
matrix:
compiler: [g++-13, clang++]
target: [Debug]
std: [11, 20]
config: [""]
steps:
- uses: actions/checkout@v2
- name: build
run: |
mkdir -p build
cd build
cmake .. \
-DCMAKE_BUILD_TYPE=${{matrix.target}} \
-DCMAKE_CXX_COMPILER=${{matrix.compiler}} \
-DCMAKE_CXX_STANDARD=${{matrix.std}} \
${{matrix.config}} \
-DCPPTRACE_BUILD_TEST=On \
-DBUILD_SHARED_LIBS=On
make -j
- name: test
working-directory: build
run: |
./test | python3 ../test/test.py "${{matrix.compiler}}"
test-windows-full-or-auto:
python3 ci/test-all-configs.py --msvc-only
build-windows-clang:
runs-on: windows-2019
strategy:
fail-fast: false
matrix:
compiler: [cl, clang++]
target: [Debug]
std: [11, 20]
config: [""]
exclude:
- config: -DCPPTRACE_FULL_TRACE_WITH_LIBBACKTRACE=On # TODO
steps:
- uses: actions/checkout@v2
- name: Enable Developer Command Prompt
uses: ilammy/msvc-dev-cmd@v1.10.0
- name: build & test
- name: build
run: |
mkdir -p build
cd build
cmake .. `
-DCMAKE_BUILD_TYPE=Debug `
-DCMAKE_CXX_COMPILER=${{matrix.compiler}} `
-DCMAKE_CXX_STANDARD=${{matrix.std}} `
${{matrix.config}} `
-DCPPTRACE_BUILD_TEST=On `
-DBUILD_SHARED_LIBS=On
msbuild .\cpptrace.sln
- name: test
working-directory: build
run: |
.\${{matrix.target}}\test.exe | python3 ..\test\test.py "${{matrix.compiler}}"
python3 ci/test-all-configs.py --clang-only

5
.gitignore vendored
View File

@ -1,4 +1,5 @@
.vscode
a.out
build*
repro*
build*/
repro*/
__pycache__

238
ci/build-in-all-configs.py Normal file
View File

@ -0,0 +1,238 @@
import argparse
import os
import platform
import shutil
import subprocess
import sys
from util import *
sys.stdout.reconfigure(encoding='utf-8') # for windows gh runner
failed = False
def run_command(*args: List[str]):
print("[🔵 Running Command \"{}\"]".format(" ".join(args)))
p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = p.communicate()
print("\033[0m", end="") # makefile in parallel sometimes messes up colors
if p.returncode != 0:
print("[🔴 Command `{}` failed]".format(" ".join(args)))
print("stdout:")
print(stdout.decode("utf-8"), end="")
print("stderr:")
print(stderr.decode("utf-8"), end="")
global failed
failed = True
return False
else:
print("[🟢 Command `{}` succeeded]".format(" ".join(args)))
return True
def build(matrix):
print(matrix)
if os.path.exists("build"):
shutil.rmtree("build")
os.mkdir("build")
os.chdir("build")
if platform.system() != "Windows":
succeeded = run_command(
"cmake",
"..",
f"-DCMAKE_BUILD_TYPE={matrix['target']}",
f"-DCMAKE_CXX_COMPILER={matrix['compiler']}",
f"-DCMAKE_CXX_STANDARD={matrix['std']}",
f"-D{matrix['unwind']}=On",
f"-D{matrix['symbols']}=On",
f"-D{matrix['demangle']}=On",
"-DCPPTRACE_BACKTRACE_PATH=/usr/lib/gcc/x86_64-linux-gnu/10/include/backtrace.h"
)
if succeeded:
run_command("make", "-j")
else:
succeeded = run_command(
"cmake",
"..",
f"-DCMAKE_BUILD_TYPE={matrix['target']}",
f"-DCMAKE_CXX_COMPILER={matrix['compiler']}",
f"-DCMAKE_CXX_STANDARD={matrix['std']}",
f"-D{matrix['unwind']}=On",
f"-D{matrix['symbols']}=On",
f"-D{matrix['demangle']}=On"
)
if succeeded:
run_command("msbuild", "cpptrace.sln")
os.chdir("..")
print()
def build_full_or_auto(matrix):
print(matrix)
if os.path.exists("build"):
shutil.rmtree("build")
os.mkdir("build")
os.chdir("build")
if platform.system() != "Windows":
args = [
"cmake",
"..",
f"-DCMAKE_BUILD_TYPE={matrix['target']}",
f"-DCMAKE_CXX_COMPILER={matrix['compiler']}",
f"-DCMAKE_CXX_STANDARD={matrix['std']}",
f"-DCPPTRACE_BACKTRACE_PATH=/usr/lib/gcc/x86_64-linux-gnu/10/include/backtrace.h",
]
if matrix["config"] != "":
args.append(f"{matrix['config']}")
succeeded = run_command(*args)
if succeeded:
run_command("make", "-j")
else:
args = [
"cmake",
"..",
f"-DCMAKE_BUILD_TYPE={matrix['target']}",
f"-DCMAKE_CXX_COMPILER={matrix['compiler']}",
f"-DCMAKE_CXX_STANDARD={matrix['std']}"
]
if matrix["config"] != "":
args.append(f"{matrix['config']}")
print(args)
succeeded = run_command(*args)
if succeeded:
run_command("msbuild", "cpptrace.sln")
os.chdir("..")
print()
def main():
parser = argparse.ArgumentParser(
prog="Build in all configs",
description="Try building the library in all possible configurations for the current host"
)
if platform.system() == "Linux":
matrix = {
"compiler": ["g++-10", "clang++-14"],
"target": ["Debug"],
"std": ["11", "20"],
"unwind": [
"CPPTRACE_UNWIND_WITH_EXECINFO",
"CPPTRACE_UNWIND_WITH_NOTHING",
],
"symbols": [
"CPPTRACE_GET_SYMBOLS_WITH_LIBBACKTRACE",
"CPPTRACE_GET_SYMBOLS_WITH_LIBDL",
"CPPTRACE_GET_SYMBOLS_WITH_ADDR2LINE",
"CPPTRACE_GET_SYMBOLS_WITH_NOTHING",
],
"demangle": [
"CPPTRACE_DEMANGLE_WITH_CXXABI",
"CPPTRACE_DEMANGLE_WITH_NOTHING",
],
}
exclude = []
run_matrix(matrix, exclude, build)
matrix = {
"compiler": ["g++-10", "clang++-14"],
"target": ["Debug"],
"std": ["11", "20"],
"config": ["-DCPPTRACE_FULL_TRACE_WITH_LIBBACKTRACE=On", ""]
}
exclude = []
run_matrix(matrix, exclude, build_full_or_auto)
if platform.system() == "Darwin":
matrix = {
"compiler": ["g++-13", "clang++"],
"target": ["Debug"],
"std": ["11", "20"],
"unwind": [
"CPPTRACE_UNWIND_WITH_EXECINFO",
"CPPTRACE_UNWIND_WITH_NOTHING",
],
"symbols": [
#"CPPTRACE_GET_SYMBOLS_WITH_LIBBACKTRACE",
"CPPTRACE_GET_SYMBOLS_WITH_LIBDL",
"CPPTRACE_GET_SYMBOLS_WITH_ADDR2LINE",
"CPPTRACE_GET_SYMBOLS_WITH_NOTHING",
],
"demangle": [
"CPPTRACE_DEMANGLE_WITH_CXXABI",
"CPPTRACE_DEMANGLE_WITH_NOTHING",
]
}
exclude = []
run_matrix(matrix, exclude, build)
matrix = {
"compiler": ["g++-13", "clang++"],
"target": ["Debug"],
"std": ["11", "20"],
"config": [""]
}
exclude = []
run_matrix(matrix, exclude, build_full_or_auto)
if platform.system() == "Windows":
parser.add_argument(
"--clang-only",
action="store_true"
)
parser.add_argument(
"--msvc-only",
action="store_true"
)
args = parser.parse_args()
compilers = ["cl", "clang++"]
if args.clang_only:
compilers = ["clang++"]
if args.msvc_only:
compilers = ["cl"]
matrix = {
"compiler": compilers,
"target": ["Debug"],
"std": ["11", "20"],
"unwind": [
"CPPTRACE_UNWIND_WITH_WINAPI",
"CPPTRACE_UNWIND_WITH_NOTHING",
],
"symbols": [
"CPPTRACE_GET_SYMBOLS_WITH_DBGHELP",
"CPPTRACE_GET_SYMBOLS_WITH_NOTHING",
],
"demangle": [
#"CPPTRACE_DEMANGLE_WITH_CXXABI",
"CPPTRACE_DEMANGLE_WITH_NOTHING",
]
}
exclude = [
{
"demangle": "CPPTRACE_DEMANGLE_WITH_CXXABI",
"compiler": "cl"
}
]
run_matrix(matrix, exclude, build)
matrix = {
"compiler": compilers,
"target": ["Debug"],
"std": ["11", "20"],
"config": [""]
}
exclude = [
{
"config": "-DCPPTRACE_FULL_TRACE_WITH_LIBBACKTRACE=On"
}
]
run_matrix(matrix, exclude, build_full_or_auto)
global failed
if failed:
print("🔴 Some checks failed")
sys.exit(1)
main()

1
ci/dump_msvc_env.ps1 Normal file
View File

@ -0,0 +1 @@
cmd.exe /c "call `"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsall.bat`" x86_amd64 && set > %temp%\vcvars.txt"

318
ci/test-all-configs.py Normal file
View File

@ -0,0 +1,318 @@
import argparse
import os
import platform
import shutil
import subprocess
import sys
from util import *
sys.stdout.reconfigure(encoding='utf-8') # for windows gh runner
failed = False
def run_command(*args: List[str]):
print("[🔵 Running Command \"{}\"]".format(" ".join(args)))
p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = p.communicate()
print("\033[0m", end="") # makefile in parallel sometimes messes up colors
if p.returncode != 0:
print("[🔴 Command `{}` failed]".format(" ".join(args)))
print("stdout:")
print(stdout.decode("utf-8"), end="")
print("stderr:")
print(stderr.decode("utf-8"), end="")
global failed
failed = True
return False
else:
print("[🟢 Command `{}` succeeded]".format(" ".join(args)))
return True
def run_test(test_binary, *driver_args: List[str]):
print("[🔵 Running Command \"{} | {}\"]".format(test_binary, " ".join(driver_args)))
test = subprocess.Popen([test_binary], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
driver = subprocess.Popen(driver_args, stdin=test.stdout, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
test.wait()
test_stderr = test.stderr.read()
driver_stdout, driver_stderr = driver.communicate()
print("\033[0m", end="") # makefile in parallel sometimes messes up colors
if test.returncode != 0 or driver.returncode != 0:
print("[🔴 Command `{} |{}` failed]".format(test_binary, " ".join(driver_args)))
print("test stderr:")
print(test_stderr.decode("utf-8"), end="")
print("stdout:")
print(driver_stdout.decode("utf-8"), end="")
print("stderr:")
print(driver_stderr.decode("utf-8"), end="")
global failed
failed = True
return False
else:
print("[🟢 Command `{} | {}` succeeded]".format(test_binary, " ".join(driver_args)))
return True
def build(matrix):
if platform.system() != "Windows":
args = [
"cmake",
"..",
f"-DCMAKE_BUILD_TYPE={matrix['target']}",
f"-DCMAKE_CXX_COMPILER={matrix['compiler']}",
f"-DCMAKE_CXX_STANDARD={matrix['std']}",
f"-D{matrix['unwind']}=On",
f"-D{matrix['symbols']}=On",
f"-D{matrix['demangle']}=On",
"-DCPPTRACE_BACKTRACE_PATH=/usr/lib/gcc/x86_64-linux-gnu/10/include/backtrace.h",
"-DCPPTRACE_BUILD_TEST=On",
"-DBUILD_SHARED_LIBS=On"
]
if matrix['symbols'] == "CPPTRACE_GET_SYMBOLS_WITH_LIBDL":
args.append("-DCPPTRACE_BUILD_TEST_RDYNAMIC=On")
succeeded = run_command(*args)
if succeeded:
return run_command("make", "-j")
else:
succeeded = run_command(
"cmake",
"..",
f"-DCMAKE_BUILD_TYPE={matrix['target']}",
f"-DCMAKE_CXX_COMPILER={matrix['compiler']}",
f"-DCMAKE_CXX_STANDARD={matrix['std']}",
f"-D{matrix['unwind']}=On",
f"-D{matrix['symbols']}=On",
f"-D{matrix['demangle']}=On",
"-DCPPTRACE_BUILD_TEST=On",
"-DBUILD_SHARED_LIBS=On"
)
if succeeded:
return run_command("msbuild", "cpptrace.sln")
def test(matrix):
if platform.system() != "Windows":
run_test(
"./test",
"python3",
"../test/test.py",
matrix["compiler"],
matrix["unwind"],
matrix["symbols"],
matrix["demangle"]
)
else:
run_test(
f".\\{matrix['target']}\\test.exe",
"python3",
"../test/test.py",
matrix["compiler"],
matrix["unwind"],
matrix["symbols"],
matrix["demangle"]
)
def build_and_test(matrix):
print(matrix)
if os.path.exists("build"):
shutil.rmtree("build")
os.mkdir("build")
os.chdir("build")
if build(matrix):
test(matrix)
os.chdir("..")
print()
def build_full_or_auto(matrix):
if platform.system() != "Windows":
args = [
"cmake",
"..",
f"-DCMAKE_BUILD_TYPE={matrix['target']}",
f"-DCMAKE_CXX_COMPILER={matrix['compiler']}",
f"-DCMAKE_CXX_STANDARD={matrix['std']}",
f"-DCPPTRACE_BACKTRACE_PATH=/usr/lib/gcc/x86_64-linux-gnu/10/include/backtrace.h",
"-DCPPTRACE_BUILD_TEST=On",
"-DBUILD_SHARED_LIBS=On"
]
if matrix["config"] != "":
args.append(f"{matrix['config']}")
succeeded = run_command(*args)
if succeeded:
return run_command("make", "-j")
else:
args = [
"cmake",
"..",
f"-DCMAKE_BUILD_TYPE={matrix['target']}",
f"-DCMAKE_CXX_COMPILER={matrix['compiler']}",
f"-DCMAKE_CXX_STANDARD={matrix['std']}",
"-DCPPTRACE_BUILD_TEST=On",
"-DBUILD_SHARED_LIBS=On"
]
if matrix["config"] != "":
args.append(f"{matrix['config']}")
print(args)
succeeded = run_command(*args)
if succeeded:
return run_command("msbuild", "cpptrace.sln")
def test_full_or_auto(matrix):
if platform.system() != "Windows":
run_test(
"./test",
"python3",
"../test/test.py",
matrix["compiler"]
)
else:
run_test(
f".\\{matrix['target']}\\test.exe",
"python3",
"../test/test.py",
matrix["compiler"]
)
def build_and_test_full_or_auto(matrix):
print(matrix)
if os.path.exists("build"):
shutil.rmtree("build")
os.mkdir("build")
os.chdir("build")
if build_full_or_auto(matrix):
test_full_or_auto(matrix)
os.chdir("..")
print()
def main():
parser = argparse.ArgumentParser(
prog="Build in all configs",
description="Try building the library in all possible configurations for the current host"
)
if platform.system() == "Linux":
matrix = {
"compiler": ["g++-10", "clang++-14"],
"target": ["Debug"],
"std": ["11", "20"],
"unwind": [
"CPPTRACE_UNWIND_WITH_EXECINFO",
#"CPPTRACE_UNWIND_WITH_NOTHING",
],
"symbols": [
"CPPTRACE_GET_SYMBOLS_WITH_LIBBACKTRACE",
"CPPTRACE_GET_SYMBOLS_WITH_LIBDL",
"CPPTRACE_GET_SYMBOLS_WITH_ADDR2LINE",
#"CPPTRACE_GET_SYMBOLS_WITH_NOTHING",
],
"demangle": [
"CPPTRACE_DEMANGLE_WITH_CXXABI",
#"CPPTRACE_DEMANGLE_WITH_NOTHING",
],
}
exclude = []
run_matrix(matrix, exclude, build_and_test)
matrix = {
"compiler": ["g++-10", "clang++-14"],
"target": ["Debug"],
"std": ["11", "20"],
"config": ["-DCPPTRACE_FULL_TRACE_WITH_LIBBACKTRACE=On", ""]
}
exclude = []
run_matrix(matrix, exclude, build_and_test_full_or_auto)
if platform.system() == "Darwin":
matrix = {
"compiler": ["g++-13", "clang++"],
"target": ["Debug"],
"std": ["11", "20"],
"unwind": [
"CPPTRACE_UNWIND_WITH_EXECINFO",
#"CPPTRACE_UNWIND_WITH_NOTHING",
],
"symbols": [
#"CPPTRACE_GET_SYMBOLS_WITH_LIBBACKTRACE",
"CPPTRACE_GET_SYMBOLS_WITH_LIBDL",
#"CPPTRACE_GET_SYMBOLS_WITH_ADDR2LINE",
#"CPPTRACE_GET_SYMBOLS_WITH_NOTHING",
],
"demangle": [
"CPPTRACE_DEMANGLE_WITH_CXXABI",
#"CPPTRACE_DEMANGLE_WITH_NOTHING",
]
}
exclude = []
run_matrix(matrix, exclude, build_and_test)
matrix = {
"compiler": ["g++-13", "clang++"],
"target": ["Debug"],
"std": ["11", "20"],
"config": [""]
}
exclude = []
run_matrix(matrix, exclude, build_and_test_full_or_auto)
if platform.system() == "Windows":
parser.add_argument(
"--clang-only",
action="store_true"
)
parser.add_argument(
"--msvc-only",
action="store_true"
)
args = parser.parse_args()
compilers = ["cl", "clang++"]
if args.clang_only:
compilers = ["clang++"]
if args.msvc_only:
compilers = ["cl"]
matrix = {
"compiler": compilers,
"target": ["Debug"],
"std": ["11", "20"],
"unwind": [
"CPPTRACE_UNWIND_WITH_WINAPI",
#"CPPTRACE_UNWIND_WITH_NOTHING",
],
"symbols": [
"CPPTRACE_GET_SYMBOLS_WITH_DBGHELP",
#"CPPTRACE_GET_SYMBOLS_WITH_NOTHING",
],
"demangle": [
#"CPPTRACE_DEMANGLE_WITH_CXXABI",
"CPPTRACE_DEMANGLE_WITH_NOTHING",
]
}
exclude = [
{
"demangle": "CPPTRACE_DEMANGLE_WITH_CXXABI",
"compiler": "cl"
}
]
run_matrix(matrix, exclude, build_and_test)
matrix = {
"compiler": compilers,
"target": ["Debug"],
"std": ["11", "20"],
"config": [""]
}
exclude = [
{
"config": "-DCPPTRACE_FULL_TRACE_WITH_LIBBACKTRACE=On"
}
]
run_matrix(matrix, exclude, build_and_test_full_or_auto)
global failed
if failed:
print("🔴 Some checks failed")
sys.exit(1)
main()

20
ci/util.py Normal file
View File

@ -0,0 +1,20 @@
import subprocess
import sys
import itertools
from typing import List
def do_exclude(matrix_config, exclude):
return all(map(lambda k: matrix_config[k] == exclude[k], exclude.keys()))
def run_matrix(matrix, exclude, fn):
#print(matrix.values())
for config in itertools.product(*matrix.values()):
#print(config)
matrix_config = {}
for k, v in zip(matrix.keys(), config):
matrix_config[k] = v
#print(matrix_config)
if any(map(lambda ex: do_exclude(matrix_config, ex), exclude)):
continue
else:
fn(matrix_config)

View File

@ -54,7 +54,7 @@ namespace cpptrace {
static backtrace_state* state = nullptr;
static bool called = false;
if(!called) {
state = backtrace_create_state(program_name(), true, error_callback, nullptr);
state = backtrace_create_state(nullptr, true, error_callback, nullptr);
called = true;
}
return state;