コンパイルするために3つのヘッダー専用ライブラリが必要な単純なプロジェクトがあります:websocketpp、spdlog、nlohmann/jsonです。CMakeでヘッダーのみの依存関係を追加する
プロジェクトの構造は次のようになります。
└── src
├── app
│ ├── CMakeLists.txt
│ ├── src
│ └── test
├── CMakeLists.txt
├── core
│ ├── CMakeLists.txt
│ ├── include
│ ├── src
│ └── test
└── vendor
├── install.cmake
├── nlohmann_json
├── spdlog
└── websocketpp
次のようにルートCMakeLists.txtは次のとおりです。
cmake_minimum_required(VERSION 3.6.1 FATAL_ERROR)
..
# External 3rd party libs that we include
include(vendor/install.cmake)
add_subdirectory(core)
add_subdirectory(app)
アイデアは、各サブディレクトリは、ライブラリー(例えばcore
)であることを基本的に、そしてapp
はそれらすべてを「集約」します。各ライブラリ(例えばcore
)は、この(core/CMakeLists.txt
)のように構築されています(!ヘッダのみのライブラリです)私は依存関係をリンクする方法
project(foo-core VERSION 0.1 LANGUAGES CXX)
add_library(foo-core
src/foobar/foobar.cc
src/foobaz/baz.cc)
target_include_directories(foo-core PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
PRIVATE src)
target_link_libraries(foo-core websocketpp spdlog) # <- see here, using spdlog & websocketpp
# 'make install' to the correct location
install(TARGETS foo-core EXPORT FooCoreConfig
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin)
install(DIRECTORY include/ DESTINATION include)
install(EXPORT FooCoreConfig DESTINATION share/FooCore/cmake)
export(TARGETS foo-core FILE FooCoreConfig.cmake)
は注意してください。これは私が(vendor/install.cmake
)それらを取得する方法である:
# spdlog
if((NOT SPDLOG_INCLUDE_DIR) OR (NOT EXISTS ${SPDLOG_INCLUDE_DIR}))
message("Unable to find spdlog, cloning...")
execute_process(COMMAND git submodule update --init -- vendor/spdlog
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
set(SPDLOG_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/vendor/spdlog/include/
CACHE PATH "spdlog include directory")
install(DIRECTORY ${SPDLOG_INCLUDE_DIR}/spdlog DESTINATION include)
# Setup a target
add_library(spdlog INTERFACE)
target_include_directories(spdlog INTERFACE
$<BUILD_INTERFACE:${SPDLOG_INCLUDE_DIR}>
$<INSTALL_INTERFACE:include>)
install(TARGETS spdlog EXPORT spdlog DESTINATION include)
endif()
# websocketpp
if((NOT WEBSOCKETPP_INCLUDE_DIR) OR (NOT EXISTS ${WEBSOCKETPP_INCLUDE_DIR}))
message("Unable to find websocketpp, cloning...")
execute_process(COMMAND git submodule update --init -- vendor/websocketpp
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
set(WEBSOCKETPP_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/vendor/websocketpp/
CACHE PATH "websocketpp include directory")
install(DIRECTORY ${WEBSOCKETPP_INCLUDE_DIR}/websocketpp DESTINATION include)
# Setup a target
add_library(websocketpp INTERFACE)
target_include_directories(websocketpp INTERFACE
$<BUILD_INTERFACE:${WEBSOCKETPP_INCLUDE_DIR}>
$<INSTALL_INTERFACE:include>)
install(TARGETS websocketpp EXPORT websocketpp DESTINATION include)
endif()
# nlohmann/json
if((NOT NLOHMANN_JSON_INCLUDE_DIR) OR (NOT EXISTS ${NLOHMANN_JSON_INCLUDE_DIR}))
message("Unable to find nlohmann/json, cloning...")
execute_process(COMMAND git submodule update --init -- vendor/nlohmann_json
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
set(NLOHMANN_JSON_INCLUDE_DIR
${CMAKE_CURRENT_SOURCE_DIR}/vendor/nlohmann_json/src/
CACHE PATH "nlohmann/json include directory")
install(FILES ${NLOHMANN_JSON_INCLUDE_DIR}/json.hpp DESTINATION include)
# Setup a target
add_library(nlohmann_json INTERFACE)
target_include_directories(nlohmann_json INTERFACE
$<BUILD_INTERFACE:${NLOHMANN_JSON_INCLUDE_DIR}>
$<INSTALL_INTERFACE:include>)
install(TARGETS nlohmann_json EXPORT nlohmann_json DESTINATION include)
endif()
これまでのところは良い:あなたは依存関係がありがたいそれが簡単にそれらを管理することができますgitのサブモジュールとしてフェッチされ見ることができます。例えばヘッダを含む
CMake Error: install(EXPORT FooCoreConfig ...) includes target foo-core which requires target websocketpp that is not in the export set.
CMake Error: install(EXPORT FooCoreConfig ...) includes target foo-core which requires target spdlog that is not in the export set.
:私はmkdir build && cd build && cmake ../src
と私のプロジェクトをコンパイルするときしかし、私は次のエラーを持っています#include <spdlog/spdlog.h>
または#include <nlohmann/json.hpp>
は、ヘッダーが見つからないというエラーを生成します。
私はCMakeにはあまり慣れていないと言いますが、私はこれをデバッグする過去2日間を過ごしました。それは本当に単純なものかもしれませんが、私はそれを達成する方法を理解することはできません。実際には、私は、私が望むようにライブラリを使用するためのコンパイラフラグとして渡しますが、CMakeの抽象化は私を混乱させるようです。なぜ誰かがこれがうまくいかないとうまくいけば、私のプロジェクトにこれらの図書館を含める正しい方法は何かを説明することができれば非常にうれしいです。前もって感謝します!
私はwebsocketpp'ライブラリのために同じメッセージを出しました: "CMake Error in core/CMakeLists.txt: ターゲットfoo-coreで呼び出され、target websocketppが必要です複数の別々の呼び出しでAPPENDオプションを使用する を検討してください。 "奇妙なことに、ファイルは 'build/CMakeFiles/Export/share/websocketpp/cmake/websocketpp.cmake'の下にあるようですが、なぜそれが見つからないのでしょうか? – arnaudoff
@arnaudoffファイルの名前から来る可能性があり、指定されたパターンに従っていなければなりません。私は自分の答えを編集し、修正された名前 'websocketpp-config'で試してください。 – wasthishelpful
それも試してみました。 – arnaudoff