CMake는 무엇입니까?
Wikipedia에 따르면 :
CMake는 컴파일러 독립적 인 방법을 사용하여 소프트웨어의 빌드 프로세스를 관리하는 [...] 소프트웨어입니다. 여러 라이브러리에 의존하는 디렉토리 계층 구조 및 애플리케이션을 지원하도록 설계되었습니다. make, Apple의 Xcode 및 Microsoft Visual Studio와 같은 기본 빌드 환경과 함께 사용됩니다.
CMake를 사용하면 더 이상 컴파일러 / 빌드 환경에 특정한 별도의 설정을 유지할 필요가 없습니다. 당신은 하나 개의 구성을하고, 그 작동 많은 환경.
CMake는 같은 파일에서 아무것도 변경하지 않고 동일한 파일 에서 Microsoft Visual Studio 솔루션, Eclipse 프로젝트 또는 Makefile 미로를 생성 할 수 있습니다.
코드가 포함 된 여러 디렉터리가있는 경우 CMake는 프로젝트를 컴파일하기 전에 수행해야하는 모든 종속성, 빌드 순서 및 기타 작업을 관리합니다. 실제로 아무것도 컴파일하지 않습니다. CMake를 사용하려면 CMakeLists.txt라는 구성 파일을 사용하여 컴파일해야하는 실행 파일, 링크 된 라이브러리, 프로젝트에있는 디렉터리 및 내부에있는 내용, 플래그와 같은 세부 정보를 알려야합니다. 또는 필요한 다른 것 (CMake는 매우 강력합니다).
이것이 올바르게 설정된 경우 CMake를 사용하여 선택한 "기본 빌드 환경"이 작업을 수행하는 데 필요한 모든 파일을 만듭니다. Linux에서는 기본적으로 Makefile을 의미합니다. 따라서 CMake를 실행하면 자체 사용을위한 파일과 Makefile
. 그 후에해야 할 일은 코드 편집을 마칠 때마다 루트 폴더에서 콘솔에 "make"를 입력하는 것입니다. 그러면 컴파일되고 연결된 실행 파일이 만들어집니다.
CMake는 어떻게 작동합니까? 그것은 무엇을합니까?
다음은 전체적으로 사용할 프로젝트 설정의 예입니다.
simple/
CMakeLists.txt
src/
tutorial.cxx
CMakeLists.txt
lib/
TestLib.cxx
TestLib.h
CMakeLists.txt
build/
각 파일의 내용은 나중에 표시되고 설명됩니다.
CMake는 프로젝트의 루트 CMakeLists.txt
에 따라 프로젝트 cmake
를 설정하고 콘솔에서 실행 한 모든 디렉터리 에서 수행 합니다. 프로젝트의 루트가 아닌 폴더에서이 작업을 수행하면 소스 외부 빌드 라고 불리는 것이 생성됩니다. 즉, 컴파일 중에 생성 된 파일 (obj 파일, lib 파일, 실행 파일)이 해당 폴더에 배치됩니다. , 실제 코드와 별도로 유지됩니다. 혼란을 줄이는 데 도움이되며 다른 이유로도 선호됩니다.
cmake
루트 이외의 다른 곳에서 실행하면 어떻게되는지 모르겠습니다 CMakeLists.txt
.
이 예제에서는 모든 build/
파일을 폴더 안에 배치하기를 원하므로 먼저 거기로 이동 한 다음 루트가있는 디렉터리를 CMake에 전달해야 CMakeLists.txt
합니다.
cd build
cmake ..
기본적으로 이것은 내가 말했듯이 Makefile을 사용하여 모든 것을 설정합니다. 다음은 빌드 폴더의 모습입니다.
simple/build/
CMakeCache.txt
cmake_install.cmake
Makefile
CMakeFiles/
(...)
src/
CMakeFiles/
(...)
cmake_install.cmake
Makefile
lib/
CMakeFiles/
(...)
cmake_install.cmake
Makefile
이 모든 파일은 무엇입니까? 걱정해야 할 것은 Makefile과 프로젝트 폴더뿐입니다 .
통지 src/
및 lib/
폴더를. 이것들은 simple/CMakeLists.txt
명령을 사용하여 그들을 가리 키기 때문에 만들어졌습니다 add_subdirectory(<folder>)
. 이 명령은 CMake에게 해당 폴더에서 다른 CMakeLists.txt
파일 을 찾고 해당 스크립트를 실행하도록 지시하므로이 방식으로 추가 된 모든 하위 디렉토리 에는 파일 이 있어야합니다CMakeLists.txt
. 이 프로젝트에서는 simple/src/CMakeLists.txt
실제 실행 파일 simple/lib/CMakeLists.txt
을 빌드하는 방법 과 라이브러리를 빌드하는 방법을 설명합니다. CMakeLists.txt
설명 하는 모든 대상은 기본적으로 빌드 트리 내의 하위 디렉터리에 배치됩니다. 그래서, 잠시 후
make
에서 완료된 콘솔 build/
에 일부 파일이 추가되었습니다.
simple/build/
(...)
lib/
libTestLib.a
(...)
src/
Tutorial
(...)
프로젝트가 빌드되고 실행 파일을 실행할 준비가되었습니다. 실행 파일을 특정 폴더에 넣으려면 어떻게해야합니까? 적절한 CMake 변수를 설정하거나 특정 대상의 속성을 변경합니다 . 나중에 CMake 변수에 대해 자세히 알아보십시오.
내 프로젝트를 빌드하는 방법을 CMake에 어떻게 알릴 수 있습니까?
다음은 소스 디렉토리에있는 각 파일의 내용입니다.
simple/CMakeLists.txt
:
cmake_minimum_required(VERSION 2.6)
project(Tutorial)
# Add all subdirectories in this project
add_subdirectory(lib)
add_subdirectory(src)
필요한 최소 버전은 항상 설정해야합니다. 그렇지 않은 경우 CMake에서 발생하는 경고에 따라 설정해야합니다. CMake의 버전을 사용하십시오.
프로젝트 이름은 나중에 사용할 수 있으며 동일한 CMake 파일에서 둘 이상의 프로젝트를 관리 할 수 있다는 사실을 알려줍니다. 그래도 자세히 다루지는 않겠습니다.
이전에 언급했듯이 add_subdirectory()
프로젝트에 폴더를 추가합니다. 즉, CMake는 폴더에 CMakeLists.txt
내부 가있을 것으로 예상하고 계속하기 전에 실행됩니다. 그런데 CMake 함수를 정의한 경우 CMakeLists.txt
하위 디렉터리의 다른 함수에서 사용할 수 있지만 사용하기 전에 정의해야 add_subdirectory()
합니다. 그렇지 않으면 찾을 수 없습니다. CMake는 라이브러리에 대해 더 똑똑하므로 이런 종류의 문제가 발생하는 유일한 경우 일 것입니다.
simple/lib/CMakeLists.txt
:
add_library(TestLib TestLib.cxx)
나만의 라이브러리를 만들려면 이름을 지정한 다음 빌드 된 모든 파일을 나열합니다. 똑바로. foo.cxx
컴파일 할 다른 파일이 필요 하면 대신 add_library(TestLib TestLib.cxx foo.cxx)
. 이것은 예를 들어 다른 디렉토리의 파일에도 적용됩니다 add_library(TestLib TestLib.cxx ${CMAKE_SOURCE_DIR}/foo.cxx)
. 나중에 CMAKE_SOURCE_DIR 변수에 대해 자세히 알아보십시오.
이것으로 할 수있는 또 다른 일은 공유 라이브러리를 원하도록 지정하는 것입니다. 예 : add_library(TestLib SHARED TestLib.cxx)
. 두려워하지 마세요. CMake가 여러분의 삶을 더 쉽게 만들어주는 곳입니다. 공유 여부에 관계없이 이제 이런 방식으로 생성 된 라이브러리를 사용하기 위해 처리해야 할 것은 여기에 지정한 이름뿐입니다. 이 라이브러리의 이름은 이제 TestLib이며 프로젝트의 어느 곳에서나 참조 할 수 있습니다 . CMake가 찾을 것입니다.
종속성을 나열하는 더 좋은 방법이 있습니까? 확실히 그렇습니다 . 이에 대한 자세한 내용은 아래를 확인하십시오.
simple/lib/TestLib.cxx
:
#include <stdio.h>
void test() {
printf("testing...\n");
}
simple/lib/TestLib.h
:
#ifndef TestLib
#define TestLib
void test();
#endif
simple/src/CMakeLists.txt
:
# Name the executable and all resources it depends on directly
add_executable(Tutorial tutorial.cxx)
# Link to needed libraries
target_link_libraries(Tutorial TestLib)
# Tell CMake where to look for the .h files
target_include_directories(Tutorial PUBLIC ${CMAKE_SOURCE_DIR}/lib)
이 명령 은 물론 실행 파일을 대신 생성한다는 점을 제외 add_executable()
하면과 정확히 동일하게 작동 add_library()
합니다. 이 실행 파일은 이제 target_link_libraries()
. tutorial.cxx는 TestLib 라이브러리에있는 코드를 사용하므로 다음과 같이 CMake를 가리 킵니다.
마찬가지로, 어떤 소스에 의해 #include하는 모든 .H 파일 add_executable()
이 있습니다 하지 소스가 어떻게 든 추가 할 필요가 같은 디렉토리에. 을 위해하지 않으면 target_include_directories()
명령, lib/TestLib.h
전체 있도록 튜토리얼을 컴파일 할 때 찾을 수없는 것 lib/
폴더에 추가됩니다은 #include를 검색 할 디렉토리를 포함한다. include_directories()
모든 실행 파일에 대해 전체적으로 대상을 설정하므로 대상을 지정할 필요가 없다는 점을 제외하면 유사한 방식으로 작동 하는 명령 을 볼 수도 있습니다 . 다시 한번 CMAKE_SOURCE_DIR에 대해 설명하겠습니다.
simple/src/tutorial.cxx
:
#include <stdio.h>
#include "TestLib.h"
int main (int argc, char *argv[])
{
test();
fprintf(stdout, "Main\n");
return 0;
}
"TestLib.h"파일이 어떻게 포함되어 있는지 확인하십시오. 전체 경로를 포함 할 필요가 없습니다. CMake는 target_include_directories()
.
기술적으로 당신은없이 할 다음과 같이 간단한 소스 트리에, 수 말하기 CMakeLists.txt
에서의 lib/
과 src/
및처럼 뭔가를 추가 add_executable(Tutorial src/tutorial.cxx)
로 simple/CMakeLists.txt
. 그것은 당신과 당신의 프로젝트의 필요에 달려 있습니다.
CMake를 올바르게 사용하려면 그 밖에 무엇을 알아야합니까?
(이해와 관련된 일명 주제)
패키지 찾기 및 사용 : 이 질문에 대한 대답 은 내가 할 수있는 것보다 더 잘 설명합니다.
변수 및 함수 선언, 제어 흐름 사용 등 : CMake가 제공하는 기본 사항을 설명하고 일반적으로 좋은 소개가되는 이 자습서 를 확인하십시오 .
CMake 변수 : 많은 것이 있으므로 다음은 올바른 방향으로 나아 가기위한 단기 집중 과정입니다. CMake wiki는 변수 및 표면적으로는 다른 것들 에 대한 더 자세한 정보를 얻을 수있는 좋은 장소 입니다.
빌드 트리를 다시 빌드하지 않고 일부 변수를 편집 할 수 있습니다. 이를 위해 ccmake를 사용하십시오 ( CMakeCache.txt
파일을 편집 합니다). 에 기억 c
변경 한 후 함께 할 때 onfigure g
업데이트 된 구성 enerate 메이크.
변수 사용에 대해 배우 려면 이전에 참조한 자습서 를 읽으십시오. 그러나 변수 set(<variable name> value)
를 변경하거나 생성하는 방법은 짧습니다
.
${<variable name>}
그것을 사용합니다.
CMAKE_SOURCE_DIR
: 소스의 루트 디렉토리입니다. 이전 예에서 이것은 항상 다음과 같습니다./simple
CMAKE_BINARY_DIR
: 빌드의 루트 디렉토리입니다. 이전 예에서 이것은 simple/build/
과 같지만 cmake simple/
과 같은 폴더에서 실행 한 경우 해당 빌드 트리의 foo/bar/etc/
모든 참조 CMAKE_BINARY_DIR
는 /foo/bar/etc
.
CMAKE_CURRENT_SOURCE_DIR
: 전류 CMakeLists.txt
가있는 디렉토리 . 이것은 전체적으로 변경됨을 의미합니다. simple/CMakeLists.txt
yields /simple
에서 인쇄하고 simple/src/CMakeLists.txt
yields 에서 인쇄합니다 /simple/src
.
CMAKE_CURRENT_BINARY_DIR
: 당신은 아이디어를 얻습니다. 이 경로는 빌드가있는 폴더뿐만 아니라 현재 CMakeLists.txt
스크립트의 위치 에 따라 다릅니다 .
이것이 왜 중요한가요? 소스 파일은 분명히 빌드 트리에 있지 않습니다. 당신이 뭔가하려고하면 target_include_directories(Tutorial PUBLIC ../lib)
앞의 예를, 해당 경로는 쓰기와 같은 것 말을하는 것입니다 빌드 트리를 기준으로 할 것이다 ${CMAKE_BINARY_DIR}/lib
내부 볼 것이다, simple/build/lib/
. 거기에는 .h 파일이 없습니다. 기껏해야 libTestLib.a
. ${CMAKE_SOURCE_DIR}/lib
대신 원합니다 .
CMAKE_CXX_FLAGS
: 컴파일러 (이 경우 C ++ 컴파일러)에 전달할 플래그입니다. 또한 이 DEBUG로 설정되어 CMAKE_CXX_FLAGS_DEBUG
있으면 대신 사용됩니다 CMAKE_BUILD_TYPE
. 이와 같은 것이 더 있습니다. CMake wiki를 확인하십시오 .
CMAKE_RUNTIME_OUTPUT_DIRECTORY
: 빌드시 모든 실행 파일을 저장할 위치를 CMake에 알립니다. 이것은 글로벌 설정입니다. 예를 들어로 설정하고 bin/
모든 것을 깔끔하게 배치 할 수 있습니다. EXECUTABLE_OUTPUT_PATH
유사하지만 우연히 발견 될 경우를 대비하여 더 이상 사용되지 않습니다.
CMAKE_LIBRARY_OUTPUT_DIRECTORY
: 마찬가지로 모든 라이브러리 파일을 저장할 위치를 CMake에 알리는 전역 설정입니다.
대상 속성 : 실행 파일이나 라이브러리 (또는 아카이브 ... 아이디어를 얻을 수 있음) 등 하나의 대상에만 영향을주는 속성을 설정할 수 있습니다. 다음은 사용 방법에 대한 좋은 예 입니다 set_target_properties()
.
소스를 대상에 자동으로 추가하는 쉬운 방법이 있습니까? GLOB 를 사용 하여 동일한 변수 아래 주어진 디렉토리의 모든 항목을 나열합니다. 구문 예는 FILE(GLOB <variable name> <directory>/*.cxx)
.
다른 빌드 유형을 지정할 수 있습니까? 예, 이것이 어떻게 작동하는지 또는 이것의 한계에 대해 잘 모르겠습니다. 아마도 약간의 if / then'ning이 필요할 수 있지만 CMake는 CMAKE_CXX_FLAGS_DEBUG
예를 들어 기본값과 같은 아무것도 구성하지 않고 몇 가지 기본 지원을 제공 합니다. CMakeLists.txt
를 통해 파일 내에서 빌드 유형을 설정 set(CMAKE_BUILD_TYPE <type>)
하거나 적절한 플래그를 사용하여 콘솔에서 CMake를 호출 하여 설정할 수 있습니다 ( 예 : cmake -DCMAKE_BUILD_TYPE=Debug
.
CMake를 사용하는 프로젝트의 좋은 예가 있습니까? Wikipedia에는 CMake를 사용하는 오픈 소스 프로젝트 목록이 있습니다. 온라인 자습서는 지금까지 이와 관련하여 저에게 실망 스러웠지만 이 Stack Overflow 질문 에는 꽤 멋지고 이해하기 쉬운 CMake 설정이 있습니다. 한 번 볼 가치가 있습니다.
코드에서 CMake의 변수 사용 : 다음은 빠르고 더러운 예제입니다 ( 다른 자습서에서 수정 됨 ).
simple/CMakeLists.txt
:
project (Tutorial)
# Setting variables
set (Tutorial_VERSION_MAJOR 1)
set (Tutorial_VERSION_MINOR 1)
# Configure_file(<input> <output>)
# Copies a file <input> to file <output> and substitutes variable values referenced in the file content.
# So you can pass some CMake variables to the source code (in this case version numbers)
configure_file (
"${PROJECT_SOURCE_DIR}/TutorialConfig.h.in"
"${PROJECT_SOURCE_DIR}/src/TutorialConfig.h"
)
simple/TutorialConfig.h.in
:
// Configured options and settings
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
CMake에 의해 생성 된 결과 파일 simple/src/TutorialConfig.h
:
// Configured options and settings
#define Tutorial_VERSION_MAJOR 1
#define Tutorial_VERSION_MINOR 1
이것들을 영리하게 사용하면 라이브러리를 끄는 것과 같은 멋진 일을 할 수 있습니다. 조만간 더 큰 프로젝트에서 매우 유용하게 될 약간 더 고급 기능이 있기 때문에이 튜토리얼 을 살펴 보는 것이 좋습니다 .
그 밖의 모든 것에 대해 Stack Overflow는 특정 질문과 간결한 답변으로 넘쳐나 며 초보자를 제외한 모든 사람에게 좋습니다.