Thursday, February 28, 2019

find_package가 지원되는 CMake module 만들기

Reference : https://cmake.org/cmake/help/v3.4/module/CMakePackageConfigHelpers.html#example-generating-package-files

여기서 예시된 cmake 프로젝트의 이름은 Foo 이다.
configure_file을 직접 쓸수도 있으나, 그보다는
include(CMakePackageConfigHelpers) 호출후 사용할 수 있는 명령어
configure_package_config_file 를 권장한다.
아래는 CMakeLists.txt의 예시로, 취소선은 version 선언을 생략한 것이다.

# foo/CMakeLists.txt
project(Foo)

set(INCLUDE_DIR ${CMAKE_SOURCE_DIR}/include/)     # find_package 로 알려줄 header file path
set(LIB_DIR ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})    # library 가 생성될 path 

...

add_library(foo src/foo.cpp)
target_link_libraries(foo some_lib_a some_lib_b some_lib_c)
...


include(CMakePackageConfigHelpers)                  # 명령어 추가. 
configure_package_config_file(cmake_modules/FooConfig.cmake.in  # <Input>
  ${PROJECT_NAME}Config.cmake                                   # <Output> 
  INSTALL_DESTINATION ${CMAKE_CURRENT_BINARY_DIR}               # <Desntination> of output. Both Absolute,relative
  PATH_VARS INCLUDE_DIR LIB_DIR)                                # <PATH_VARS> are the variables which contain install destinations

write_basic_package_version_file(
  ${CMAKE_CURRENT_BINARY_DIR}/FooConfigVersion.cmake
  VERSION 1.2.3
  COMPATIBILITY SameMajorVersion )

install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
              ${CMAKE_CURRENT_BINARY_DIR}/FooConfigVersion.cmake  # Version information 생략
        DESTINATION lib/${PROJECT_NAME}/cmake ) # /usr/local/lib/Foo/cmake/에 FooConfig.cmake 설치

# foo library 에 dependent한 module이 some_lib_[a/b/c] 를 자동으로 링크할 수 있도록 export.
export(TARGETS foo some_lib_a some_lib_b some_lib_c
 FILE "${CMAKE_BINARY_DIR}/fooTargets.cmake" )
export(PACKAGE ${PROJECT_NAME} ) 


이상의 cmake lists의 명령어가 cmake_modules/FooConfig.cmake.in 파일을 참고하여, FooConfig.cmake를 binary directory (예를 들면 build) 에 생성한다.

추가적으로 필요한 FooConfig.cmake.in 는 다음과 같다.

# foo/cmake_modules/FooConfig.cmake.in
set(FOO_VERSION x.y.z)
@PACKAGE_INIT@ 

# configure_package_config_file 함수가 호출하는 .cmake.in 에서는 set 대신 set_and_check를 권장.
set_and_check(FOO_INCLUDE_DIR "@PACKAGE_INCLUDE_DIR@"
set_and_check(FOO_LIB_DIR "@PACKAGE_LIB_DIR@")
set_and_check(FOO_SRC_DIR "@PROJECT_SOURCE_DIR@") # ${} 대신 @ 연산자로 foo module의 변수를 넘겨줌.

include("@CMAKE_BINARY_DIR@/fooTargets.cmake")  # CMakeLists.txt에서 export한 target들을 포함.
check_required_components(Foo) # component를 선언했을때만 필요


Bar project에서 foo package를 찾아보자.

# bar/CMakeLists.txt
...

find_package(Foo REQUIRED)
include_directories(${FOO_INCLUDE_DIR})  # FooConfig.cmake.in 에서 선언한 경로를 확인할 수 있음

add_executable(bar src/main.cpp)
target_link_libraries(bar foo) # libfoo.so 를 링크



...


TODO
export(PACKAGE ) 의 역할.
https://stackoverflow.com/questions/48661265/what-does-export-package-mean

P.S
cmake 를 실행하고 나면, build directory에 CMakeCache.txt가 생성된다. 다음은 find_package(OpenCV)의 결과, CMakeCache.txt에 추가된 message이다.

//The directory containing a CMake configuration file for OpenCV. OpenCV_DIR:PATH=/~~~~~/OpenCV-3.3.1-dev

이를통해 find_package는 /~~~~ 에 설치된 opencv의 configuration file, "OpenCVConfig.cmake" 를 선택했음을 알 수 있다. 해당 config.cmake

파일을 보면, find_package를 실행함으로써 주어진 정보들에 대해 알 수 있다.



Friday, February 15, 2019

git merge tool

$ sudo apt-get install meld
$ git config -global merge.tool meld
$ git merge [Other branch to merge]
$ git mergetool