[解決済み] cmakeで共有ライブラリを作成する方法は?
質問
今まで自作のMakefileを使ってコンパイルしていたライブラリを、cmakeに切り替えたいと考えています。ツリーは以下のような感じです(無関係なファイルはすべて削除しました)。
.
├── include
│ ├── animation.h
│ ├── buffers.h
│ ├── ...
│ ├── vertex.h
│ └── world.h
└── src
├── animation.cpp
├── buffers.cpp
├── ...
├── vertex.cpp
└── world.cpp
つまり、私がやろうとしていることは、ソースを共有ライブラリにコンパイルして、ヘッダーファイルと一緒にインストールするだけなのです。
私が見つけたほとんどの例は、いくつかの共有ライブラリを含む実行ファイルをコンパイルしますが、単なる共有ライブラリをコンパイルすることはありません。 また、誰かがcmakeを使用する非常に単純なライブラリを教えてくれれば、私はこれを例として使用することができます。
どのように解決するのですか?
の必要最小限のバージョンを常に指定します。
cmake
cmake_minimum_required(VERSION 3.9)
プロジェクトを宣言する必要があります。
cmake
は必須であり、便利な変数を定義することになります。
PROJECT_NAME
,
PROJECT_VERSION
と
PROJECT_DESCRIPTION
(後者の変数はcmake 3.9が必要です)。
project(mylib VERSION 1.0.1 DESCRIPTION "mylib description")
新しいライブラリターゲットを宣言します。の使用は避けてください。
file(GLOB ...)
. この機能では、コンパイル処理のマスタリングに参加することはできません。もし、あなたが怠け者なら、コピーペーストで
ls -1 sources/*.cpp
:
add_library(mylib SHARED
sources/animation.cpp
sources/buffers.cpp
[...]
)
設定
VERSION
プロパティを設定します(オプションですが、良い習慣です)。
set_target_properties(mylib PROPERTIES VERSION ${PROJECT_VERSION})
を設定することもできます。
SOVERSION
をメジャーナンバーに
VERSION
. そこで
libmylib.so.1
へのシンボリックリンクになります。
libmylib.so.1.0.0
.
set_target_properties(mylib PROPERTIES SOVERSION 1)
ライブラリの公開APIを宣言します。このAPIは、サードパーティアプリケーションのためにインストールされることになります。プロジェクトツリーの中で分離しておくとよいでしょう。
include/
ディレクトリに移動します)。なお、プライベートヘッダはインストールしてはいけませんので、ソースファイルと一緒に配置することを強くお勧めします。
set_target_properties(mylib PROPERTIES PUBLIC_HEADER include/mylib.h)
サブディレクトリを扱う場合
"../include/mylib.h"
. そこで、インクルードディレクトリにトップディレクトリを渡します。
target_include_directories(mylib PRIVATE .)
または
target_include_directories(mylib PRIVATE include)
target_include_directories(mylib PRIVATE src)
ライブラリのインストールルールを作成します。変数
CMAKE_INSTALL_*DIR
で定義された
GNUInstallDirs
:
include(GNUInstallDirs)
そして、インストールするファイルを宣言します。
install(TARGETS mylib
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
をエクスポートすることもできます。
pkg-config
ファイルを作成します。このファイルによって、サードパーティのアプリケーションは簡単にあなたのライブラリをインポートすることができます。
-
は、Makefileを使用して、以下を参照してください。
pkg-config
-
を、Autotoolsを使用して、参照してください。
PKG_CHECK_MODULES
-
cmakeを使用する場合は、以下を参照してください。
pkg_check_modules
という名前のテンプレートファイルを作成します。
mylib.pc.in
(参照
pc(5)
マンページ
をご覧ください)。
prefix=@CMAKE_INSTALL_PREFIX@
exec_prefix=@CMAKE_INSTALL_PREFIX@
libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@
includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
Name: @PROJECT_NAME@
Description: @PROJECT_DESCRIPTION@
Version: @PROJECT_VERSION@
Requires:
Libs: -L${libdir} -lmylib
Cflags: -I${includedir}
あなたの
CMakeLists.txt
を展開するルールを追加します。
@
マクロ (
@ONLY
という形式の変数を展開しないように cmake に依頼します。
${VAR}
):
configure_file(mylib.pc.in mylib.pc @ONLY)
そして最後に、生成されたファイルをインストールします。
install(FILES ${CMAKE_BINARY_DIR}/mylib.pc DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig)
を使用することもできます。
cmake
EXPORT
特徴
. ただし、この機能が対応するのは
cmake
と、使いにくさを感じています。
最後に、全体の
CMakeLists.txt
は、次のようになります。
cmake_minimum_required(VERSION 3.9)
project(mylib VERSION 1.0.1 DESCRIPTION "mylib description")
include(GNUInstallDirs)
add_library(mylib SHARED src/mylib.c)
set_target_properties(mylib PROPERTIES
VERSION ${PROJECT_VERSION}
SOVERSION 1
PUBLIC_HEADER api/mylib.h)
configure_file(mylib.pc.in mylib.pc @ONLY)
target_include_directories(mylib PRIVATE .)
install(TARGETS mylib
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
install(FILES ${CMAKE_BINARY_DIR}/mylib.pc
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig)
EDIT
コメントにあるように、標準に準拠するためには、共有ライブラリだけでなく、静的ライブラリも生成できるようにする必要があります。このプロセスはもう少し複雑で、最初の質問とは一致しません。しかし、それは非常に説明されていることを言及する価値がある こちら .
関連
-
[解決済み】致命的なエラー LNK1169: ゲームプログラミングで1つ以上の多重定義されたシンボルが発見された
-
[解決済み】関数名の前に期待されるイニシャライザー
-
[解決済み】#include<iostream>は存在するのですが、「識別子 "cout "は未定義です」というエラーが出ます。なぜですか?
-
[解決済み】システムが指定されたファイルを見つけられませんでした。
-
[解決済み] 文字列の単語を反復処理するにはどうすればよいですか?
-
[解決済み] 1ビットのセット、クリア、トグルはどのように行うのですか?
-
[解決済み] スタティック・ライブラリとシェアード・ライブラリの違い?
-
[解決済み】共有オブジェクト(.so)、静的ライブラリ(.a)、DLL(.so)の違い?)
-
[解決済み] LinuxにおけるC++ダイナミックシェアードライブラリ
-
[解決済み] CMake:ユニットテストによるプロジェクト構造
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】クラステンプレートの引数リストがない
-
[解決済み] エラーが発生する。ISO C++は型を持たない宣言を禁じています。
-
[解決済み] error: 'ostream' does not name a type.
-
[解決済み】 != と =! の違いと例(C++の場合)
-
[解決済み] error: 'if' の前に unqualified-id を期待した。
-
[解決済み】cc1plus:エラー:g++で認識されないコマンドラインオプション"-std=c++11"
-
[解決済み] gdbを使用してもデバッグシンボルが見つからない
-
[解決済み】 while(cin) と while(cin >> num) の違いは何ですか?)
-
[解決済み] 配列のベクトルを扱う正しい方法
-
[解決済み] CMakeで静的ライブラリと共有ライブラリを同時にビルドさせることは可能でしょうか?