183

自作の Makefile を使用してコンパイルするために使用するライブラリを作成しましたが、今は cmake に切り替えたいと考えています。ツリーは次のようになります (関係のないファイルはすべて削除しました)。

.
├── include
│   ├── animation.h
│   ├── buffers.h
│   ├── ...
│   ├── vertex.h
│   └── world.h
└── src
    ├── animation.cpp
    ├── buffers.cpp
    ├── ...
    ├── vertex.cpp
    └── world.cpp

私がやろうとしているのは、ソースを共有ライブラリにコンパイルしてから、ヘッダー ファイルと共にインストールすることです。

私が見つけたほとんどの例は、いくつかの共有ライブラリを使用して実行可能ファイルをコンパイルしますが、単純な共有ライブラリだけではありません。また、誰かが cmake を使用する非常に単純なライブラリを教えてくれると助かるので、これを例として使用できます。

4

4 に答える 4

318

の最低限必要なバージョンを常に指定します。cmake

cmake_minimum_required(VERSION 3.9)

プロジェクトを宣言する必要があります。cmakeそれは必須であり、便利な変数を定義しますPROJECT_NAMEPROJECT_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できます。このファイルにより、サードパーティ アプリケーションがライブラリを簡単にインポートできるようになります。

次の名前のテンプレート ファイルを作成します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を展開するルールを追加します(フォームの変数を展開しないように cmake に依頼します)。@@ONLY${VAR}

configure_file(mylib.pc.in mylib.pc @ONLY)

最後に、生成されたファイルをインストールします。

install(FILES ${CMAKE_BINARY_DIR}/mylib.pc DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig)

cmake EXPORTfeatureを使用することもできます。ただ、この機能は互換性があるだけで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)

編集

コメントで述べたように、標準に準拠するには、静的ライブラリと共有ライブラリを生成できる必要があります。プロセスはもう少し複雑で、最初の質問と一致しません。しかし、それはここで大いに説明されていることに言及する価値があります。

于 2017-08-23T15:20:15.310 に答える
96

この最小限のCMakeLists.txtファイルは、単純な共有ライブラリをコンパイルします。

cmake_minimum_required(VERSION 2.8)

project (test)
set(CMAKE_BUILD_TYPE Release)

include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
add_library(test SHARED src/test.cpp)

ただし、CMake でファイルを別の場所にコピーした経験はありません。COPY/INSTALL シグネチャを使用した file コマンドは便利なようです。

于 2013-07-07T11:22:26.457 に答える
28

私はこれを自分で行う方法を学ぼうとしていますが、次のようにライブラリをインストールできるようです:

cmake_minimum_required(VERSION 2.4.0)

project(mycustomlib)

# Find source files
file(GLOB SOURCES src/*.cpp)

# Include header files
include_directories(include)

# Create shared library
add_library(${PROJECT_NAME} SHARED ${SOURCES})

# Install library
install(TARGETS ${PROJECT_NAME} DESTINATION lib/${PROJECT_NAME})

# Install library headers
file(GLOB HEADERS include/*.h)
install(FILES ${HEADERS} DESTINATION include/${PROJECT_NAME})
于 2016-07-01T08:07:25.583 に答える