2016-12-27 54 views
5

コンパイルするために3つのヘッダー専用ライブラリが必要な単純なプロジェクトがあります:websocketppspdlognlohmann/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の抽象化は私を混乱させるようです。なぜ誰かがこれがうまくいかないとうまくいけば、私のプロジェクトにこれらの図書館を含める正しい方法は何かを説明することができれば非常にうれしいです。前もって感謝します!

答えて

1

あなたが言ったのと同じように、ターゲットをエクスポートセットにインストールしませんでした。つまり、ヘッダーのみのターゲットにはinstall(EXPORT ...行がありません。たとえば、あなたのヘッダのみのライブラリwebsocketppを考慮すると、あなたが持っている必要があります。

add_library(websocketpp INTERFACE) 
target_include_directories(websocketpp INTERFACE 
    $<BUILD_INTERFACE:${WEBSOCKETPP_INCLUDE_DIR}> 
    $<INSTALL_INTERFACE:include>) 

install(TARGETS websocketpp EXPORT websocketpp-config DESTINATION include) 

# here is the missing line: 

install(EXPORT websocketpp-config DESTINATION share/websocketpp/cmake) 

同じことが他のライブラリのために行きます。

+0

私はwebsocketpp'ライブラリのために同じメッセージを出しました: "CMake Error in core/CMakeLists.txt: ターゲットfoo-coreで呼び出され、target websocketppが必要です複数の別々の呼び出しでAPPENDオプションを使用する を検討してください。 "奇妙なことに、ファイルは 'build/CMakeFiles/Export/share/websocketpp/cmake/websocketpp.cmake'の下にあるようですが、なぜそれが見つからないのでしょうか? – arnaudoff

+0

@arnaudoffファイルの名前から来る可能性があり、指定されたパターンに従っていなければなりません。私は自分の答えを編集し、修正された名前 'websocketpp-config'で試してください。 – wasthishelpful

+0

それも試してみました。 – arnaudoff

関連する問題