diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index cec0447..e9b5696 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -142,11 +142,29 @@ jobs: - uses: actions/checkout@v4 - name: dependencies run: | + sudo apt install gcc-10 g++-10 libgcc-10-dev ninja-build cd .. cpptrace/ci/setup-prerequisites-unittest.sh - name: build and test run: | python3 ci/unittest.py + unittest-macos: + runs-on: macos-14 + steps: + - uses: actions/checkout@v4 + - uses: maxim-lobanov/setup-xcode@v1 + with: + xcode-version: "15.4" + - name: dependencies + run: | + brew install ninja + python3 -m venv env + env/bin/pip install colorama + cd .. + cpptrace/ci/setup-prerequisites-unittest-macos.sh + - name: build and test + run: | + env/bin/python ci/unittest.py unittest-windows: runs-on: windows-2022 strategy: diff --git a/ci/setup-prerequisites-unittest-macos.sh b/ci/setup-prerequisites-unittest-macos.sh new file mode 100755 index 0000000..6df6fa6 --- /dev/null +++ b/ci/setup-prerequisites-unittest-macos.sh @@ -0,0 +1,44 @@ +#!/bin/bash + +mkdir zstd +cd zstd +git init +git remote add origin https://github.com/facebook/zstd.git +git fetch --depth 1 origin 63779c798237346c2b245c546c40b72a5a5913fe # 1.5.5 +git checkout FETCH_HEAD +make -j +sudo make install + +cd .. + +mkdir libdwarf +cd libdwarf +git init +git remote add origin https://github.com/davea42/libdwarf-code.git +git fetch --depth 1 origin e2ab28a547ed8a53f2c96a825247a7cc8f7e40bb +git checkout FETCH_HEAD +mkdir build +cd build +cmake .. -GNinja -DPIC_ALWAYS=TRUE -DBUILD_DWARFDUMP=FALSE +sudo ninja install + +cd ../.. + +mkdir googletest +cd googletest +git init +git remote add origin https://github.com/google/googletest.git +git fetch --depth 1 origin f8d7d77c06936315286eb55f8de22cd23c188571 +git checkout FETCH_HEAD +mkdir build +cd build +cmake .. -GNinja -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_INSTALL_PREFIX=/tmp/gtest_install +sudo ninja install +rm -rf * +# There's a false-positive container-overflow for apple clang/relwithdebinfo/sanitizers=on if gtest isn't built with +# sanitizers. https://github.com/google/sanitizers/wiki/AddressSanitizerContainerOverflow#false-positives +cmake .. -GNinja -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_INSTALL_PREFIX=/tmp/gtest_asan_install -DCMAKE_CXX_FLAGS=-fsanitize=address +sudo ninja install +rm -rf * +cmake .. -GNinja -DCMAKE_CXX_COMPILER=g++-12 -DCMAKE_INSTALL_PREFIX=/tmp/gtest_install_gcc +sudo ninja install diff --git a/ci/setup-prerequisites-unittest.sh b/ci/setup-prerequisites-unittest.sh index 551552f..6387460 100755 --- a/ci/setup-prerequisites-unittest.sh +++ b/ci/setup-prerequisites-unittest.sh @@ -1,5 +1,4 @@ #!/bin/bash -sudo apt install gcc-10 g++-10 libgcc-10-dev ninja-build mkdir zstd cd zstd diff --git a/ci/unittest.py b/ci/unittest.py index 0e17837..148fa6d 100644 --- a/ci/unittest.py +++ b/ci/unittest.py @@ -15,7 +15,7 @@ def get_c_compiler_counterpart(compiler: str) -> str: return compiler.replace("clang++", "clang").replace("g++", "gcc") def build(runner: MatrixRunner): - if platform.system() != "Windows": + if platform.system() == "Linux": matrix = runner.current_config() args = [ "cmake", @@ -24,7 +24,7 @@ def build(runner: MatrixRunner): f"-DCMAKE_CXX_COMPILER={matrix['compiler']}", f"-DCMAKE_C_COMPILER={get_c_compiler_counterpart(matrix['compiler'])}", f"-DCMAKE_BUILD_TYPE={matrix['build_type']}", - f"-DBUILD_SHARED_LIBS={matrix['shared']}", + f"-DCPPTRACE_BUILD_SHARED={matrix['shared']}", f"-DHAS_DL_FIND_OBJECT={matrix['has_dl_find_object']}", "-DCPPTRACE_WERROR_BUILD=On", "-DCPPTRACE_STD_FORMAT=Off", @@ -37,6 +37,32 @@ def build(runner: MatrixRunner): f"-DCPPTRACE_USE_EXTERNAL_GTEST=On", ] return runner.run_command(*args) and runner.run_command("ninja") + elif platform.system() == "Darwin": + matrix = runner.current_config() + if "clang++" in matrix["compiler"]: + gtest_path = "/tmp/gtest_asan_install" if matrix['sanitizers'] == "ON" else "/tmp/gtest_install" + else: + gtest_path = "/tmp/gtest_install_gcc" + args = [ + "cmake", + "..", + "-GNinja", + f"-DCMAKE_CXX_COMPILER={matrix['compiler']}", + f"-DCMAKE_C_COMPILER={get_c_compiler_counterpart(matrix['compiler'])}", + f"-DCMAKE_BUILD_TYPE={matrix['build_type']}", + f"-DCPPTRACE_BUILD_SHARED={matrix['shared']}", + "-DCPPTRACE_WERROR_BUILD=On", + "-DCPPTRACE_STD_FORMAT=Off", + "-DCPPTRACE_BUILD_TESTING=On", + f"-DCPPTRACE_SANITIZER_BUILD={matrix['sanitizers']}", + # f"-DCPPTRACE_BUILD_TESTING_SPLIT_DWARF={matrix['split_dwarf']}", + # f"-DCPPTRACE_BUILD_TESTING_SPLIT_DWARF={matrix['dwarf_version']}", + f"-DCPPTRACE_USE_EXTERNAL_LIBDWARF=On", + f"-DCPPTRACE_USE_EXTERNAL_ZSTD=On", + f"-DCPPTRACE_USE_EXTERNAL_GTEST=On", + f"-DCMAKE_PREFIX_PATH={gtest_path}", + ] + return runner.run_command(*args) and runner.run_command("ninja") else: raise ValueError() @@ -50,9 +76,12 @@ def build_and_test(runner: MatrixRunner): # the build directory has to be purged on compiler or shared change last = runner.last_config() current = runner.current_config() - if last is None or last["compiler"] != current["compiler"] or last["shared"] != current["shared"]: - if os.path.exists("build"): - shutil.rmtree("build", ignore_errors=True) + if ( + last is None + or last["compiler"] != current["compiler"] + or (platform.system() == "Darwin" and last["sanitizers"] != current["sanitizers"]) + ) and os.path.exists("build"): + shutil.rmtree("build", ignore_errors=True) if not os.path.exists("build"): os.mkdir("build") @@ -71,9 +100,9 @@ def run_linux_matrix(): MatrixRunner( matrix = { "compiler": ["g++-10", "clang++-14"], - "shared": ["OFF", "ON"], - "build_type": ["Debug", "RelWithDebInfo"], "sanitizers": ["OFF", "ON"], + "build_type": ["Debug", "RelWithDebInfo"], + "shared": ["OFF", "ON"], "has_dl_find_object": ["OFF", "ON"], "split_dwarf": ["OFF", "ON"], "dwarf_version": ["4", "5"], @@ -81,11 +110,29 @@ def run_linux_matrix(): exclude = [] ).run(build_and_test) +def run_macos_matrix(): + MatrixRunner( + matrix = { + "compiler": ["g++-12", "clang++"], + "sanitizers": ["OFF", "ON"], + "build_type": ["Debug", "RelWithDebInfo"], + "shared": ["OFF", "ON"], + # "split_dwarf": ["OFF", "ON"], + # "dwarf_version": ["4", "5"], + }, + exclude = [ + { + "compiler": "g++-12", + "sanitizers": "ON", + } + ] + ).run(build_and_test) + def main(): if platform.system() == "Linux": run_linux_matrix() if platform.system() == "Darwin": - raise ValueError() # run_macos_matrix() + run_macos_matrix() if platform.system() == "Windows": raise ValueError() # run_windows_matrix()