본문 바로가기

CMAKE

[CMAKE] 1. VS CODE 코딩을 위한 CMAKE 경로 설정 하기(기본)

1. CMAKE란?

 

CMAKE는 단순히 VS Code 환경 내에서 파일 간의 빌드 프로세스 잡아주는 플랫폼이다. 친절한 컴파일러나 최신 개발환경에서는 딱히 세부적으로 경로를 잡아줄 일이 없이 간단한 경로추가와 main.c파일의 빌드 버튼만 누르면 바로 빌드가 가능하다. 하지만 VS Code(GNU 툴체인 , GCC 컴파일러 등)에서 개발할 경우 CMAKE를 통해 경로를 잡아주어 빌드 프로세스를 완성해야한다.

 

2. VS Code 내에서 테스트를 위한 C 코딩

 

경로는 먼저 D드라이브에서 Cmake_Test_2라는 폴더를 생성한다. (D:\Cmake_Test_2)

그리고 아래와 같이 main.c에서 코드를 입력한다. 간단한 덧셈, 곱셈 코드이다.

///main.c


#include <stdio.h>
#include "calculator.h"

int main()
{
    int x = 2;
    int y = 3;

    add(x, y);
    mul(x, y);

}

 

또한 경로를 복잡하게 하기 위해서 Cmake_Test_2내에 calculator.c를 담을 src폴더(D:\Cmake_Test_2\src) calculator.h를 담을 inc폴더(D:\Cmake_Test_2\inc)를 추가한다.

 

그리고 헤더파일과 소스파일에 각각 아래와 같이 코드를 추가한다.

 

///calculator.h


#include <stdio.h>

void add(int x, int y);
void mul(int x, int y);

 

///calculator.c

#include <stdio.h>
#include "calculator.h"

void add(int x, int y){
    printf("%d + %d = %d \n", x, y, x+y);
}

void mul(int x, int y){
    printf("%d * %d = %d \n", x, y, x*y);
}

위와 같이 설정을 진행하였다면, 아래와 같은 경로가 완성될 것이다.

 

3. 경로 설정을 위한 CMAKELIST 파일 만들기

 

위와 같이 코딩을 완료 했다면 main.c 파일을 빌드시키기 위한 CmakeLists.txt파일을 만들어야한다. 이 CmakeLists.txt를 최상위 디렉토리에 만들게 되면 최상위 CmakeLists.txt파일부터 빌드가 시작되어 각 디렉토리에 존재하는 CmakeLists.txt 파일로 또 타고 들어가면서 빌드가 진행된다. 여기서 꼭 알아야 하는 점은 최상위 디렉토리의 CmakeLists.txt파일부터 빌드가 시작된다는 것이다.

 

이해가 되기 쉽게 예를 들어보자.

 

두 가지 경우의 수가 있다.

 

최상위 디렉토리의 CmakeLists.txt에서 필요한 파일이 존재하는 모든 경로를 다 잡아주어 파일을 연결시키는 경우

최상위 디렉토리의 CmakeLists.txt에서 모든 경로를 다 잡지 않고, 필요한 파일이 존재하는 곳에 CmakeLists.txt 파일을 만들어 연결시키는 경우


글만 보면 잘 모르겠으니 ①의 경우와 ②의 경우를 예로 들면서 CmakeLists.txt에서 쓰이는 함수도 함께 알아보자.

 

<①의 경우>

 먼저 위와 같이 main.c가 존재하는 최상위 디렉토리에 CmakeLists.txt 파일을 추가하자.

CmakeLists.txt파일을 추가했다면 아래와 같이 코드를 추가하자.

cmake_minimum_required(VERSION 3.0) #cmake 버전 선언

add_library(TEST_FILES STATIC ${CMAKE_CURRENT_SOURCE_DIR}/src/calculator.c)     #calculator.h의 소스파일인 calculator.c파일을 TEST_FILES 이라는 라이브러리로 선언
target_include_directories(TEST_FILES PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/inc)   #calculator.c파일 참조하는 calculator.h파일이 있는 디렉토리를 포함시켜줌

