Skip to content

Commit 3cdac94

Browse files
committed
make CI generate both static and shared libs
1 parent fe03bcc commit 3cdac94

3 files changed

Lines changed: 137 additions & 53 deletions

File tree

.github/workflows/cmake.yml

Lines changed: 31 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,15 @@ jobs:
2424
# 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.
2525
fail-fast: false
2626

27-
# Set up a matrix to run the following 3 configurations:
28-
# 1. <Windows, Release, latest MSVC compiler toolchain on the default runner image, default generator>
29-
# 2. <Linux, Release, latest GCC compiler toolchain on the default runner image, default generator>
30-
# 3. <Linux, Release, latest Clang compiler toolchain on the default runner image, default generator>
31-
#
32-
# To add more build types (Release, Debug, RelWithDebInfo, etc.) customize the build_type list.
27+
# Set up a matrix to run the following configurations:
28+
# - Multiple platforms (Windows, Linux, macOS)
29+
# - Multiple compilers (cl, gcc, clang)
30+
# - Multiple library types (static, shared)
3331
matrix:
3432
os: [ubuntu-latest, windows-latest, macOS-latest]
3533
build_type: ${{ fromJSON(format('[{0}]', inputs.build_type || '"Debug","Release"')) }}
3634
c_compiler: [gcc, clang, cl]
35+
lib_type: [static, shared]
3736
include:
3837
- os: windows-latest
3938
c_compiler: cl
@@ -70,6 +69,19 @@ jobs:
7069
shell: bash
7170
run: |
7271
echo "build-output-dir=${{ github.workspace }}/build" >> "$GITHUB_OUTPUT"
72+
# Map OS to platform
73+
if [ "${{ matrix.os }}" == "ubuntu-latest" ]; then
74+
echo "platform=linux_x64" >> "$GITHUB_OUTPUT"
75+
elif [ "${{ matrix.os }}" == "windows-latest" ]; then
76+
echo "platform=win64" >> "$GITHUB_OUTPUT"
77+
elif [ "${{ matrix.os }}" == "macOS-latest" ]; then
78+
echo "platform=osx" >> "$GITHUB_OUTPUT"
79+
fi
80+
81+
- name: Set up Python
82+
uses: actions/setup-python@v5
83+
with:
84+
python-version: '3.x'
7385

