Skip to content

Commit 466d65d

Browse files
committed
Add ccache and sccache support in CI workflows
- Introduced `ccache` on Linux and `sccache` on Windows for improved compilation caching in GitHub workflows. - Updated build scripts with compiler launcher configurations to leverage caching tools. - Added steps to install and configure `ccache`/`sccache` based on the runner's platform. - Enhanced CI efficiency with cache restoration for Vulkan SDK and compiler caches. - Defined platform-specific `AssetManagerType` for better Android and desktop compatibility.
1 parent d446322 commit 466d65d

File tree

2 files changed

+79
-49
lines changed

2 files changed

+79
-49
lines changed

.github/workflows/workflow.yml

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ jobs:
1414
os: [ubuntu-latest, windows-latest]
1515
include:
1616
- os: ubuntu-latest
17+
ccache: ccache
1718
vulkan-install: |
1819
# Download and install Vulkan SDK using the tar.gz method
1920
VULKAN_VERSION=$(curl -s https://vulkan.lunarg.com/sdk/latest/linux.txt)
@@ -64,6 +65,7 @@ jobs:
6465
exit 1
6566
fi
6667
- os: windows-latest
68+
ccache: sccache
6769
vulkan-install: |
6870
# Download the Vulkan SDK installer
6971
Invoke-WebRequest -Uri "https://sdk.lunarg.com/sdk/download/latest/windows/vulkan-sdk.exe" -OutFile "$env:TEMP\vulkan-sdk.exe"
@@ -163,6 +165,17 @@ jobs:
163165
restore-keys: |
164166
${{ runner.os }}-apt-
165167
168+
# Cache ccache files
169+
- name: Cache ccache files
170+
uses: actions/cache@v3
171+
with:
172+
path: |
173+
~/.ccache
174+
~/.cache/sccache
175+
key: ${{ runner.os }}-${{ matrix.ccache }}-${{ github.sha }}
176+
restore-keys: |
177+
${{ runner.os }}-${{ matrix.ccache }}-
178+
166179
# Cache Vulkan SDK for Ubuntu
167180
- name: Cache Vulkan SDK (Ubuntu)
168181
if: runner.os == 'Linux'
@@ -175,6 +188,27 @@ jobs:
175188
${{ runner.os }}-vulkan-sdk-${{ hashFiles('**/CMakeLists.txt') }}-
176189
${{ runner.os }}-vulkan-sdk-
177190
191+
# Install ccache or sccache
192+
- name: Install ccache (Ubuntu)
193+
if: runner.os == 'Linux'
194+
run: |
195+
sudo apt-get update
196+
sudo apt-get install -y ccache
197+
ccache --max-size=2G
198+
ccache -z
199+
echo "CCACHE_DIR=$HOME/.ccache" >> $GITHUB_ENV
200+
echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV
201+
202+
- name: Install sccache (Windows)
203+
if: runner.os == 'Windows'
204+
run: |
205+
Invoke-WebRequest -Uri "https://github.com/mozilla/sccache/releases/download/v0.5.4/sccache-v0.5.4-x86_64-pc-windows-msvc.tar.gz" -OutFile "sccache.tar.gz"
206+
tar -xzf sccache.tar.gz
207+
$sccachePath = Join-Path -Path (Get-Location) -ChildPath "sccache-v0.5.4-x86_64-pc-windows-msvc"
208+
echo "$sccachePath" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
209+
echo "SCCACHE_DIR=$HOME/.cache/sccache" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
210+
echo "SCCACHE_CACHE_SIZE=2G" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
211+
178212
- name: Install dependencies
179213
run: ${{ matrix.deps-install }}
180214

@@ -237,7 +271,9 @@ jobs:
237271
-DVulkan_INCLUDE_DIR="$env:Vulkan_INCLUDE_DIR" `
238272
-DVulkan_LIBRARY="$env:Vulkan_LIBRARY" `
239273
-DCMAKE_PREFIX_PATH="$env:VULKAN_SDK" `
240-
-DCMAKE_TOOLCHAIN_FILE="$env:CMAKE_TOOLCHAIN_FILE"
274+
-DCMAKE_TOOLCHAIN_FILE="$env:CMAKE_TOOLCHAIN_FILE" `
275+
-DCMAKE_C_COMPILER_LAUNCHER=sccache `
276+
-DCMAKE_CXX_COMPILER_LAUNCHER=sccache
241277
242278
# Display CMake cache to debug Vulkan detection
243279
if (Test-Path "build/CMakeCache.txt") {
@@ -273,17 +309,28 @@ jobs:
273309
if: runner.os != 'Windows'
274310
run: |
275311
# Use Clang for better C++20 module support
276-
export CC=clang
277-
export CXX=clang++
312+
export CC="ccache clang"
313+
export CXX="ccache clang++"
278314
279315
cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release \
280316
-DCMAKE_CXX_SCAN_FOR_MODULES=ON \
281-
-DCMAKE_CXX_FLAGS="-std=c++20"
317+
-DCMAKE_CXX_FLAGS="-std=c++20" \
318+
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
319+
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache
282320
283321
- name: Build
284322
working-directory: ${{github.workspace}}/attachments
285323
run: cmake --build build --config Release
286324

325+
# Display ccache/sccache statistics
326+
- name: ccache statistics
327+
if: runner.os == 'Linux'
328+
run: ccache -s
329+
330+
- name: sccache statistics
331+
if: runner.os == 'Windows'
332+
run: sccache -s
333+
287334
- name: Test Build Output
288335
working-directory: ${{github.workspace}}/attachments/build
289336
run: ${{ matrix.test-cmd }}

attachments/34_android.cpp

Lines changed: 28 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -36,18 +36,26 @@ import vulkan_hpp;
3636
#include <android/asset_manager.h>
3737
#include <android/asset_manager_jni.h>
3838

39+
// Define AAssetManager type for Android
40+
typedef AAssetManager AssetManagerType;
41+
3942
// Define logging macros for Android
4043
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "VulkanTutorial", __VA_ARGS__))
4144
#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "VulkanTutorial", __VA_ARGS__))
4245
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "VulkanTutorial", __VA_ARGS__))
4346
#define LOG_INFO(msg) LOGI("%s", msg)
4447
#define LOG_ERROR(msg) LOGE("%s", msg)
4548
#else
49+
// Define AAssetManager type for non-Android platforms
50+
typedef void AssetManagerType;
4651
// Desktop-specific includes
4752
#define GLFW_INCLUDE_VULKAN
4853
#include <GLFW/glfw3.h>
4954

5055
// Define logging macros for Desktop
56+
#define LOGI(...) printf(__VA_ARGS__); printf("\n")
57+
#define LOGW(...) printf(__VA_ARGS__); printf("\n")
58+
#define LOGE(...) fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n")
5159
#define LOG_INFO(msg) std::cout << msg << std::endl
5260
#define LOG_ERROR(msg) std::cerr << msg << std::endl
5361
#endif
@@ -107,7 +115,7 @@ struct UniformBufferObject {
107115
};
108116

109117
// Cross-platform file reading function
110-
std::vector<char> readFile(const std::string& filename, std::optional<AAssetManager*> assetManager = std::nullopt) {
118+
std::vector<char> readFile(const std::string& filename, std::optional<AssetManagerType*> assetManager = std::nullopt) {
111119
#if PLATFORM_ANDROID
112120
// On Android, use asset manager if provided
113121
if (assetManager.has_value() && *assetManager != nullptr) {
@@ -224,47 +232,13 @@ class HelloTriangleApplication {
224232
void cleanup() {
225233
if (initialized) {
226234
// Wait for device to finish operations
227-
if (device) {
235+
if (*device) {
228236
device.waitIdle();
229237
}
230238

231239
// Cleanup resources
232240
cleanupSwapChain();
233241

234-
// Cleanup other resources
235-
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
236-
uniformBuffers[i] = nullptr;
237-
uniformBuffersMemory[i] = nullptr;
238-
}
239-
240-
descriptorPool = nullptr;
241-
descriptorSetLayout = nullptr;
242-
243-
textureImageView = nullptr;
244-
textureImage = nullptr;
245-
textureImageMemory = nullptr;
246-
textureSampler = nullptr;
247-
248-
indexBuffer = nullptr;
249-
indexBufferMemory = nullptr;
250-
vertexBuffer = nullptr;
251-
vertexBufferMemory = nullptr;
252-
253-
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
254-
imageAvailableSemaphores[i] = nullptr;
255-
renderFinishedSemaphores[i] = nullptr;
256-
inFlightFences[i] = nullptr;
257-
}
258-
259-
commandPool = nullptr;
260-
graphicsPipeline = nullptr;
261-
pipelineLayout = nullptr;
262-
renderPass = nullptr;
263-
264-
device = nullptr;
265-
surface = nullptr;
266-
instance = nullptr;
267-
268242
initialized = false;
269243
}
270244
}
@@ -273,7 +247,7 @@ class HelloTriangleApplication {
273247
#if PLATFORM_ANDROID
274248
// Android-specific members
275249
android_app* androidApp = nullptr;
276-
AAssetManager* assetManager = nullptr;
250+
AssetManagerType* assetManager = nullptr;
277251
#else
278252
// Desktop-specific members
279253
GLFWwindow* window = nullptr;
@@ -466,7 +440,7 @@ class HelloTriangleApplication {
466440

467441
// Print device information
468442
vk::PhysicalDeviceProperties deviceProperties = physicalDevice.getProperties();
469-
LOGI("Selected GPU: %s", deviceProperties.deviceName);
443+
LOGI("Selected GPU: %s", deviceProperties.deviceName.data());
470444
} else {
471445
throw std::runtime_error("Failed to find a suitable GPU");
472446
}
@@ -711,9 +685,9 @@ class HelloTriangleApplication {
711685

712686
// Load shader files using cross-platform function
713687
#if PLATFORM_ANDROID
714-
std::optional<AAssetManager*> optionalAssetManager = assetManager;
688+
std::optional<AssetManagerType*> optionalAssetManager = assetManager;
715689
#else
716-
std::optional<AAssetManager*> optionalAssetManager = std::nullopt;
690+
std::optional<void*> optionalAssetManager = std::nullopt;
717691
#endif
718692
std::vector<char> vertShaderCode = readFile("shaders/vert.spv", optionalAssetManager);
719693
std::vector<char> fragShaderCode = readFile("shaders/frag.spv", optionalAssetManager);
@@ -882,7 +856,7 @@ class HelloTriangleApplication {
882856

883857
#if PLATFORM_ANDROID
884858
// Load image from Android assets
885-
std::optional<AAssetManager*> optionalAssetManager = assetManager;
859+
std::optional<AssetManagerType*> optionalAssetManager = assetManager;
886860
std::vector<char> imageData = readFile(TEXTURE_PATH, optionalAssetManager);
887861
pixels = stbi_load_from_memory(
888862
reinterpret_cast<const stbi_uc*>(imageData.data()),
@@ -990,7 +964,7 @@ class HelloTriangleApplication {
990964

991965
#if PLATFORM_ANDROID
992966
// Load OBJ file from Android assets
993-
std::optional<AAssetManager*> optionalAssetManager = assetManager;
967+
std::optional<AssetManagerType*> optionalAssetManager = assetManager;
994968
std::vector<char> objData = readFile(MODEL_PATH, optionalAssetManager);
995969
std::string objString(objData.begin(), objData.end());
996970
std::istringstream objStream(objString);
@@ -1076,8 +1050,13 @@ class HelloTriangleApplication {
10761050
void createUniformBuffers() {
10771051
vk::DeviceSize bufferSize = sizeof(UniformBufferObject);
10781052

1079-
uniformBuffers.resize(MAX_FRAMES_IN_FLIGHT);
1080-
uniformBuffersMemory.resize(MAX_FRAMES_IN_FLIGHT);
1053+
uniformBuffers.clear();
1054+
uniformBuffersMemory.clear();
1055+
1056+
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
1057+
uniformBuffers.push_back(nullptr);
1058+
uniformBuffersMemory.push_back(nullptr);
1059+
}
10811060

10821061
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
10831062
createBuffer(bufferSize, vk::BufferUsageFlagBits::eUniformBuffer, vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent, uniformBuffers[i], uniformBuffersMemory[i]);
@@ -1211,7 +1190,8 @@ class HelloTriangleApplication {
12111190
}
12121191
};
12131192

1214-
vk::ClearValue clearColor = {{{0.0f, 0.0f, 0.0f, 1.0f}}};
1193+
vk::ClearValue clearColor;
1194+
clearColor.color.float32 = std::array<float, 4>{0.0f, 0.0f, 0.0f, 1.0f};
12151195
renderPassInfo.clearValueCount = 1;
12161196
renderPassInfo.pClearValues = &clearColor;
12171197

@@ -1256,6 +1236,9 @@ class HelloTriangleApplication {
12561236
return;
12571237
}
12581238

1239+
// Update uniform buffer with current transformation
1240+
updateUniformBuffer(currentFrame);
1241+
12591242
device.resetFences({*inFlightFences[currentFrame]});
12601243

12611244
commandBuffers[currentFrame].reset();

0 commit comments

Comments
 (0)