개발 이야기/CMake

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

nodiscard 2024. 12. 11. 17:00

이번 글에서는 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 파일을 지정합니다.

참고 자료

반응형