自作の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)
ライブラリのインストールルールを作成します。 GNUInstallDirs
で定義されている変数CMAKE_INSTALL_*DIR
を使用することをお勧めします。
include(GNUInstallDirs)
そして、インストールするファイルを宣言します:
install(TARGETS mylib
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
pkg-config
ファイルをエクスポートすることもできます。このファイルにより、サードパーティアプリケーションがライブラリを簡単にインポートできます。
pkg-config
を参照してくださいPKG_CHECK_MODULES
を参照してください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
は、フォーム${VAR}
の変数を展開しないようにcmakeに要求します):
configure_file(mylib.pc.in mylib.pc @ONLY)
最後に、生成されたファイルをインストールします。
install(FILES ${CMAKE_BINARY_DIR}/mylib.pc DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig)
cmake EXPORT
feature を使用することもできます。ただし、この機能は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)
この最小限の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コマンドは、役に立つかもしれません。
私は自分でこれを行う方法を学ぼうとしていますが、次のようにライブラリをインストールできるようです:
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})
まず、これは私が使用しているディレクトリレイアウトです。
.
├── include
│ ├── class1.hpp
│ ├── ...
│ └── class2.hpp
└── src
├── class1.cpp
├── ...
└── class2.cpp
これを数日見てから、これは現代のCMakeのおかげでこれを行うための私のお気に入りの方法です:
cmake_minimum_required(VERSION 3.5)
project(mylib VERSION 1.0.0 LANGUAGES CXX)
set(DEFAULT_BUILD_TYPE "Release")
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "Setting build type to '${DEFAULT_BUILD_TYPE}' as none was specified.")
set(CMAKE_BUILD_TYPE "${DEFAULT_BUILD_TYPE}" CACHE STRING "Choose the type of build." FORCE)
# Set the possible values of build type for cmake-gui
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
endif()
include(GNUInstallDirs)
set(SOURCE_FILES src/class1.cpp src/class2.cpp)
add_library(${PROJECT_NAME} ...)
target_include_directories(${PROJECT_NAME} PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
PRIVATE src)
set_target_properties(${PROJECT_NAME} PROPERTIES
VERSION ${PROJECT_VERSION}
SOVERSION 1)
install(TARGETS ${PROJECT_NAME} EXPORT MyLibConfig
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME})
install(EXPORT MyLibConfig DESTINATION share/MyLib/cmake)
export(TARGETS ${PROJECT_NAME} FILE MyLibConfig.cmake)
CMakeを実行してライブラリをインストールした後、Find ***。cmakeファイルを使用する必要はありません。次のように使用できます。
find_package(MyLib REQUIRED)
#No need to perform include_directories(...)
target_link_libraries(${TARGET} mylib)
それだけです。標準のディレクトリにインストールされている場合は検出され、他に何もする必要はありません。非標準のパスにインストールされている場合も簡単です。次を使用してMyLibConfig.cmakeの場所をCMakeに指示するだけです。
cmake -DMyLib_DIR=/non/standard/install/path ..
これが私を助けてくれたのと同じくらいみんなに役立つことを願っています。これを行う古い方法は非常に面倒でした。