2023.04.20

C++開発とCMake ~その2 : 自作ライブラリの作り方~

前回までの記事


前回までのコードはこちら https://github.com/gollowars/cpp_cmake_bootstrap/tree/main このコードを修正して使っていく。

続いてライブラリの作り方使い方。その1の続き

静的、動的(共有)ライブラリの違い

静的ライブラリはコンパイルされた実行ファイルに直接含まれる。 動的ライブラリは実行時に必要となる部分に動的にリンクするライブラリ、実行ファイルには含まれない。 動的ライブラリは共有可能になるので、複数のアプリケーションが同じライブラリを使う場合は最終的な実行ファイルが軽くなる。(ならないこともある。使い方次第)また、ライブラリが更新された場合再コンパイルせずに使用できるのでリビルドが速い?

静的ライブラリ

main.cppの場所を変えた。ルート直下に持ってきた。

.
├── CMakeLists.txt
├── README.md
├── data
│   └── sample.csv
├── include
│   ├── CSVParser.h
│   └── MyClass.h
├── main.cpp
└── src
    ├── CSVParser.cpp
    └── MyClass.cpp
CMakeLists.txt
cmake_minimum_required(VERSION 3.0.0)
# プロジェクト名
project(Example VERSION 0.1.0)

# include(CTest)
# enable_testing()


# C++標準の設定
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True) ## C++11であることを指定して、C++11以外のコンパイラを使うとエラーにする


# Library
set(MY_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)
# mylibという名前で静的ライブラリを作成
add_library(mylib STATIC 
    ${MY_SOURCE_DIR}/CSVParser.cpp
    ${MY_SOURCE_DIR}/MyClass.cpp
)

# ライブラリで必要となるヘッダーファイルのディレクトリをターゲットに`mylib`にして指定。
# `PUBLIC`はmain.cppでも読み込めるようにする設定。外部から読み込まない場合は`PRIVATE`になる。
# この場合はmain.cppからヘッダーが読み込めなくなるのでエラーが起こる。
target_include_directories(mylib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)

# buildターゲット(この場合はPROJECT_NAMEであるExampleに)main.cppを追加
add_executable(${PROJECT_NAME} ./main.cpp) 

# ライブラリをリンクする。
target_link_libraries(${PROJECT_NAME} mylib)


## assetをコピーする
configure_file(${CMAKE_SOURCE_DIR}/data/sample.csv ${CMAKE_CURRENT_BINARY_DIR}/data/sample.csv COPYONLY)


get_target_property(headers ${PROJECT_NAME} SOURCES)
message(STATUS "headers : ${headers}") # これはあってもなくても良いけどメッセージを確認す

buildされたファイル

drwxr-xr-x   3     96B Apr 20 16:54 .cmake
-rw-r--r--   1     65K Apr 20 16:54 .ninja_deps
-rw-r--r--   1    396B Apr 20 16:54 .ninja_log
-rw-r--r--   1     14K Apr 20 16:54 CMakeCache.txt
drwxr-xr-x  11    352B Apr 20 16:54 CMakeFiles
-rwxr-xr-x   1    145K Apr 20 16:54 Example
-rw-r--r--   1     25K Apr 20 16:54 build.ninja
-rw-r--r--   1    1.5K Apr 20 16:54 cmake_install.cmake
-rw-r--r--   1    1.6K Apr 20 16:54 compile_commands.json
drwxr-xr-x   3     96B Apr 20 16:54 data
-rw-r--r--   1    349K Apr 20 16:54 libmylib.a

動的ライブラリ

add_library(mylib SHARED
    ${MY_SOURCE_DIR}/CSVParser.cpp
    ${MY_SOURCE_DIR}/MyClass.cpp
)

STATICだったところをSHAREDに変えるだけ。

-rw-r--r--   1     14K Apr 20 16:51 CMakeCache.txt
drwxr-xr-x  10    320B Apr 20 16:51 CMakeFiles
-rwxr-xr-x   1     69K Apr 20 16:51 Example
-rw-r--r--   1     11K Apr 20 16:51 build.ninja
-rw-r--r--   1    1.5K Apr 20 16:51 cmake_install.cmake
-rw-r--r--   1    1.6K Apr 20 16:51 compile_commands.json
drwxr-xr-x   3     96B Apr 20 16:51 data
-rwxr-xr-x   1    120K Apr 20 16:51 libmylib.dylib

比較

静的 : Example (145KB) 動的 : 69KB (Example) + 120KB (libmylib.dylib) = 189KB

やはりExampleの実行ファイルは動的ライブラリの場合軽くなっているが、 合計すると動的の方が重い。


次は他のライブラリを読み込む方法など

今回の完成ファイルはこちら https://github.com/gollowars/cpp_cmake_bootstrap/tree/testlib


次のリファレンスメモ

C++開発シリーズ