2013-10-13 5 views
11

मैं एक प्रोजेक्ट में FindProtobuf मॉड्यूल का उपयोग कर रहा हूं जहां प्रोटोकॉल बफर फ़ाइलें उप-निर्देशिका में हैं। मैं सीपीपी फाइलें उत्पन्न करने के लिए प्रोटोकॉल का आह्वान करने के लिए उस उप-निर्देशिका में CMakeLists.txt फ़ाइल चाहता हूं। मेरे परियोजना फ़ोल्डर संरचना इस तरह है:सीएमके और FindProtobuf

cammy/CMakeLists.txt # Root CMakeLists.txt 
cammy/protofiles/test.proto # protofile 
cammy/protofiles/CMakeLists.txt 

मैं शामिल (FindProtobuf) है, find_package मंगलाचरण और Protobuf फ़ोल्डर में CMakeLists.txt फ़ाइल में PROTOBUF_GENERATE_CPP करने के लिए कॉल।

निष्पादन योग्य बिल्ड चरण रूट CMakeLists.txt फ़ाइल में है और मैं इस फ़ाइल यानी इस फ़ाइल में निष्पादन योग्य लक्ष्य उत्पन्न करता हूं।

add_executable(${EXEC} ${SRCS} ${PROTO_SRC} ${PROTO_HEADER}) 
target_link_libraries(${EXEC} ${PROTOBUF_LIBRARIES}) 

दोनों जड़ CMakeLists.txt

जब मैं cmake चलाने में परिभाषित कर रहे हैं, यह protoc नहीं चलता है उत्पन्न करने के लिए स्रोत फ़ाइलें भले ही मैं expilicitly निष्पादन जिससे एक निर्भरता बनाने के लिए उत्पन्न सूत्रों टाई।

जब मैं protakeiles फ़ोल्डर में रूट CMMELists.txt में CMakeLists.txt की सभी सामग्री को स्थानांतरित करता हूं, तो प्रोटो फ़ाइलों को संकलित किया जाता है।

क्या कोई इस से मेरी सहायता कर सकता है? मैं प्रोटोकॉल फ़ोल्डर में बनाई गई CMakeLists.txt फ़ाइल में जाने के लिए सभी प्रोटोकॉल बफर बिल्डिंग सामान चाहता हूं।

मैंने यह भी देखा कि आंतरिक CMakeLists.txt (जैसे PROTO_SRC) में उत्पन्न चर को आंतरिक फ़ाइल में मुद्रित किया जाता है (यानी मुझे सही जेनरेट सीपीपी फ़ाइल नाम मिलता है) लेकिन जब मैं रूट फ़ाइल में एक ही चर मुद्रित करता हूं। । यह खाली है। इसके लगभग जैसे कि मुझे "निर्यात" करने की आवश्यकता है (अगर cmake में कोई रास्ता था) रूट फ़ोल्डर में चर।

किसी भी मदद की बहुत सराहना की जाएगी।

धन्यवाद कार्तिक

उत्तर

19

मुझे लगता है कि वास्तव में FindProtobuf इस तरह से इस्तेमाल किया जा करने के लिए नहीं है। अपने डॉक्स से:

नोट: PROTOBUF_GENERATE_CPP मैक्रो & add_executable() या add_library() कॉल ठीक से केवल एक ही निर्देशिका के भीतर काम करते हैं।

आप उप-निर्देशिका के PROTOBUF_GENERATE_CPP मैक्रो का उपयोग करने की कोशिश कर रहे हैं, और यद्यपि CMake डॉक्स वास्तव में यह स्पष्ट नहीं करते हैं, एक उपनिर्देशिका चर के लिए एक नया गुंजाइश परिचय देता है। इसका मतलब यह है कि उपदिर क्षेत्र में सेट या संशोधित कोई भी चर माता-पिता के दायरे में समान नामित चर को प्रभावित नहीं करता है। इसलिए PROTO_SRC आपके प्रोटोफाइल डीआईआर में उपलब्ध होने का कारण है, लेकिन माता-पिता में नहीं।

रास्ता चर ऊपर एक गुंजाइश पारित करने के लिए set(... PARENT_SCOPE) उपयोग करने के लिए है, तो protofiles में है/CMakeLists.txt तुम कर सकते हो:

PROTOBUF_GENERATE_CPP(PROTO_SRC PROTO_HEADER test.proto) 

