[모던 CMake] Qt 프로젝트 구성과 빌드

이번 글에서는 CMake를 사용하여 Qt 기반의 응용 프로그램을 구성하고 빌드하는 방법을 알아보겠습니다. Qt는 크로스 플랫폼 GUI 애플리케이션 개발을 위한 강력한 프레임워크로, CMake와 함께 사용하면 효율적인 빌드 시스템을 구축할 수 있습니다.

CMake와 Qt의 통합

Qt는 기존에 자체 빌드 시스템인 qmake를 사용했지만, 최근에는 CMake를 공식적으로 지원하고 있습니다. CMake를 사용하면 Qt 애플리케이션의 빌드 설정을 보다 유연하고 강력하게 관리할 수 있습니다.

Qt5와 Qt6의 차이점

  • Qt5: CMake에서 find_package()를 통해 Qt 모듈을 찾습니다.
  • Qt6: Qt6부터는 CMake 지원이 더욱 강화되어 더 간단하게 설정할 수 있습니다.

간단한 Qt 프로젝트 구성

디렉토리 구조

my_qt_project/
├── CMakeLists.txt
├── src/
│   ├── CMakeLists.txt
│   ├── main.cpp
│   └── MainWindow.h
├── ui/
│   └── MainWindow.ui
└── resources/
    └── resources.qrc

최상위 CMakeLists.txt

cmake_minimum_required(VERSION 3.16)
project(MyQtProject)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

add_subdirectory(src)

src/CMakeLists.txt

# Qt 패키지 찾기
find_package(Qt5 COMPONENTS Widgets REQUIRED)

# UI 파일 처리
set(UI_FILES
    ${CMAKE_SOURCE_DIR}/ui/MainWindow.ui
)

# 리소스 파일 처리
set(RESOURCE_FILES
    ${CMAKE_SOURCE_DIR}/resources/resources.qrc
)

# UI 및 리소스 파일을 처리하여 헤더와 소스를 생성
qt5_wrap_ui(UISrcs ${UI_FILES})
qt5_add_resources(ResourceSrcs ${RESOURCE_FILES})

# 실행 파일 생성
add_executable(MyQtApp
    main.cpp
    MainWindow.h
    ${UISrcs}
    ${ResourceSrcs}
)

# Qt 라이브러리 링크
target_link_libraries(MyQtApp PRIVATE Qt5::Widgets)

# 인클루드 디렉토리 설정
target_include_directories(MyQtApp PRIVATE ${CMAKE_CURRENT_BINARY_DIR})

main.cpp 예제

#include <QApplication>
#include "MainWindow.h"

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    MainWindow window;
    window.show();

    return app.exec();
}

MainWindow.h 예제

#pragma once

#include <QMainWindow>
#include "ui_MainWindow.h"

class MainWindow : public QMainWindow {
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);

private:
    Ui::MainWindow ui;
};

MainWindow.cpp 예제

#include "MainWindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent) {
    ui.setupUi(this);
}

ui/MainWindow.ui 예제

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <!-- UI 구성 요소 -->
 </widget>
 <resources/>
 <connections/>
</ui>

resources/resources.qrc 예제

<RCC>
    <qresource prefix="/images">
        <!-- 리소스 파일 목록 -->
    </qresource>
</RCC>

빌드 및 실행

mkdir build
cd build
cmake ..
make
./MyQtApp

Qt6를 사용하는 경우

Qt6에서는 CMake와의 통합이 더욱 간소화되었습니다.

src/CMakeLists.txt 수정

# Qt6 패키지 찾기
find_package(Qt6 COMPONENTS Widgets REQUIRED)

# Qt 추가 설정
qt_standard_project_setup()

# 실행 파일 생성 및 Qt 라이브러리 링크
qt_add_executable(MyQtApp
    main.cpp
    MainWindow.h
    ${CMAKE_SOURCE_DIR}/ui/MainWindow.ui
    ${CMAKE_SOURCE_DIR}/resources/resources.qrc
)

target_link_libraries(MyQtApp PRIVATE Qt6::Widgets)
  • qt_standard_project_setup(): 기본적인 프로젝트 설정을 자동으로 적용합니다.
  • qt_add_executable(): Qt6에서 제공하는 함수로, UI 파일과 리소스 파일을 자동으로 처리합니다.

주요 설정 설명

find_package()

  • Qt 모듈을 찾고 CMake에 필요한 정보를 제공합니다.
  • COMPONENTS를 통해 필요한 Qt 모듈을 지정합니다. 예: Widgets, Core, Gui 등.

qt5_wrap_ui(), qt5_add_resources()

  • UI 파일과 리소스 파일을 처리하여 C++ 코드로 변환합니다.
  • UI 파일은 uic를 통해 처리되고, 리소스 파일은 rcc를 통해 처리됩니다.

target_link_libraries()

  • Qt 라이브러리를 실행 파일에 링크합니다.
  • 모던 CMake에서는 Qt5::Widgets와 같은 타겟을 사용합니다.

target_include_directories()

  • qt5_wrap_ui()로 생성된 헤더 파일을 포함하기 위해 CMAKE_CURRENT_BINARY_DIR을 인클루드 디렉토리에 추가합니다.

Qt 플러그인 및 추가 모듈 사용

필요에 따라 추가적인 Qt 모듈을 사용할 수 있습니다.

예제: 네트워크 모듈 추가

find_package(Qt5 COMPONENTS Widgets Network REQUIRED)

# ...

target_link_libraries(MyQtApp PRIVATE Qt5::Widgets Qt5::Network)

CMake와 Qt Designer의 통합

  • Qt Designer에서 .ui 파일을 편집하고, CMake를 통해 자동으로 처리할 수 있습니다.
  • .ui 파일을 수정한 후 다시 빌드하면 변경 사항이 반영됩니다.

플랫폼별 설정

Qt 애플리케이션을 다양한 플랫폼에서 빌드하기 위해 플랫폼별 설정을 추가할 수 있습니다.

예제: macOS 번들 생성

set_target_properties(MyQtApp PROPERTIES
    MACOSX_BUNDLE TRUE
    MACOSX_BUNDLE_INFO_PLIST ${CMAKE_SOURCE_DIR}/Info.plist
)
  • MACOSX_BUNDLE: macOS에서 애플리케이션 번들을 생성합니다.
  • MACOSX_BUNDLE_INFO_PLIST: 번들의 메타데이터를 정의하는 Info.plist 파일을 지정합니다.

참고 자료

반응형