add_executable(Test_make main.c)                    #컴파일 하고 싶은 파일인 main.c 파일을 test_make.exe 파일로 추출

target_link_libraries(Test_make PRIVATE TEST_FILES) #main.c가 calculator 파일들을 포함하고 있기 때문에 상위에서 선언된 TEST_FILES을 연결 시켜줌

cmake_minimum_required(VERSION 3.0) : 최상위 디렉토리의 CmakeLists.txt 파일에 디폴트로 꼭 추가하자.

cmake를 실행시키기 위한 최소 버전을 명시하는 함수라고 생각하면 된다.

 

add_library(TEST_FILES STATIC ${CMAKE_CURRENT_SOURCE_DIR}/src/calculator.c) : 

우리는 먼저 알아야할 것이 main.c에서 calculator.c와 헤더파일을 사용하는 것을 알고 있다. 이를 파일들의 연결을 어떻게 시켜주는지 생각해보자. 우리는 C 코딩에서 단순히 상위에 #include로 헤더만 추가하면 되었다. 하지만 main.c에 연결시키기 위해 CMAKE에서는 calculator.h의 소스파일인 calculator.c파일을 TEST_FILES 이라는 라이브러리로 선언하는 작업을 먼저 해야한다.

TEST_FILES은 라이브러리의 이름을 사용자가 원하는대로 설정해서 다른곳에서 TEST_FILES 이라는 이름만 사용하면 calculator파일이 포함된 라이브러리를 사용할 수 있다.

 

STATIC을 통해 모든 Cmakelists 파일에서 사용할 수 있도록 선언한다.

 

${CMAKE_CURRENT_SOURCE_DIR}/src/calculator.c calculator.c가 있는 파일의 경로(현재 CMakeLists.txt파일 기준으로부터의 경로)를 명시해서 주면 CMakeLists.txt파일이 해당 경로를 찾아갈 수 있다. 특히 ${CMAKE_CURRENT_SOURCE_DIR} 라는 것이 궁금할 수도 있는데, 이는 현재 디렉토리를 나타내는 명령어라고 생각하면 된다.


target_include_directories(TEST_FILES PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/inc) :   

이는 calculator.c파일 상단에 #include로 calculator.h파일을 포함시켰기에 calculator.h이 있는 디렉토리를 포함시켜주는 것이라고 생각하면 된다. 만약 어떤 c파일이 헤더파일을 아예 포함하지 않는 경우 이 함수를 쓸 필요는 없다.

add_executable(Test_make main.c) :

우리는 최종적으로 이 프로젝트 폴더 내의 main.c라는 파일을 컴파일 해야한다. 컴파일 및 실행을 도와주는 함수라고 생각하면 된다. 위와 같이 함수를 사용하면, 컴파일 하고 싶은 파일인 main.c 파일을 test_make.exe 파일로 추출한다고 생각하면 된다.

target_link_libraries(Test_make PRIVATE TEST_FILES) :

main.c가 calculator 파일을 사용하는 것을 우리는 이미 알고 있다. 이를 연결 시키기 위해서 사전 작업으로 calculator.c에 대한 라이브러리를 만든 것이다. target_link_libraries 함수를 통해서 상위에서 선언된 TEST_FILES을 이렇게 연결시켜줄 수 있다. 이 함수 또한 마찬가지로 실행할 파일이 어떤 파일도 포함하거나 사용하지 않는 경우 이 함수를 쓸 필요는 없다.

 

정리하자면,

컴파일할 파일(main.c)이 포함하는 파일(calculator.c, calculator.h)의 라이브러리를 생성(add_library 함수) 하고, 컴파일할 파일(main.c)을 실행시킬 수 있도록 exe 파일 생성(add_executable 함수) 및 실행할 파일(main.c)이 사용하는 add_library 함수를 통해 만든 라이브러리를 연결(target_link_libraries 함수)한다.

 

<②의 경우>

의 경우는 필요한 파일이 존재하는 곳에 CmakeLists.txt 파일을 만들어 연결시키는 경우이다.

즉 calculator.c가 있는 디렉토리에 CmakeLists.txt를 추가해서 실행시킨다는 것이다.

