Build and test a multiplatform C++ project with GitHub Actions

In this tutorial, I will give you the instruction how I set up CI/CD to build and test my C++ multiplatform game engine named NeoSekaiEngine with GitHub Actions.

Note: The original post is at LinkedIn: Link here

Oh wait! What is NeoSekaiEngine?

NeoSekaiEngine is my 2D game engine built base on what I know about game development. This game engine is written in C++ and can run on Windows, Linux and Web platform.

Here the link for the repository if you are interested. Link

Let get started

First at all, set thing up by creating a file named build_test.yaml in the folder .github/workflows

Checkout the code

In the build_test.yaml file, we configure it to clone the source code first.

name: Build and Test Engine
run-name: ${{ github.ref }} on ${{ github.repository }} is being built and tested out Github actions
on: [ push ]
jobs: Build-Engine: runs-on: ubuntu-latest steps: - run: echo "The job was automatically triggered by a ${{ github.event_name }} event." - name: Check out the repository code uses: actions/checkout@v4 - run: echo "The ${{ github.repository }} repository has been cloned to the runner." - name: Check repository run: ls ${{ github.workspace }} 
Enter fullscreen mode
Exit fullscreen mode

Let see what inside here

  • name: The name of the workflow.
  • run-name: The name for workflow runs generated from the workflow.
  • on: It defines which event can causes workflow runs. In this file, workflow run when you push your code.
  • jobs: This sections is defined the jobs of the workflow.
  • runs-on: The platform the the workflow runs on.
  • steps: The instructions to executing the job

And here is the result.

Summary for checking out the code

Build Engine jobs for checking out the code

Install the dependencies

Because at that moment, I built for single platform(Ubuntu). Let’s install dependencies.

name: Build and Test Engine
run-name: ${{ github.ref }} on ${{ github.repository }} is being built and tested out Github actions
on: [ push ]
jobs: Build-Engine: runs-on: ubuntu-latest steps: - run: echo "The job was automatically triggered by a ${{ github.event_name }} event." - name: Check out the repository code uses: actions/checkout@v4 - name: setup library run: /bin/bash ./scripts/pre-installer/linux/debian/preinstaller.sh 
Enter fullscreen mode
Exit fullscreen mode

And here is the result.

Summary for installing dependencies

Build Engine job for installing dependencies

Build and run test

It seemed like everything good. Let build and run test.

name: Build and Test Engine
run-name: ${{ github.ref }} on ${{ github.repository }} is being built and tested out Github actions
on: [ push ]
jobs: Build-Engine: runs-on: ubuntu-latest steps: - run: echo "The job was automatically triggered by a ${{ github.event_name }} event." - name: Check out the repository code uses: actions/checkout@v4 - name: setup library run: /bin/bash ./scripts/pre-installer/linux/debian/preinstaller.sh - name: build project with test for static lib run: cmake -S ./ -B ./build -DRUN_TEST=1 -DBUILD_SHARED_LIBS=0 && cmake --build ./build - name: run test run: build/out/engine_test --gtest_output="xml:build/test-results.xml"
Enter fullscreen mode
Exit fullscreen mode

Here is the result.

Summary of building and testing

Build Engine job for building and testing

Create artifacts

After running test, we need something to get the result and storing into artifacts is a good idea. By using actions/upload-artifact@v4, you can store file in artifacts.

name: Build and Test Engine
run-name: ${{ github.ref }} on ${{ github.repository }} is being built and tested out Github actions
on: [ push ]
jobs: Build-Engine: runs-on: ubuntu-latest steps: - run: echo "The job was automatically triggered by a ${{ github.event_name }} event." - name: Check out the repository code uses: actions/checkout@v4 - name: setup library run: /bin/bash ./scripts/pre-installer/linux/debian/preinstaller.sh - name: build project with test for static lib run: cmake -S ./ -B ./build -DRUN_TEST=1 -DBUILD_SHARED_LIBS=0 && cmake --build ./build - name: run test run: build/out/engine_test --gtest_output="xml:build/test-results.xml" - name: Upload test result uses: actions/upload-artifact@v4 with: name: test-results-ubuntu-static.xml path: build/test-results.xml
Enter fullscreen mode
Exit fullscreen mode

And here is the result

Build Engine job for creating artifacts

Run workflows for multiplatform

After completing a workflow for a single platform, let make it for multiple one.

name: Build and Test Engine
run-name: ${{ github.ref }} on ${{ github.repository }} is being built and tested out Github actions
on: [ push ]
jobs: Build-Engine: strategy: fail-fast: false matrix: build_shared: [0, 1] os: [ubuntu-latest, windows-latest] runs-on: ${{ matrix.os }} steps: - run: echo "The job was automatically triggered by a ${{ github.event_name }} event." - name: Check out the repository code uses: actions/checkout@v4 - name: setup library if: ${{ matrix.os != 'windows-latest' }} run: /bin/bash ./scripts/pre-installer/linux/debian/preinstaller.sh - name: build project with test for BUILD_SHARED_LIBS=${{ matrix.build_shared }} run: cmake -S ./ -B ./build -DRUN_TEST=1 -DBUILD_SHARED_LIBS=${{ matrix.build_shared }} && cmake --build ./build - name: run test if: ${{ matrix.os != 'windows-latest' }} run: build/out/engine_test --gtest_output="xml:build/test-results.xml" - name: run test if: ${{ matrix.os == 'windows-latest' }} run: .\build\out\Debug\engine_test.exe --gtest_output="xml:build/test-results.xml" - name: Upload test result if: ${{ matrix.build_shared == 0 }} uses: actions/upload-artifact@v4 with: name: test-results-${{matrix.os}}-static.xml path: build/test-results.xml - name: Upload test result if: ${{ matrix.build_shared == 1 }} uses: actions/upload-artifact@v4 with: name: test-results-${{matrix.os}}-shared.xml path: build/test-results.xml
Enter fullscreen mode
Exit fullscreen mode

Here we can see something new named matrix. This is a strategy on GitHub Actions that helps you use variables in a single job definition to automatically create multiple job runs that are based on the combinations of the variables.

Here is the result

Summary of building for multiplatform

Inconclusion

Here is all the instructions how I built and test my multiplatform project using GitHub Actions. Hope you learn something from it.

See you in next article.


Discover more from Coursity

Subscribe to get the latest posts sent to your email.

Leave a Comment

Your email address will not be published. Required fields are marked *

Discover more from Coursity

Subscribe now to keep reading and get access to the full archive.

Continue reading

Scroll to Top