From b4deabca23341f18da6da257422cb32be6043264 Mon Sep 17 00:00:00 2001 From: Sergiu Deitsch Date: Tue, 9 Nov 2021 20:42:56 +0100 Subject: [PATCH] ci: reworked windows builds --- .../{android-builds.yml => android.yml} | 25 +-- .github/workflows/coveralls.yml | 84 --------- .github/workflows/linux-builds.yml | 126 -------------- .github/workflows/linux.yml | 142 ++++++++++++++++ .github/workflows/macos-builds.yml | 47 ----- .github/workflows/macos.yml | 86 ++++++++++ .github/workflows/windows-builds.yml | 116 ------------- .github/workflows/windows.yml | 160 ++++++++++++++++++ CMakeLists.txt | 11 +- README.rst | 12 +- src/config.h.cmake.in | 3 + src/demangle.cc | 7 + src/demangle_unittest.cc | 2 + src/glog/logging.h.in | 2 +- src/googletest.h | 4 +- src/logging_custom_prefix_unittest.cc | 14 +- src/logging_unittest.cc | 14 +- src/mock-log_unittest.cc | 22 +-- src/symbolize_unittest.cc | 19 +++ src/utilities.cc | 2 +- 20 files changed, 473 insertions(+), 425 deletions(-) rename .github/workflows/{android-builds.yml => android.yml} (69%) delete mode 100644 .github/workflows/coveralls.yml delete mode 100644 .github/workflows/linux-builds.yml create mode 100644 .github/workflows/linux.yml delete mode 100644 .github/workflows/macos-builds.yml create mode 100644 .github/workflows/macos.yml delete mode 100644 .github/workflows/windows-builds.yml create mode 100644 .github/workflows/windows.yml diff --git a/.github/workflows/android-builds.yml b/.github/workflows/android.yml similarity index 69% rename from .github/workflows/android-builds.yml rename to .github/workflows/android.yml index 0e0571ea9..2df948b7d 100644 --- a/.github/workflows/android-builds.yml +++ b/.github/workflows/android.yml @@ -3,15 +3,15 @@ name: Android on: [push, pull_request] jobs: - build: + build-android: name: NDK-C++${{matrix.std}}-${{matrix.abi}}-${{matrix.build_type}} runs-on: ubuntu-latest strategy: - fail-fast: false + fail-fast: true matrix: - std: [98, 11, 14, 17, 20] - abi: [arm64-v8a, armeabi-v7a, x86_64, x86] - build_type: [Debug] + std: [98, 11, 14, 17, 20] + abi: [arm64-v8a, armeabi-v7a, x86_64, x86] + build_type: [Debug, Release] steps: - uses: actions/checkout@v2 @@ -24,17 +24,18 @@ jobs: - name: Configure shell: bash run: | - cmake -S . -B ${{runner.workspace}}/build_CXX${{matrix.std}}-${{matrix.abi}} \ - -G "Ninja Multi-Config" \ + cmake -S . -B build_${{matrix.abi}} \ + -DANDROID_ABI=${{matrix.abi}} \ + -DANDROID_NATIVE_API_LEVEL=28 \ + -DANDROID_STL=c++_shared \ + -DCMAKE_BUILD_TYPE=${{matrix.build_type}} \ -DCMAKE_CXX_EXTENSIONS=OFF \ -DCMAKE_CXX_STANDARD=${{matrix.std}} \ -DCMAKE_CXX_STANDARD_REQUIRED=ON \ -DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK_HOME}/build/cmake/android.toolchain.cmake \ - -DANDROID_STL=c++_shared \ - -DANDROID_NATIVE_API_LEVEL=28 \ - -DANDROID_ABI=${{matrix.abi}} \ + -G Ninja + - name: Build run: | - cmake --build ${{runner.workspace}}/build_CXX${{matrix.std}}-${{matrix.abi}} \ + cmake --build build_${{matrix.abi}} \ --config ${{matrix.build_type}} - diff --git a/.github/workflows/coveralls.yml b/.github/workflows/coveralls.yml deleted file mode 100644 index 21b5be350..000000000 --- a/.github/workflows/coveralls.yml +++ /dev/null @@ -1,84 +0,0 @@ -name: Coveralls - -on: - workflow_run: - workflows: [Linux] - types: - - completed - -jobs: - merge: - name: Aggregate coverage reports - defaults: - run: - shell: bash - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - - name: Setup Dependencies - env: - DEBIAN_FRONTEND: noninteractive - run: | - sudo apt-get update - sudo apt-get install -y lcov - - - name: Download Artifacts - uses: actions/github-script@v3.1.0 - with: - script: | - var artifacts = await github.actions.listWorkflowRunArtifacts({ - owner: context.repo.owner, - repo: context.repo.repo, - run_id: ${{github.event.workflow_run.id}}, - }); - var matchArtifacts = artifacts.data.artifacts; - for (artifact of matchArtifacts) { - var download = await github.actions.downloadArtifact({ - owner: context.repo.owner, - repo: context.repo.repo, - artifact_id: artifact.id, - archive_format: 'zip', - }); - var fs = require('fs'); - fs.writeFileSync('${{github.workspace}}/' + artifact.name + '.zip', Buffer.from(download.data)); - } - - - name: Unpack Artifacts - run: | - for file in *.zip; do - unzip "$file" -d "build_${file%.zip}" - done - - - name: Generate Coverage - run: | - lcov --directory . --capture --output-file coverage.info - lcov --remove coverage.info \ - '*/install/include/*' \ - '*/msys64/mingw32/*' \ - '*/msys64/mingw64/*' \ - '*/src/*_unittest.cc' \ - '*/src/googletest.h' \ - '*/src/mock-log.h' \ - '/usr/*' \ - --output-file coverage.info - - readarray -t build_dirs < <(ls -d build_*/) - - for file in src/glog/*.h.in; do - name=$(basename ${file}) - name_we=${name%.h.in} - - for build_dir in ${build_dirs[@]}; do - sed -i "s|${build_dir%/}/glog/${name_we}.h\$|${file}|g" coverage.info - done - done - - lcov --list coverage.info - - - name: Upload Coverage to Coveralls - uses: coverallsapp/github-action@master - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - path-to-lcov: ./coverage.info diff --git a/.github/workflows/linux-builds.yml b/.github/workflows/linux-builds.yml deleted file mode 100644 index c4c22d280..000000000 --- a/.github/workflows/linux-builds.yml +++ /dev/null @@ -1,126 +0,0 @@ -name: Linux - -on: [push, pull_request] - -jobs: - build: - defaults: - run: - shell: bash - name: "GCC-C++${{matrix.std}}-${{matrix.build_type}} (shared: ${{matrix.shared}} custom prefix: ${{matrix.custom_prefix}})" - runs-on: ubuntu-latest - strategy: - fail-fast: true - matrix: - build_type: [Release, Debug] - std: [98, 11, 14, 17, 20] - custom_prefix: [ON, OFF] - shared: [ON, OFF] - - steps: - - uses: actions/checkout@v2 - - - name: Setup Dependencies - run: | - sudo apt-get update - DEBIAN_FRONTEND=noninteractive sudo apt-get install -y \ - build-essential \ - cmake \ - lcov \ - libgflags-dev \ - libunwind-dev \ - ninja-build - - - name: Build GTest - run: | - wget https://github.com/google/googletest/archive/refs/tags/release-1.11.0.tar.gz - tar xvf release-1.11.0.tar.gz - cmake -S googletest-release-1.11.0 -B build-googletest \ - -DBUILD_SHARED_LIBS=${{matrix.shared}} \ - -DCMAKE_INSTALL_PREFIX=./install \ - -G Ninja - cmake --build build-googletest --target install - - - name: Setup Environment - if: ${{matrix.build_type == 'Debug'}} - run: | - echo 'CXXFLAGS=--coverage' >> $GITHUB_ENV - - - name: Configure - run: | - cmake -S . -B build_${{matrix.build_type}} -G Ninja \ - -DBUILD_SHARED_LIBS=${{matrix.shared}} \ - -DCMAKE_CXX_STANDARD=${{matrix.std}} \ - -DCMAKE_CXX_STANDARD_REQUIRED=ON \ - -DCMAKE_INSTALL_PREFIX:PATH=./install \ - -DWITH_CUSTOM_PREFIX=${{matrix.custom_prefix}} - - - name: Build - run: | - cmake --build build_${{matrix.build_type}} \ - --config ${{matrix.build_type}} - - - name: Install - run: | - cmake --build build_${{matrix.build_type}} \ - --config ${{matrix.build_type}} \ - --target install - - cmake build_${{matrix.build_type}} -G Ninja \ - -DCMAKE_INSTALL_INCLUDEDIR=${{runner.workspace}}/foo/include \ - -DCMAKE_INSTALL_LIBDIR=${{runner.workspace}}/foo/lib \ - -DCMAKE_INSTALL_DATAROOTDIR=${{runner.workspace}}/foo/share - cmake --build build_${{matrix.build_type}} \ - --config ${{matrix.build_type}} \ - --target install - - - name: Test CMake Package (relative GNUInstallDirs) - run: | - cmake -S src/package_config_unittest/working_config \ - -B build_${{matrix.build_type}}_package \ - -DCMAKE_BUILD_TYPE=${{matrix.build_type}} \ - -DCMAKE_PREFIX_PATH=./build_${{matrix.build_type}}/install \ - -G Ninja - cmake --build build_${{matrix.build_type}}_package \ - --config ${{matrix.build_type}} - - - name: Test CMake Package (absolute GNUInstallDirs) - run: | - cmake -S src/package_config_unittest/working_config \ - -B build_${{matrix.build_type}}_package_foo \ - -DCMAKE_BUILD_TYPE=${{matrix.build_type}} \ - -DCMAKE_PREFIX_PATH=${{runner.workspace}}/foo \ - -G Ninja - cmake --build build_${{matrix.build_type}}_package_foo \ - --config ${{matrix.build_type}} - - - name: Test - run: | - ctest --test-dir build_${{matrix.build_type}} -j$(nproc) --output-on-failure - - - name: Generate Coverage - if: ${{ startswith(matrix.build_type, 'Debug') }} - run: | - lcov --directory . --capture --output-file coverage.info - lcov --remove coverage.info \ - '*/install/include/*' \ - '*/src/*_unittest.cc' \ - '*/src/googletest.h' \ - '*/src/mock-log.h' \ - '/usr/*' \ - --output-file coverage.info - - for file in src/glog/*.h.in; do - name=$(basename ${file}) - name_we=${name%.h.in} - sed -i "s|build_${{matrix.build_type}}/glog/${name_we}.h\$|${file}|g" coverage.info - done - - lcov --list coverage.info - - - name: Upload Coverage to Coveralls - if: ${{ startswith(matrix.build_type, 'Debug') }} - uses: coverallsapp/github-action@master - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - path-to-lcov: ./coverage.info diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml new file mode 100644 index 000000000..ab9109a45 --- /dev/null +++ b/.github/workflows/linux.yml @@ -0,0 +1,142 @@ +name: Linux + +on: [push, pull_request] + +jobs: + build-linux: + defaults: + run: + shell: bash + name: GCC-C++${{matrix.std}}-${{matrix.build_type}}-${{matrix.lib}}-${{matrix.extra}} + runs-on: ubuntu-latest + env: + BUILDDIR: 'build_GCC-C++${{matrix.std}}-${{matrix.build_type}}-${{matrix.lib}}-${{matrix.extra}}' + strategy: + fail-fast: true + matrix: + build_type: [Release, Debug] + extra: [no-custom-prefix, custom-prefix] + lib: [shared, static] + std: [98, 11, 14, 17, 20] + + steps: + - uses: actions/checkout@v2 + + - name: Setup Dependencies + run: | + sudo apt-get update + DEBIAN_FRONTEND=noninteractive sudo apt-get install -y \ + build-essential \ + cmake \ + lcov \ + libgflags-dev \ + libunwind-dev \ + ninja-build + + - name: Cache GTest + id: cache-gtest + uses: actions/cache@v2 + with: + path: gtest/ + key: ${{runner.os}}-gtest-1.11 + + - name: Download GTest + if: steps.cache-gtest.outputs.cache-hit != 'true' + run: | + wget https://github.com/google/googletest/archive/refs/tags/release-1.11.0.tar.gz + tar xvf release-1.11.0.tar.gz + + - name: Build GTest + if: steps.cache-gtest.outputs.cache-hit != 'true' + run: | + cmake -S googletest-release-1.11.0 -B build-googletest \ + -DBUILD_SHARED_LIBS=${{matrix.shared}} \ + -DCMAKE_BUILD_TYPE=${{matrix.build_type}} \ + -DCMAKE_INSTALL_PREFIX=./gtest \ + -G Ninja + cmake --build build-googletest --target install + + - name: Setup Environment + if: matrix.build_type == 'Debug' + run: | + echo 'CXXFLAGS=--coverage' >> $GITHUB_ENV + + - name: Configure + run: | + cmake -S . -B "${{env.BUILDDIR}}" \ + -DBUILD_SHARED_LIBS=${{matrix.lib == 'shared'}} \ + -DCMAKE_CXX_STANDARD=${{matrix.std}} \ + -DCMAKE_CXX_STANDARD_REQUIRED=ON \ + -DCMAKE_INSTALL_PREFIX:PATH=./gtest \ + -DWITH_CUSTOM_PREFIX=${{matrix.extra == 'custom-prefix'}} \ + -G Ninja + + - name: Build + run: | + cmake --build "${{env.BUILDDIR}}" \ + --config ${{matrix.build_type}} + + - name: Install + run: | + cmake --build "${{env.BUILDDIR}}" \ + --config ${{matrix.build_type}} \ + --target install + + cmake "${{env.BUILDDIR}}" -G Ninja \ + -DCMAKE_INSTALL_INCLUDEDIR=${{runner.workspace}}/foo/include \ + -DCMAKE_INSTALL_LIBDIR=${{runner.workspace}}/foo/lib \ + -DCMAKE_INSTALL_DATAROOTDIR=${{runner.workspace}}/foo/share + cmake --build "${{env.BUILDDIR}}" \ + --config ${{matrix.build_type}} \ + --target install + + - name: Test CMake Package (relative GNUInstallDirs) + run: | + cmake -S src/package_config_unittest/working_config \ + -B "${{env.BUILDDIR}}_package" \ + -DCMAKE_BUILD_TYPE=${{matrix.build_type}} \ + -DCMAKE_PREFIX_PATH="./${BUILDDIR}/install" \ + -G Ninja + cmake --build "${{env.BUILDDIR}}_package" \ + --config ${{matrix.build_type}} + + - name: Test CMake Package (absolute GNUInstallDirs) + run: | + cmake -S src/package_config_unittest/working_config \ + -B "${{env.BUILDDIR}}_package_foo" \ + -DCMAKE_BUILD_TYPE=${{matrix.build_type}} \ + -DCMAKE_PREFIX_PATH=${{runner.workspace}}/foo \ + -G Ninja + cmake --build "${{env.BUILDDIR}}_package_foo" \ + --config ${{matrix.build_type}} + + - name: Test + run: | + ctest --test-dir "${{env.BUILDDIR}}" -j$(nproc) --output-on-failure + + - name: Generate Coverage + if: matrix.build_type == 'Debug' + run: | + lcov --directory . --capture --output-file coverage.info + lcov --remove coverage.info \ + '*/install/include/*' \ + '*/src/*_unittest.cc' \ + '*/src/googletest.h' \ + '*/src/mock-log.h' \ + '/usr/*' \ + --output-file coverage.info + + for file in src/glog/*.h.in; do + name=$(basename ${file}) + name_we=${name%.h.in} + sed -i "s|${{env.BUILDDIR}}/glog/${name_we}.h\$|${file}|g" coverage.info + done + + lcov --list coverage.info + + - name: Upload Coverage to Codecov + if: matrix.build_type == 'Debug' + uses: codecov/codecov-action@v2 + with: + fail_ci_if_error: true + verbose: true diff --git a/.github/workflows/macos-builds.yml b/.github/workflows/macos-builds.yml deleted file mode 100644 index 3629d34c0..000000000 --- a/.github/workflows/macos-builds.yml +++ /dev/null @@ -1,47 +0,0 @@ -name: macOS - -on: [push, pull_request] - -jobs: - build: - name: AppleClang-C++${{matrix.std}}-${{matrix.build_type}} - runs-on: macos-10.15 - strategy: - fail-fast: false - matrix: - std: [98, 11, 14, 17, 20] - include: - - generator: Ninja - - build_type: Debug - - steps: - - uses: actions/checkout@v2 - - - name: Setup Ninja - uses: ashutoshvarma/setup-ninja@master - with: - version: 1.10.0 - - - name: Configure - shell: bash - env: - CXXFLAGS: -Wall -Wextra -Wsign-conversion -Wtautological-compare -Werror - run: | - if [[ ${{matrix.std}} == 98 ]]; then - export CXXFLAGS="-Werror=c++11-extensions ${CXXFLAGS}" - fi - cmake -S . -B ${{runner.workspace}}/build_${{matrix.name}}_${{matrix.build_type}} \ - -G "${{matrix.generator}}" \ - -DCMAKE_CXX_EXTENSIONS=OFF \ - -DCMAKE_CXX_FLAGS_DEBUG=-pedantic-errors \ - -DCMAKE_CXX_FLAGS_RELEASE=-pedantic-errors \ - -DCMAKE_CXX_STANDARD=${{matrix.std}} \ - -DCMAKE_CXX_STANDARD_REQUIRED=ON - - name: Build - run: | - cmake --build ${{runner.workspace}}/build_${{matrix.name}}_${{matrix.build_type}} \ - --config ${{matrix.build_type}} - - name: Run tests - run: | - ctest --test-dir ${{runner.workspace}}/build_${{matrix.name}}_${{matrix.build_type}} \ - --output-on-failure diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml new file mode 100644 index 000000000..e9b196ef7 --- /dev/null +++ b/.github/workflows/macos.yml @@ -0,0 +1,86 @@ +name: macOS + +on: [push, pull_request] + +jobs: + build-macos: + name: AppleClang-C++${{matrix.std}}-${{matrix.build_type}} + runs-on: macos-10.15 + strategy: + fail-fast: true + matrix: + std: [98, 11, 14, 17, 20] + include: + - generator: Ninja + - build_type: Debug + + steps: + - uses: actions/checkout@v2 + + - name: Setup Ninja + uses: ashutoshvarma/setup-ninja@master + with: + version: 1.10.0 + + - name: Setup Dependencies + run: | + brew install lcov + + - name: Setup Environment + if: matrix.build_type == 'Debug' + run: | + echo 'CXXFLAGS=--coverage' >> $GITHUB_ENV + + - name: Setup C++98 Environment + if: matrix.std == '98' + run: | + echo 'CXXFLAGS=-Wall -Wextra -Wsign-conversion -Wtautological-compare -Werror ${{env.CXXFLAGS}}' >> $GITHUB_ENV + + - name: Configure + shell: bash + env: + CXXFLAGS: -Wall -Wextra -Wsign-conversion -Wtautological-compare -Werror ${{env.CXXFLAGS}} + run: | + cmake -S . -B build_${{matrix.build_type}} \ + -G "${{matrix.generator}}" \ + -DCMAKE_CXX_EXTENSIONS=OFF \ + -DCMAKE_CXX_FLAGS_DEBUG=-pedantic-errors \ + -DCMAKE_CXX_FLAGS_RELEASE=-pedantic-errors \ + -DCMAKE_CXX_STANDARD=${{matrix.std}} \ + -DCMAKE_CXX_STANDARD_REQUIRED=ON + + - name: Build + run: | + cmake --build build_${{matrix.build_type}} \ + --config ${{matrix.build_type}} + + - name: Test + run: | + ctest --test-dir build_${{matrix.build_type}} \ + --output-on-failure + + - name: Generate Coverage + if: matrix.build_type == 'Debug' + run: | + lcov --directory . --capture --output-file coverage.info + lcov --remove coverage.info \ + '*/src/*_unittest.cc' \ + '*/src/googletest.h' \ + '*/src/mock-log.h' \ + '*/usr/*' \ + --output-file coverage.info + + for file in src/glog/*.h.in; do + name=$(basename ${file}) + name_we=${name%.h.in} + sed -i "s|${{env.BUILDDIR}}/glog/${name_we}.h\$|${file}|g" coverage.info + done + + lcov --list coverage.info + + - name: Upload Coverage to Codecov + if: matrix.build_type == 'Debug' + uses: codecov/codecov-action@v2 + with: + fail_ci_if_error: true + verbose: true diff --git a/.github/workflows/windows-builds.yml b/.github/workflows/windows-builds.yml deleted file mode 100644 index 911daa74f..000000000 --- a/.github/workflows/windows-builds.yml +++ /dev/null @@ -1,116 +0,0 @@ -name: Windows - -on: [push, pull_request] - -jobs: - build: - # available environments: https://github.com/actions/virtual-environments - name: ${{matrix.config.name}} ${{matrix.build_type}} - runs-on: ${{matrix.config.os}} - strategy: - fail-fast: false - matrix: - config: - - { - name: "VS-15-2017-win64-C++11", - os: windows-2016, - generator: "Visual Studio 15 2017", - std: 11, - test_target: RUN_TESTS, - } - - { - name: "VS-16-2019-win64-C++98", - os: windows-2019, - generator: "Visual Studio 16 2019", - std: 98, - test_target: RUN_TESTS, - } - - { - name: "VS-16-2019-win64-C++11", - os: windows-2019, - generator: "Visual Studio 16 2019", - std: 11, - test_target: RUN_TESTS, - } - - { - name: "VS-16-2019-win64-C++17", - os: windows-2019, - generator: "Visual Studio 16 2019", - std: 17, - test_target: RUN_TESTS, - } - - { - name: "VS-16-2019-win64-C++20", - os: windows-2019, - generator: "Visual Studio 16 2019", - std: 20, - test_target: RUN_TESTS, - } - - { - name: "MinGW-C++98", - os: windows-latest, - generator: "MinGW Makefiles", - std: 98, - test_target: test, - } - - { - name: "MinGW-C++11", - os: windows-latest, - generator: "MinGW Makefiles", - std: 11, - test_target: test, - } - - { - name: "MinGW-C++14", - os: windows-latest, - generator: "MinGW Makefiles", - std: 14, - test_target: test, - } - - { - name: "MinGW-C++17", - os: windows-latest, - generator: "MinGW Makefiles", - std: 17, - test_target: test, - } - - { - name: "MinGW-C++20", - os: windows-latest, - generator: "MinGW Makefiles", - std: 20, - test_target: test, - } - build_type: [Debug] #, Release] - ARCH: ["x64"] - - steps: - - uses: actions/checkout@v2 - - # Visual Studio build steps - - name: Configure build MSVC - if: ${{ startswith(matrix.config.name, 'VS-') }} - shell: powershell - run: cmake -S . -B ${{runner.workspace}}/build_${{matrix.config.name}}_${{matrix.build_type}} -G "${{matrix.config.generator}}" -A "${{matrix.ARCH}}" -DCMAKE_CXX_STANDARD=${{matrix.config.std}} -DCMAKE_CXX_STANDARD_REQUIRED=ON -DCMAKE_CXX_EXTENSIONS=OFF - - name: Build MSVC - if: ${{ startswith(matrix.config.name, 'VS-') }} - shell: powershell - run: cmake --build ${{runner.workspace}}/build_${{matrix.config.name}}_${{matrix.build_type}} --config ${{matrix.build_type}} - - # MinGW build steps - - name: Configure build MinGW - if: ${{ startswith(matrix.config.name, 'MinGW-') }} - shell: powershell - env: - CXXFLAGS: -Wall -Wextra -Wpedantic -Wsign-conversion -Wtautological-compare -Werror -Wno-error=variadic-macros -Wno-error=long-long - run: cmake -S . -B ${{runner.workspace}}/build_${{matrix.config.name}}_${{matrix.build_type}} -G "${{matrix.config.generator}}" -DCMAKE_CXX_STANDARD=${{matrix.config.std}} -DCMAKE_CXX_EXTENSIONS=OFF -DCMAKE_CXX_STANDARD_REQUIRED=ON -DCMAKE_BUILD_TYPE=${{matrix.build_type}} - - name: Build MinGW - if: ${{ startswith(matrix.config.name, 'MinGW-') }} - shell: powershell - run: cmake --build ${{runner.workspace}}/build_${{matrix.config.name}}_${{matrix.build_type}} - - - name: Run tests - shell: powershell - env: - CTEST_OUTPUT_ON_FAILURE: 1 - run: cmake --build ${{runner.workspace}}/build_${{matrix.config.name}}_${{matrix.build_type}} --target ${{matrix.config.test_target}} diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml new file mode 100644 index 000000000..1329c2151 --- /dev/null +++ b/.github/workflows/windows.yml @@ -0,0 +1,160 @@ +name: Windows + +on: [push, pull_request] + +jobs: + build-msvc: + name: ${{matrix.msvc}}-${{matrix.arch}}-C++${{matrix.std}}-${{matrix.build_type}}-${{matrix.lib}}-${{matrix.extra}} + runs-on: ${{matrix.os}} + defaults: + run: + shell: powershell + strategy: + fail-fast: true + matrix: + arch: [Win32, x64] + build_type: [Debug, Release] + extra: [no-custom-prefix, custom-prefix] + lib: [shared, static] + msvc: [VS-15-2017, VS-16-2019, VS-17-2022] + std: [98, 11, 14, 17, 20] + include: + - msvc: VS-15-2017 + os: windows-2016 + generator: 'Visual Studio 15 2017' + - msvc: VS-16-2019 + os: windows-2019 + generator: 'Visual Studio 16 2019' + - msvc: VS-17-2022 + os: windows-2022 + generator: 'Visual Studio 17 2022' + + steps: + - uses: actions/checkout@v2 + + - name: Configure + run: | + cmake -S . -B build_${{matrix.build_type}} ` + -A ${{matrix.arch}} ` + -DBUILD_SHARED_LIBS=${{matrix.lib == 'shared'}} ` + -DCMAKE_CXX_EXTENSIONS=OFF ` + -DCMAKE_CXX_STANDARD=${{matrix.std}} ` + -DCMAKE_CXX_STANDARD_REQUIRED=ON ` + -DCMAKE_INSTALL_PREFIX:PATH=./install ` + -DWITH_CUSTOM_PREFIX=${{matrix.extra == 'custom-prefix'}} ` + -G "${{matrix.generator}}" + + - name: Build + run: cmake --build build_${{matrix.build_type}} ` + --config ${{matrix.build_type}} + + - name: Test + env: + CTEST_OUTPUT_ON_FAILURE: 1 + run: | + cmake --build build_${{matrix.build_type}}/ ` + --config ${{matrix.build_type}} ` + --target RUN_TESTS + + - name: Install + run: | + cmake --build build_${{matrix.build_type}}/ ` + --config ${{matrix.build_type}} ` + --target install + + build-mingw: + name: ${{matrix.sys}}-${{matrix.env}}-C++${{matrix.std}}-${{matrix.build_type}}-${{matrix.lib}}-${{matrix.extra}} + runs-on: windows-latest + env: + BUILDDIR: 'build_${{matrix.sys}}-${{matrix.env}}-C++${{matrix.std}}-${{matrix.build_type}}-${{matrix.lib}}-${{matrix.extra}}' + defaults: + run: + shell: msys2 {0} + strategy: + fail-fast: true + matrix: + build_type: [Debug] + extra: [no-custom-prefix, custom-prefix] + lib: [shared, static] + std: [98, 11, 14, 17, 20] + sys: [mingw32, mingw64] + include: + - sys: mingw32 + env: i686 + - sys: mingw64 + env: x86_64 + + steps: + - uses: actions/checkout@v2 + - uses: msys2/setup-msys2@v2 + with: + msystem: ${{matrix.sys}} + install: >- + lcov + mingw-w64-${{matrix.env}}-cmake + mingw-w64-${{matrix.env}}-gcc + mingw-w64-${{matrix.env}}-gflags + mingw-w64-${{matrix.env}}-ninja + + - name: Configure + env: + CXXFLAGS: -Wall -Wextra -Wpedantic -Wsign-conversion -Wtautological-compare -Werror -Wno-error=variadic-macros -Wno-error=long-long + run: | + if [[ ${{matrix.build_type}} == "Debug" ]]; then + export CXXFLAGS="--coverage ${CXXFLAGS}" + fi + + cmake -S . -B build_${{matrix.build_type}}/ \ + -DBUILD_SHARED_LIBS=${{matrix.lib == 'shared'}} \ + -DCMAKE_BUILD_TYPE=${{matrix.build_type}} \ + -DCMAKE_CXX_EXTENSIONS=OFF \ + -DCMAKE_CXX_STANDARD=${{matrix.std}} \ + -DCMAKE_CXX_STANDARD_REQUIRED=ON \ + -DCMAKE_INSTALL_PREFIX:PATH=./install \ + -DWITH_CUSTOM_PREFIX=${{matrix.extra == 'custom-prefix'}} \ + -G Ninja + + - name: Build + run: | + cmake --build build_${{matrix.build_type}}/ --config ${{matrix.build_type}} + + - name: Test + env: + CTEST_OUTPUT_ON_FAILURE: 1 + run: | + cmake --build build_${{matrix.build_type}}/ --config ${{matrix.build_type}} \ + --target test + + - name: Install + run: | + cmake --build build_${{matrix.build_type}}/ \ + --config ${{matrix.build_type}} \ + --target install + + - name: Generate Coverage + if: matrix.build_type == 'Debug' + run: | + lcov --directory . --capture --output-file coverage.info + lcov --remove coverage.info \ + '*/install/include/*' \ + '*/msys64/mingw32/*' \ + '*/msys64/mingw64/*' \ + '*/src/*_unittest.cc' \ + '*/src/googletest.h' \ + '*/src/mock-log.h' \ + --output-file coverage.info + + for file in src/glog/*.h.in; do + name=$(basename ${file}) + name_we=${name%.h.in} + sed -i "s|build_${{matrix.build_type}}/glog/${name_we}.h\$|${file}|g" coverage.info + done + + lcov --list coverage.info + + - name: Upload Coverage to Codecov + if: matrix.build_type == 'Debug' + uses: codecov/codecov-action@v2 + with: + fail_ci_if_error: true + verbose: true diff --git a/CMakeLists.txt b/CMakeLists.txt index bcf04c6dc..d37582ba6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -638,16 +638,16 @@ add_library (glog add_library (glog::glog ALIAS glog) if (Unwind_FOUND) - target_link_libraries (glog PUBLIC unwind::unwind) + target_link_libraries (glog PRIVATE unwind::unwind) set (Unwind_DEPENDENCY "find_dependency (Unwind ${Unwind_VERSION})") endif (Unwind_FOUND) if (HAVE_DBGHELP) - target_link_libraries (glog PUBLIC dbghelp) + target_link_libraries (glog PRIVATE dbghelp) endif (HAVE_DBGHELP) if (HAVE_PTHREAD) - target_link_libraries (glog PUBLIC ${CMAKE_THREAD_LIBS_INIT}) + target_link_libraries (glog PRIVATE ${CMAKE_THREAD_LIBS_INIT}) endif (HAVE_PTHREAD) if (gflags_FOUND) @@ -665,8 +665,8 @@ if (gflags_FOUND) endif (gflags_FOUND) if (ANDROID) - target_link_libraries (glog PUBLIC log) -endif() + target_link_libraries (glog PRIVATE log) +endif (ANDROID) set_target_properties (glog PROPERTIES VERSION ${PROJECT_VERSION}) set_target_properties (glog PROPERTIES SOVERSION 1) @@ -899,6 +899,7 @@ if (BUILD_TESTING) add_test (NAME cmake_package_config_build COMMAND ${CMAKE_COMMAND} --build ${CMAKE_CURRENT_BINARY_DIR}/test_package_config/working_config + --config $ ) add_test (NAME cmake_package_config_cleanup COMMAND ${CMAKE_COMMAND} -E diff --git a/README.rst b/README.rst index 6965ecba3..d85ad11cd 100644 --- a/README.rst +++ b/README.rst @@ -1,7 +1,7 @@ Google Logging Library ====================== -|Linux Github actions| |Windows Github actions| |macOS Github actions| |Total alerts| |Language grade: C++| |Coveralls| +|Linux Github actions| |Windows Github actions| |macOS Github actions| |Total alerts| |Language grade: C++| |Codecov| Google Logging (glog) is a C++98 library that implements application-level logging. The library provides logging APIs based on C++-style streams and @@ -865,15 +865,15 @@ Submitting a Patch request `__. -.. |Linux Github actions| image:: https://github.com/google/glog/actions/workflows/linux-builds.yml/badge.svg +.. |Linux Github actions| image:: https://github.com/google/glog/actions/workflows/linux.yml/badge.svg :target: https://github.com/google/glog/actions -.. |Windows Github actions| image:: https://github.com/google/glog/actions/workflows/windows-builds.yml/badge.svg +.. |Windows Github actions| image:: https://github.com/google/glog/actions/workflows/windows.yml/badge.svg :target: https://github.com/google/glog/actions -.. |macOS Github actions| image:: https://github.com/google/glog/actions/workflows/macos-builds.yml/badge.svg +.. |macOS Github actions| image:: https://github.com/google/glog/actions/workflows/macos.yml/badge.svg :target: https://github.com/google/glog/actions .. |Total alerts| image:: https://img.shields.io/lgtm/alerts/g/google/glog.svg?logo=lgtm&logoWidth=18 :target: https://lgtm.com/projects/g/google/glog/alerts/ .. |Language grade: C++| image:: https://img.shields.io/lgtm/grade/cpp/g/google/glog.svg?logo=lgtm&logoWidth=18) :target: https://lgtm.com/projects/g/google/glog/context:cpp -.. |Coveralls| image:: https://coveralls.io/repos/github/google/glog/badge.svg?branch=master - :target: https://coveralls.io/github/google/glog?branch=master +.. |Codecov| image:: https://codecov.io/gh/google/glog/branch/master/graph/badge.svg?token=8an420vNju + :target: https://codecov.io/gh/google/glog diff --git a/src/config.h.cmake.in b/src/config.h.cmake.in index 4d379a366..ca278ad4f 100644 --- a/src/config.h.cmake.in +++ b/src/config.h.cmake.in @@ -40,6 +40,9 @@ /* define if you have google gtest library */ #cmakedefine HAVE_LIB_GTEST +/* define if you have dbghelp library */ +#cmakedefine HAVE_DBGHELP + /* define if you have libunwind */ #cmakedefine HAVE_LIB_UNWIND diff --git a/src/demangle.cc b/src/demangle.cc index d7db165cd..2d86edca1 100644 --- a/src/demangle.cc +++ b/src/demangle.cc @@ -1325,6 +1325,7 @@ static bool ParseTopLevelMangledName(State *state) { // The demangler entry point. bool Demangle(const char *mangled, char *out, size_t out_size) { #if defined(GLOG_OS_WINDOWS) +#if defined(HAVE_DBGHELP) // When built with incremental linking, the Windows debugger // library provides a more complicated `Symbol->Name` with the // Incremental Linking Table offset, which looks like @@ -1346,6 +1347,12 @@ bool Demangle(const char *mangled, char *out, size_t out_size) { } // Else the symbol wasn't inside a set of parentheses // We use the ANSI version to ensure the string type is always `char *`. return UnDecorateSymbolName(mangled, out, out_size, UNDNAME_COMPLETE); +#else + (void)mangled; + (void)out; + (void)out_size; + return false; +#endif #else State state; InitState(&state, mangled, out, out_size); diff --git a/src/demangle_unittest.cc b/src/demangle_unittest.cc index fe3974b13..ddc90b0a4 100644 --- a/src/demangle_unittest.cc +++ b/src/demangle_unittest.cc @@ -64,6 +64,7 @@ static const char *DemangleIt(const char * const mangled) { #if defined(GLOG_OS_WINDOWS) +#if defined(HAVE_DBGHELP) && !defined(NDEBUG) TEST(Demangle, Windows) { EXPECT_STREQ( "public: static void __cdecl Foo::func(int)", @@ -75,6 +76,7 @@ TEST(Demangle, Windows) { "int __cdecl foobarArray(int * const)", DemangleIt("?foobarArray@@YAHQAH@Z")); } +#endif #else diff --git a/src/glog/logging.h.in b/src/glog/logging.h.in index e64e44acd..c6762cf96 100644 --- a/src/glog/logging.h.in +++ b/src/glog/logging.h.in @@ -144,7 +144,7 @@ struct LogMessageTime { const time_t& timestamp() const { return ts; } const int& sec() const { return time_struct.tm_sec; } const int32_t& usec() const { return usecs; } - const int& min() const { return time_struct.tm_min; } + const int& (min)() const { return time_struct.tm_min; } const int& hour() const { return time_struct.tm_hour; } const int& day() const { return time_struct.tm_mday; } const int& month() const { return time_struct.tm_mon; } diff --git a/src/googletest.h b/src/googletest.h index 039474dca..f731770c6 100644 --- a/src/googletest.h +++ b/src/googletest.h @@ -565,7 +565,7 @@ class Thread { handle_ = CreateThread(NULL, 0, &Thread::InvokeThreadW, - (LPVOID)this, + this, 0, &th_); CHECK(handle_) << "CreateThread"; @@ -594,7 +594,7 @@ class Thread { } #if defined(GLOG_OS_WINDOWS) && !defined(GLOG_OS_CYGWIN) - static DWORD InvokeThreadW(void* self) { + static DWORD __stdcall InvokeThreadW(LPVOID self) { InvokeThread(self); return 0; } diff --git a/src/logging_custom_prefix_unittest.cc b/src/logging_custom_prefix_unittest.cc index fa822a2f6..a35fcd34a 100644 --- a/src/logging_custom_prefix_unittest.cc +++ b/src/logging_custom_prefix_unittest.cc @@ -1246,7 +1246,7 @@ TEST(DVLog, Basic) { // We are expecting that nothing is logged. EXPECT_CALL(log, Log(_, _, _)).Times(0); #else - EXPECT_CALL(log, Log(INFO, __FILE__, "debug log")); + EXPECT_CALL(log, Log(GLOG_INFO, __FILE__, "debug log")); #endif FLAGS_v = 1; @@ -1267,13 +1267,13 @@ TEST(LogAtLevel, Basic) { ScopedMockLog log; // The function version outputs "logging.h" as a file name. - EXPECT_CALL(log, Log(WARNING, StrNe(__FILE__), "function version")); - EXPECT_CALL(log, Log(INFO, __FILE__, "macro version")); + EXPECT_CALL(log, Log(GLOG_WARNING, StrNe(__FILE__), "function version")); + EXPECT_CALL(log, Log(GLOG_INFO, __FILE__, "macro version")); - int severity = WARNING; + int severity = GLOG_WARNING; LogAtLevel(severity, "function version"); - severity = INFO; + severity = GLOG_INFO; // We can use the macro version as a C++ stream. LOG_AT_LEVEL(severity) << "macro" << ' ' << "version"; } @@ -1294,9 +1294,9 @@ TEST(TestExitOnDFatal, ToBeOrNotToBe) { // downgraded to ERROR if not debugging. const LogSeverity severity = #ifdef NDEBUG - ERROR; + GLOG_ERROR; #else - FATAL; + GLOG_FATAL; #endif EXPECT_CALL(log, Log(severity, __FILE__, "This should not be fatal")); LOG(DFATAL) << "This should not be fatal"; diff --git a/src/logging_unittest.cc b/src/logging_unittest.cc index e20420a4e..0221814d7 100644 --- a/src/logging_unittest.cc +++ b/src/logging_unittest.cc @@ -1334,7 +1334,7 @@ TEST(DVLog, Basic) { // We are expecting that nothing is logged. EXPECT_CALL(log, Log(_, _, _)).Times(0); #else - EXPECT_CALL(log, Log(INFO, __FILE__, "debug log")); + EXPECT_CALL(log, Log(GLOG_INFO, __FILE__, "debug log")); #endif FLAGS_v = 1; @@ -1355,13 +1355,13 @@ TEST(LogAtLevel, Basic) { ScopedMockLog log; // The function version outputs "logging.h" as a file name. - EXPECT_CALL(log, Log(WARNING, StrNe(__FILE__), "function version")); - EXPECT_CALL(log, Log(INFO, __FILE__, "macro version")); + EXPECT_CALL(log, Log(GLOG_WARNING, StrNe(__FILE__), "function version")); + EXPECT_CALL(log, Log(GLOG_INFO, __FILE__, "macro version")); - int severity = WARNING; + int severity = GLOG_WARNING; LogAtLevel(severity, "function version"); - severity = INFO; + severity = GLOG_INFO; // We can use the macro version as a C++ stream. LOG_AT_LEVEL(severity) << "macro" << ' ' << "version"; } @@ -1382,9 +1382,9 @@ TEST(TestExitOnDFatal, ToBeOrNotToBe) { // downgraded to ERROR if not debugging. const LogSeverity severity = #ifdef NDEBUG - ERROR; + GLOG_ERROR; #else - FATAL; + GLOG_FATAL; #endif EXPECT_CALL(log, Log(severity, __FILE__, "This should not be fatal")); LOG(DFATAL) << "This should not be fatal"; diff --git a/src/mock-log_unittest.cc b/src/mock-log_unittest.cc index 88f6996c5..cb881ae65 100644 --- a/src/mock-log_unittest.cc +++ b/src/mock-log_unittest.cc @@ -40,9 +40,9 @@ namespace { -using GOOGLE_NAMESPACE::INFO; -using GOOGLE_NAMESPACE::WARNING; -using GOOGLE_NAMESPACE::ERROR; +using GOOGLE_NAMESPACE::GLOG_INFO; +using GOOGLE_NAMESPACE::GLOG_WARNING; +using GOOGLE_NAMESPACE::GLOG_ERROR; using GOOGLE_NAMESPACE::glog_testing::ScopedMockLog; using std::string; using testing::_; @@ -55,10 +55,10 @@ TEST(ScopedMockLogTest, InterceptsLog) { ScopedMockLog log; InSequence s; - EXPECT_CALL(log, Log(WARNING, HasSubstr("/mock-log_unittest.cc"), "Fishy.")); - EXPECT_CALL(log, Log(INFO, _, "Working...")) + EXPECT_CALL(log, Log(GLOG_WARNING, HasSubstr("/mock-log_unittest.cc"), "Fishy.")); + EXPECT_CALL(log, Log(GLOG_INFO, _, "Working...")) .Times(2); - EXPECT_CALL(log, Log(ERROR, _, "Bad!!")); + EXPECT_CALL(log, Log(GLOG_ERROR, _, "Bad!!")); LOG(WARNING) << "Fishy."; LOG(INFO) << "Working..."; @@ -86,13 +86,13 @@ void LogForest() { TEST(ScopedMockLogTest, LogDuringIntercept) { ScopedMockLog log; InSequence s; - EXPECT_CALL(log, Log(INFO, __FILE__, "Logging a branch...")) + EXPECT_CALL(log, Log(GLOG_INFO, __FILE__, "Logging a branch...")) .WillOnce(InvokeWithoutArgs(LogTree)); - EXPECT_CALL(log, Log(INFO, __FILE__, "Logging the whole tree...")) + EXPECT_CALL(log, Log(GLOG_INFO, __FILE__, "Logging the whole tree...")) .WillOnce(InvokeWithoutArgs(LogForest)); - EXPECT_CALL(log, Log(INFO, __FILE__, "Logging the entire forest.")); - EXPECT_CALL(log, Log(INFO, __FILE__, "Logging the entire forest..")); - EXPECT_CALL(log, Log(INFO, __FILE__, "Logging the entire forest...")); + EXPECT_CALL(log, Log(GLOG_INFO, __FILE__, "Logging the entire forest.")); + EXPECT_CALL(log, Log(GLOG_INFO, __FILE__, "Logging the entire forest..")); + EXPECT_CALL(log, Log(GLOG_INFO, __FILE__, "Logging the entire forest...")); LogBranch(); } diff --git a/src/symbolize_unittest.cc b/src/symbolize_unittest.cc index 985fabf07..2f93b335c 100644 --- a/src/symbolize_unittest.cc +++ b/src/symbolize_unittest.cc @@ -107,9 +107,12 @@ TEST(Symbolize, Symbolize) { // The name of an internal linkage symbol is not specified; allow either a // mangled or an unmangled name here. const char *static_func_symbol = TrySymbolize((void *)(&static_func)); + +#if !defined(_MSC_VER) || !defined(NDEBUG) CHECK(NULL != static_func_symbol); EXPECT_TRUE(strcmp("static_func", static_func_symbol) == 0 || strcmp("static_func()", static_func_symbol) == 0); +#endif EXPECT_TRUE(NULL == TrySymbolize(NULL)); } @@ -128,7 +131,9 @@ void ATTRIBUTE_NOINLINE Foo::func(int x) { #ifdef TEST_WITH_MODERN_GCC TEST(Symbolize, SymbolizeWithDemangling) { Foo::func(100); +#if !defined(_MSC_VER) || !defined(NDEBUG) EXPECT_STREQ("Foo::func()", TrySymbolize((void *)(&Foo::func))); +#endif } #endif @@ -332,8 +337,11 @@ static void ATTRIBUTE_NOINLINE TestWithPCInsideNonInlineFunction() { #if defined(TEST_X86_32_AND_64) && defined(HAVE_ATTRIBUTE_NOINLINE) void *pc = non_inline_func(); const char *symbol = TrySymbolize(pc); + +#if !defined(_MSC_VER) || !defined(NDEBUG) CHECK(symbol != NULL); CHECK_STREQ(symbol, "non_inline_func"); +#endif cout << "Test case TestWithPCInsideNonInlineFunction passed." << endl; #endif } @@ -342,8 +350,11 @@ static void ATTRIBUTE_NOINLINE TestWithPCInsideInlineFunction() { #if defined(TEST_X86_32_AND_64) && defined(HAVE_ALWAYS_INLINE) void *pc = inline_func(); // Must be inlined. const char *symbol = TrySymbolize(pc); + +#if !defined(_MSC_VER) || !defined(NDEBUG) CHECK(symbol != NULL); CHECK_STREQ(symbol, __FUNCTION__); +#endif cout << "Test case TestWithPCInsideInlineFunction passed." << endl; #endif } @@ -354,8 +365,11 @@ static void ATTRIBUTE_NOINLINE TestWithReturnAddress() { #if defined(HAVE_ATTRIBUTE_NOINLINE) void *return_address = __builtin_return_address(0); const char *symbol = TrySymbolize(return_address); + +#if !defined(_MSC_VER) || !defined(NDEBUG) CHECK(symbol != NULL); CHECK_STREQ(symbol, "main"); +#endif cout << "Test case TestWithReturnAddress passed." << endl; #endif } @@ -379,7 +393,10 @@ __declspec(noinline) void Foo::func(int x) { TEST(Symbolize, SymbolizeWithDemangling) { Foo::func(100); const char* ret = TrySymbolize((void *)(&Foo::func)); + +#if defined(HAVE_DBGHELP) && !defined(NDEBUG) EXPECT_STREQ("public: static void __cdecl Foo::func(int)", ret); +#endif } __declspec(noinline) void TestWithReturnAddress() { @@ -391,8 +408,10 @@ __declspec(noinline) void TestWithReturnAddress() { #endif ; const char *symbol = TrySymbolize(return_address); +#if !defined(_MSC_VER) || !defined(NDEBUG) CHECK(symbol != NULL); CHECK_STREQ(symbol, "main"); +#endif cout << "Test case TestWithReturnAddress passed." << endl; } # endif // __ELF__ diff --git a/src/utilities.cc b/src/utilities.cc index c5dd863fb..a332f1a19 100644 --- a/src/utilities.cc +++ b/src/utilities.cc @@ -292,7 +292,7 @@ pid_t GetTID() { #if defined GLOG_OS_LINUX return getpid(); // Linux: getpid returns thread ID when gettid is absent #elif defined GLOG_OS_WINDOWS && !defined GLOG_OS_CYGWIN - return GetCurrentThreadId(); + return static_cast(GetCurrentThreadId()); #elif defined(HAVE_PTHREAD) // If none of the techniques above worked, we use pthread_self(). return (pid_t)(uintptr_t)pthread_self();