Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 34 additions & 44 deletions .github/workflows/cmake.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,15 @@ jobs:
# Set fail-fast to false to ensure that feedback is delivered for all matrix combinations. Consider changing this to true when your workflow is stable.
fail-fast: false

# Set up a matrix to run the following 3 configurations:
# 1. <Windows, Release, latest MSVC compiler toolchain on the default runner image, default generator>
# 2. <Linux, Release, latest GCC compiler toolchain on the default runner image, default generator>
# 3. <Linux, Release, latest Clang compiler toolchain on the default runner image, default generator>
#
# To add more build types (Release, Debug, RelWithDebInfo, etc.) customize the build_type list.
# Set up a matrix to run the following configurations:
# - Multiple platforms (Windows, Linux, macOS)
# - Multiple compilers (cl, gcc, clang)
# - Multiple library types (static, shared)
matrix:
os: [ubuntu-latest, windows-latest, macOS-latest]
build_type: ${{ fromJSON(format('[{0}]', inputs.build_type || '"Debug","Release"')) }}
c_compiler: [gcc, clang, cl]
lib_type: [static, shared]
include:
- os: windows-latest
c_compiler: cl
Expand Down Expand Up @@ -70,22 +69,27 @@ jobs:
shell: bash
run: |
echo "build-output-dir=${{ github.workspace }}/build" >> "$GITHUB_OUTPUT"
# Map OS to platform
if [ "${{ matrix.os }}" == "ubuntu-latest" ]; then
echo "platform=linux_x64" >> "$GITHUB_OUTPUT"
elif [ "${{ matrix.os }}" == "windows-latest" ]; then
echo "platform=win64" >> "$GITHUB_OUTPUT"
elif [ "${{ matrix.os }}" == "macOS-latest" ]; then
echo "platform=osx" >> "$GITHUB_OUTPUT"
fi

- name: Install Clang and Libraries
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.x'

- name: Install libc++ on Ubuntu
if: matrix.os == 'ubuntu-latest' && matrix.c_compiler == 'clang'
run: |
sudo apt-get update
sudo apt-get install -y clang libc++-dev libc++abi-dev
sudo apt-get install -y libc++-dev libc++abi-dev

- name: Set Clang 16 as Default
if: matrix.os == 'ubuntu-24.04' && matrix.c_compiler == 'clang'
run: |
sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-16 100
sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-16 100
sudo update-alternatives --set clang /usr/bin/clang-16
sudo update-alternatives --set clang++ /usr/bin/clang++-16

- name: Check Clang Settings
- name: Display Clang Info
if: matrix.os == 'ubuntu-latest' && matrix.c_compiler == 'clang'
run: |
clang --version
Expand All @@ -95,39 +99,25 @@ jobs:
echo "check lld..."
ldd --version

- name: Configure CMake
# Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make.
# See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
run: >
cmake -B ${{ steps.strings.outputs.build-output-dir }}
-DCMAKE_CXX_COMPILER=${{ matrix.cpp_compiler }}
-DCMAKE_C_COMPILER=${{ matrix.c_compiler }}
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
-S ${{ github.workspace }}

- name: Build
# Build your program with the given configuration. Note that --config is needed because the default Windows generator is a multi-config generator (Visual Studio generator).
run: cmake --build ${{ steps.strings.outputs.build-output-dir }} --config ${{ matrix.build_type }} --verbose

- name: Test
working-directory: ${{ steps.strings.outputs.build-output-dir }}
# Execute tests defined by the CMake configuration. Note that --build-config is needed because the default Windows generator is a multi-config generator (Visual Studio generator).
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
run: ctest --build-config ${{ matrix.build_type }} --verbose --output-on-failure

