LoginSignup
3
5

More than 1 year has passed since last update.

CMakeで実行, Static, Sharedファイルを同時に生成/インストールする

Posted at

0. 経緯

友人から急ぎで実行ファイルと静的ライブラリ、共有ライブラリをコンパイル・インストールするCMakeLists.txtの作成を依頼された
まぁさほど難しくない+手持ちのテンプレートそのままなので,お歳暮に豪華干物セットを戴くことで合意
環境は macOS 13.0.1 M1 MacBook Air

1. 大雑把な概要

実際にはC++で書かれたソースコード群から上記のように3種類の出力ファイルを生成,インストールするまでがセット
さすがに依頼されたソースコード名は使えないので SQliteのコードで説明します
SQLiteはCで記述されているがこのCMakeLists.txtはC++でも基本的に対応できる
当然の事ながらファイル名が直接記述されている箇所は変更が必要
cxx_std_17の指定が追加されているのを蛇足or問題無しと判断するかはご自由に

2. SQLite

SQLite https://www.sqlite.org/index.html は本来はCMakeを使わない手順でコンパイル/リンク/インストールする仕組みになっている
そこであえて必要なソースだけダウンロードしCMakeでコンパイル/リンク/インストールを実行する事にする
https://www.sqlite.org/download.html
sqlite-amalgamation-xxxxxx.zip
上記のファイルを入手/展開し、下記のディレクトリ構造に格納する
他にも色々ファイルがあるが最低限以下のファイルがあればとりあえず問題ない
この構造は私の好みなので変更はご自由に

    $ tree .
    .
    ├── CMakeLists.txt
    ├── build
    └── src
        ├── include
        │   └── sqlite3.h
        ├── shell.c
        └── sqlite3.c

3. CMakeLists.txtに関する説明

6つのブロックで構成

  1. コメント
  2. プロジェクト全体に関する共通設定
  3. 実行ファイル生成に関する記述
  4. Static Library生成に関する記述
  5. Shared Library生成に関する記述
  6. インストールに関する記述

重要なのは

  • 判りやすくする為にブロック単位で分けること
  • 仮のプロジェクト名を付けてファイル出力のプロパティをセットして出力ファイル名を適切にセットする事
    • set_target_properties関数がキモとなるので必要ならドキュメントを参照して下さい
      1. 仮のプロジェクト名で生成
      2. 出力名をプロパティで変更
        という流れが判りにくいのでチェックして下さい

短いのでインラインで説明します。

CMakeLists.txt
# CMakeLists.txt 
# CMake Template file. 12/Nov/2022
#[[
    ゴール
        1.実行ファイルの生成
        2.static libraryの生成
        3. shared libraryの生成
        4. 上記3つのインストール
        5. 必要なヘッダーのインストール

    注意事項
        macOS + clangでのみテスト

    ファイルの配置を以下にした変更はお好みで
    $ tree .
    .
    ├── CMakeLists.txt
    ├── build
    └── src
        ├── include
        │   └── sqlite3.h
        ├── shell.c
        └── sqlite3.c

    実行は
        cd build
        cmake ..
        make
        sudo make install
    で行う(他にも方法はある)

    私は自分用 CMakeLists.txtではPUBLICを極力避けて個々にPRIVATEで指定するようにしている
    ${PROJECT_NAME}のように直接ファイル名、プロジェクト名を記述するのは避けている
]]

#[[ Require a minimum version of cmake. ]]
cmake_minimum_required(VERSION 3.1.0)

# Set the name of the project. 
# project(sqlite3 VERSION 0.0.1)
project(sqlite3)

set(CMAKE_BUILD_TYPE Release)

#  ---------  共通部分終了  ---------------------------------------

#
#  ---------  実行ファイル部分  ---------------------------------------
#
file(GLOB SRC "src/*.cpp" "src/*.c" "src/*.m" "src/*.mm" "src/*.f90") # 不要な拡張子があるが気にしない事
add_executable(${PROJECT_NAME}
    ${SRC}  # これで src/に含まれるソースコードが全て対象となる
)
target_compile_features(${PROJECT_NAME} PRIVATE c_std_17 cxx_std_17)
target_compile_options(${PROJECT_NAME} PRIVATE -O2 -Wall ) # -v
target_include_directories(${PROJECT_NAME} PRIVATE ${PROJECT_SOURCE_DIR}/src/include)


#
#  ---------  スタティックライブラリ部分  ---------------------------------------
#

# テンポラリな名前として,STATIC_PROJECTを設定,これでSTATIC_sqlite3と展開される
set( STATIC_PROJECT STATIC_${PROJECT_NAME})
#[[ AAdd a library to the project using the specified source files. ]]
add_library(${STATIC_PROJECT}
    STATIC
    # SHARED
    src/sqlite3.c   # shell.cは不要なので個別指定
)
target_compile_features(${STATIC_PROJECT} PRIVATE c_std_17 cxx_std_17)
target_compile_options(${STATIC_PROJECT} PRIVATE -O2 -Wall ) # -v
target_include_directories(${STATIC_PROJECT} PRIVATE ${PROJECT_SOURCE_DIR}/src/include)

# static libraryを出力すると,STATIC_sqlite3は libsqlite3.aとして生成される
set_target_properties(${STATIC_PROJECT} PROPERTIES OUTPUT_NAME ${PROJECT_NAME})

#
#  ---------  共有ライブラリ部分  ---------------------------------------
#

# テンポラリな名前として,SHARE_PROJECTを設定,これでSHARE_sqlite3と展開される
set( SHARE_PROJECT SHARE_${PROJECT_NAME})
add_library(${SHARE_PROJECT}
    # STATIC
    SHARED
    src/sqlite3.c   # shell.cは不要なので個別指定
)
target_compile_features(${SHARE_PROJECT} PRIVATE c_std_17 cxx_std_17)
target_compile_options(${SHARE_PROJECT} PRIVATE -O2 -Wall ) # -v
target_include_directories(${SHARE_PROJECT} PRIVATE ${PROJECT_SOURCE_DIR}/src/include)

# shared libraryを出力すると,SHARE_sqlite3は libsqlite3.dylibとして生成される
set_target_properties(${SHARE_PROJECT} PROPERTIES OUTPUT_NAME ${PROJECT_NAME})

#
#  ---------  インストールセクション  ---------------------------------------
#
install(TARGETS ${PROJECT_NAME})       # /usr/local/binにインストール
install(TARGETS ${STATIC_PROJECT})     # /usr/local/libにインストール
install(TARGETS ${SHARE_PROJECT})      # /usr/local/libにインストール
# ヘッダーのインストール(コピー)
install (
    # 本来ならライブラリに必要なヘッダーと実行ファイル生成に必要なヘッダーを分けておくのが筋と思うが今回は全部コピー
    DIRECTORY ${CMAKE_SOURCE_DIR}/src/include/
    DESTINATION include
    FILES_MATCHING PATTERN "*.h*")  # すべてのヘッダーを /usr/local/includeにインストール

# That's all folks.
3
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
5