2015-12-23 3 views
9

मैं सीएमके के शुरुआती उपयोगकर्ता हूं। मेरे पर्यावरण में कई परियोजनाएं हैं जैसे:सीएमके कई परियोजनाओं के लिए एक निर्माण निर्देशिका

project 
    |------ CMakeLists.txt (The main Cmake) 
    |------ ProjectA 
    |   |----- .cpp files 
    |   |----- .hpp files 
    |   |----- CMakeList.txt 
    |------ ProjectB 
    |   |----- .cpp files 
    |   |----- .hpp files 
    |   |----- CMakeList.txt 
    | 
    |------ build 
    |   |----- CMakeStuff 
    |------ bin 
    |  |---- executables 
    |------ lib 
    |  |---- libwhatever.a 
    |------ db 
      |---- Database stuff 

मैं ऊपर दिखाए गए अनुसार प्रत्येक परियोजना के लिए एक एकल निर्माण निर्देशिका का उपयोग करना चाहता हूं। पसंदीदा रूप से इसे build/projectA, build/ProjectB जैसे कई उपप्रोजेक्ट्स में विभाजित किया जा सकता है ताकि अगर मुझे एक एकल प्रोजेक्ट का पुनर्निर्माण करने की आवश्यकता हो तो मैं पूरी build/Project फ़ाइल को हटा सकता हूं और सब खत्म हो गया है और एक नया Cmake इसे फिर से बनाएगा।

मुझे सीएमकेई को कॉन्फ़िगर करने में कठिनाइयां हो रही हैं।

प्रोजेक्ट फ़ोल्डर पर मेरे मूल CMakeList.txt:

cmake_minimum_required(VERSION 3.2.2.) 
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/../lib) 
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/../lib) 
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/../bin) 

project(projectA) 
set(CMAKE_BUILD_TYPE Debug) 

file(GLOB SOURCES "*.cpp") 

add_library(commonmessage SHARED ${SOURCES}) 

install(TARGETS commonmessage DESTINATION ../lib) 

मेरे प्रश्न हैं:

ए) अगर मैं एक भी निर्माण निर्देशिका पर cmake चलाने क्या होगा - कि संभव है और क्या होगा सही सीएमकेई कॉन्फ़िगरेशन बनें?

बी) ProjectA के लिए मेरा संकलन ProjectB से फ़ाइलों को शामिल करने की आवश्यकता है - मैं प्रत्येक व्यक्तिगत परियोजना के लिए CMakeLists.txt में इसे कैसे सेट कर सकता हूं?

सी) अंत में मुझे सभी को बनाने के लिए एक ही मेकफ़ाइल की आवश्यकता है, साथ ही प्रत्येक प्रोजेक्ट को व्यक्तिगत रूप से बनाने का विकल्प भी है। क्या यह एक एकल निर्माण निर्देशिका के साथ संभव होगा?

मदद के लिए धन्यवाद।

उत्तर

16

सबसे पहले, ऐसा लगता है कि आपके द्वारा पोस्ट किए गए सीएमके कोड को शीर्ष CMakeList.txt फ़ाइल से संबंधित नहीं है, क्योंकि यह सीधे संदर्भित करता है .cpp फ़ाइलें, और "projectA"। वहाँ भी कुछ चीजें हैं जो मुहावरेदार नहीं कर रहे हैं:

cmake_minimum_required(VERSION 3.2.2.) 

क्यों यहाँ डॉट अनुगामी? सुनिश्चित नहीं है कि cmake शिकायत करेगा, लेकिन यह किसी भी तरह बेकार है।

set(CMAKE_BUILD_TYPE Debug) 

ऐसा मत करो। इसके बजाय -DCMAKE_BUILD_TYPE=Debug कमांड लाइन ध्वज का उपयोग करके सेमेक का आह्वान करें, या सीसीएमके, या जीयूआई का उपयोग करें, या CMakeCache.txt फ़ाइल को संपादित करें।

file(GLOB SOURCES "*.cpp") 

ऐसा न करें। सीएमके में स्रोत फ़ाइलों को स्पष्ट रूप से सूचीबद्ध करना अच्छा अभ्यास है, क्योंकि ग्लोबिंग सेमेक को नई जोड़े या हटाए गए फ़ाइलों को स्वचालित रूप से पहचान नहीं पाएगा। हालांकि कुछ लोग असहमत हो सकते हैं।

अब विषय के दिल के लिए, यहाँ कैसे चीजें आम तौर पर किया जाता है है:

