2016-12-27 7 views
5

के साथ हेडर-केवल निर्भरताओं को जोड़ना मेरे पास एक साधारण प्रोजेक्ट है जिसमें संकलन के लिए तीन शीर्षलेख-केवल पुस्तकालयों की आवश्यकता होती है: websocketpp, spdlog और nlohmann/jsonसीएमके

परियोजना संरचना इस तरह दिखता है:

└── 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 submodules, जो शुक्र है यह आसान उन्हें प्रबंधित करने के लिए बनाता है के रूप में लाई जाती हैं, देख सकते हैं।

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 के साथ इतना सहज नहीं हूँ और मैं पिछले दो दिनों इस डिबगिंग खर्च किए हैं। यह कुछ सचमुच सरल हो सकता है, लेकिन मैं यह नहीं समझ सकता कि इसे कैसे प्राप्त किया जाए। हकीकत में, मैं बस पुस्तकालयों का उपयोग करने के लिए एक कंपाइलर ध्वज के रूप में पास करता हूं, लेकिन सीएमके अबाउट्रेशन मुझे भ्रमित करने लगता है। अगर कोई यह समझा सकता है कि यह क्यों काम नहीं करता है तो मुझे बहुत खुशी होगी और उम्मीद है कि, मेरी परियोजना में इन पुस्तकालयों को शामिल करने का सही तरीका क्या है। अग्रिम में धन्यवाद!

उत्तर

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' लाइब्रेरी के लिए एक ही संदेश मिलता है: "कोर/सीएमकेलिस्ट में सीएमके त्रुटि। Txt: निर्यात फ़ू-कोर के साथ निर्यात किया जाता है जिसके लिए लक्ष्य websocketpp की आवश्यकता होती है जो कि नहीं है निर्यात सेट "और" यदि इस कॉल में आवश्यक लक्ष्य को संदर्भित करना आसान नहीं है, तो अलग-अलग कॉल के साथ APPEND विकल्प का उपयोग करके पर विचार करें। " यह अजीब है, फ़ाइल 'निर्माण/सीएमकेफ़ाइल/निर्यात/शेयर/websocketpp/cmake/websocketpp.cmake' के अंतर्गत प्रतीत होती है, इसे क्यों नहीं मिलेगा? – arnaudoff

+0

@arnaudoff जो फ़ाइल के नाम से आ सकता है, जिसे किसी दिए गए पैटर्न का पालन करना चाहिए। मैंने अपना जवाब संपादित किया, संशोधित नाम 'websocketpp-config' – wasthishelpful

+0

के साथ प्रयास करने का प्रयास किया, यह भी कोशिश की, – arnaudoff