Programming Tools/CMake

[CMake] Git Submodules/external library(서브모듈, 외부 라이브러리)를 이용하기

LiDARian 2021. 9. 6. 14:00
반응형

 

 

Git Submodules를 이용해보자.

 

Git에 대해서 잘 모른다면, 혹은 Git 관련 커맨드라인 명령어에 대해서 잘 모른다면 다음 글을 먼저 읽어보자

2021.08.04 - [Computer_Engineering/Git] - [Git] 초보를 위한 깃허브 사용법 (Github) 1편

2021.08.06 - [Computer_Engineering/Git] - [Git] 초보를 위한 깃허브 사용법 (Github) 2편

 

Git에서 submodule의 의미는 다음 글들을 읽어보는 것이 더 좋을 것 같다.

git에서 submodule이란???

Git 의 서브모듈(Submodule) - Sungho's Blog (sgc109.github.io)

 

 

다음 .gitignore파일을 추가하자.

 

# Prerequisites
*.d

# Compiled Object files
*.slo
*.lo
*.o
*.obj

# Precompiled Headers
*.gch
*.pch

# Compiled Dynamic libraries
*.so
*.dylib
*.dll

# Fortran module files
*.mod
*.smod

# Compiled Static libraries
*.lai
*.la
*.a
*.lib

# Executables
*.exe
*.out
*.app

# CMake
CMakeLists.txt.user
CMakeCache.txt
CMakeFiles
CMakeScripts
Testing
Makefile
cmake_install.cmake
install_manifest.txt
compile_commands.json
CTestTestfile.cmake
_deps

# Build Folder
out/build/

# everything called a build folder
[Bb][Uu][Ii][Ll][Dd]/

 

다음 명령어를 실행해서 외부 라이브러리를 다운받는다.
해당 라이브러리는 glfw로, ubuntu GUI 및 그래픽 렌더링 라이브러리이다.

소개는 다음 링크를 참고하자. (링크)

 

git init
git submodule add https://github.com/glfw/glfw.git external/glfw

 

이러면 cmake_practice 폴더 아래에 external/glfw폴더가 생김과 동시에 해당 git에서 모든 코드가 다운로드 된다.

 

다 다운로드 되면 다음과 같이 처리해준다.

 

git add .
git commit -am "add submodules"

 

아래의 명령어를 터미널에 쳐준다.

 

git init
git status
git add .
git status

 

다음 쉘 파일을 만들어서 쉽게 명령어 세트를 동작시키고자한다.

 

touch configure.sh
touch build.sh
touch run.sh

chmod +x configure.sh build.sh run.sh

 

윈도우에서는 .bat이나 cmake gui를 사용하면 된다.

 

configure.sh 파일을 만들고 다음과 같이 쉘 명령어를 넣어준다.

 

#! /bin/sh

cmake -S . -B out/build

 

build.sh도,

 

#! /bin/sh

cd out/build ; make

 

run.sh도 해준다.

 

#! /bin/sh

cd out/build ; ./OLAS

 

다음은 CMakeLists.txt를 수정한다. 설명은 주석을 참고하자.

 

cmake_minimum_required(VERSION 3.21.1)

# 프로젝트명 : 실행파일 이름이 된다.
project(OLAS)

# 빌드해서 나올 것들. 프로젝트명을 실행파일 이름으로 한다. 빌드 대상은 main.cpp
add_executable(${PROJECT_NAME} main.cpp)

# 빌드할 라이브러리 지정. 하위폴더를 지정
add_subdirectory(Adder)

add_subdirectory(external/glfw)

# 헤더파일을 추가하는 곳을 지정. #include "Adder/adder.h"라고 안적을 수 있다.
target_include_directories(${PROJECT_NAME} PRIVATE Adder)

# 링크할 라이브러리를 찾는곳. 디렉토리를 빌드하기 위해 경로를 지정한다. 이때 경로는 build된 파일이 있는 경로. 즉, out/build 기준이다.
target_link_directories(${PROJECT_NAME} PRIVATE Adder)

# exe파일에 링크할 라이브러리
target_link_libraries(${PROJECT_NAME} adder)

 

이제 빌드해보자

 

configure.sh
build.sh

 

configure.sh에서 다음과 같이 수정하면 glfw의 몇가지 옵션을 끌 수 있다.


glfw의 옵션은 glfw의 CMakeLists.txt를 확인하는 것이 좋다. 예를 들어 CMakeLists.txt에서 다음과 같은 옵션명을 확인하면 된다.

 

 

위 사진의 가장 아래가 옵션값인데, 이를 사용하여 configure.sh를 다음과 같이 설정할 수 있다.

 