शीर्ष CMakeLists।txt फ़ाइल:

cmake_minimum_required(VERSION 3.2.2) 
project(globalProject) 

add_subdirectory(projectA) 
add_subdirectory(projectB) 

PROJECTA CMakeLists.txt फ़ाइल (यह मानते हुए PROJECTA एक ​​निष्पादन योग्य है):

add_executable(projectA file1.cpp file2.cpp ...) 
include_directories(${CMAKE_SOURCE_DIR}/projectB) # include files from ProjectB 
target_link_libraries(projectA projectB) 

install(TARGETS projectA RUNTIME DESTINATION bin) 

ProjectB CMakeLists.txt फ़ाइल (यह मानते हुए projectB एक पुस्तकालय है):

add_library(projectB file1.cpp file2.cpp ...) 

install(TARGETS projectB 
    LIBRARY DESTINATION lib 
    ARCHIVE DESTINATION lib) 

कृपया ध्यान दें कि इस सेटअप को make install चरण को अपनी पसंद के स्थान पर बिन और lib बनाने के लिए आवश्यक है जैसा कि cmake -DCMAKE_INSTALL_PREFIX=.. के कमांड लाइन आमंत्रण में दिया गया है (मान लीजिए आईएनजी निर्माण डीआईआर से चलाया जाता है)।

इसके अलावा, यह सेटअप आपको यह चुनने देता है कि आप स्थिर या साझा पुस्तकालयों का निर्माण कर रहे हैं या नहीं: -DBUILD_SHARED_LIBS=ON। दोनों को बनाने के लिए, आपको दो अलग-अलग नाम, एक स्टेटिक, अन्य साझा किए गए दो add_library कॉल करने की आवश्यकता है।

इस काम करने के लिए आवश्यक कदम सारांश में:

$ mkdir build && cd build 
$ cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=.. -DBUILD_SHARED_LIBS=ON 
$ make 
$ make install 

आप पुनर्प्रयोग के लिए एक स्क्रिप्ट में इन आदेशों डाल सकता है।

अब, आपके सवालों का जवाब दिया जा सकता:

ए) यह संभव है और सिफारिश की है, को देखने के कोड से ऊपर, केवल एक ही निर्माण निर्देशिका आवश्यक है।

बी) PROJECTA/CMakeLists.txt के लिए कोड देखें, तो आप include_directories()

सी) कॉल करने के लिए हाँ, यह संभव है। अपनी परियोजना में प्रत्येक लक्ष्य को बनाने और लक्ष्य नाम का उपयोग कर निर्माण निर्देशिका से व्यक्तिगत रूप से बनाया जा सकता है: make projectB और make projectA

+0

महोदय, मदद के लिए धन्यवाद ... यदि मुझे लक्ष्य फ़ोल्डर में lib और bin फ़ाइलों को उत्पन्न करने की आवश्यकता है तो क्या होगा 'इंस्टॉल करने' की आवश्यकता के बिना? – Mendes

+0

जबकि 'CMAKE _ * _ OUTPUT_DIRECTORY' चर का उपयोग करके यह संभव है, मैं ऐसा करने की अनुशंसा नहीं करता, क्योंकि आपके पास कई कॉन्फ़िगरेशन (डीबग बनाम रिलीज, विभिन्न कंपाइलर इत्यादि) के साथ कई बिल्ड निर्देशिकाएं हो सकती हैं और यह हमेशा अच्छा होता है संकलन करते समय फ़ाइलों को ओवरराइट किए बिना समानांतर में उनका परीक्षण करने में सक्षम हो। आपको अपनी परियोजना की जड़ पर बिन/lib की आवश्यकता क्यों है? – SirDarius

+0

अच्छा बिंदु। 'bin' वह है जहां सभी निष्पादन योग्य स्थापित किए जाएंगे। 'पुस्तकालय' सभी पुस्तकालयों को पकड़ेंगे। – Mendes

1

ए) आप एन परियोजनाओं के लिए 1 सीएमकेलिस्ट.txt कर सकते हैं। जब आप लाइब्रेरी को परिभाषित करते हैं, तो आप इसे cmake (add_executable और target_link_libraries को देखने के लिए) में परिभाषित निष्पादन योग्य में उपयोग कर सकते हैं।

बी) target_include_directories

सी देखें) ऐसा लगता है आप cmake --target target फोन अपने cmakelists.txt फ़ाइल का लक्ष्य का केवल एक के लिए Makefile उत्पन्न करने के लिए कर सकते हैं।

संबंधित मुद्दे