みつきんのメモ

組み込みエンジニアです。Interface誌で「Yocto Projectではじめる 組み込みLinux開発入門」連載中

CMakeLists.txt 覚書

2020年に書き直したものはこちら

プロジェクト名の変数化

プロジェクト名を変数化しておくといろいろと便利。set(変数名 値)で変数を定義できる。

cmake_minimum_required(VERSION 2.8)
set(PROJ_NAME hello)

add_executable(${PROJ_NAME}
    ${PROJECT_SOURCE_DIR}/main.cpp
)

C++14有効化

include(CheckCXXCompilerFlag)コンパイラフラグチェックを有効化

include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++14" COMPILER_SUPPORTS_CXX14)
if(COMPILER_SUPPORTS_CXX14)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
else()
    message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++14 support. Please use a different C++ compiler.")
endif()

pkg-configによるモジュールの追加

find_package(PkgConfig)でpkg-configを有効化

# find opengl via pkg-config
find_package(PkgConfig)
pkg_check_modules(OPENCV REQUIRED opencv)
pkg_check_modules(LIBAV REQUIRED libavcodec libavfilter libavformat libavutil libavdevice libavformat libavresample)

この例ではOpenCV関連の変数のプリフィックスOPENCV_となる。インクルードディレクトリはOPENCV_INCLUDE_DIRS、ライブラリはOPENCV_LIBRARIESとしてアクセスできるようになる。

LIBAVのように複数のパッケージをまとめて検索することもできる

インクルードディレクトリの設定

INCLUDE_DIRECTORIESのように変数にパスを設定しておき、include_directoriesで登録する。

# Include directories for this project
set(INCLUDE_DIR
  ${OPENCV_INCLUDE_DIRS}
  ${QT4_INCLUDE_DIRS}
  ${PROJECT_SOURCE_DIR}/include
)

# Add a include files
include_directories("${INCLUDE_DIR}")

ここによると、 次にようにINCLUDE_DIRECTORIES変数に設定することでもできるらしい。

set(INCLUDE_DIRECTORIES
  ${PROJECT_SOURCE_DIR}/../include
)

追加のライブラリ(dll)

LIBRARIESのように変数にライブラリを設定しておき、target_link_librariesで登録する。

set(LIBRARIES
    ${LIBAV_LIBRARIES}
    ${QT4_LIBRARIES}
    -lrt 
    -lpthread)

target_link_libraries(${PROJ_NAME} ${LIBRARIES})

pkg-configの変数や、-lrtのように個別に設定することもできる。

追加のライブラリ(static)

DLLの場合同様にSTATIC_LIBRARIESのように変数に登録しておき、target_link_librariesで登録する。

set(STATIC_LIBRARIES
    ${PROJECT_SOURCE_DIR}/prebuilt_lib/libsdi.a
    ${PROJECT_SOURCE_DIR}/prebuilt_lib/libgdi.a
    jpegdecdrv
)

target_link_libraries(${PROJ_NAME} ${STATIC_LIBRARIES})

ビルド済みのバイナリをリンクする場合は、ライブラリまでのフルパスを書く。

ソースからコンパイルする場合は、jpegdecdrvのようにライブラリ名のみ記述すると、パスの解決などをCMakeがやってくれる。

DLLとスタティックを同時にリンク

DLLとスタティックなライブラリを同時にリンクしたい場合は、次のように同時に設定できる。

target_link_libraries(${PROJ_NAME} ${LIBRARIES} ${STATIC_LIBRARIES})

実行ファイルの生成

CMakeで実行形式を生成したい場合は、add_executable(実行ファイル名 ソースファイル名)で設定する。

# Add a target executable
add_executable(${PROJ_NAME}
    ${PROJECT_SOURCE_DIR}/main.cpp
)

一つのCMakeLists.txtに複数add_executableを書くこともできる。

アセンブラの有効化

add_executableにhello.Sなどアセンブラのソースファイルを登録したい場合は、予め有効化しておく必要がある。

# Enable assembler
enable_language(ASM)

add_executable(${PROJ_NAME}
    ${PROJECT_SOURCE_DIR}/main.c
    ${PROJECT_SOURCE_DIR}/hello.S
)

サブディレクトリの登録

ライブラリなどのサブモジュールを一緒にビルドする場合、1つのCMakeLists.txtに全て定義することもできるが、 従来のMakefileのようにディレクトリごとにCMakeLists.txtを置くこともできる。

その場合はadd_subdirectory(ディレクトリ名)で登録する。

# Add sub-directories
add_subdirectory(libhello)
add_subdirectory(libbye)

スタティックライブラリの生成

スタティックライブラリをビルドする場合はadd_librarySTATICを設定する。

add_library(hello STATIC
    hello.cpp
    hello_func.cpp
)

この例ではlibhello.aが生成される。

CXX_FLAGSの設定

CXX_FLAGSなどの一般的に変数に関してはCMAKE_CXX_FLAGSのように予め定義してある。

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D__ARMV8")