7486
- name: Install libc++ on Ubuntu
7587
if: matrix.os == 'ubuntu-latest' && matrix.c_compiler == 'clang'
@@ -87,39 +99,25 @@ jobs:
8799
echo "check lld..."
88100
ldd --version
89101
90-
- name: Configure CMake
91-
# Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make.
92-
# See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
93-
run: >
94-
cmake -B ${{ steps.strings.outputs.build-output-dir }}
95-
-DCMAKE_CXX_COMPILER=${{ matrix.cpp_compiler }}
96-
-DCMAKE_C_COMPILER=${{ matrix.c_compiler }}
97-
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
98-
-S ${{ github.workspace }}
99-
100-
- name: Build
101-
# 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).
102-
run: cmake --build ${{ steps.strings.outputs.build-output-dir }} --config ${{ matrix.build_type }} --verbose
103-
104-
- name: Test
105-
working-directory: ${{ steps.strings.outputs.build-output-dir }}
106-
# 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).
107-
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
108-
run: ctest --build-config ${{ matrix.build_type }} --verbose --output-on-failure
109-
110-
- name: Package Build Artifacts
111-
if: ${{ inputs.upload_artifacts && success() }}
102+
- name: Build, Test, and Package with setup.py
103+
shell: bash
112104
run: |
113-
mkdir -p ${{ steps.strings.outputs.build-output-dir }}/package
114-
# Adjust the path to your built library files
115-
cp ${{ steps.strings.outputs.build-output-dir }}/${{ matrix.build_type }}/*GameAnalytics.* ${{ steps.strings.outputs.build-output-dir }}/package/
116-
cp -r ${{ github.workspace }}/include ${{ steps.strings.outputs.build-output-dir }}/package/
105+
SHARED_FLAG=""
106+
if [ "${{ matrix.lib_type }}" == "shared" ]; then
107+
SHARED_FLAG="--shared"
108+
fi
109+
110+
if [ "${{ matrix.os }}" == "ubuntu-latest" ]; then
111+
python setup.py --platform ${{ steps.strings.outputs.platform }} --compiler ${{ matrix.c_compiler }} --cfg ${{ matrix.build_type }} $SHARED_FLAG --build --test
112+
else
113+
python setup.py --platform ${{ steps.strings.outputs.platform }} --cfg ${{ matrix.build_type }} $SHARED_FLAG --build --test
114+
fi
117115
118116
- name: Upload Build Artifact
119117
if: ${{ inputs.upload_artifacts && success() }}
120118
uses: actions/upload-artifact@v4
121119
with:
122-
name: ga-cpp-sdk-${{ matrix.os }}-${{ matrix.c_compiler }}-${{ matrix.build_type }}
120+
name: ga-cpp-sdk-${{ matrix.os }}-${{ matrix.c_compiler }}-${{ matrix.build_type }}-${{ matrix.lib_type }}
123121
path: ${{ steps.strings.outputs.build-output-dir }}/package/
124122
retention-days: 3
125123

.github/workflows/create_release.yml

Lines changed: 54 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -44,31 +44,65 @@ jobs:
4444

4545
- name: Organize release files
4646
run: |
47-
# Create the base include directory in the final release
48-
mkdir -p ./final-release/include
47+
# Create separate directories for static and shared libraries
48+
mkdir -p ./static-release/include
49+
mkdir -p ./shared-release/include
4950
50-
# Copy the entire include directory from one of the platform folders (assuming they are the same across platforms)
51-
cp -r ./release-artifacts/ga-cpp-sdk-macOS-latest-clang-Release/include/* ./final-release/include/
51+
# Copy include directory from any artifact (they're all identical)
52+
FIRST_ARTIFACT=$(find ./release-artifacts -mindepth 1 -maxdepth 1 -type d | head -n 1)
53+
cp -r $FIRST_ARTIFACT/include/* ./static-release/include/
54+
cp -r $FIRST_ARTIFACT/include/* ./shared-release/include/
55+
56+
# Copy GameAnalyticsExtern.h for shared library release
57+
cp ./source/gameanalytics/GameAnalyticsExtern.h ./shared-release/include/GameAnalytics/
5258

53-
# Dynamically find all platform directories
54-
platform_dirs=$(find ./release-artifacts -mindepth 1 -maxdepth 1 -type d)
55-
56-
# Iterate over each platform directory and copy the respective binaries
57-
for platform in $platform_dirs; do
58-
platform_name=$(basename $platform)
59-
mkdir -p ./final-release/$platform_name
60-
if [[ $platform_name == *"windows"* ]]; then
61-
cp $platform/*.lib ./final-release/$platform_name/
59+
# Process static library artifacts
60+
for artifact_dir in ./release-artifacts/*-static; do
61+
artifact_name=$(basename $artifact_dir)
62+
# Extract platform info (remove ga-cpp-sdk- prefix and -static suffix)
63+
platform_info=${artifact_name#ga-cpp-sdk-}
64+
platform_info=${platform_info%-static}
65+
66+
mkdir -p ./static-release/$platform_info
67+
68+
# Copy static libraries
69+
if [[ $artifact_name == *"windows"* ]]; then
70+
cp $artifact_dir/*.lib ./static-release/$platform_info/ 2>/dev/null || true
6271
else
63-
cp $platform/*.a ./final-release/$platform_name/
72+
cp $artifact_dir/*.a ./static-release/$platform_info/ 2>/dev/null || true
73+
fi
74+
done
75+
76+
# Process shared library artifacts
77+
for artifact_dir in ./release-artifacts/*-shared; do
78+
artifact_name=$(basename $artifact_dir)
79+
# Extract platform info (remove ga-cpp-sdk- prefix and -shared suffix)
80+
platform_info=${artifact_name#ga-cpp-sdk-}
81+
platform_info=${platform_info%-shared}
82+
83+
mkdir -p ./shared-release/$platform_info
84+
85+
# Copy shared libraries
86+
if [[ $artifact_name == *"windows"* ]]; then
87+
cp $artifact_dir/*.dll ./shared-release/$platform_info/ 2>/dev/null || true
88+
elif [[ $artifact_name == *"macOS"* ]]; then
89+
cp $artifact_dir/*.dylib ./shared-release/$platform_info/ 2>/dev/null || true
90+
else
91+
cp $artifact_dir/*.so ./shared-release/$platform_info/ 2>/dev/null || true
6492
fi
6593
done
6694

67-
# Create a zip archive of the final-release directory
68-
zip -r ga-sdk-release-${{ inputs.tag_name }}.zip ./final-release
95+
# Create zip archives
96+
zip -r ga-sdk-static-${{ inputs.tag_name }}.zip ./static-release
97+
zip -r ga-sdk-shared-${{ inputs.tag_name }}.zip ./shared-release
6998

7099
- name: Show organized release files
71-
run: tree ./final-release
100+
run: |
101+
echo "=== Static Libraries ==="
102+
tree ./static-release || ls -R ./static-release
103+
echo ""
104+
echo "=== Shared Libraries ==="
105+
tree ./shared-release || ls -R ./shared-release
72106
73107
- name: Create release
74108
uses: softprops/action-gh-release@v2.0.8
@@ -77,4 +111,6 @@ jobs:
77111
name: Release GA-CPP-SDK ${{ inputs.tag_name }}
78112
generate_release_notes: true
79113
make_latest: true
80-
files: ga-sdk-release-${{ inputs.tag_name }}.zip
114+
files: |
115+
ga-sdk-static-${{ inputs.tag_name }}.zip
116+
ga-sdk-shared-${{ inputs.tag_name }}.zip

setup.py

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import subprocess
44
import shutil
55
import glob
6+
import platform as plat
67

78
def run_command(command, shell=True, cwd=None):
89
if os.name == 'nt': # Check if the OS is Windows
@@ -11,21 +12,67 @@ def run_command(command, shell=True, cwd=None):
1112
result = subprocess.run(command, shell=shell, check=True, text=True, cwd=cwd)
1213
return result
1314

15+
def get_compiler_for_platform(platform, compiler=None):
16+
"""Get compiler configuration for a platform (single compiler, matching cmake.yml behavior)"""
17+
if platform == 'osx':
18+
return {'c': 'clang', 'cxx': 'clang++'}
19+
elif platform.startswith('win'):
20+
return {'c': 'cl', 'cxx': 'cl'}
21+
elif platform.startswith('linux'):
22+
if compiler == 'gcc':
23+
return {'c': 'gcc', 'cxx': 'g++'}
24+
else:
25+
# Default to Clang for Linux
26+
return {'c': 'clang', 'cxx': 'clang++'}
27+
return {}
28+
1429
def main():
1530
parser = argparse.ArgumentParser(description="CMake Build and Test Script")
16-
parser.add_argument('--platform', required=True, choices=['linux_x64', 'linux_x86', 'osx', 'win32', 'win64', 'uwp'], help='Platform to build for')
31+
parser.add_argument('--platform', choices=['linux_x64', 'linux_x86', 'osx', 'win32', 'win64', 'uwp'], help='Platform to build for', required=True)
1732
parser.add_argument('--cfg', default='Debug', choices=['Release', 'Debug'], help='Configuration Type')
33+
parser.add_argument('--compiler', choices=['gcc', 'clang'], help='Compiler to use (Linux only: gcc or clang, default=clang)')
34+
parser.add_argument('--shared', action='store_true', help='Build shared library instead of static')
1835
parser.add_argument('--build', action='store_true', help='Execute the build step')
1936
parser.add_argument('--test', action='store_true', help='Execute the test step')
2037
parser.add_argument('--coverage', action='store_true', help='Generate code coverage report')
2138

2239
args = parser.parse_args()
2340

41+
# Validate compiler argument is only used with Linux
42+
if args.compiler and not args.platform.startswith('linux'):
43+
parser.error('--compiler can only be used with Linux platforms')
44+
45+
# Get compiler configuration for this platform (single compiler, like cmake.yml)
46+
compiler_config = get_compiler_for_platform(args.platform, args.compiler)
47+
c_compiler = compiler_config.get('c', '')
48+
cxx_compiler = compiler_config.get('cxx', '')
49+
compiler_name = c_compiler if c_compiler else 'default'
50+
51+
lib_type = 'shared' if args.shared else 'static'
52+
print(f"\n{'='*60}")
53+
print(f"Building {lib_type} library for {args.platform} with {compiler_name}")
54+
print(f"{'='*60}\n")
55+
56+
# Always use 'build/' directory (matching cmake.yml behavior)
2457
build_output_dir = os.path.join(os.getcwd(), 'build')
2558
os.makedirs(build_output_dir, exist_ok=True)
2659

2760
# Configure
2861
cmake_command = f'cmake -B {build_output_dir} -S {os.getcwd()}'
62+
63+
# Add compiler flags
64+
if c_compiler:
65+
cmake_command += f' -DCMAKE_C_COMPILER={c_compiler}'
66+
if cxx_compiler:
67+
cmake_command += f' -DCMAKE_CXX_COMPILER={cxx_compiler}'
68+
69+
# Add build type for single-config generators (Makefile, Ninja)
70+
cmake_command += f' -DCMAKE_BUILD_TYPE={args.cfg}'
71+
72+
# Configure for shared library build
73+
if args.shared:
74+
cmake_command += ' -DGA_SHARED_LIB=ON -DGA_BUILD_SAMPLE=OFF'
75+
2976
if args.platform == 'osx':
3077
cmake_command += ' -G "Xcode"'
3178
if args.platform:
@@ -37,7 +84,7 @@ def main():
3784

3885
# Build
3986
if args.build:
40-
run_command(f'cmake --build {build_output_dir} --config {args.cfg}')
87+
run_command(f'cmake --build {build_output_dir} --config {args.cfg} --verbose')
4188
else:
4289
exit(0)
4390

@@ -68,6 +115,9 @@ def main():
68115

69116
if args.platform == 'osx':
70117
run_command(f'lipo -info {package_dir}/*GameAnalytics.*')
118+
119+
print(f"\n{lib_type.capitalize()} library build completed for {args.platform} with {compiler_name}")
120+
print(f" Package location: {package_dir}\n")
71121

72122
if __name__ == "__main__":
73123
main()

0 commit comments

Comments
 (0)