モーダルを閉じる工作HardwareHub ロゴ画像

工作HardwareHubは、ロボット工作や電子工作に関する情報やモノが行き交うコミュニティサイトです。さらに詳しく

利用規約プライバシーポリシー に同意したうえでログインしてください。

cmake チートシート

モーダルを閉じる

ステッカーを選択してください

お支払い手続きへ
モーダルを閉じる

お支払い内容をご確認ください

購入商品
」ステッカーの表示権
メッセージ
料金
(税込)
決済方法
GooglePayマーク
決済プラットフォーム
確認事項

利用規約をご確認のうえお支払いください

※カード情報はGoogleアカウント内に保存されます。本サイトやStripeには保存されません

※記事の執筆者は購入者のユーザー名を知ることができます

※購入後のキャンセルはできません

作成日作成日
2016/06/09
最終更新最終更新
2022/01/06
記事区分記事区分
一般公開

目次

    初心者にもわかりやすい内容を心がけています!

    cmake の簡単な使い方をまとめます。

    静的ライブラリ 動的ライブラリ 実行ファイル
    Linux .a .so 無し
    Windows .lib .dll .exe
    ビルド方法 add_library(mylib STATIC mylib.cpp) add_library(mylib SHARED mylib.cpp) add_executable(main main.cpp)

    実行ファイルのビルド add_executable

    main.cpp

    #include <iostream>
    
    int main() {
        std::cout << "hi" << std::endl;
        return 0;
    }
    

    CMakeLists.txt

    cmake_minimum_required (VERSION 3.10)
    add_executable(main main.cpp)
    

    ビルド例

    mkdir build
    cd build/
    cmake ..
    make
    ./main
    hi
    

    静的/動的ライブラリのビルド add_library

    mylib.cpp

    #include <iostream>
    
    void MyFunc() {
        std::cout << "hi" << std::endl;
    }
    

    CMakeLists.txt

    cmake_minimum_required (VERSION 3.10)
    add_library(mylib SHARED mylib.cpp)
    add_library(mylib2 STATIC mylib.cpp)
    

    ビルド例

    mkdir build
    cd build/
    cmake ..
    make
    

    成果物

    libmylib.so
    libmylib2.a
    

    静的ライブラリと実行ファイルのビルド

    mylib.cpp

    #include <iostream>
    
    void MyFunc() {
        std::cout << "hi" << std::endl;
    }
    

    include/mylib.hpp

    #pragma once はインクルードガードの方法の一つです。

    #pragma once
    void MyFunc();
    

    main.cpp

    #include <mylib.hpp>
    
    int main() {
        MyFunc();
        return 0;
    }
    

    CMakeLists.txt

    cmake_minimum_required (VERSION 3.10)
    
    add_library(mylib STATIC mylib.cpp)
    
    add_executable(main main.cpp)
    target_link_libraries(main mylib)
    target_include_directories(main PRIVATE include)
    

    ビルド例

    mkdir build
    cd build/
    cmake ..
    make
    ./main
    hi
    

    成果物

    libmylib.a
    main
    

    動的ライブラリと実行ファイルのビルド

    CMakeLists.txt を以下のように変更します。

    cmake_minimum_required (VERSION 3.10)
    
    add_library(mylib SHARED mylib.cpp)
    
    add_executable(main main.cpp)
    target_link_libraries(main mylib)
    target_include_directories(main PRIVATE include)
    

    成果物

    libmylib.so
    main
    

    /usr/lib/libfoo.so-lfoo

    動的ライブラリのリンク方法には、絶対パスを指定する方法とリンカに検索させる方法の二つがあります。

    後者について、-L で指定したディレクトリ等に存在する libxxx.so/a という静的または動的ライブラリを g++ などで指定するときは "lib" を除外して -lxxx とします。

    既定では実行ファイルは動的ライブラリを絶対パスで参照します。実行時に検索するように変更するためには以下のようにします。

    cmake_minimum_required (VERSION 3.10)
    
    set(CMAKE_SKIP_BUILD_RPATH true)
    add_library(mylib SHARED mylib.cpp)
    
    add_executable(main main.cpp)
    target_link_libraries(main mylib)
    target_include_directories(main PRIVATE include)
    

    ldd main の結果が

    libmylib.so => /path/to/build/libmylib.so (0x00007f4676f50000)
    

    から以下のように変更されます。

    libmylib.so => not found
    

    カレントディレクトリがライブラリの検索対象ではないため LD_LIBRARY_PATH 等で対応します。

    LD_LIBRARY_PATH=$LD_LIBRARY_PATH:. ./main
    hi
    

    よく使う cmake 設定

    project

    プロジェクト名を指定します。

    project( gtest_main )
    

    PROJECT_NAME で参照できます。

    add_executable(${PROJECT_NAME} main.cpp)
    

    cmake_minimum_required

    CMakeLists.txt の一番最初に記載します。project() コマンドよりも前である必要があります。最低限必要な cmake のバージョンを指定します。

    cmake_minimum_required(VERSION 2.8)
    

    message

    変数をコンソールに出力できます。CMakeLists.txt のデバッグ時に便利です。

    message("hi")
    find_library(gtest NAMES libgtest.a PATHS googletest-master/googletest)
    message(${gtest})
    

    CMAKE_VERBOSE_MAKEFILE

    出力情報を増やして cmake デバッグしやすくします。

    set(CMAKE_VERBOSE_MAKEFILE TRUE)
    

    ビルド成果物の出力先を指定 (EXECUTABLE_OUTPUT_PATHLIBRARY_OUTPUT_PATH)

    set(EXECUTABLE_OUTPUT_PATH /tmp)
    set(LIBRARY_OUTPUT_PATH /tmp)
    

    コンパイラのオプション指定 target_compile_options

    add_executable(main main.cpp)
    target_compile_options(main PRIVATE "-Wall")
    

    ヘッダーファイルのインクルード -I target_include_directories

    add_executable(main main.cpp)
    target_include_directories(main PRIVATE path/to/include)
    

    ファイルシステムに存在するライブラリの絶対パスを検索 find_library

    ライブラリの指定方法は複数あります。

    CMakeLists.txt

    cmake_minimum_required (VERSION 3.10)
    
    find_library(mylib NAMES libcurl.so.4)
    find_library(mylib2 NAMES EGL)
    
    message("hi")
    message(${mylib})
    message(${mylib2})
    

    実行例

    mkdir build
    cd build/
    cmake ..
    hi
    /usr/lib/x86_64-linux-gnu/libcurl.so.4
    /usr/lib/x86_64-linux-gnu/libEGL.so
    

    実行ファイルの絶対パスを検索 find_program

    cmake_minimum_required (VERSION 3.10)
    find_program(path NAMES python)
    message(${path})
    

    cmake パッケージを利用したパス検索 find_package

    cmake に登録されているモジュールの一覧は以下のコマンドで確認できます。

    cmake --help-module-list
    

    例えば FindPython を利用すると以下のようにパス検索できます。

    cmake_minimum_required (VERSION 3.10)
    find_package(Python REQUIRED)
    message(${Python_FOUND})
    message(${Python_EXECUTABLE})
    

    実行例

    $ cmake .
    TRUE
    /usr/bin/python3.7
    -- Configuring done
    -- Generating done
    -- Build files have been written to: /path/to/somewhere
    

    ファイル分割

    include ファイル分割

    cmake_minimum_required (VERSION 3.10)
    include("a/1.cmake")
    include("a/2.cmake")
    

    ソースコードと CMakeLists.txt が存在するディレクトリを読み込む場合 add_subdirectory

    add_subdirectory("b")
    

    正規表現の利用 string

    cmake_minimum_required (VERSION 3.10)
    string(REGEX REPLACE [[([0-9]+)]] [[!\1!]] replaced "abc123")
    message(${replaced})
    

    実行例

    abc!123!
    

    make install

    install によって make install 時のインストール先を設定できます。

    mylib.hpp

    #pragma once
    void MyFunc();
    

    mylib.cpp

    #include <iostream>
    void MyFunc() {
        std::cout << "hi" << std::endl;
    }
    

    CMakeLists.txt

    cmake_minimum_required (VERSION 3.10)
    add_library(mylib SHARED mylib.cpp)
    install(TARGETS mylib DESTINATION /tmp/lib)
    install(FILES mylib.hpp DESTINATION /tmp/include)
    

    実行例

    mkdir build
    cd build/
    cmake ..
    make
    make install
    [100%] Built target mylib
    Install the project...
    -- Install configuration: ""
    -- Installing: /tmp/lib/libmylib.so
    -- Installing: /tmp/include/mylib.hpp
    

    外部コマンドの実行 execute_process

    cmake_minimum_required (VERSION 3.10)
    execute_process(
      COMMAND mkdir -p hello
      WORKING_DIRECTORY /tmp
    )
    

    別プロジェクトのライブラリを参照するサンプル

    cmake で管理されたソースコードがある場合

    main の CMakeLists.txttarget_include_directories していないのがポイントです。ライブラリの利用側で都度設定する必要がなくなるため、特に依存関係が多段になった場合に有用です。

    CMakeLists.txt

    cmake_minimum_required (VERSION 3.10)
    add_subdirectory("a")
    add_executable(main main.cpp)
    target_link_libraries(main mylib)
    

    main.cpp

    #include <mylib.hpp>
    int main() {
        MyFunc();
        return 0;
    }
    

    a/CMakeLists.txt

    cmake_minimum_required (VERSION 3.10)
    add_library(mylib SHARED mylib.cpp)
    target_include_directories(mylib INTERFACE include)
    install(TARGETS mylib DESTINATION /tmp/a/lib)
    install(DIRECTORY include DESTINATION /tmp/a)
    

    a/mylib.cpp

    #include <iostream>
    void MyFunc() {
        std::cout << "hi" << std::endl;
    }
    

    a/include/mylib.hpp

    #pragma once
    void MyFunc();
    

    ビルド例

    mkdir build
    cd build/
    cmake ..
    make
    ./main
    hi
    make install
    

    cmake で target_include_directories する際には PUBLIC、PRIVATE、INTERFACE を選択します。

    • PUBLIC → 上記例で a および main の両方のビルドで必要という設定になります。
    • PRIVATE → 上記例で a のビルドについてのみ必要という設定になります。
    • INTERFACE → 上記例で main のビルドについてのみ必要という設定になります。

    自身 a のビルドについては不要で、a を利用する main において必要となるため target_include_directories(mylib INTERFACE include) としています。参考: INTERFACE 設定は、ヘッダーのみからなるライブラリを作る際にも利用できます。

    cmake で管理されたソースコードがない場合

    IMPORTED ライブラリとして外部ライブラリを add_library しています。依存関係が多段になった場合に有用です。find_library で main に対して直接 target_link_libraries しても動作します。

    CMakeLists.txt

    cmake_minimum_required (VERSION 3.10)
    
    add_library(mylib SHARED IMPORTED)
    set_target_properties(mylib PROPERTIES IMPORTED_LOCATION /tmp/a/lib/libmylib.so)
    set_target_properties(mylib PROPERTIES INTERFACE_INCLUDE_DIRECTORIES /tmp/a/include)
    
    add_executable(main main.cpp)
    target_link_libraries(main mylib)
    

    main.cpp

    #include <mylib.hpp>
    int main() {
        MyFunc();
        return 0;
    }
    

    ビルド例

    mkdir build
    cd build/
    cmake ..
    make
    ./main 
    hi
    
    Likeボタン(off)0
    詳細設定を開く/閉じる
    アカウント プロフィール画像

    初心者にもわかりやすい内容を心がけています!

    記事の執筆者にステッカーを贈る

    有益な情報に対するお礼として、またはコメント欄における質問への返答に対するお礼として、 記事の読者は、執筆者に有料のステッカーを贈ることができます。

    >>さらに詳しくステッカーを贈る
    ステッカーを贈る コンセプト画像

    Feedbacks

    Feedbacks コンセプト画像

      ログインするとコメントを投稿できます。

      ログインする

      関連記事