From 2f852f5d5eead05028d54e827fd0695f64cf4681 Mon Sep 17 00:00:00 2001 From: Wink Saville Date: Thu, 29 Oct 2020 13:06:37 -0700 Subject: [PATCH] Update README.md, add .gitignore reformat build_cmake.yml - Add instructions to README.md to build locally on Linux - Add .gitignore to ignore build/ and bin/ - Used Redhad YAML extension to reformat build_cmake.yml --- .github/workflows/build_cmake.yml | 547 +++++++++++++++--------------- .gitignore | 2 + README.md | 81 +++++ 3 files changed, 361 insertions(+), 269 deletions(-) create mode 100644 .gitignore diff --git a/.github/workflows/build_cmake.yml b/.github/workflows/build_cmake.yml index 437a6b5..f930509 100644 --- a/.github/workflows/build_cmake.yml +++ b/.github/workflows/build_cmake.yml @@ -16,220 +16,225 @@ jobs: fail-fast: false matrix: config: - - { - name: "Windows Latest MSVC", artifact: "Windows-MSVC.7z", - os: windows-latest, - cc: "cl", cxx: "cl", - environment_script: "C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Auxiliary/Build/vcvars64.bat" - } - - { - name: "Windows Latest MinGW", artifact: "Windows-MinGW.7z", - os: windows-latest, - cc: "gcc", cxx: "g++" - } - - { - name: "Ubuntu Latest GCC", artifact: "Linux.7z", - os: ubuntu-latest, - cc: "gcc", cxx: "g++" - } - - { - name: "macOS Latest Clang", artifact: "macOS.7z", - os: macos-latest, - cc: "clang", cxx: "clang++" - } + - { + name: "Windows Latest MSVC", + artifact: "Windows-MSVC.7z", + os: windows-latest, + cc: "cl", + cxx: "cl", + environment_script: "C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Auxiliary/Build/vcvars64.bat", + } + - { + name: "Windows Latest MinGW", + artifact: "Windows-MinGW.7z", + os: windows-latest, + cc: "gcc", + cxx: "g++", + } + - { + name: "Ubuntu Latest GCC", + artifact: "Linux.7z", + os: ubuntu-latest, + cc: "gcc", + cxx: "g++", + } + - { + name: "macOS Latest Clang", + artifact: "macOS.7z", + os: macos-latest, + cc: "clang", + cxx: "clang++", + } steps: - - uses: actions/checkout@v1 - - - name: Download Ninja and CMake - shell: cmake -P {0} - run: | - set(cmake_version $ENV{CMAKE_VERSION}) - set(ninja_version $ENV{NINJA_VERSION}) - - message(STATUS "Using host CMake version: ${CMAKE_VERSION}") - - if ("${{ runner.os }}" STREQUAL "Windows") - set(ninja_suffix "win.zip") - set(cmake_suffix "win64-x64.zip") - set(cmake_dir "cmake-${cmake_version}-win64-x64/bin") - elseif ("${{ runner.os }}" STREQUAL "Linux") - set(ninja_suffix "linux.zip") - set(cmake_suffix "Linux-x86_64.tar.gz") - set(cmake_dir "cmake-${cmake_version}-Linux-x86_64/bin") - elseif ("${{ runner.os }}" STREQUAL "macOS") - set(ninja_suffix "mac.zip") - set(cmake_suffix "Darwin-x86_64.tar.gz") - set(cmake_dir "cmake-${cmake_version}-Darwin-x86_64/CMake.app/Contents/bin") - endif() - - set(ninja_url "https://github.com/ninja-build/ninja/releases/download/v${ninja_version}/ninja-${ninja_suffix}") - file(DOWNLOAD "${ninja_url}" ./ninja.zip SHOW_PROGRESS) - execute_process(COMMAND ${CMAKE_COMMAND} -E tar xvf ./ninja.zip) - - set(cmake_url "https://github.com/Kitware/CMake/releases/download/v${cmake_version}/cmake-${cmake_version}-${cmake_suffix}") - file(DOWNLOAD "${cmake_url}" ./cmake.zip SHOW_PROGRESS) - execute_process(COMMAND ${CMAKE_COMMAND} -E tar xvf ./cmake.zip) - - # Add to PATH environment variable - file(TO_CMAKE_PATH "$ENV{GITHUB_WORKSPACE}/${cmake_dir}" cmake_dir) - set(path_separator ":") - if ("${{ runner.os }}" STREQUAL "Windows") - set(path_separator ";") - endif() - file(APPEND "$ENV{GITHUB_PATH}" "$ENV{GITHUB_WORKSPACE}${path_separator}${cmake_dir}") - - if (NOT "${{ runner.os }}" STREQUAL "Windows") + - uses: actions/checkout@v1 + + - name: Download Ninja and CMake + shell: cmake -P {0} + run: | + set(cmake_version $ENV{CMAKE_VERSION}) + set(ninja_version $ENV{NINJA_VERSION}) + + message(STATUS "Using host CMake version: ${CMAKE_VERSION}") + + if ("${{ runner.os }}" STREQUAL "Windows") + set(ninja_suffix "win.zip") + set(cmake_suffix "win64-x64.zip") + set(cmake_dir "cmake-${cmake_version}-win64-x64/bin") + elseif ("${{ runner.os }}" STREQUAL "Linux") + set(ninja_suffix "linux.zip") + set(cmake_suffix "Linux-x86_64.tar.gz") + set(cmake_dir "cmake-${cmake_version}-Linux-x86_64/bin") + elseif ("${{ runner.os }}" STREQUAL "macOS") + set(ninja_suffix "mac.zip") + set(cmake_suffix "Darwin-x86_64.tar.gz") + set(cmake_dir "cmake-${cmake_version}-Darwin-x86_64/CMake.app/Contents/bin") + endif() + + set(ninja_url "https://github.com/ninja-build/ninja/releases/download/v${ninja_version}/ninja-${ninja_suffix}") + file(DOWNLOAD "${ninja_url}" ./ninja.zip SHOW_PROGRESS) + execute_process(COMMAND ${CMAKE_COMMAND} -E tar xvf ./ninja.zip) + + set(cmake_url "https://github.com/Kitware/CMake/releases/download/v${cmake_version}/cmake-${cmake_version}-${cmake_suffix}") + file(DOWNLOAD "${cmake_url}" ./cmake.zip SHOW_PROGRESS) + execute_process(COMMAND ${CMAKE_COMMAND} -E tar xvf ./cmake.zip) + + # Add to PATH environment variable + file(TO_CMAKE_PATH "$ENV{GITHUB_WORKSPACE}/${cmake_dir}" cmake_dir) + set(path_separator ":") + if ("${{ runner.os }}" STREQUAL "Windows") + set(path_separator ";") + endif() + file(APPEND "$ENV{GITHUB_PATH}" "$ENV{GITHUB_WORKSPACE}${path_separator}${cmake_dir}") + + if (NOT "${{ runner.os }}" STREQUAL "Windows") + execute_process( + COMMAND chmod +x ninja + COMMAND chmod +x ${cmake_dir}/cmake + ) + endif() + + - name: Download ccache + id: ccache + shell: cmake -P {0} + run: | + set(ccache_url "https://github.com/cristianadam/ccache/releases/download/v$ENV{CCACHE_VERSION}/${{ runner.os }}.tar.xz") + file(DOWNLOAD "${ccache_url}" ./ccache.tar.xz SHOW_PROGRESS) + execute_process(COMMAND ${CMAKE_COMMAND} -E tar xvf ./ccache.tar.xz) + + - name: Prepare ccache timestamp + id: ccache_cache_timestamp + shell: cmake -P {0} + run: | + string(TIMESTAMP current_date "%Y-%m-%d-%H;%M;%S" UTC) + message("::set-output name=timestamp::${current_date}") + + - name: ccache cache files + uses: actions/cache@v1.1.0 + with: + path: .ccache + key: ${{ matrix.config.name }}-ccache-${{ steps.ccache_cache_timestamp.outputs.timestamp }} + restore-keys: | + ${{ matrix.config.name }}-ccache- + + - name: Configure + shell: cmake -P {0} + run: | + set(ENV{CC} ${{ matrix.config.cc }}) + set(ENV{CXX} ${{ matrix.config.cxx }}) + + if ("${{ runner.os }}" STREQUAL "Windows" AND NOT "x${{ matrix.config.environment_script }}" STREQUAL "x") + execute_process( + COMMAND "${{ matrix.config.environment_script }}" && set + OUTPUT_FILE environment_script_output.txt + ) + file(STRINGS environment_script_output.txt output_lines) + foreach(line IN LISTS output_lines) + if (line MATCHES "^([a-zA-Z0-9_-]+)=(.*)$") + set(ENV{${CMAKE_MATCH_1}} "${CMAKE_MATCH_2}") + endif() + endforeach() + endif() + + set(path_separator ":") + if ("${{ runner.os }}" STREQUAL "Windows") + set(path_separator ";") + endif() + set(ENV{PATH} "$ENV{GITHUB_WORKSPACE}${path_separator}$ENV{PATH}") + + execute_process( + COMMAND cmake + -S . + -B build + -D CMAKE_BUILD_TYPE=$ENV{BUILD_TYPE} + -G Ninja + -D CMAKE_MAKE_PROGRAM=ninja + -D CMAKE_C_COMPILER_LAUNCHER=ccache + -D CMAKE_CXX_COMPILER_LAUNCHER=ccache + RESULT_VARIABLE result + ) + if (NOT result EQUAL 0) + message(FATAL_ERROR "Bad exit status") + endif() + + - name: Build + shell: cmake -P {0} + run: | + set(ENV{NINJA_STATUS} "[%f/%t %o/sec] ") + + if ("${{ runner.os }}" STREQUAL "Windows" AND NOT "x${{ matrix.config.environment_script }}" STREQUAL "x") + file(STRINGS environment_script_output.txt output_lines) + foreach(line IN LISTS output_lines) + if (line MATCHES "^([a-zA-Z0-9_-]+)=(.*)$") + set(ENV{${CMAKE_MATCH_1}} "${CMAKE_MATCH_2}") + endif() + endforeach() + endif() + + file(TO_CMAKE_PATH "$ENV{GITHUB_WORKSPACE}" ccache_basedir) + set(ENV{CCACHE_BASEDIR} "${ccache_basedir}") + set(ENV{CCACHE_DIR} "${ccache_basedir}/.ccache") + set(ENV{CCACHE_COMPRESS} "true") + set(ENV{CCACHE_COMPRESSLEVEL} "6") + set(ENV{CCACHE_MAXSIZE} "400M") + if ("${{ matrix.config.cxx }}" STREQUAL "cl") + set(ENV{CCACHE_MAXSIZE} "600M") + endif() + + execute_process(COMMAND ccache -p) + execute_process(COMMAND ccache -z) + execute_process( - COMMAND chmod +x ninja - COMMAND chmod +x ${cmake_dir}/cmake + COMMAND cmake --build build + RESULT_VARIABLE result + OUTPUT_VARIABLE output + ERROR_VARIABLE output + ECHO_OUTPUT_VARIABLE ECHO_ERROR_VARIABLE ) - endif() - - - name: Download ccache - id: ccache - shell: cmake -P {0} - run: | - set(ccache_url "https://github.com/cristianadam/ccache/releases/download/v$ENV{CCACHE_VERSION}/${{ runner.os }}.tar.xz") - file(DOWNLOAD "${ccache_url}" ./ccache.tar.xz SHOW_PROGRESS) - execute_process(COMMAND ${CMAKE_COMMAND} -E tar xvf ./ccache.tar.xz) - - - name: Prepare ccache timestamp - id: ccache_cache_timestamp - shell: cmake -P {0} - run: | - string(TIMESTAMP current_date "%Y-%m-%d-%H;%M;%S" UTC) - message("::set-output name=timestamp::${current_date}") - - - name: ccache cache files - uses: actions/cache@v1.1.0 - with: - path: .ccache - key: ${{ matrix.config.name }}-ccache-${{ steps.ccache_cache_timestamp.outputs.timestamp }} - restore-keys: | - ${{ matrix.config.name }}-ccache- - - - name: Configure - shell: cmake -P {0} - run: | - set(ENV{CC} ${{ matrix.config.cc }}) - set(ENV{CXX} ${{ matrix.config.cxx }}) - - if ("${{ runner.os }}" STREQUAL "Windows" AND NOT "x${{ matrix.config.environment_script }}" STREQUAL "x") + if (NOT result EQUAL 0) + string(REGEX MATCH "FAILED:.*$" error_message "${output}") + string(REPLACE "\n" "%0A" error_message "${error_message}") + message("::error::${error_message}") + message(FATAL_ERROR "Build failed") + endif() + + execute_process(COMMAND ccache -s) + + - name: Run tests + shell: cmake -P {0} + run: | + include(ProcessorCount) + ProcessorCount(N) + + set(ENV{CTEST_OUTPUT_ON_FAILURE} "ON") + execute_process( - COMMAND "${{ matrix.config.environment_script }}" && set - OUTPUT_FILE environment_script_output.txt + COMMAND ctest -j ${N} + WORKING_DIRECTORY build + RESULT_VARIABLE result + OUTPUT_VARIABLE output + ERROR_VARIABLE output + ECHO_OUTPUT_VARIABLE ECHO_ERROR_VARIABLE ) - file(STRINGS environment_script_output.txt output_lines) - foreach(line IN LISTS output_lines) - if (line MATCHES "^([a-zA-Z0-9_-]+)=(.*)$") - set(ENV{${CMAKE_MATCH_1}} "${CMAKE_MATCH_2}") - endif() - endforeach() - endif() - - set(path_separator ":") - if ("${{ runner.os }}" STREQUAL "Windows") - set(path_separator ";") - endif() - set(ENV{PATH} "$ENV{GITHUB_WORKSPACE}${path_separator}$ENV{PATH}") - - execute_process( - COMMAND cmake - -S . - -B build - -D CMAKE_BUILD_TYPE=$ENV{BUILD_TYPE} - -G Ninja - -D CMAKE_MAKE_PROGRAM=ninja - -D CMAKE_C_COMPILER_LAUNCHER=ccache - -D CMAKE_CXX_COMPILER_LAUNCHER=ccache - RESULT_VARIABLE result - ) - if (NOT result EQUAL 0) - message(FATAL_ERROR "Bad exit status") - endif() - - - - name: Build - shell: cmake -P {0} - run: | - set(ENV{NINJA_STATUS} "[%f/%t %o/sec] ") - - if ("${{ runner.os }}" STREQUAL "Windows" AND NOT "x${{ matrix.config.environment_script }}" STREQUAL "x") - file(STRINGS environment_script_output.txt output_lines) - foreach(line IN LISTS output_lines) - if (line MATCHES "^([a-zA-Z0-9_-]+)=(.*)$") - set(ENV{${CMAKE_MATCH_1}} "${CMAKE_MATCH_2}") - endif() - endforeach() - endif() - - file(TO_CMAKE_PATH "$ENV{GITHUB_WORKSPACE}" ccache_basedir) - set(ENV{CCACHE_BASEDIR} "${ccache_basedir}") - set(ENV{CCACHE_DIR} "${ccache_basedir}/.ccache") - set(ENV{CCACHE_COMPRESS} "true") - set(ENV{CCACHE_COMPRESSLEVEL} "6") - set(ENV{CCACHE_MAXSIZE} "400M") - if ("${{ matrix.config.cxx }}" STREQUAL "cl") - set(ENV{CCACHE_MAXSIZE} "600M") - endif() - - execute_process(COMMAND ccache -p) - execute_process(COMMAND ccache -z) - - execute_process( - COMMAND cmake --build build - RESULT_VARIABLE result - OUTPUT_VARIABLE output - ERROR_VARIABLE output - ECHO_OUTPUT_VARIABLE ECHO_ERROR_VARIABLE - ) - if (NOT result EQUAL 0) - string(REGEX MATCH "FAILED:.*$" error_message "${output}") - string(REPLACE "\n" "%0A" error_message "${error_message}") - message("::error::${error_message}") - message(FATAL_ERROR "Build failed") - endif() - - execute_process(COMMAND ccache -s) - - - name: Run tests - shell: cmake -P {0} - run: | - include(ProcessorCount) - ProcessorCount(N) - - set(ENV{CTEST_OUTPUT_ON_FAILURE} "ON") - - execute_process( - COMMAND ctest -j ${N} - WORKING_DIRECTORY build - RESULT_VARIABLE result - OUTPUT_VARIABLE output - ERROR_VARIABLE output - ECHO_OUTPUT_VARIABLE ECHO_ERROR_VARIABLE - ) - if (NOT result EQUAL 0) - string(REGEX MATCH "[0-9]+% tests.*[0-9.]+ sec.*$" test_results "${output}") - string(REPLACE "\n" "%0A" test_results "${test_results}") - message("::error::${test_results}") - message(FATAL_ERROR "Running tests failed!") - endif() - - - name: Install Strip - run: cmake --install build --prefix instdir --strip - - - - name: Pack - working-directory: instdir - run: cmake -E tar cfv ../${{ matrix.config.artifact }} --format=7zip . - - - - name: Upload - uses: actions/upload-artifact@v1 - with: - path: ./${{ matrix.config.artifact }} - name: ${{ matrix.config.artifact }} + if (NOT result EQUAL 0) + string(REGEX MATCH "[0-9]+% tests.*[0-9.]+ sec.*$" test_results "${output}") + string(REPLACE "\n" "%0A" test_results "${test_results}") + message("::error::${test_results}") + message(FATAL_ERROR "Running tests failed!") + endif() + + - name: Install Strip + run: cmake --install build --prefix instdir --strip + + - name: Pack + working-directory: instdir + run: cmake -E tar cfv ../${{ matrix.config.artifact }} --format=7zip . + + - name: Upload + uses: actions/upload-artifact@v1 + with: + path: ./${{ matrix.config.artifact }} + name: ${{ matrix.config.artifact }} release: if: contains(github.ref, 'tags/v') @@ -237,25 +242,25 @@ jobs: needs: build steps: - - name: Create Release - id: create_release - uses: actions/create-release@v1.0.0 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: ${{ github.ref }} - release_name: Release ${{ github.ref }} - draft: false - prerelease: false - - - name: Store Release url - run: | - echo "${{ steps.create_release.outputs.upload_url }}" > ./upload_url - - - uses: actions/upload-artifact@v1 - with: - path: ./upload_url - name: upload_url + - name: Create Release + id: create_release + uses: actions/create-release@v1.0.0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ github.ref }} + release_name: Release ${{ github.ref }} + draft: false + prerelease: false + + - name: Store Release url + run: | + echo "${{ steps.create_release.outputs.upload_url }}" > ./upload_url + + - uses: actions/upload-artifact@v1 + with: + path: ./upload_url + name: upload_url publish: if: contains(github.ref, 'tags/v') @@ -265,48 +270,52 @@ jobs: fail-fast: false matrix: config: - - { - name: "Windows Latest MSVC", artifact: "Windows-MSVC.7z", - os: ubuntu-latest - } - - { - name: "Windows Latest MinGW", artifact: "Windows-MinGW.7z", - os: ubuntu-latest - } - - { - name: "Ubuntu Latest GCC", artifact: "Linux.7z", - os: ubuntu-latest - } - - { - name: "macOS Latest Clang", artifact: "macOS.7z", - os: ubuntu-latest - } + - { + name: "Windows Latest MSVC", + artifact: "Windows-MSVC.7z", + os: ubuntu-latest, + } + - { + name: "Windows Latest MinGW", + artifact: "Windows-MinGW.7z", + os: ubuntu-latest, + } + - { + name: "Ubuntu Latest GCC", + artifact: "Linux.7z", + os: ubuntu-latest, + } + - { + name: "macOS Latest Clang", + artifact: "macOS.7z", + os: ubuntu-latest, + } needs: release steps: - - name: Download artifact - uses: actions/download-artifact@v1 - with: - name: ${{ matrix.config.artifact }} - path: ./ - - - name: Download URL - uses: actions/download-artifact@v1 - with: - name: upload_url - path: ./ - - id: set_upload_url - run: | - upload_url=`cat ./upload_url` - echo ::set-output name=upload_url::$upload_url - - - name: Upload to Release - id: upload_to_release - uses: actions/upload-release-asset@v1.0.1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ steps.set_upload_url.outputs.upload_url }} - asset_path: ./${{ matrix.config.artifact }} - asset_name: ${{ matrix.config.artifact }} - asset_content_type: application/x-gtar + - name: Download artifact + uses: actions/download-artifact@v1 + with: + name: ${{ matrix.config.artifact }} + path: ./ + + - name: Download URL + uses: actions/download-artifact@v1 + with: + name: upload_url + path: ./ + - id: set_upload_url + run: | + upload_url=`cat ./upload_url` + echo ::set-output name=upload_url::$upload_url + + - name: Upload to Release + id: upload_to_release + uses: actions/upload-release-asset@v1.0.1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.set_upload_url.outputs.upload_url }} + asset_path: ./${{ matrix.config.artifact }} + asset_name: ${{ matrix.config.artifact }} + asset_content_type: application/x-gtar diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d5697ec --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +build/ +bin/ diff --git a/README.md b/README.md index 74ab0aa..d7a20fc 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,83 @@ # HelloWorld A C++ Hello World project, using CMake, ninja, ccache, and GitHub Actions. + +## Instructions to build, test, install and run locally on Linux + +**Prerequisites:** +- cmake 3.18.3+ +- Ninja 1.10.1+ +- g++/gcc + +**Clean:** +``` +$ rm -rf build/ bin/ +``` + +**Prepare build to install in current directory:** +``` +cmake -S . -B build -G Ninja -DCMAKE_INSTALL_PREFIX=. +``` + +**Build locally:** +``` +cmake --build build +``` + +**Test:** +``` +(cd build ; ctest) +``` + +**Install:** +``` +cmake --install build +``` + +**Run:** +``` +./bin/main +``` + +**Example output:** +``` +$ rm -rf build/ bin/ + +$ cmake -S . -B build -DCMAKE_INSTALL_PREFIX=. +-- The C compiler identification is GNU 10.2.0 +-- The CXX compiler identification is GNU 10.2.0 +-- Detecting C compiler ABI info +-- Detecting C compiler ABI info - done +-- Check for working C compiler: /usr/bin/cc - skipped +-- Detecting C compile features +-- Detecting C compile features - done +-- Detecting CXX compiler ABI info +-- Detecting CXX compiler ABI info - done +-- Check for working CXX compiler: /usr/bin/c++ - skipped +-- Detecting CXX compile features +-- Detecting CXX compile features - done +-- Configuring done +-- Generating done +-- Build files have been written to: /home/wink/prgs/cmake/projects/gha-cmake-HelloWorld/build + +$ cmake --build build +Scanning dependencies of target main +[ 50%] Building CXX object CMakeFiles/main.dir/main.cpp.o +[100%] Linking CXX executable main +[100%] Built target main + +$ (cd build ; ctest) +Test project /home/wink/prgs/cmake/projects/gha-cmake-HelloWorld/build + Start 1: main +1/1 Test #1: main ............................. Passed 0.00 sec + +100% tests passed, 0 tests failed out of 1 + +Total Test time (real) = 0.00 sec + +$ cmake --install build +-- Install configuration: "" +-- Installing: /home/wink/prgs/cmake/projects/gha-cmake-HelloWorld/bin/main + +$ ./bin/main +Hello world +```