From b2df292d80052f517beaf46f5d5c792a1a03b163 Mon Sep 17 00:00:00 2001 From: Jeremy Rifkin <51220084+jeremy-rifkin@users.noreply.github.com> Date: Wed, 19 Jul 2023 22:30:37 -0400 Subject: [PATCH] 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. --- .github/workflows/build.yml | 191 +------------ .github/workflows/test.yml | 208 +------------- .gitignore | 5 +- ci/build-in-all-configs.py | 238 ++++++++++++++++ ci/dump_msvc_env.ps1 | 1 + ci/test-all-configs.py | 318 ++++++++++++++++++++++ ci/util.py | 20 ++ src/full/full_trace_with_libbacktrace.cpp | 2 +- 8 files changed, 596 insertions(+), 387 deletions(-) create mode 100644 ci/build-in-all-configs.py create mode 100644 ci/dump_msvc_env.ps1 create mode 100644 ci/test-all-configs.py create mode 100644 ci/util.py diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4ca0290..e4761ff 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -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 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ffd5ebe..cbf9f63 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -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 diff --git a/.gitignore b/.gitignore index ef80ab0..7000e71 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .vscode a.out -build* -repro* +build*/ +repro*/ +__pycache__ diff --git a/ci/build-in-all-configs.py b/ci/build-in-all-configs.py new file mode 100644 index 0000000..75548dc --- /dev/null +++ b/ci/build-in-all-configs.py @@ -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() diff --git a/ci/dump_msvc_env.ps1 b/ci/dump_msvc_env.ps1 new file mode 100644 index 0000000..24216c3 --- /dev/null +++ b/ci/dump_msvc_env.ps1 @@ -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" diff --git a/ci/test-all-configs.py b/ci/test-all-configs.py new file mode 100644 index 0000000..9cb4599 --- /dev/null +++ b/ci/test-all-configs.py @@ -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() diff --git a/ci/util.py b/ci/util.py new file mode 100644 index 0000000..84a9bee --- /dev/null +++ b/ci/util.py @@ -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) diff --git a/src/full/full_trace_with_libbacktrace.cpp b/src/full/full_trace_with_libbacktrace.cpp index d5de589..d180ef4 100644 --- a/src/full/full_trace_with_libbacktrace.cpp +++ b/src/full/full_trace_with_libbacktrace.cpp @@ -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;