- name: Package Build Artifacts
if: ${{ inputs.upload_artifacts && success() }}
- name: Build, Test, and Package with setup.py
shell: bash
run: |
mkdir -p ${{ steps.strings.outputs.build-output-dir }}/package
# Adjust the path to your built library files
cp ${{ steps.strings.outputs.build-output-dir }}/${{ matrix.build_type }}/*GameAnalytics.* ${{ steps.strings.outputs.build-output-dir }}/package/
cp -r ${{ github.workspace }}/include ${{ steps.strings.outputs.build-output-dir }}/package/
SHARED_FLAG=""
if [ "${{ matrix.lib_type }}" == "shared" ]; then
SHARED_FLAG="--shared"
fi

if [ "${{ matrix.os }}" == "ubuntu-latest" ]; then
python setup.py --platform ${{ steps.strings.outputs.platform }} --compiler ${{ matrix.c_compiler }} --cfg ${{ matrix.build_type }} $SHARED_FLAG --build --test
else
python setup.py --platform ${{ steps.strings.outputs.platform }} --cfg ${{ matrix.build_type }} $SHARED_FLAG --build --test
fi

- name: Upload Build Artifact
if: ${{ inputs.upload_artifacts && success() }}
uses: actions/upload-artifact@v4
with:
name: ga-cpp-sdk-${{ matrix.os }}-${{ matrix.c_compiler }}-${{ matrix.build_type }}
name: ga-cpp-sdk-${{ matrix.os }}-${{ matrix.c_compiler }}-${{ matrix.build_type }}-${{ matrix.lib_type }}
path: ${{ steps.strings.outputs.build-output-dir }}/package/
retention-days: 3

72 changes: 54 additions & 18 deletions .github/workflows/create_release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,31 +44,65 @@ jobs:

- name: Organize release files
run: |
# Create the base include directory in the final release
mkdir -p ./final-release/include
# Create separate directories for static and shared libraries
mkdir -p ./static-release/include
mkdir -p ./shared-release/include

# Copy the entire include directory from one of the platform folders (assuming they are the same across platforms)
cp -r ./release-artifacts/ga-cpp-sdk-macOS-latest-clang-Release/include/* ./final-release/include/
# Copy include directory from any artifact (they're all identical)
FIRST_ARTIFACT=$(find ./release-artifacts -mindepth 1 -maxdepth 1 -type d | head -n 1)
cp -r $FIRST_ARTIFACT/include/* ./static-release/include/
cp -r $FIRST_ARTIFACT/include/* ./shared-release/include/

# Copy GameAnalyticsExtern.h for shared library release
cp ./source/gameanalytics/GameAnalyticsExtern.h ./shared-release/include/GameAnalytics/

# Dynamically find all platform directories
platform_dirs=$(find ./release-artifacts -mindepth 1 -maxdepth 1 -type d)

# Iterate over each platform directory and copy the respective binaries
for platform in $platform_dirs; do
platform_name=$(basename $platform)
mkdir -p ./final-release/$platform_name
if [[ $platform_name == *"windows"* ]]; then
cp $platform/*.lib ./final-release/$platform_name/
# Process static library artifacts
for artifact_dir in ./release-artifacts/*-static; do
artifact_name=$(basename $artifact_dir)
# Extract platform info (remove ga-cpp-sdk- prefix and -static suffix)
platform_info=${artifact_name#ga-cpp-sdk-}
platform_info=${platform_info%-static}

mkdir -p ./static-release/$platform_info

# Copy static libraries
if [[ $artifact_name == *"windows"* ]]; then
cp $artifact_dir/*.lib ./static-release/$platform_info/ 2>/dev/null || true
else
cp $platform/*.a ./final-release/$platform_name/
cp $artifact_dir/*.a ./static-release/$platform_info/ 2>/dev/null || true
fi
done

# Process shared library artifacts
for artifact_dir in ./release-artifacts/*-shared; do
artifact_name=$(basename $artifact_dir)
# Extract platform info (remove ga-cpp-sdk- prefix and -shared suffix)
platform_info=${artifact_name#ga-cpp-sdk-}
platform_info=${platform_info%-shared}

mkdir -p ./shared-release/$platform_info

# Copy shared libraries
if [[ $artifact_name == *"windows"* ]]; then
cp $artifact_dir/*.dll ./shared-release/$platform_info/ 2>/dev/null || true
elif [[ $artifact_name == *"macOS"* ]]; then
cp $artifact_dir/*.dylib ./shared-release/$platform_info/ 2>/dev/null || true
else
cp $artifact_dir/*.so ./shared-release/$platform_info/ 2>/dev/null || true
fi
done

# Create a zip archive of the final-release directory
zip -r ga-sdk-release-${{ inputs.tag_name }}.zip ./final-release
# Create zip archives
zip -r ga-sdk-static-${{ inputs.tag_name }}.zip ./static-release
zip -r ga-sdk-shared-${{ inputs.tag_name }}.zip ./shared-release

- name: Show organized release files
run: tree ./final-release
run: |
echo "=== Static Libraries ==="
tree ./static-release || ls -R ./static-release
echo ""
echo "=== Shared Libraries ==="
tree ./shared-release || ls -R ./shared-release

- name: Create release
uses: softprops/action-gh-release@v2.0.8
Expand All @@ -77,4 +111,6 @@ jobs:
name: Release GA-CPP-SDK ${{ inputs.tag_name }}
generate_release_notes: true
make_latest: true
files: ga-sdk-release-${{ inputs.tag_name }}.zip
files: |
ga-sdk-static-${{ inputs.tag_name }}.zip
ga-sdk-shared-${{ inputs.tag_name }}.zip
67 changes: 40 additions & 27 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,11 @@ elseif(LINUX)
endif()

if(${GA_BUILD_SAMPLE})
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/sample")
if(${GA_SHARED_LIB})
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/sample_shared")
else()
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/sample")
endif()
endif()

add_library(GameAnalytics ${LIB_TYPE} ${CPP_SOURCES})
Expand All @@ -217,43 +221,52 @@ message(STATUS "CMAKE_EXE_LINKER_FLAGS: ${CMAKE_EXE_LINKER_FLAGS}")
message(STATUS "CMAKE_SHARED_LINKER_FLAGS: ${CMAKE_SHARED_LINKER_FLAGS}")
# --------------------------- Google Test Setup --------------------------- #

# Set Project Name
set(UT_PROJECT_NAME "${PROJECT_NAME}UnitTests")
# Only build tests for static library builds
# Shared library builds don't export internal symbols needed by tests
if(NOT GA_SHARED_LIB)
message(STATUS "Building unit tests (tests are only available for static library builds)")

# Set Project Name
set(UT_PROJECT_NAME "${PROJECT_NAME}UnitTests")

# Add Google Test
set(GTEST_DIR "${EXTERNALS_DIR}/googletest")
add_subdirectory(${GTEST_DIR} ${PROJECT_SOURCE_DIR}/gtest_build)
# Add Google Test
set(GTEST_DIR "${EXTERNALS_DIR}/googletest")
add_subdirectory(${GTEST_DIR} ${PROJECT_SOURCE_DIR}/gtest_build)

# Add tests
enable_testing()
# Add tests
enable_testing()

########################################
# Test files
########################################
########################################
# Test files
########################################

file(GLOB_RECURSE TEST_SRC_FILES "${PROJECT_SOURCE_DIR}/test/*.cpp")
file(GLOB_RECURSE TEST_SRC_FILES "${PROJECT_SOURCE_DIR}/test/*.cpp")

########################################
# Unit Tests
#######################################
add_executable(${UT_PROJECT_NAME} ${TEST_SRC_FILES})
########################################
# Unit Tests
#######################################
add_executable(${UT_PROJECT_NAME} ${TEST_SRC_FILES})

########################################
# Standard linking to gtest and gmock components
########################################
target_link_libraries(${UT_PROJECT_NAME} gtest gtest_main gmock_main)
########################################
# Standard linking to gtest and gmock components
########################################
target_link_libraries(${UT_PROJECT_NAME} gtest gtest_main gmock_main)

########################################
# Linking to GA SDK
########################################
target_link_libraries(${UT_PROJECT_NAME} ${PROJECT_NAME})
########################################
# Linking to GA SDK
########################################
target_link_libraries(${UT_PROJECT_NAME} ${PROJECT_NAME})

########################################
add_test(NAME ${UT_PROJECT_NAME} COMMAND GameAnalyticsUnitTests)
########################################
add_test(NAME ${UT_PROJECT_NAME} COMMAND GameAnalyticsUnitTests)
else()
message(STATUS "Skipping unit tests (not available for shared library builds)")
endif()

# --------------------------- Code Coverage Setup --------------------------- #

if (ENABLE_COVERAGE)
# Coverage requires tests, which are only available for static library builds
if (ENABLE_COVERAGE AND NOT GA_SHARED_LIB)
find_program(GCOV_PATH gcov)
if (NOT GCOV_PATH)
message(WARNING "program gcov not found")
Expand Down
Binary file removed include/.DS_Store
Binary file not shown.
20 changes: 20 additions & 0 deletions sample_shared/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# set directories
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG "${CMAKE_BINARY_DIR}/Debug")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE "${CMAKE_BINARY_DIR}/Release")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG "${CMAKE_BINARY_DIR}/Debug")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE "${CMAKE_BINARY_DIR}/Release")

set(CMAKE_CXX_STANDARD 17)

if(LINUX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")

if(CLANG)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
endif()
endif()

set(SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/Main.cpp")

add_executable(GASampleShared ${SOURCES})
target_link_libraries(GASampleShared GameAnalytics)
68 changes: 68 additions & 0 deletions sample_shared/Main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#include <iostream>
#include <thread>
#include <chrono>

#include "GameAnalyticsExtern.h"

constexpr const char* GAME_KEY = "INSERT_GAME_KEY";
constexpr const char* SECRET_KEY = "INSERT_SECRET_KEY";

void testCrash()
{
int* i = nullptr;
*i = 10;
}

int main(int argc, char** argv)
{
std::cout << "start\n";

gameAnalytics_setEnabledVerboseLog(EGAEnabled);
gameAnalytics_setEnabledInfoLog(EGAEnabled);

gameAnalytics_setGlobalCustomEventFields("{\"my_field\": 1000}");

gameAnalytics_configureExternalUserId("user_supernew657566453442");
gameAnalytics_setEnabledErrorReporting(EGAEnabled);
gameAnalytics_setEnabledManualSessionHandling(EGAEnabled);

gameAnalytics_configureBuild("1.0.0");

const char* resourceCurrencies[] = {"diamonds"};
gameAnalytics_configureAvailableResourceCurrencies(resourceCurrencies, 1);

const char* resourceItemTypes[] = {"diamonds_pack_10000"};
gameAnalytics_configureAvailableResourceItemTypes(resourceItemTypes, 1);

const char* customDimensions01[] = {"test"};
gameAnalytics_configureAvailableCustomDimensions01(customDimensions01, 1);

gameAnalytics_enableSDKInitEvent(EGAEnabled);
gameAnalytics_enableMemoryHistogram(EGAEnabled);
gameAnalytics_enableHardwareTracking(EGAEnabled);
gameAnalytics_enableFPSHistogram([]() -> float { return 60.f; }, EGAEnabled);

gameAnalytics_setCustomDimension01("test");

using namespace std::chrono_literals;

gameAnalytics_initialize(GAME_KEY, SECRET_KEY);

gameAnalytics_startSession();
gameAnalytics_addDesignEventWithValue("test_event", 10.0, "", EGADisabled);
gameAnalytics_addBusinessEvent("EUR", 100, "diamonds", "diamond_pack_10000", "dungeon_shop", "", EGADisabled);
gameAnalytics_addErrorEvent(EGACritical, "failed to load level", "", EGADisabled);
gameAnalytics_addResourceEvent(EGASource, "diamonds", 100, "diamonds", "big_pack_01", "", EGADisabled);
gameAnalytics_addProgressionEventWithScore(EGAComplete, "volcano", "dungeon", "dragon", 100, "", EGADisabled);

std::this_thread::sleep_for(5000ms);
//testCrash();

//gameAnalytics_endSession();

std::cout << "test\n";

//std::cin.get();

return 0;
}
Loading