45

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

एटीएम यह FindXXX.cmake संकुल के रूप में हासिल करना काफी मुश्किल लगता है, या अधिक सटीक रूप से find_library आदेश हमेशा गतिशील पुस्तकालयों को चुनता है जब भी स्थिर और गतिशील दोनों उपलब्ध होते हैं।

इस कार्यक्षमता को कार्यान्वित करने के तरीकों पर युक्तियाँ - अधिमानतः एक सुरुचिपूर्ण तरीके से - बहुत स्वागत है!

+0

काफी डुप्ली नहीं: http://stackoverflow.com/questions/2113231/making-cmake-choose-static -लिंकेज-जब संभव हो, जो जीसीसी-विशिष्ट है। –

+0

वास्तव में न केवल यह कि जीसीसी विशिष्ट है, यह भी एक असुविधाजनक समाधान है। दूसरे प्रश्न पर मेरी टिप्पणी देखें। – pszilard

+0

@pszilard क्या आपको अंततः समाधान मिला है? मैं जी ++ के साथ ऐसा करने की कोशिश कर रहा हूं। – augustin

उत्तर

14

एक अच्छी तरह से बनाई गई FindXXX.cmake फ़ाइल में इसके लिए कुछ शामिल होगा। यदि आप FindBoost.cmake में देखते हैं, तो आप यह नियंत्रित करने के लिए Boost_USE_STATIC_LIBS चर सेट कर सकते हैं कि यह स्थिर या साझा पुस्तकालयों को पाता है या नहीं। दुर्भाग्य से, अधिकांश पैकेज इस पर लागू नहीं होते हैं।

यदि कोई मॉड्यूल find_library कमांड (अधिकांश करते हैं) का उपयोग करता है, तो आप CMAKE_FIND_LIBRARY_SUFFIXES चर के माध्यम से सीएमके के व्यवहार को बदल सकते हैं। यहाँ FindBoost.cmake से प्रासंगिक CMake कोड इस का उपयोग करने के तरीके:

IF(WIN32) 
    SET(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) 
ELSE(WIN32) 
    SET(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) 
ENDIF(WIN32) 

आप या तो find_package कॉल करने से पहले इस डाल सकते हैं, या, बेहतर है, तो आप खुद को फाइल .cmake को संशोधित करने और वापस समुदाय के लिए योगदान कर सकते हैं।

.cmake फ़ाइलों के लिए मैं अपने प्रोजेक्ट में उपयोग करता हूं, मैं उन सभी को अपने नियंत्रण में स्रोत नियंत्रण में रखता हूं। मैंने ऐसा इसलिए किया क्योंकि मुझे पता चला कि कुछ पुस्तकालयों के लिए सही .cmake फ़ाइल असंगत थी और मेरी अपनी प्रतिलिपि रखने से मुझे संशोधन करने की अनुमति मिली और यह सुनिश्चित किया गया कि कोड की जांच करने वाले प्रत्येक व्यक्ति के पास समान बिल्ड सिस्टम फाइलें होंगी।

+0

टिप्पणी के लिए धन्यवाद, मैं वास्तव में इस दौरान निष्कर्ष पर आया हूं कि उपर्युक्त बाहरी libs के स्थिर संस्करण को प्राप्त करने के लिए उपरोक्त एकमात्र व्यवहार्य समाधान है। हालांकि, यह एक बहुत गंदा तरीका है, मैं प्रत्यय निर्दिष्ट नहीं करना चाहता हूं। दुर्भाग्यवश, सीएमके मेलिंग सूची पर चर्चाओं के आधार पर ऐसा लगता है कि विंडोज़ में काफी उलझन में लाइब्रेरी नामकरण है क्योंकि इसे ठीक से लागू करने की कोई योजना नहीं है। हालांकि, अधिकांश * एनआईक्स सिस्टम पर काम करना चाहिए। – pszilard

+0

