이번 글에서는 CMake를 사용하여 Vulkan 기반의 그래픽스 응용 프로그램을 구성하고 빌드하는 방법을 알아보겠습니다. Vulkan은 차세대 그래픽 및 컴퓨팅 API로, 고성능과 낮은 오버헤드를 제공합니다. CMake를 활용하여 Vulkan 프로젝트를 효율적으로 관리하고 빌드 시스템에 통합하는 방법을 살펴보겠습니다.
Vulkan과 CMake의 통합
Vulkan 프로젝트를 CMake로 빌드하려면 Vulkan SDK와 라이브러리를 설정하고, CMake에서 이를 올바르게 찾고 링크해야 합니다. Vulkan은 플랫폼에 따라 설치 방법이 다를 수 있으므로, 개발 환경에 맞게 설정해야 합니다.
Vulkan SDK 설치
- Windows: LunarG에서 제공하는 Vulkan SDK를 설치합니다.
- macOS: Vulkan은 공식적으로 macOS를 지원하지 않지만, MoltenVK를 통해 Vulkan API를 Metal로 매핑하여 사용할 수 있습니다.
- Linux: 패키지 매니저를 통해 Vulkan 라이브러리를 설치하거나, LunarG에서 SDK를 다운로드합니다.
- Ubuntu 예시:
sudo apt-get install libvulkan1 vulkan-utils vulkan-validationlayers-dev
프로젝트 구성
디렉토리 구조
my_vulkan_project/
├── CMakeLists.txt
├── src/
│ ├── CMakeLists.txt
│ └── main.cpp
├── shaders/
│ ├── shader.vert
│ └── shader.frag
└── include/
└── vulkan_app.hpp
최상위 CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(MyVulkanProject LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_subdirectory(src)
src/CMakeLists.txt
# Vulkan 패키지 찾기
find_package(Vulkan REQUIRED)
# 실행 파일 생성
add_executable(MyVulkanApp main.cpp)
# Vulkan 라이브러리 링크
target_link_libraries(MyVulkanApp PRIVATE Vulkan::Vulkan)
# 인클루드 디렉토리 설정
target_include_directories(MyVulkanApp PRIVATE ${Vulkan_INCLUDE_DIRS})
# 쉐이더 컴파일 설정
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/shader.vert.spv
COMMAND ${Vulkan_GLSLC_EXECUTABLE} ${CMAKE_SOURCE_DIR}/shaders/shader.vert -o shader.vert.spv
DEPENDS ${CMAKE_SOURCE_DIR}/shaders/shader.vert
COMMENT "Compiling vertex shader"
)
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/shader.frag.spv
COMMAND ${Vulkan_GLSLC_EXECUTABLE} ${CMAKE_SOURCE_DIR}/shaders/shader.frag -o shader.frag.spv
DEPENDS ${CMAKE_SOURCE_DIR}/shaders/shader.frag
COMMENT "Compiling fragment shader"
)
add_custom_target(Shaders
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/shader.vert.spv
${CMAKE_CURRENT_BINARY_DIR}/shader.frag.spv
)
add_dependencies(MyVulkanApp Shaders)
# 실행 파일에 쉐이더 경로 정의
target_compile_definitions(MyVulkanApp PRIVATE
SHADER_DIR="${CMAKE_CURRENT_BINARY_DIR}"
)
main.cpp 예제
#include <iostream>
#include <stdexcept>
#include <cstdlib>
#include "vulkan_app.hpp"
int main() {
VulkanApp app;
try {
app.run();
} catch (const std::exception &e) {
std::cerr << "오류: " << e.what() << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
vulkan_app.hpp 및 vulkan_app.cpp 예제
vulkan_app.hpp
#pragma once
#define GLFW_INCLUDE_VULKAN
#include <GLFW/glfw3.h>
class VulkanApp {
public:
void run();
private:
void initWindow();
void initVulkan();
void mainLoop();
void cleanup();
GLFWwindow* window;
const uint32_t WIDTH = 800;
const uint32_t HEIGHT = 600;
};
vulkan_app.cpp
#include "vulkan_app.hpp"
#include <stdexcept>
void VulkanApp::run() {
initWindow();
initVulkan();
mainLoop();
cleanup();
}
void VulkanApp::initWindow() {
glfwInit();
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
window = glfwCreateWindow(WIDTH, HEIGHT, "Vulkan App", nullptr, nullptr);
}
void VulkanApp::initVulkan() {
// Vulkan 인스턴스 생성 등 초기화 코드
}
void VulkanApp::mainLoop() {
while (!glfwWindowShouldClose(window)) {
glfwPollEvents();
}
}
void VulkanApp::cleanup() {
glfwDestroyWindow(window);
glfwTerminate();
}
GLFW 라이브러리 설정
Vulkan에서는 창 관리 및 입력 처리를 위해 GLFW를 사용할 수 있습니다.
GLFW 패키지 찾기
src/CMakeLists.txt에 다음을 추가합니다.
find_package(glfw3 3.3 REQUIRED)
target_link_libraries(MyVulkanApp PRIVATE glfw)
GLFW가 시스템에 설치되지 않은 경우
GLFW를 프로젝트에 포함시키거나 FetchContent를 사용할 수 있습니다.
include(FetchContent)
FetchContent_Declare(
glfw
GIT_REPOSITORY https://github.com/glfw/glfw.git
GIT_TAG 3.3.8
)
FetchContent_MakeAvailable(glfw)
target_link_libraries(MyVulkanApp PRIVATE glfw)
쉐이더 컴파일 설정
Vulkan은 쉐이더를 SPIR-V 바이트코드로 컴파일해야 합니다. 이를 위해 glslc 컴파일러를 사용합니다.
find_package(Vulkan REQUIRED)의 역할
- Vulkan_INCLUDE_DIRS: Vulkan 헤더 파일의 경로
- Vulkan_LIBRARIES: Vulkan 라이브러리
- Vulkan_GLSLC_EXECUTABLE: glslc 컴파일러의 경로
쉐이더 컴파일 명령어 설정
add_custom_command()를 사용하여 쉐이더를 자동으로 컴파일합니다.
add_custom_command(
OUTPUT shader.vert.spv
COMMAND ${Vulkan_GLSLC_EXECUTABLE} shader.vert -o shader.vert.spv
DEPENDS shader.vert
)
전체적인 CMake 파일 구조
최종적으로 src/CMakeLists.txt는 다음과 같습니다.
# Vulkan 패키지 찾기
find_package(Vulkan REQUIRED)
# GLFW 패키지 찾기
find_package(glfw3 3.3 REQUIRED)
# 실행 파일 생성
add_executable(MyVulkanApp main.cpp vulkan_app.cpp)
# Vulkan 및 GLFW 라이브러리 링크
target_link_libraries(MyVulkanApp PRIVATE Vulkan::Vulkan glfw)
# 인클루드 디렉토리 설정
target_include_directories(MyVulkanApp PRIVATE
${Vulkan_INCLUDE_DIRS}
${CMAKE_CURRENT_SOURCE_DIR}
)
# 쉐이더 컴파일 설정
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/shader.vert.spv
COMMAND ${Vulkan_GLSLC_EXECUTABLE} ${CMAKE_SOURCE_DIR}/shaders/shader.vert -o shader.vert.spv
DEPENDS ${CMAKE_SOURCE_DIR}/shaders/shader.vert
COMMENT "Compiling vertex shader"
)
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/shader.frag.spv
COMMAND ${Vulkan_GLSLC_EXECUTABLE} ${CMAKE_SOURCE_DIR}/shaders/shader.frag -o shader.frag.spv
DEPENDS ${CMAKE_SOURCE_DIR}/shaders/shader.frag
COMMENT "Compiling fragment shader"
)
add_custom_target(Shaders
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/shader.vert.spv
${CMAKE_CURRENT_BINARY_DIR}/shader.frag.spv
)
add_dependencies(MyVulkanApp Shaders)
# 실행 파일에 쉐이더 경로 정의
target_compile_definitions(MyVulkanApp PRIVATE
SHADER_DIR="${CMAKE_CURRENT_BINARY_DIR}"
)
빌드 및 실행
빌드
mkdir build
cd build
cmake ..
cmake --build .
실행
./MyVulkanApp
- Vulkan 런타임과 드라이버가 올바르게 설치되어 있어야 합니다.
- 실행 시 Vulkan 인스턴스 생성, 물리 디바이스 선택 등 초기화 과정을 구현해야 합니다.
참고 사항
Vulkan 초기화 코드
Vulkan의 초기화는 복잡할 수 있으므로, 공식 튜토리얼을 참고하여 단계별로 구현하는 것이 좋습니다.
- Vulkan 인스턴스 생성
- 물리 디바이스 선택
- 논리 디바이스 생성
- 큐 패밀리 선택
- 스왑 체인 설정
- 렌더 패스 및 파이프라인 설정
Vulkan Validation Layers 사용
개발 중 오류를 조기에 발견하기 위해 Vulkan Validation Layers를 활성화할 수 있습니다.
- VK_LAYER_KHRONOS_validation 레이어를 활성화
- 디버그 메시지를 콘솔에 출력하거나 파일로 저장
참고 자료
- Vulkan 공식 사이트
- Vulkan SDK 다운로드
- Vulkan 튜토리얼
- GLFW 공식 사이트
- CMake 공식 문서: find_package()
- CMake로 Vulkan 프로젝트 설정하기
- MoltenVK를 사용한 macOS에서의 Vulkan
- Vulkan API 레퍼런스
반응형
'개발 이야기 > CMake' 카테고리의 다른 글
[모던 CMake] SIMD 프로젝트 구성과 빌드 (1) | 2024.12.13 |
---|---|
[모던 CMake] OpenCL 프로젝트 구성과 빌드 (0) | 2024.12.13 |
[모던 CMake] 재사용 가능한 라이브러리를 위한 CMake 패키지 구성 (0) | 2024.12.12 |
[모던 CMake] Qt 프로젝트 구성과 빌드 (1) | 2024.12.11 |
[모던 CMake] CUDA 프로젝트 구성과 빌드 (0) | 2024.12.10 |