이 짓을 왜하냐? 라고 물을 수 있다. 이유는 최상위 디렉토리의 CmakeLists.txt파일에 모든 라이브러리와 경로를 다 때려 넣으면 나중에  CmakeLists.txt의 코드를 보수할 때, 혹은 파일이 추가될 때 굉장히 복잡해질 수 있기 때문이다.

 

이렇게 src 디렉토리에 CmakeLists.txt 파일을 하나 더 추가하자.

그리고 앞서 만든 TEST_FILES 라이브러리를 이 곳에 만들고, STATIC으로 선언하면 최상위 디렉토리의 CmakeLists.txt파일에서도 좀 더 효율적으로 간결하게 사용할 수 있다는 생각이 든다.

 

 src 디렉토리에 CmakeLists.txt 파일에 아래와 같이 코드를 추가해보자.

add_library(TEST_FILES STATIC calculator.c)
target_include_directories(TEST_FILES PUBLIC ${CMAKE_SOURCE_DIR}/inc)

아까 ①의 예시에서 만든 TEST_FILES 라이브러리를 하위 디렉토리의 CmakeLists.txt파일에서 만든 것이다.

①의 예시와 코드가 좀 다르다는 생각이 든다. 경로가 바뀐 이유는 선언하는 CmakeLists.txt의 입장에서 경로가 바뀌었기 때문이다. add_library에는 현재 디렉토리에 이미 calculator.c가 있으므로 별다른 경로를 전달해주지 않더라도 calculator.c만 써주면 바로 CmakeLists.txt파일이 c파일을 찾을 수 있다.

calculator.h가 존재하는 디렉토리는 현재 CmakeLists.txt파일의 경로로부터 가려면 뒤로 갔다가 inc디렉토리로 들어가는 과정을 거쳐야한다. 이럴 때는 쉽게 최상위 디렉토리부터 시작할 수 있도록하는 명령어인 ${CMAKE_SOURCE_DIR}를 사용한다.

 

이렇게  파일이 존재하는 곳에 CmakeLists.txt 파일을 만들어 해당 라이브러리만 선언할 수 있다.

 

이렇게 되면 최상위 디렉토리의 CmakeLists.txt 파일은 아래와 같이 간결하게 작성할 수 있다.

cmake_minimum_required(VERSION 3.0) #cmake 버전 선언

add_executable(Test_make main.c)                    #컴파일 하고 싶은 파일인 main.c 파일을 test_make.exe 파일로 추출
target_link_libraries(Test_make PRIVATE TEST_FILES) #main.c가 calculator 파일들을 포함하고 있기 때문에 상위에서 선언된 TEST_FILES을 연결 시켜줌

add_subdirectory(src)

위 코드에서는 add_subdirectory(src)라는 코드가 추가되었는데, 이 함수를 통해 최상위 디렉토리의 CmakeLists.txt 파일이 src 디렉토리의 CmakeLists.txt 파일로 이동이 가능하다. 꼭 넣어주어야 한다. 이러한 경로설정을 하지 않고 컴파일할 경우 컴파일러가 디렉토리를 찾지 못하는 경우가 발생한다. 

 

이렇게 의 경우를 통해 코딩을 하게 되면 좀 더 효율적이고 간결하게 코드 작성 및 보수가 가능하다.

 

4. 실행 단계

 

VS Code의 하위 터미널 창에서 D:\Cmake_Test_2의 위치에서 아래와 같은 명령어를 사용하여 빌드 파일을 생성해보자.

위 명령어를 실행하면 아래와 같이 build 디렉토리가 생성된 것을 알 수 있다.

cd build로 build 디렉토리로 이동해보자. 그리고 아래와 같이 컴파일을 진행하면 된다.

컴파일을 진행하면 아래와 같이 성공적으로 Test_make.exe 파일이 생성됨을 알 수 있다.

이를 윈도우의 cmd 창에서 실행해보자.

이렇게 우리가 만든 코드를 VS Code에서 컴파일 할 수 있다.

'CMAKE' 카테고리의 다른 글

[CMAKE] 2. 추가적인 CMAKE 경로 설정 방법  (0) 2023.09.20