2015年10月2日金曜日

cmake / ExternalProject

Introduction

外部ライブラリーを git / submodule とcmake / add_subdirectory から cmake / ExternalProject を使うようにしたら楽になったので紹介したい。

Background

近年のソフトウェア開発プロジェクトは git リポジトリーと cmake プロジェクトで管理している。

これまで、外部ライブラリーへの依存は次のように解決していた。

  1. git: git submodule add hogehoge.git submodule/hogehoge
  2. cmake: add_subdirectory(submodule/hogehoge)
    • 外部ライブラリーが非cmakeなら: CMakeLists.txt を定義したり .sh と .bat を書いたりして対応

しかし、この方法では本来プロジェクトの直接制御下に無い外部ライブラリーに対して様々な問題への対処を考慮しなければならない事がままあった。

  • ターゲット名が被る: set_property(GLOBAL PROPERTY ALLOW_DUPLICATE_CUSTOM_TARGETS ON) で凌ぐ
  • CMAKEパラメーターを制御する必要がある: set(PARAMETER_NAME ON CACHE INTERNAL "") で凌ぐ
  • add_subdirectoryされCMAKEルートが変化する事に対応できなかったり、独自のスクリプトが仕込んであったり…: add_custom_targetadd_custom_command や .sh .bat を…

このように手間が増える事がままあった。

Usage

  1. cmake: include(ExternalProject)
  2. cmake: ExternalProject_Add( ... )

Example

OpenGL アプリで glbinding を採用するプロジェクト hoge を想定した例:

cmake_minimum_required(VERSION 2.8)
project(hoge)
include(ExternalProject)
ExternalProject_Add(external_glbinding
  GIT_REPOSITORY git@github.com:cginternals/glbinding.git
  GIT_TAG        v1.1.0
  PREFIX         ${CMAKE_CURRENT_BINARY_DIR}/external/glbinding
  INSTALL_DIR    ${CMAKE_CURRENT_BINARY_DIR}
  CMAKE_ARGS     -DOPTION_BUILD_TOOLS=off -DOPTION_BUILD_STATIC=on -DCMAKE_INSTALL_PREFIX=${CMAKE_CURRENT_BINARY_DIR}
)
include_directories(${CMAKE_CURRENT_BINARY_DIR}/include)
link_directories(${CMAKE_CURRENT_BINARY_DIR}/lib)
add_executable(hoge hoge.cxx)
target_link_libraries(hoge glbinding)
add_dependencies(hoge external_glbinding)
// hoge.cxx
#include <glbinding/Version.h>
int main() { }

Reference

Appendix

もし、gtestのように、対象のプロジェクトにinstall()が無い場合にはINSTALL_COMMANDで比較的簡単かつやや強引に対応できます。

ExternalProject_Add(external_gtest
  GIT_REPOSITORY git@github.com:svn2github/googletest.git
  PREFIX         ${CMAKE_CURRENT_BINARY_DIR}/external/gtest
  INSTALL_DIR    ${CMAKE_CURRENT_BINARY_DIR}
  CMAKE_ARGS     -DCMAKE_INSTALL_PREFIX=${CMAKE_CURRENT_BINARY_DIR}
  INSTALL_COMMAND
    COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_BINARY_DIR}/external/gtest/src/external_gtest/include ${CMAKE_CURRENT_BINARY_DIR}/include
    COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/external/gtest/src/external_gtest-build/libgtest.a ${CMAKE_CURRENT_BINARY_DIR}/lib
    COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/external/gtest/src/external_gtest-build/libgtest_main.a ${CMAKE_CURRENT_BINARY_DIR}/lib
)

0 件のコメント:

コメントを投稿