#! /bin/sh

cmake -DGLFW_BUILD_DOCS=OFF -S . -B out/build

 


 

 


 

커맨드에서 다음과 같이 명령하자.

 

configure.sh
build.sh

 

명령 수행 후 나오는 결과를 보면, "cmake는 make할 때 무엇이 필요한지 timestamp에 따라 정하고, make는 그 timestamp를 따라 필요한 것만 컴파일한다."는 것을 알 수 있다. 이미 컴파일되었거나 불필요한 부분은 다시 컴파일하지 않는다.

 

하지만 아직 glfw가 main.cpp에는 추가되지 않았다. 다음과 같이 추가하자.

top-level의 CMakeLists.txt를 다음과 같이 수정한다.

cmake_minimum_required(VERSION 3.21.1)

# 프로젝트명 : 실행파일 이름이 된다. 버전도 여기에 적을 수 있다.
project(OLAS)

# 빌드해서 나올 것들. 프로젝트명을 실행파일 이름으로 한다. 빌드 대상은 main.cpp
add_executable(${PROJECT_NAME} main.cpp)

# 빌드할 라이브러리 지정. 하위폴더를 지정
add_subdirectory(Adder)

add_subdirectory(external/glfw)

# 헤더파일을 추가하는 곳을 지정. #include "Adder/adder.h"라고 안적을 수 있다.
target_include_directories(${PROJECT_NAME} 
    PUBLIC Adder
    PUBLIC external/glfw/include
)

# 링크할 라이브러리를 찾는곳. 디렉토리를 빌드하기 위해 경로를 지정한다. 이때 경로는 build된 파일이 있는 경로. 즉, out/build 기준이다.
target_link_directories(${PROJECT_NAME}
    PRIVATE Adder
    PRIVATE external/glfw/src
)

# exe파일에 링크할 라이브러리
target_link_libraries(${PROJECT_NAME} adder glfw)

 

main.cpp는 다음과 같이 수정한다.
아래는 glfw의 창을 띄웠다가 끄는 예제를 복붙한거다.

 

#include <iostream>
#include <adder.h>
#include <GLFW/glfw3.h>

using namespace std;


int main(int argc, char * argv[]){
   cout << "Hello" << '\n';
   cout << add(72.1, 73.8) << '\n';

   GLFWwindow *window;

    if( !glfwInit() )
    {
        fprintf( stderr, "Failed to initialize GLFW\n" );
        exit( EXIT_FAILURE );
    }

   window = glfwCreateWindow( 300, 300, "Gears", NULL, NULL );
    if (!window)
    {
        fprintf( stderr, "Failed to open GLFW window\n" );
        glfwTerminate();
        exit( EXIT_FAILURE );
    }

        // Main loop
    while( !glfwWindowShouldClose(window) )
    {
        // Swap buffers
        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    // Terminate GLFW
    glfwTerminate();

   return 0;
}

 

다음과 같이 명령한다.

configure.sh
build.sh
run.sh

 

다른 편집자가 git을 clone할 떄 submodule이 자동으로 같이 다운되도록하려면 다음과 같은 명령어를 쳐주자.

git submodule update --init --recursive

혹은 CMakeLists.txt를 통해서 같은 효과를 낼 수 있다. 다음 코드를 추가하자.

# Download all the Submodules
find_package(Git QUIET)
if(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git")
    option(GIT_SUBMODULE "Check submodules during build" ON)
    if(GIT_SUBMODULE)
        message(STATUS "Submodule update")
        execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive
                        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
                        RESULT_VARIABLE GIT_SUBMOD_RESULT)
        if(NOT GIT_SUBMOD_RESULT EQUAL "0")
            message(FATAL_ERROR "git submodule update --init failed with ${GIT_SUBMOD_RESULT}. please check...")
        endif()
    endif()
endif()

# Check all the Submodules
if(NOT EXISTS "${PROJECT_SOURCE_DIR}/external/glfw/CMakeLists.txt")
    message(FATAL_ERROR "git submodules was not downloaded! GIT_SUBMODULE was turned off or failed. Please...")
endif()

 

execute_process : 커맨드라인에 명령어를 치는 것과 같은 효과를 낸다.

 


 

 


공대생지식창고 오픈카톡방

https://open.kakao.com/o/swnAyLyc

 

공대생지식창고님의 오픈프로필

공대생에게 도움이 될만한 글을 씁니다. www.knowledgeforenginners.tistory.com

open.kakao.com

 

공대생지식창고 Github

engineerJPark (github.com)

 

engineerJPark - Overview

engineerJPark has 2 repositories available. Follow their code on GitHub.

github.com

 

반응형