set(PROTOBUF_INCLUDE_DIRS ${PROTOBUF_INCLUDE_DIRS} PARENT_SCOPE) 
set(PROTOBUF_LIBRARIES ${PROTOBUF_LIBRARIES} PARENT_SCOPE) 
set(PROTO_SRC ${PROTO_SRC} PARENT_SCOPE) 
set(PROTO_HEADER ${PROTO_HEADER} PARENT_SCOPE) 

बहरहाल, यह अभी भी हम सभी तरह से नहीं मिलता है!

सीएमके वास्तव में .pb.h और .pb.cc फ़ाइलों को उत्पन्न करने के लिए प्रोटोकॉल कंपाइलर का आह्वान नहीं करता है - यह करने के लिए add_custom_command का उपयोग करता है। कस्टम कमांड .pb.h और .pb निर्दिष्ट करता है।आउटपुट के रूप में सीसी फाइलें, और कस्टम कमांड केवल तभी लागू किया जाता है (यानी प्रोटोक निष्पादित) यदि इन फ़ाइलों पर निर्भर एक अगला लक्ष्य बनाया गया है।

तो कॉन्फ़िगर समय (जब सीएमके निष्पादित करता है) पर ये फ़ाइलें मौजूद नहीं हैं। यह एक समस्या है यदि आप उन्हें add_library या add_executable कमांड के स्रोत के रूप में जोड़ने का प्रयास करते हैं - सीएमके को यह बताया जाना चाहिए कि यह फ़ाइलें तब चलती हैं जब यह चलती है, लेकिन बिल्ड समय पर मौजूद होगी।

ऐसा करने का तरीका GENERATED संपत्ति को TRUE पर इन फ़ाइलों के लिए सेट करना है। PROTOBUF_GENERATE_CPP मैक्रो स्वचालित रूप से करता है, लेकिन चर के साथ, संपत्ति मूल दायरे में नहीं आती है।

set_source_files_properties(${PROTO_SRC} ${PROTO_HEADER} PROPERTIES 
          GENERATED TRUE) 
एक अलग निर्देशिका में इसी add_library/ add_executable आदेशों का

आप देख सकते हैं, का उपयोग कर PROTOBUF_GENERATE_CPP थोड़ा कमजोर है: तो अपने उच्च-स्तरीय CMakeLists.txt में, आप भी जोड़ने की जरूरत है। यदि आप कर सकते हैं तो इसे करने से बचें, आपको शायद चाहिए।

+0

चीजों को साफ़ करने के लिए धन्यवाद। इसे समेटने के लिए, क्या मैं यह कहने में सही हूं कि नेस्टेड प्रोटो संकलन क्यों काम नहीं करता है क्योंकि कारण उत्पन्न किए गए चर रुकने के दायरे में नहीं हैं? साथ ही, क्या जेनरेटेड फ्लैग को चिह्नित करना संभव है जब हम रूट फ़ाइल में इसे करने के बजाय स्थानीय लोगों से पैरेंट स्कोप चर सेट करते हैं? आखिरकार, एक वैकल्पिक दृष्टिकोण प्रोटोबफ सामान को पुस्तकालय के रूप में बनाने के लिए होगा और इसे रूट निष्पादन योग्य से लिंक करें? –

+0

@ कार्टिकएयर निश्चित नहीं है कि "रुक के दायरे में नहीं" का अर्थ है, लेकिन यदि यह "शीर्ष-स्तर के CMakeLists.txt के दायरे में नहीं है", तो हाँ। क्यू 2 के लिए, नहीं - जहां तक ​​मुझे पता है कि मूल दायरे में परिभाषित फाइलों पर गुण सेट करने का कोई तरीका नहीं है। क्यू 3 के लिए, हाँ - मेरा मानना ​​है कि यह एक अच्छा दृष्टिकोण होगा। – Fraser

+0

@Fraser आपके उत्तर के लिए धन्यवाद, मेरे पास एक समान सवाल है, मैं प्रोजेक्ट को एडजस्ट करता हूं और अभी भी काम नहीं करता, क्या यह संभव है कि मुझे और सुझाव दें? रेफरी: http://stackoverflow.com/questions/29720410/no-member-found-when-use-cmake-construct-proto, नमूना प्रोजेक्ट: https://github.com/yuikns/cmake-proto –