ध्यान दें कि यदि आप * केवल * स्थिर पुस्तकालयों का पता लगाना चाहते हैं (और इस प्रकार शायद विफल होने के लिए कॉन्फ़िगरेशन, तो उपरोक्त आदेशों को स्थिर-पुस्तकालय फ़ाइल नामों को CMAKE_FIND_LIBRARY_SUFFIXES पर प्रीपेड नहीं करना चाहिए, बल्कि इसके बजाय उन चर नामों को उस चर सेट पर सेट करें। यह find_ *() सामान्य प्रत्यय – mabraham

+1

के साथ साझा पुस्तकालयों को कभी भी चुनने से फ़ंक्शंस यह भी ध्यान दें कि इससे कोई फर्क नहीं पड़ता कि FindXXXX.cmake पैकेज "लाइब्रेरी" कैसे मिलता है, यदि लाइब्रेरी एक अंतर्निहित लिंक निर्देशिका में पाई जाती है, उदाहरण के लिए सिस्टम पथ। जानबूझकर सीएमके लिंकर को उस मामले में अपने सामान्य रिज़ॉल्यूशन का उपयोग करने की अनुमति देने के लिए -lXXXX पर वापस जाता है - http://public.kitware.com/pipermail/cmake/2015-January/059702.html – mabraham

26

मैंने कुछ जांच की और हालांकि मुझे समस्या का संतोषजनक समाधान नहीं मिला, मुझे आधा समाधान मिला।

स्थिर की समस्या बनाता है 3 चीजें करने पर निर्भर करता:

  1. भवन और परियोजना के आंतरिक पुस्तकालयों को जोड़ने।

    बहुत आसान, केवल BUILD_SHARED_LIBS स्विच OFF स्विच करना है।

  2. बाहरी पुस्तकालयों के स्थिर संस्करण ढूंढना।

    वांछित फ़ाइल प्रत्यय (एसएस) (यह प्राथमिकता सूची है) रखने के लिए CMAKE_FIND_LIBRARY_SUFFIXES सेट करने का एकमात्र तरीका लगता है।

    यह समाधान काफी "गंदे" है और सीएमके की क्रॉस-प्लेटफार्म आकांक्षाओं के खिलाफ बहुत अधिक है। आईएमएचओ को सीएमके द्वारा दृश्यों के पीछे संभाला जाना चाहिए, लेकिन जहां तक ​​मुझे समझ में आया, विंडोज़ पर ".lib" भ्रम की वजह से, ऐसा लगता है कि सीएमके डेवलपर्स वर्तमान कार्यान्वयन को प्राथमिकता देते हैं।

  3. सिस्टम पुस्तकालयों के खिलाफ स्थैतिक रूप से लिंक करना। "एक लिंक लाइन ऐसा है कि स्थिर प्रणाली पुस्तकालयों उपयोग किया जाता है अंत:

CMake एक विकल्प LINK_SEARCH_END_STATIC जो प्रलेखन के आधार पर प्रदान करता है।" कोई सोचता है, यह है, समस्या हल हो गई है। हालांकि, ऐसा लगता है कि वर्तमान कार्यान्वयन कार्य तक नहीं है। यदि विकल्प चालू है, तो सीएमके एक तर्क सूची के साथ एक निहित लिंकर कॉल उत्पन्न करता है जो समाप्त होता है -Wl,-Bstatic समेत लिंकर को पास किए गए विकल्प। हालांकि, यह पर्याप्त नहीं है। केवल मेरे मामले में: /usr/bin/ld: cannot find -lgcc_s में लिंकर को स्थिर रूप से जोड़ने के लिए लिंकर को निर्देश देना। गायब क्या है, यह भी है कि हमें जीसीसी को बता रहा है कि हमें स्थिर लिंकिंग की आवश्यकता है -static तर्क जो नहीं CMake द्वारा लिंकर कॉल करने के लिए उत्पन्न होता है। मुझे लगता है कि यह एक बग है, लेकिन मैं अभी तक डेवलपर्स से एक पुष्टिकरण पाने में कामयाब रहे नहीं किया है।

अंत में, मुझे लगता है कि यह सब कर सकता है और ऐसा करना चाहिए दृश्यों के पीछे सीएमके द्वारा किया जाना चाहिए, आखिरकार यह इतना जटिल नहीं है, सिवाय इसके कि विंडोज़ पर यह असंभव है - अगर यह जटिल के रूप में गिनती है ...

+1

देखें कि आप 'BUILD_SHARED_LIBS' को बंद नहीं करना चाहिए (इसलिए यह * साझा पुस्तकालयों का निर्माण नहीं करेगा)? – Nooble

+0

हाहा, लगभग पांच वर्षों में आप उस गलती को नोट करने वाले पहले व्यक्ति हैं। धन्यवाद। – pszilard