CMake 시작하기
CMake
는 애플리케이션을 빌드, 테스트 및 패키징할 수 있는 도구 그룹입니다. Qt와 마찬가지로 모든 주요 개발 플랫폼에서 사용할 수 있습니다. 또한 다음과 같은 다양한 IDE에서 지원됩니다. Qt Creator.
이 섹션에서는 CMake 프로젝트에서 Qt를 사용하는 가장 기본적인 방법을 보여드리겠습니다. 먼저 기본 콘솔 애플리케이션을 생성합니다. 그런 다음 프로젝트를 GUI 애플리케이션으로 확장하여 Qt Widgets.
Qt로 기존 CMake 프로젝트를 빌드하는 방법을 알고 싶다면 명령줄에서 CMake로 프로젝트를 빌드하는 방법에 대한 문서를 참조하세요.
CMake 시작하기의 기본 사항을 배우려면 Cmake로 빌 드하기를 참조하세요: Qt 아카데미에서 CMake와 Qt로 시작하기 강좌를 수강하세요.
C++ 콘솔 애플리케이션 빌드하기
CMake
프로젝트는 CMake 언어로 작성된 파일로 정의됩니다. 메인 파일은 CMakeLists.txt
이라고 하며, 보통 실제 프로그램 소스와 같은 디렉터리에 위치합니다.
다음은 Qt를 사용하여 C++로 작성된 콘솔 애플리케이션의 일반적인 CMakeLists.txt
파일입니다:
cmake_minimum_required(VERSION 3.16) project(helloworld VERSION 1.0.0 LANGUAGES CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(Qt6 REQUIRED COMPONENTS Core) qt_standard_project_setup() qt_add_executable(helloworld main.cpp ) target_link_libraries(helloworld PRIVATE Qt6::Core)
내용을 살펴봅시다.
cmake_minimum_required(VERSION 3.16)
cmake_minimum_required()
프로젝트를 성공적으로 구성하는 데 필요한 최소 CMake 버전을 지정합니다. Qt에 필요한 최소 버전은 지원되는 CMake 버전을 참조하십시오.
project(helloworld VERSION 1.0.0 LANGUAGES CXX)
project()
프로젝트 이름과 기본 프로젝트 버전을 설정합니다. LANGUAGES
인수는 프로그램이 C++로 작성되었음을 CMake에 알립니다.
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON)
Qt 6는 C++ 버전 17 이상을 지원하는 컴파일러가 필요합니다. CMAKE_CXX_STANDARD
, CMAKE_CXX_STANDARD_REQUIRED
변수를 설정하여 이를 강제하면 컴파일러가 너무 오래된 경우 CMake에서 오류를 출력합니다.
find_package(Qt6 REQUIRED COMPONENTS Core)
이렇게 하면 CMake가 Qt 6을 조회하고 Core
모듈을 임포트하도록 지시합니다. CMake
에서 모듈을 찾을 수 없다면 계속 진행할 필요가 없으므로 REQUIRED
플래그를 설정하여 이 경우 CMake가 중단하도록 합니다.
성공하면 모듈은 모듈 변수에 문서화된 일부 CMake 변수를 설정합니다. 또한 아래에서 사용하는 Qt6::Core
대상을 임포트합니다.
find_package
가 성공하려면 CMake가 Qt XML 설치를 찾아야 합니다. Qt Creator 그리고 qt-cmake
(Windows의 경우qt-cmake.bat
)는 이를 투명하게 처리합니다.
바닐라 CMake를 직접 사용하는 경우, CMake에 Qt에 대해 알려주는 방법은 여러 가지가 있지만, 가장 일반적이고 권장되는 방법은 CMake 캐시 변수 CMAKE_PREFIX_PATH
에 Qt 6 설치 접두사를 포함하도록 설정하는 것입니다. 이 디렉터리는 Qt 바이너리가 설치되는 디렉터리입니다. Linux에서는 일반적으로 다음과 같이 보입니다: "~/Qt/6.8.2/gcc_64"
그리고 명령줄에 -DCMAKE_PREFIX_PATH=$HOME/Qt/6.8.2/gcc_64
으로 전달합니다.
참고: 크로스 컴파일(사용 중인 플랫폼이 아닌 다른 플랫폼에 대한 컴파일, 예: WebAssembly 또는 Android)과 바닐라 cmake
를 사용하는 경우 CMAKE_PREFIX_PATH
대신 CMAKE_TOOLCHAIN_FILE
을 설정합니다. Linux에서 툴체인 파일(특정 대상 플랫폼에 한정)은 일반적으로 다음과 유사한 경로에 위치합니다: "~/Qt/6.8.2/wasm_singlethread/lib/cmake/Qt6/qt.toolchain.cmake"
. CMAKE_PREFIX_PATH
, CMAKE_FIND_ROOT_PATH
, QT_HOST_PATH
와 같은 필수 변수를 설정합니다.
qt_standard_project_setup()
qt_standard_project_setup 명령은 일반적인 Qt 응용 프로그램에 대한 프로젝트 전체 기본값을 설정합니다.
무엇보다도 이 명령은 CMAKE_AUTOMOC
변수를 ON
로 설정하여 필요할 때 Qt의 Meta-Object Compiler (moc )가 투명하게 호출되도록 CMake가 자동으로 규칙을 설정하도록 지시합니다.
자세한 내용은 qt_standard_project_setup의 참조를 참조하십시오.
qt_add_executable(helloworld main.cpp )
qt_add_executable()은 helloworld
이라는 실행 파일(라이브러리가 아닌)을 대상으로 빌드하고 싶다고 CMake에 알려줍니다. 이 함수는 내장된 add_executable()
명령에 대한 래퍼이며, 정적 Qt 빌드에서 Qt 플러그인 연결, 라이브러리 이름의 플랫폼별 사용자 정의 등을 자동으로 처리하기 위한 추가 로직을 제공합니다.
대상은 C++ 소스 파일 main.cpp
에서 빌드해야 합니다.
일반적으로 여기에 헤더 파일을 나열하지 않습니다. 이는 헤더 파일을 명시적으로 나열하여 Meta-Object Compiler (moc)에서 처리하도록 해야 하는 qmake와는 다릅니다.
라이브러리 생성에 대해서는 qt_add_library를 참조하십시오.
target_link_libraries(helloworld PRIVATE Qt6::Core)
마지막으로, target_link_libraries
은 helloworld
실행 파일이 가져온 타겟을 참조하여 Qt Core 를 참조하여 위의 find_package()
호출에서 가져온 Qt6::Core
대상을 참조합니다. 이렇게 하면 링커에 올바른 인수를 추가할 뿐만 아니라 올바른 인클루드 디렉터리, 컴파일러 정의가 C++ 컴파일러에 전달되도록 합니다. PRIVATE
키워드는 실행 대상에 반드시 필요한 것은 아니지만 지정하는 것이 좋습니다. helloworld
가 실행 파일이 아닌 라이브러리인 경우 PRIVATE
또는 PUBLIC
를 지정해야 합니다(라이브러리의 헤더에 Qt6::Core
의 내용을 언급하는 경우PUBLIC
, 그렇지 않은 경우 PRIVATE
).
C++ GUI 애플리케이션 빌드하기
지난 섹션에서는 간단한 콘솔 애플리케이션을 위한 CMakeLists.txt 파일을 보여드렸습니다. 이제 이번에는 모듈의 Qt Widgets 모듈을 사용하는 GUI 애플리케이션을 만들어 보겠습니다.
이것이 전체 프로젝트 파일입니다:
cmake_minimum_required(VERSION 3.16) project(helloworld VERSION 1.0.0 LANGUAGES CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(Qt6 REQUIRED COMPONENTS Widgets) qt_standard_project_setup() qt_add_executable(helloworld mainwindow.ui mainwindow.cpp main.cpp ) target_link_libraries(helloworld PRIVATE Qt6::Widgets) set_target_properties(helloworld PROPERTIES WIN32_EXECUTABLE ON MACOSX_BUNDLE ON )
변경 사항을 살펴보겠습니다.
find_package(Qt6 REQUIRED COMPONENTS Widgets)
find_package
호출에서 Core
을 Widgets
으로 바꿉니다. 이렇게 하면 Qt6Widgets
모듈을 찾고 나중에 링크할 Qt6::Widgets
타깃을 제공합니다.
Qt6::Widgets
이 종속되어 있으므로 애플리케이션은 여전히 Qt6::Core
에 링크됩니다.
qt_standard_project_setup()
qt_standard_project_setup은 CMAKE_AUTOMOC
외에도 CMAKE_AUTOUIC
변수를 ON
로 설정합니다. 이렇게 하면 .ui
소스 파일에서 Qt의 User Interface Compiler (uic) 를 호출하는 규칙이 자동으로 생성됩니다.
qt_add_executable(helloworld mainwindow.ui mainwindow.cpp main.cpp )
우리는 Qt Widgets Designer 파일(mainwindow.ui
)과 해당 C++ 소스 파일(mainwindow.cpp
)을 애플리케이션 대상의 소스에 추가합니다.
include 지시어가 상대 경로를 사용하는 아래 예시와 같은 특정 경우에는 AUTOUIC 대신 qt_add_ui를 사용하여 ui_calculatorform.h
파일을 생성할 수 있습니다.
#include "src/files/ui_mainwindow.h"
qt_add_ui(calculatorform SOURCES mainwindow.ui INCLUDE_PREFIX src/files)
qt_add_ui
을 사용하는 경우 qt_add_executable
명령에 mainwindow.ui
을 전달할 필요가 없습니다.
target_link_libraries(helloworld PRIVATE Qt6::Widgets)
target_link_libraries
명령에서는 Qt6::Core
대신 Qt6::Widgets
에 연결합니다.
set_target_properties(helloworld PROPERTIES WIN32_EXECUTABLE ON MACOSX_BUNDLE ON )
마지막으로 애플리케이션 대상에 다음과 같은 효과로 속성을 설정합니다:
- Windows에서 콘솔 창이 생성되지 않도록 합니다.
- macOS에서 애플리케이션 번들을 만듭니다.
이러한 대상 프로퍼티에 대한 자세한 내용은 CMake 문서를 참조하세요.
프로젝트 구조화
하나 이상의 대상을 포함하는 프로젝트는 명확한 프로젝트 파일 구조의 이점을 누릴 수 있습니다. CMake의 서브디렉토리 기능을 사용하겠습니다.
프로젝트를 더 많은 대상으로 확장할 계획이므로 애플리케이션의 소스 파일을 하위 디렉터리로 옮기고 그 안에 CMakeLists.txt
을 새로 만듭니다.
<project root> ├── CMakeLists.txt └── src └── app ├── CMakeLists.txt ├── main.cpp ├── mainwindow.cpp ├── mainwindow.h └── mainwindow.ui
최상위 CMakeLists.txt
에는 전체 프로젝트 설정, find_package
및 add_subdirectory
호출이 포함됩니다:
cmake_minimum_required(VERSION 3.16) project(helloworld VERSION 1.0.0 LANGUAGES CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(Qt6 REQUIRED COMPONENTS Widgets) qt_standard_project_setup() add_subdirectory(src/app)
이 파일에 설정된 변수는 하위 디렉터리 프로젝트 파일에서 볼 수 있습니다.
애플리케이션의 프로젝트 파일 src/app/CMakeLists.txt
에는 실행 대상이 포함되어 있습니다:
qt_add_executable(helloworld mainwindow.ui mainwindow.cpp main.cpp ) target_link_libraries(helloworld PRIVATE Qt6::Widgets) set_target_properties(helloworld PROPERTIES WIN32_EXECUTABLE ON MACOSX_BUNDLE ON )
이러한 구조를 사용하면 라이브러리나 단위 테스트 등 프로젝트에 더 많은 대상을 쉽게 추가할 수 있습니다.
참고: 시스템에서 실행되는 모든 바이러스 백신 애플리케이션의 제외된 디렉터리 목록에 프로젝트 빌드 디렉터리를 추가하세요.
라이브러리 빌드
프로젝트가 성장함에 따라 애플리케이션 코드의 일부를 애플리케이션과 단위 테스트에서 사용하는 라이브러리로 전환하고 싶을 수 있습니다. 이 섹션에서는 이러한 라이브러리를 만드는 방법을 보여줍니다.
우리 애플리케이션은 현재 main.cpp
에 직접 비즈니스 로직을 포함하고 있습니다. 이전 섹션에서 설명한 대로 하위 디렉터리 "src/businesslogic"
에 businesslogic
라는 새 정적 라이브러리로 코드를 추출합니다.
간단하게 하기 위해 라이브러리는 하나의 C++ 소스 파일과 애플리케이션의 main.cpp
에 포함된 해당 헤더 파일로만 구성됩니다:
<project root> ├── CMakeLists.txt └── src ├── app │ ├── ... │ └── main.cpp └── businesslogic ├── CMakeLists.txt ├── businesslogic.cpp └── businesslogic.h
라이브러리의 프로젝트 파일(src/businesslogic/CMakeLists.txt
)을 살펴봅시다.
qt_add_library(businesslogic STATIC businesslogic.cpp ) target_link_libraries(businesslogic PRIVATE Qt6::Core) target_include_directories(businesslogic INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
내용을 살펴봅시다.
qt_add_library(businesslogic STATIC businesslogic.cpp )
add_library 명령은 라이브러리 businesslogic
를 만듭니다. 나중에 애플리케이션이 이 대상에 대해 링크하도록 할 것입니다.
STATIC
키워드는 정적 라이브러리를 나타냅니다. 공유 또는 동적 라이브러리를 만들려면 SHARED
키워드를 사용합니다.
target_link_libraries(businesslogic PRIVATE Qt6::Core)
정적 라이브러리가 있으므로 실제로 다른 라이브러리를 링크할 필요는 없습니다. 하지만 우리 라이브러리는 QtCore
의 클래스를 사용하므로 Qt6::Core
에 링크 종속성을 추가합니다. 그러면 필요한 QtCore
포함 경로와 전처리기 정의를 가져옵니다.
target_include_directories(businesslogic INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
라이브러리 API는 헤더 파일 businesslogic/businesslogic.h
에 정의되어 있습니다. target_include_directories를 호출하면 businesslogic
디렉터리의 절대 경로가 라이브러리를 사용하는 모든 대상에 대한 포함 경로로 자동으로 추가됩니다.
이렇게 하면 main.cpp
에서 businesslogic.h
을 찾기 위해 상대 경로를 사용할 필요가 없습니다. 대신 다음과 같이 작성하면 됩니다.
#include <businesslogic.h>
마지막으로 라이브러리의 하위 디렉터리를 최상위 프로젝트 파일에 추가해야 합니다:
add_subdirectory(src/app) add_subdirectory(src/businesslogic)
라이브러리 사용하기
이전 섹션에서 만든 라이브러리를 사용하려면 CMake에 해당 라이브러리에 대해 링크하도록 지시합니다:
target_link_libraries(helloworld PRIVATE
businesslogic
Qt6::Widgets
)
이렇게 하면 main.cpp가 컴파일될 때 businesslogic.h
을 찾을 수 있습니다. 또한 비즈니스 로직 정적 라이브러리는 helloworld
실행 파일의 일부가 됩니다.
CMake 용어로, 라이브러리 businesslogic
는 라이브러리의 모든 소비자(애플리케이션)가 충족해야 하는 사용 요구 사항 (포함 경로)을 지정합니다. target_link_libraries
명령이 이를 처리합니다.
리소스 추가하기
애플리케이션에 일부 이미지를 표시하고 싶으므로 Qt 리소스 시스템을 사용하여 이미지를 추가합니다.
qt_add_resources(helloworld imageresources PREFIX "/images" FILES logo.png splashscreen.png )
qt_add_resources 명령은 참조된 이미지가 포함된 Qt 리소스를 자동으로 생성합니다. C++ 소스 코드에서 지정된 리소스 접두사를 앞에 붙여서 이미지에 액세스할 수 있습니다:
logoLabel->setPixmap(QPixmap(":/images/logo.png"));
qt_add_resources 명령은 변수 이름 또는 대상 이름을 첫 번째 인수로 받습니다. 위의 예시와 같이 이 명령의 대상 기반 변형을 사용하는 것이 좋습니다.
번역 추가하기
Qt 프로젝트에서 문자열의 번역은 .ts
파일에 인코딩됩니다. 이 .ts
파일은 바이너리 .qm
파일로 컴파일된 다음 런타임에 Qt 애플리케이션에 의해 로드됩니다. 자세한 내용은 Qt를 사용한 국제화를 참조하십시오.
이 섹션에서는 helloworld
애플리케이션에 독일어 및 프랑스어 번역을 추가하는 방법을 설명합니다.
qt_standard_project_setup으로 두 언어를 모두 지정합니다:
qt_standard_project_setup(I18N_TRANSLATED_LANGUAGES de fr)
그런 다음 .qm
파일을 로드할 대상에서 qt_add_translations를 호출합니다:
qt_add_translations(helloworld)
첫 번째 구성에서 이 명령은 프로젝트의 소스 디렉터리에 helloworld_de.ts
및 helloworld_fr.ts
파일을 생성합니다. 이 파일에는 번역된 문자열이 포함되며 버전 관리하에 두어야 합니다.
이 명령은 또한 .ts
파일에서 .qm
파일을 자동으로 생성하는 빌드 시스템 규칙을 만듭니다. 기본적으로 .qm
파일은 리소스에 임베드되며 "/i18n"
리소스 접두사로 액세스할 수 있습니다.
.ts
파일의 항목을 업데이트하려면 update_translations
대상을 빌드하세요:
$ cmake --build . --target update_translations
.qm
파일 생성을 수동으로 트리거하려면 release_translations
타깃을 빌드합니다:
$ cmake --build . --target release_translations
.ts
파일 처리 및 리소스에 임베딩하는 방법에 대한 자세한 내용은 qt_add_translations 문서를 참조하세요.
qt_add_translations 명령은 편의상 래퍼입니다. .ts
파일과 .qm
파일의 처리 방식을 보다 세밀하게 제어하려면 기본 명령인 qt_add_lupdate와 qt_add_lrelease를 사용하십시오.
더 읽어보기
공식 CMake 문서는 CMake를 사용하는 데 있어 매우 귀중한 자료입니다.
공식 CMake 튜토리얼에서는 일반적인 빌드 시스템 작업을 다룹니다.
프로페셔널 CMake: 실용 가이드는 가장 관련성이 높은 CMake 기능에 대한 훌륭한 소개를 제공합니다.
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.